Merge pull request #12 from jl777/FSM

Fsm
This commit is contained in:
blackjok3rtt
2019-01-23 21:20:26 +08:00
committed by GitHub
46 changed files with 3371 additions and 1858 deletions

View File

@@ -13,12 +13,13 @@ export BITCOIND=${REAL_BITCOIND}
testScripts=( testScripts=(
'cryptoconditions_faucet.py' 'cryptoconditions_faucet.py'
'cryptoconditions_channels.py'
'cryptoconditions_dice.py' 'cryptoconditions_dice.py'
'cryptoconditions_oracles.py' 'cryptoconditions_oracles.py'
'cryptoconditions_rewards.py' 'cryptoconditions_rewards.py'
'cryptoconditions_token.py' 'cryptoconditions_token.py'
#'cryptoconditions_gateways.py' #'cryptoconditions_gateways.py'
# TODO: cant reconnect nodes back in channels test because of crash (seems regtest only specific)
'cryptoconditions_channels.py'
); );
extArg="-extended" extArg="-extended"

View File

@@ -4,6 +4,7 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php. # file COPYING or http://www.opensource.org/licenses/mit-license.php.
import time
from test_framework.test_framework import CryptoconditionsTestFramework from test_framework.test_framework import CryptoconditionsTestFramework
from test_framework.authproxy import JSONRPCException from test_framework.authproxy import JSONRPCException
from test_framework.util import assert_equal, assert_greater_than, \ from test_framework.util import assert_equal, assert_greater_than, \
@@ -71,6 +72,58 @@ class CryptoconditionsChannelsTest(CryptoconditionsTestFramework):
result = rpc.channelsinfo(channel_txid) result = rpc.channelsinfo(channel_txid)
assert_equal(result["Transactions"][1]["Payment"], payment_tx_id) assert_equal(result["Transactions"][1]["Payment"], payment_tx_id)
# number of payments should be equal 1 (one denomination used)
result = rpc.channelsinfo(channel_txid)["Transactions"][1]["Number of payments"]
assert_equal(result, 1)
# payments left param should reduce 1 and be equal 9 now ( 10 - 1 = 9 )
result = rpc.channelsinfo(channel_txid)["Transactions"][1]["Payments left"]
assert_equal(result, 9)
# lets try payment with x2 amount to ensure that counters works correct
result = rpc.channelspayment(channel_txid, "200000")
assert_success(result)
payment_tx_id = self.send_and_mine(result["hex"], rpc)
assert payment_tx_id, "got txid"
result = rpc.channelsinfo(channel_txid)
assert_equal(result["Transactions"][2]["Payment"], payment_tx_id)
result = rpc.channelsinfo(channel_txid)["Transactions"][2]["Number of payments"]
assert_equal(result, 2)
result = rpc.channelsinfo(channel_txid)["Transactions"][2]["Payments left"]
assert_equal(result, 7)
# check if payment value really transferred
raw_transaction = rpc.getrawtransaction(payment_tx_id, 1)
result = raw_transaction["vout"][3]["valueSat"]
assert_equal(result, 200000)
result = rpc1.validateaddress(raw_transaction["vout"][3]["scriptPubKey"]["addresses"][0])["ismine"]
assert_equal(result, True)
# have to check that second node have coins to cover txfee at least
rpc.sendtoaddress(rpc1.getnewaddress(), 1)
rpc.sendtoaddress(rpc1.getnewaddress(), 1)
rpc.generate(2)
self.sync_all()
result = rpc1.getbalance()
assert_greater_than(result, 0.1)
# trying to initiate channels payment from node B without any secret
# TODO: have to add RPC validation
payment_hex = rpc1.channelspayment(channel_txid, "100000")
try:
result = rpc1.sendrawtransaction(payment_hex["hex"])
except Exception as e:
pass
# trying to initiate channels payment from node B with secret from previous payment
result = rpc1.channelspayment(channel_txid, "100000", rpc1.channelsinfo(channel_txid)["Transactions"][1]["Secret"])
#result = rpc1.sendrawtransaction(payment_hex["hex"])
assert_error(result)
# executing channel close # executing channel close
result = rpc.channelsclose(channel_txid) result = rpc.channelsclose(channel_txid)
assert_success(result) assert_success(result)
@@ -82,7 +135,7 @@ class CryptoconditionsChannelsTest(CryptoconditionsTestFramework):
# now in channelinfo closed flag should appear # now in channelinfo closed flag should appear
result = rpc.channelsinfo(channel_txid) result = rpc.channelsinfo(channel_txid)
assert_equal(result["Transactions"][2]["Close"], channel_close_txid) assert_equal(result["Transactions"][3]["Close"], channel_close_txid)
# executing channel refund # executing channel refund
result = rpc.channelsrefund(channel_txid, channel_close_txid) result = rpc.channelsrefund(channel_txid, channel_close_txid)
@@ -90,6 +143,92 @@ class CryptoconditionsChannelsTest(CryptoconditionsTestFramework):
refund_txid = self.send_and_mine(result["hex"], rpc) refund_txid = self.send_and_mine(result["hex"], rpc)
assert refund_txid, "got txid" assert refund_txid, "got txid"
# TODO: check if it refunded to opener address
raw_transaction = rpc.getrawtransaction(refund_txid, 1)
result = raw_transaction["vout"][2]["valueSat"]
assert_equal(result, 700000)
result = rpc.validateaddress(raw_transaction["vout"][2]["scriptPubKey"]["addresses"][0])["ismine"]
assert_equal(result, True)
# creating and draining channel (10 payment by 100000 satoshies in total to fit full capacity)
new_channel_hex1 = rpc.channelsopen(self.pubkey1, "10", "100000")
assert_success(new_channel_hex1)
channel1_txid = self.send_and_mine(new_channel_hex1["hex"], rpc)
assert channel1_txid, "got channel txid"
# need to have 2+ confirmations in the test mode
rpc.generate(2)
self.sync_all()
for i in range(10):
result = rpc.channelspayment(channel1_txid, "100000")
assert_success(result)
payment_tx_id = self.send_and_mine(result["hex"], rpc)
assert payment_tx_id, "got txid"
# last payment should indicate that 0 payments left
result = rpc.channelsinfo(channel1_txid)["Transactions"][10]["Payments left"]
assert_equal(result, 0)
# no more payments possible
result = rpc.channelspayment(channel1_txid, "100000")
assert_error(result)
# creating new channel to test the case when node B initiate payment when node A revealed secret in offline
# 10 payments, 100000 sat denomination channel opening with second node pubkey
new_channel_hex2 = rpc.channelsopen(self.pubkey1, "10", "100000")
assert_success(new_channel_hex)
channel2_txid = self.send_and_mine(new_channel_hex2["hex"], rpc)
assert channel2_txid, "got channel txid"
rpc.generate(2)
self.sync_all()
# disconnecting first node from network
rpc.setban("127.0.0.0/24","add")
assert_equal(rpc.getinfo()["connections"], 0)
assert_equal(rpc1.getinfo()["connections"], 0)
rpc1.generate(1)
# sending one payment to mempool to reveal the secret but not mine it
payment_hex = rpc.channelspayment(channel2_txid, "100000")
result = rpc.sendrawtransaction(payment_hex["hex"])
assert result, "got payment txid"
secret = rpc.channelsinfo(channel2_txid)["Transactions"][1]["Secret"]
assert secret, "Secret revealed"
# secret shouldn't be available for node B
secret_not_revealed = None
try:
rpc1.channelsinfo(channel2_txid)["Transactions"][1]["Secret"]
except Exception:
secret_not_revealed = True
assert_equal(secret_not_revealed, True)
# trying to initiate payment from second node with revealed secret
assert_equal(rpc1.getinfo()["connections"], 0)
dc_payment_hex = rpc1.channelspayment(channel2_txid, "100000", secret)
assert_success(dc_payment_hex)
result = rpc1.sendrawtransaction(dc_payment_hex["hex"])
assert result, "got channelspayment transaction id"
# TODO: it crash first node after block generating on mempools merging
# # restoring connection between nodes
# rpc.setban("127.0.0.0/24","remove")
# #rpc.generate(1)
# #rpc1.generate(1)
# sync_blocks(self.nodes)
# rpc.generate(1)
# sync_blocks(self.nodes)
# sync_mempools(self.nodes)
# assert_equal(rpc.getinfo()["connections"], 1)
# assert_equal(rpc1.getinfo()["connections"], 1)
def run_test(self): def run_test(self):
print("Mining blocks...") print("Mining blocks...")
rpc = self.nodes[0] rpc = self.nodes[0]

View File

@@ -15,21 +15,35 @@ from cryptoconditions import assert_success, assert_error, generate_random_strin
class CryptoconditionsTokenTest(CryptoconditionsTestFramework): class CryptoconditionsTokenTest(CryptoconditionsTestFramework):
def run_token_tests(self): def run_token_tests(self):
rpc = self.nodes[0]
rpc = self.nodes[0]
rpc1 = self.nodes[1]
result = rpc.tokenaddress() result = rpc.tokenaddress()
assert_success(result) assert_success(result)
for x in ['AssetsCCaddress', 'myCCaddress', 'Assetsmarker', 'myaddress']: for x in ['TokensCCaddress', 'myCCaddress', 'Tokensmarker', 'myaddress']:
assert_equal(result[x][0], 'R') assert_equal(result[x][0], 'R')
result = rpc.tokenaddress(self.pubkey) result = rpc.tokenaddress(self.pubkey)
assert_success(result) assert_success(result)
for x in ['TokensCCaddress', 'myCCaddress', 'Tokensmarker', 'myaddress', 'CCaddress']:
assert_equal(result[x][0], 'R')
result = rpc.assetsaddress()
assert_success(result)
for x in ['AssetsCCaddress', 'myCCaddress', 'Assetsmarker', 'myaddress']:
assert_equal(result[x][0], 'R')
result = rpc.assetsaddress(self.pubkey)
assert_success(result)
for x in ['AssetsCCaddress', 'myCCaddress', 'Assetsmarker', 'myaddress', 'CCaddress']: for x in ['AssetsCCaddress', 'myCCaddress', 'Assetsmarker', 'myaddress', 'CCaddress']:
assert_equal(result[x][0], 'R') assert_equal(result[x][0], 'R')
# there are no tokens created yet # there are no tokens created yet
result = rpc.tokenlist() result = rpc.tokenlist()
assert_equal(result, []) assert_equal(result, [])
# trying to create token with negaive supply # trying to create token with negative supply
result = rpc.tokencreate("NUKE", "-1987420", "no bueno supply") result = rpc.tokencreate("NUKE", "-1987420", "no bueno supply")
assert_error(result) assert_error(result)
@@ -50,12 +64,9 @@ class CryptoconditionsTokenTest(CryptoconditionsTestFramework):
result = rpc.tokenorders() result = rpc.tokenorders()
assert_equal(result, []) assert_equal(result, [])
# getting token balance for pubkey # getting token balance for non existing tokenid
result = rpc.tokenbalance(self.pubkey) result = rpc.tokenbalance(self.pubkey)
assert_success(result) assert_error(result)
assert_equal(result['balance'], 0)
assert_equal(result['CCaddress'], 'RCRsm3VBXz8kKTsYaXKpy7pSEzrtNNQGJC')
assert_equal(result['tokenid'], self.pubkey)
# get token balance for token with pubkey # get token balance for token with pubkey
result = rpc.tokenbalance(tokenid, self.pubkey) result = rpc.tokenbalance(tokenid, self.pubkey)
@@ -131,11 +142,25 @@ class CryptoconditionsTokenTest(CryptoconditionsTestFramework):
# checking ask cancellation # checking ask cancellation
testorder = rpc.tokenask("100", tokenid, "7.77") testorder = rpc.tokenask("100", tokenid, "7.77")
testorderid = self.send_and_mine(testorder['hex'], rpc) testorderid = self.send_and_mine(testorder['hex'], rpc)
# from other node (ensuring that second node have enough balance to cover txfee
# to get the actual error - not "not enough balance" one
rpc.sendtoaddress(rpc1.getnewaddress(), 1)
rpc.sendtoaddress(rpc1.getnewaddress(), 1)
rpc.generate(2)
self.sync_all()
result = rpc1.getbalance()
assert_greater_than(result, 0.1)
result = rpc1.tokencancelask(tokenid, testorderid)
assert_error(result)
# from valid node
cancel = rpc.tokencancelask(tokenid, testorderid) cancel = rpc.tokencancelask(tokenid, testorderid)
self.send_and_mine(cancel["hex"], rpc) self.send_and_mine(cancel["hex"], rpc)
result = rpc.tokenorders() result = rpc.tokenorders()
assert_equal(result, []) assert_equal(result, [])
# invalid numtokens bid # invalid numtokens bid
result = rpc.tokenbid("-1", tokenid, "1") result = rpc.tokenbid("-1", tokenid, "1")
assert_error(result) assert_error(result)
@@ -184,6 +209,15 @@ class CryptoconditionsTokenTest(CryptoconditionsTestFramework):
# checking bid cancellation # checking bid cancellation
testorder = rpc.tokenbid("100", tokenid, "7.77") testorder = rpc.tokenbid("100", tokenid, "7.77")
testorderid = self.send_and_mine(testorder['hex'], rpc) testorderid = self.send_and_mine(testorder['hex'], rpc)
# from other node
result = rpc1.getbalance()
assert_greater_than(result, 0.1)
result = rpc1.tokencancelbid(tokenid, testorderid)
assert_error(result)
# from valid node
cancel = rpc.tokencancelbid(tokenid, testorderid) cancel = rpc.tokencancelbid(tokenid, testorderid)
self.send_and_mine(cancel["hex"], rpc) self.send_and_mine(cancel["hex"], rpc)
result = rpc.tokenorders() result = rpc.tokenorders()
@@ -220,5 +254,6 @@ class CryptoconditionsTokenTest(CryptoconditionsTestFramework):
rpc1.importprivkey(self.privkey1) rpc1.importprivkey(self.privkey1)
self.run_token_tests() self.run_token_tests()
if __name__ == '__main__': if __name__ == '__main__':
CryptoconditionsTokenTest().main() CryptoconditionsTokenTest().main()

View File

@@ -571,7 +571,8 @@ komodod_LDADD += \
$(LIBBITCOIN_CRYPTO) \ $(LIBBITCOIN_CRYPTO) \
$(LIBVERUS_CRYPTO) \ $(LIBVERUS_CRYPTO) \
$(LIBVERUS_PORTABLE_CRYPTO) \ $(LIBVERUS_PORTABLE_CRYPTO) \
$(LIBZCASH_LIBS) $(LIBZCASH_LIBS) \
cclib.so
if ENABLE_PROTON if ENABLE_PROTON
komodod_LDADD += $(LIBBITCOIN_PROTON) $(PROTON_LIBS) komodod_LDADD += $(LIBBITCOIN_PROTON) $(PROTON_LIBS)

View File

@@ -94,7 +94,8 @@ void WaitForShutdown(boost::thread_group* threadGroup)
// //
// Start // Start
// //
extern int32_t IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,ASSETCHAIN_INIT; extern int32_t IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY;
extern uint32_t ASSETCHAIN_INIT;
extern std::string NOTARY_PUBKEY; extern std::string NOTARY_PUBKEY;
int32_t komodo_is_issuer(); int32_t komodo_is_issuer();
void komodo_passport_iteration(); void komodo_passport_iteration();

View File

@@ -212,7 +212,7 @@ bool FaucetExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction
bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx) bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs) int64_t AddFaucetInputs(struct CCcontract_infoCC_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
std::string FaucetGet(uint64_t txfee) std::string FaucetGet(uint64_t txfee)

View File

@@ -27,10 +27,10 @@ bool HeirValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,
class CoinHelper; class CoinHelper;
class TokenHelper; class TokenHelper;
UniValue HeirFundCoinCaller(uint64_t txfee, int64_t funds, std::string heirName, CPubKey heirPubkey, int64_t inactivityTimeSec, uint256 tokenid); UniValue HeirFundCoinCaller(int64_t txfee, int64_t satoshis, std::string heirName, CPubKey heirPubkey, int64_t inactivityTimeSec, uint256 tokenid);
UniValue HeirFundTokenCaller(uint64_t txfee, int64_t funds, std::string heirName, CPubKey heirPubkey, int64_t inactivityTimeSec, uint256 tokenid); UniValue HeirFundTokenCaller(int64_t txfee, int64_t satoshis, std::string heirName, CPubKey heirPubkey, int64_t inactivityTimeSec, uint256 tokenid);
UniValue HeirClaimCaller(uint256 fundingtxid, uint64_t txfee, int64_t amount); UniValue HeirClaimCaller(uint256 fundingtxid, int64_t txfee, std::string amount);
UniValue HeirAddCaller(uint256 fundingtxid, uint64_t txfee, int64_t amount); UniValue HeirAddCaller(uint256 fundingtxid, int64_t txfee, std::string amount);
UniValue HeirInfo(uint256 fundingtxid); UniValue HeirInfo(uint256 fundingtxid);
UniValue HeirList(); UniValue HeirList();

View File

@@ -23,15 +23,18 @@
#define MARMARA_GROUPSIZE 60 #define MARMARA_GROUPSIZE 60
#define MARMARA_MINLOCK (1440 * 3 * 30) #define MARMARA_MINLOCK (1440 * 3 * 30)
#define MARMARA_MAXLOCK (1440 * 24 * 30) #define MARMARA_MAXLOCK (1440 * 24 * 30)
#define MARMARA_VINS 16
extern uint8_t ASSETCHAINS_MARMARA;
uint64_t komodo_block_prg(uint32_t nHeight); uint64_t komodo_block_prg(uint32_t nHeight);
int32_t MarmaraGetcreatetxid(uint256 &createtxid,uint256 txid); int32_t MarmaraGetcreatetxid(uint256 &createtxid,uint256 txid);
int32_t MarmaraGetbatontxid(std::vector<uint256> &creditloop,uint256 &batontxid,uint256 txid); int32_t MarmaraGetbatontxid(std::vector<uint256> &creditloop,uint256 &batontxid,uint256 txid);
UniValue MarmaraCreditloop(uint256 txid); UniValue MarmaraCreditloop(uint256 txid);
UniValue MarmaraSettlement(uint64_t txfee,uint256 batontxid); UniValue MarmaraSettlement(uint64_t txfee,uint256 batontxid);
UniValue MarmaraLock(uint64_t txfee,int64_t amount,int32_t height);
UniValue MarmaraPoolPayout(uint64_t txfee,int32_t firstheight,double perc,char *jsonstr); // [[pk0, shares0], [pk1, shares1], ...] UniValue MarmaraPoolPayout(uint64_t txfee,int32_t firstheight,double perc,char *jsonstr); // [[pk0, shares0], [pk1, shares1], ...]
UniValue MarmaraReceive(uint64_t txfee,CPubKey senderpk,int64_t amount,std::string currency,int32_t matures,uint256 batontxid); UniValue MarmaraReceive(uint64_t txfee,CPubKey senderpk,int64_t amount,std::string currency,int32_t matures,uint256 batontxid,bool automaticflag);
UniValue MarmaraIssue(uint64_t txfee,uint8_t funcid,CPubKey receiverpk,int64_t amount,std::string currency,int32_t matures,uint256 approvaltxid,uint256 batontxid); UniValue MarmaraIssue(uint64_t txfee,uint8_t funcid,CPubKey receiverpk,int64_t amount,std::string currency,int32_t matures,uint256 approvaltxid,uint256 batontxid);
UniValue MarmaraInfo(CPubKey refpk,int32_t firstheight,int32_t lastheight,int64_t minamount,int64_t maxamount,std::string currency); UniValue MarmaraInfo(CPubKey refpk,int32_t firstheight,int32_t lastheight,int64_t minamount,int64_t maxamount,std::string currency);

View File

@@ -477,14 +477,10 @@ std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 a
std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid) std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid)
{ {
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CTransaction vintx; CTransaction vintx; uint64_t mask;
uint64_t mask; uint256 hashBlock; int64_t bidamount;
uint256 hashBlock; CPubKey mypk; struct CCcontract_info *cpAssets, C;
int64_t bidamount; uint8_t funcid,dummyEvalCode; uint256 dummyAssetid, dummyAssetid2; int64_t dummyPrice; std::vector<uint8_t> dummyOrigpubkey;
CPubKey mypk;
struct CCcontract_info *cpAssets, C;
uint8_t dummyEvalCode; uint256 dummyAssetid, dummyAssetid2; int64_t dummyPrice; std::vector<uint8_t> dummyOrigpubkey;
cpAssets = CCinit(&C, EVAL_ASSETS); cpAssets = CCinit(&C, EVAL_ASSETS);
@@ -501,9 +497,12 @@ std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid)
bidamount = vintx.vout[0].nValue; bidamount = vintx.vout[0].nValue;
mtx.vin.push_back(CTxIn(bidtxid, 0, CScript())); // coins in Assets mtx.vin.push_back(CTxIn(bidtxid, 0, CScript())); // coins in Assets
if( DecodeAssetTokenOpRet(vintx.vout[vintx.vout.size() - 1].scriptPubKey, dummyEvalCode, dummyAssetid, dummyAssetid2, dummyPrice, dummyOrigpubkey) == 'b') if((funcid=DecodeAssetTokenOpRet(vintx.vout[vintx.vout.size() - 1].scriptPubKey, dummyEvalCode, dummyAssetid, dummyAssetid2, dummyPrice, dummyOrigpubkey))!=0)
mtx.vin.push_back(CTxIn(bidtxid, 1, CScript())); // spend marker if funcid='b' (not 'B') {
// TODO: spend it also in FillBuyOffer?
if (funcid == 's') mtx.vin.push_back(CTxIn(bidtxid, 1, CScript())); // spend marker if funcid='b'
else if (funcid=='S') mtx.vin.push_back(CTxIn(bidtxid, 3, CScript())); // spend marker if funcid='B'
}
mtx.vout.push_back(CTxOut(bidamount,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); mtx.vout.push_back(CTxOut(bidamount,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
@@ -523,12 +522,9 @@ std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid)
{ {
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CTransaction vintx; uint64_t mask; CTransaction vintx; uint64_t mask;
uint256 hashBlock; uint256 hashBlock; int64_t askamount;
int64_t askamount; CPubKey mypk; struct CCcontract_info *cpTokens, *cpAssets, tokensC, assetsC;
CPubKey mypk; uint8_t funcid,dummyEvalCode; uint256 dummyAssetid, dummyAssetid2; int64_t dummyPrice; std::vector<uint8_t> dummyOrigpubkey;
struct CCcontract_info *cpTokens, *cpAssets, tokensC, assetsC;
uint8_t dummyEvalCode; uint256 dummyAssetid, dummyAssetid2; int64_t dummyPrice; std::vector<uint8_t> dummyOrigpubkey;
cpAssets = CCinit(&assetsC, EVAL_ASSETS); cpAssets = CCinit(&assetsC, EVAL_ASSETS);
@@ -545,9 +541,11 @@ std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid)
askamount = vintx.vout[0].nValue; askamount = vintx.vout[0].nValue;
mtx.vin.push_back(CTxIn(asktxid, 0, CScript())); mtx.vin.push_back(CTxIn(asktxid, 0, CScript()));
if (DecodeAssetTokenOpRet(vintx.vout[vintx.vout.size() - 1].scriptPubKey, dummyEvalCode, dummyAssetid, dummyAssetid2, dummyPrice, dummyOrigpubkey) == 's') if ((funcid=DecodeAssetTokenOpRet(vintx.vout[vintx.vout.size() - 1].scriptPubKey, dummyEvalCode, dummyAssetid, dummyAssetid2, dummyPrice, dummyOrigpubkey))!=0)
mtx.vin.push_back(CTxIn(asktxid, 1, CScript())); // marker if funcid='s' (not 'S') {
// TODO: spend it also in FillSell? if (funcid == 's') mtx.vin.push_back(CTxIn(asktxid, 1, CScript())); // marker if funcid='s'
else if (funcid=='S') mtx.vin.push_back(CTxIn(asktxid, 3, CScript())); // marker if funcid='S'
}
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, askamount, mypk)); // one-eval token vout mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, askamount, mypk)); // one-eval token vout
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
@@ -607,7 +605,7 @@ std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t f
mypk = pubkey2pk(Mypubkey()); mypk = pubkey2pk(Mypubkey());
if (AddNormalinputs(mtx, mypk, txfee, 3) > 0) if (AddNormalinputs(mtx, mypk, 2*txfee, 3) > 0)
{ {
mask = ~((1LL << mtx.vin.size()) - 1); mask = ~((1LL << mtx.vin.size()) - 1);
if (GetTransaction(bidtxid, vintx, hashBlock, false) != 0) if (GetTransaction(bidtxid, vintx, hashBlock, false) != 0)
@@ -637,9 +635,10 @@ std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t f
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, bidamount - paid_amount, unspendableAssetsPk)); // vout0 coins remainder mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, bidamount - paid_amount, unspendableAssetsPk)); // vout0 coins remainder
mtx.vout.push_back(CTxOut(paid_amount,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); // vout1 coins to normal mtx.vout.push_back(CTxOut(paid_amount,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); // vout1 coins to normal
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, fillamount, pubkey2pk(origpubkey))); // vout2 single-eval tokens sent to the buyer mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, fillamount, pubkey2pk(origpubkey))); // vout2 single-eval tokens sent to the buyer
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,txfee,origpubkey)); // vout3 marker to origpubkey
if (CCchange != 0) if (CCchange != 0)
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, CCchange, mypk)); // vout3 change in single-eval tokens mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, CCchange, mypk)); // vout4 change in single-eval tokens
fprintf(stderr,"FillBuyOffer remaining %llu -> origpubkey\n", (long long)remaining_required); fprintf(stderr,"FillBuyOffer remaining %llu -> origpubkey\n", (long long)remaining_required);
@@ -698,7 +697,7 @@ std::string FillSell(int64_t txfee, uint256 assetid, uint256 assetid2, uint256 a
txfee = 10000; txfee = 10000;
mypk = pubkey2pk(Mypubkey()); mypk = pubkey2pk(Mypubkey());
if (AddNormalinputs(mtx, mypk, txfee, 3) > 0) if (AddNormalinputs(mtx, mypk, 2*txfee, 3) > 0)
{ {
mask = ~((1LL << mtx.vin.size()) - 1); mask = ~((1LL << mtx.vin.size()) - 1);
if (GetTransaction(asktxid, vintx, hashBlock, false) != 0) if (GetTransaction(asktxid, vintx, hashBlock, false) != 0)
@@ -747,6 +746,7 @@ std::string FillSell(int64_t txfee, uint256 assetid, uint256 assetid2, uint256 a
//std::cerr << "FillSell() paid_value=" << paid_nValue << " origpubkey=" << HexStr(pubkey2pk(origpubkey)) << std::endl; //std::cerr << "FillSell() paid_value=" << paid_nValue << " origpubkey=" << HexStr(pubkey2pk(origpubkey)) << std::endl;
mtx.vout.push_back(CTxOut(paid_nValue, CScript() << origpubkey << OP_CHECKSIG)); //vout.2 coins to tokens seller's normal addr mtx.vout.push_back(CTxOut(paid_nValue, CScript() << origpubkey << OP_CHECKSIG)); //vout.2 coins to tokens seller's normal addr
} }
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,txfee,origpubkey)); //vout.3 marker to origpubkey
// not implemented // not implemented
if (CCchange != 0) { if (CCchange != 0) {

View File

@@ -234,6 +234,34 @@ uint8_t TokensCCpriv[32] = { 0x1d, 0x0d, 0x0d, 0xce, 0x2d, 0xd2, 0xe1, 0x9d, 0xf
#undef FUNCNAME #undef FUNCNAME
#undef EVALCODE #undef EVALCODE
#define FUNCNAME IsCClibInput
#define EVALCODE EVAL_FIRSTUSER
const char *CClibNormaladdr = "RVVeUg43rNcq3mZFnvZ8yqagyzqFgUnq4u";
char CClibCChexstr[67] = { "032447d97655da079729dc024c61088ea415b22f4c15d4810ddaf2069ac6468d2f" };
uint8_t CClibCCpriv[32] = { 0x57, 0xcf, 0x49, 0x71, 0x7d, 0xb4, 0x15, 0x1b, 0x4f, 0x98, 0xc5, 0x45, 0x8d, 0x26, 0x52, 0x4b, 0x7b, 0xe9, 0xbd, 0x55, 0xd8, 0x20, 0xd6, 0xc4, 0x82, 0x0f, 0xf5, 0xec, 0x6c, 0x1c, 0xa0, 0xc0 };
#include "CCcustom.inc"
#undef FUNCNAME
#undef EVALCODE
int32_t CClib_initcp(struct CCcontract_info *cp,uint8_t evalcode)
{
CPubKey pk; uint8_t pub33[33]; char CCaddr[64];
if ( evalcode == EVAL_FIRSTUSER ) // eventually make a hashchain for each evalcode
{
cp->evalcode = evalcode;
cp->ismyvin = IsCClibInput;
strcpy(cp->CChexstr,CClibCChexstr);
memcpy(cp->CCpriv,CClibCCpriv,32);
decode_hex(pub33,33,cp->CChexstr);
pk = buf2pk(pub33);
Getscriptaddress(cp->normaladdr,CScript() << ParseHex(HexStr(pk)) << OP_CHECKSIG);
if ( strcmp(cp->normaladdr,CClibNormaladdr) != 0 )
fprintf(stderr,"CClib_initcp addr mismatch %s vs %s\n",cp->normaladdr,CClibNormaladdr);
GetCCaddress(cp,cp->unspendableCCaddr,pk);
return(0);
}
return(-1);
}
struct CCcontract_info *CCinit(struct CCcontract_info *cp, uint8_t evalcode) struct CCcontract_info *CCinit(struct CCcontract_info *cp, uint8_t evalcode)
{ {
@@ -369,6 +397,10 @@ struct CCcontract_info *CCinit(struct CCcontract_info *cp, uint8_t evalcode)
cp->validate = TokensValidate; cp->validate = TokensValidate;
cp->ismyvin = IsTokensInput; cp->ismyvin = IsTokensInput;
break; break;
default:
if ( CClib_initcp(cp,evalcode) < 0 )
return(0);
break;
} }
return(cp); return(cp);
} }

View File

@@ -51,10 +51,6 @@ one other technical note is that komodod has the insight-explorer extensions bui
#include "../utlist.h" #include "../utlist.h"
#include "../uthash.h" #include "../uthash.h"
extern int32_t KOMODO_CONNECTING,KOMODO_CCACTIVATE,KOMODO_DEALERNODE;
extern uint32_t ASSETCHAINS_CC;
extern char ASSETCHAINS_SYMBOL[];
extern std::string CCerror;
#define CC_MAXVINS 1024 #define CC_MAXVINS 1024
@@ -68,6 +64,7 @@ extern std::string CCerror;
typedef union _bits256 bits256; typedef union _bits256 bits256;
#endif #endif
#include "../komodo_cJSON.h"
struct CC_utxo struct CC_utxo
{ {
@@ -133,6 +130,9 @@ CBlockIndex *komodo_getblockindex(uint256 hash);
int32_t komodo_nextheight(); int32_t komodo_nextheight();
int32_t CCgetspenttxid(uint256 &spenttxid,int32_t &vini,int32_t &height,uint256 txid,int32_t vout); int32_t CCgetspenttxid(uint256 &spenttxid,int32_t &vini,int32_t &height,uint256 txid,int32_t vout);
void CCclearvars(struct CCcontract_info *cp);
UniValue CClib(struct CCcontract_info *cp,char *method,cJSON *params);
UniValue CClib_info(struct CCcontract_info *cp);
static const uint256 zeroid; static const uint256 zeroid;
bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock); bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock);
@@ -199,6 +199,7 @@ CC *MakeTokensCCcond1(uint8_t evalcode, CPubKey pk);
bool GetTokensCCaddress(struct CCcontract_info *cp, char *destaddr, CPubKey pk); bool GetTokensCCaddress(struct CCcontract_info *cp, char *destaddr, CPubKey pk);
bool GetTokensCCaddress1of2(struct CCcontract_info *cp, char *destaddr, CPubKey pk, CPubKey pk2); bool GetTokensCCaddress1of2(struct CCcontract_info *cp, char *destaddr, CPubKey pk, CPubKey pk2);
void CCaddrTokens1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2, char *coinaddr); void CCaddrTokens1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2, char *coinaddr);
int32_t CClib_initcp(struct CCcontract_info *cp,uint8_t evalcode);
bool IsCCInput(CScript const& scriptSig); bool IsCCInput(CScript const& scriptSig);
int32_t unstringbits(char *buf,uint64_t bits); int32_t unstringbits(char *buf,uint64_t bits);
@@ -222,9 +223,11 @@ std::vector<uint8_t> Mypubkey();
bool Myprivkey(uint8_t myprivkey[]); bool Myprivkey(uint8_t myprivkey[]);
int64_t CCduration(int32_t &numblocks,uint256 txid); int64_t CCduration(int32_t &numblocks,uint256 txid);
bool komodo_txnotarizedconfirmed(uint256 txid); bool komodo_txnotarizedconfirmed(uint256 txid);
CPubKey check_signing_pubkey(CScript scriptSig);
// CCtx // CCtx
bool SignTx(CMutableTransaction &mtx,int32_t vini,int64_t utxovalue,const CScript scriptPubKey); bool SignTx(CMutableTransaction &mtx,int32_t vini,int64_t utxovalue,const CScript scriptPubKey);
std::string FinalizeCCTx(uint64_t skipmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret); extern std::vector<CPubKey> NULL_pubkeys;
std::string FinalizeCCTx(uint64_t skipmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret,std::vector<CPubKey> pubkeys = NULL_pubkeys);
void SetCCunspents(std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs,char *coinaddr); void SetCCunspents(std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs,char *coinaddr);
void SetCCtxids(std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex,char *coinaddr); void SetCCtxids(std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex,char *coinaddr);
int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int32_t maxinputs); int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int32_t maxinputs);

View File

@@ -404,7 +404,6 @@ int64_t IsTokensvout(bool goDeeper, bool checkPubkeys, struct CCcontract_info *c
uint8_t evalCodeInOpret; uint8_t evalCodeInOpret;
if (vopretExtra.size() >= 2 /*|| vopretExtra.size() != vopretExtra.begin()[0] <-- shold we check this?*/) { if (vopretExtra.size() >= 2 /*|| vopretExtra.size() != vopretExtra.begin()[0] <-- shold we check this?*/) {
std::cerr << "IsTokensvout() empty or incorrect contract opret" << std::endl;
evalCodeInOpret = vopretExtra.begin()[1]; evalCodeInOpret = vopretExtra.begin()[1];
} }
else { else {

View File

@@ -16,6 +16,8 @@
#include "CCinclude.h" #include "CCinclude.h"
#include "key_io.h" #include "key_io.h"
std::vector<CPubKey> NULL_pubkeys;
/* /*
FinalizeCCTx is a very useful function that will properly sign both CC and normal inputs, adds normal change and the opreturn. FinalizeCCTx is a very useful function that will properly sign both CC and normal inputs, adds normal change and the opreturn.
@@ -38,18 +40,18 @@ bool SignTx(CMutableTransaction &mtx,int32_t vini,int64_t utxovalue,const CScrip
return(false); return(false);
} }
std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret) std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret,std::vector<CPubKey> pubkeys)
{ {
auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus()); auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
CTransaction vintx; std::string hex; uint256 hashBlock; uint64_t mask=0,nmask=0,vinimask=0; CTransaction vintx; std::string hex; CPubKey globalpk; uint256 hashBlock; uint64_t mask=0,nmask=0,vinimask=0;
int64_t utxovalues[CC_MAXVINS],change,normalinputs=0,totaloutputs=0,normaloutputs=0,totalinputs=0,normalvins=0,ccvins=0; int64_t utxovalues[CC_MAXVINS],change,normalinputs=0,totaloutputs=0,normaloutputs=0,totalinputs=0,normalvins=0,ccvins=0;
int32_t i,utxovout,n,err = 0; int32_t i,flag,utxovout,n,err = 0;
char myaddr[64], destaddr[64], unspendable[64], mytokensaddr[64], mysingletokensaddr[64], tokensunspendable[64]; char myaddr[64], destaddr[64], unspendable[64], mytokensaddr[64], mysingletokensaddr[64], tokensunspendable[64];
uint8_t *privkey, myprivkey[32], unspendablepriv[32], tokensunspendablepriv[32], *msg32 = 0; uint8_t *privkey, myprivkey[32], unspendablepriv[32], tokensunspendablepriv[32], *msg32 = 0;
CC *mycond=0, *othercond=0, *othercond2=0, *othercond3=0, *othercond1of2=NULL, *othercond1of2tokens = NULL, *cond, *mytokenscond = NULL, *mysingletokenscond = NULL, *othertokenscond = NULL; CC *mycond=0, *othercond=0, *othercond2=0,*othercond4=0, *othercond3=0, *othercond1of2=NULL, *othercond1of2tokens = NULL, *cond, *mytokenscond = NULL, *mysingletokenscond = NULL, *othertokenscond = NULL;
CPubKey unspendablepk /*, tokensunspendablepk*/; CPubKey unspendablepk /*, tokensunspendablepk*/;
struct CCcontract_info *cpTokens, tokensC; struct CCcontract_info *cpTokens, tokensC;
globalpk = GetUnspendable(cp,0);
n = mtx.vout.size(); n = mtx.vout.size();
for (i=0; i<n; i++) for (i=0; i<n; i++)
{ {
@@ -221,8 +223,27 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
} }
else else
{ {
fprintf(stderr,"CC signing error: vini.%d has unknown CC address.(%s)\n",i,destaddr); flag = 0;
return(""); if ( pubkeys != NULL_pubkeys )
{
char coinaddr[64];
GetCCaddress1of2(cp,coinaddr,globalpk,pubkeys[i]);
//fprintf(stderr,"%s + %s -> %s vs %s\n",HexStr(globalpk).c_str(),HexStr(pubkeys[i]).c_str(),coinaddr,destaddr);
if ( strcmp(destaddr,coinaddr) == 0 )
{
privkey = cp->CCpriv;
if ( othercond4 != 0 )
cc_free(othercond4);
othercond4 = MakeCCcond1of2(cp->evalcode,globalpk,pubkeys[i]);
cond = othercond4;
flag = 1;
}
}
if ( flag == 0 )
{
fprintf(stderr,"CC signing error: vini.%d has unknown CC address.(%s)\n",i,destaddr);
continue;
}
} }
uint256 sighash = SignatureHash(CCPubKey(cond), mtx, i, SIGHASH_ALL, utxovalues[i],consensusBranchId, &txdata); uint256 sighash = SignatureHash(CCPubKey(cond), mtx, i, SIGHASH_ALL, utxovalues[i],consensusBranchId, &txdata);
if ( cc_signTreeSecp256k1Msg32(cond,privkey,sighash.begin()) != 0 ) if ( cc_signTreeSecp256k1Msg32(cond,privkey,sighash.begin()) != 0 )
@@ -252,6 +273,8 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
cc_free(othercond2); cc_free(othercond2);
if ( othercond3 != 0 ) if ( othercond3 != 0 )
cc_free(othercond3); cc_free(othercond3);
if ( othercond4 != 0 )
cc_free(othercond4);
std::string strHex = EncodeHexTx(mtx); std::string strHex = EncodeHexTx(mtx);
if ( strHex.size() > 0 ) if ( strHex.size() > 0 )
return(strHex); return(strHex);
@@ -450,8 +473,8 @@ int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int3
{ {
int32_t abovei,belowi,ind,vout,i,n = 0,maxutxos=64; int64_t sum,threshold,above,below; int64_t remains,nValue,totalinputs = 0; uint256 txid,hashBlock; std::vector<COutput> vecOutputs; CTransaction tx; struct CC_utxo *utxos,*up; int32_t abovei,belowi,ind,vout,i,n = 0,maxutxos=64; int64_t sum,threshold,above,below; int64_t remains,nValue,totalinputs = 0; uint256 txid,hashBlock; std::vector<COutput> vecOutputs; CTransaction tx; struct CC_utxo *utxos,*up;
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
const CKeyStore& keystore = *pwalletMain;
assert(pwalletMain != NULL); assert(pwalletMain != NULL);
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
pwalletMain->AvailableCoins(vecOutputs, false, NULL, true); pwalletMain->AvailableCoins(vecOutputs, false, NULL, true);
utxos = (struct CC_utxo *)calloc(maxutxos,sizeof(*utxos)); utxos = (struct CC_utxo *)calloc(maxutxos,sizeof(*utxos));

View File

@@ -493,39 +493,10 @@ CPubKey GetUnspendable(struct CCcontract_info *cp,uint8_t *unspendablepriv)
return(pubkey2pk(ParseHex(cp->CChexstr))); return(pubkey2pk(ParseHex(cp->CChexstr)));
} }
bool ProcessCC(struct CCcontract_info *cp,Eval* eval, std::vector<uint8_t> paramsNull,const CTransaction &ctx, unsigned int nIn) void CCclearvars(struct CCcontract_info *cp)
{ {
CTransaction createTx; uint256 assetid,assetid2,hashBlock; uint8_t funcid; int32_t height,i,n,from_mempool = 0; int64_t amount; std::vector<uint8_t> origpubkey;
height = KOMODO_CONNECTING;
if ( KOMODO_CONNECTING < 0 ) // always comes back with > 0 for final confirmation
return(true);
if ( ASSETCHAINS_CC == 0 || (height & ~(1<<30)) < KOMODO_CCACTIVATE )
return eval->Invalid("CC are disabled or not active yet");
if ( (KOMODO_CONNECTING & (1<<30)) != 0 )
{
from_mempool = 1;
height &= ((1<<30) - 1);
}
//fprintf(stderr,"KOMODO_CONNECTING.%d mempool.%d vs CCactive.%d\n",height,from_mempool,KOMODO_CCACTIVATE);
// there is a chance CC tx is valid in mempool, but invalid when in block, so we cant filter duplicate requests. if any of the vins are spent, for example
//txid = ctx.GetHash();
//if ( txid == cp->prevtxid )
// return(true);
//fprintf(stderr,"process CC %02x\n",cp->evalcode);
cp->evalcode2 = cp->evalcode3 = 0; cp->evalcode2 = cp->evalcode3 = 0;
cp->unspendableaddr2[0] = cp->unspendableaddr3[0] = 0; cp->unspendableaddr2[0] = cp->unspendableaddr3[0] = 0;
if ( paramsNull.size() != 0 ) // Don't expect params
return eval->Invalid("Cannot have params");
//else if ( ctx.vout.size() == 0 ) // spend can go to z-addresses
// return eval->Invalid("no-vouts");
else if ( (*cp->validate)(cp,eval,ctx,nIn) != 0 )
{
//fprintf(stderr,"done CC %02x\n",cp->evalcode);
//cp->prevtxid = txid;
return(true);
}
//fprintf(stderr,"invalid CC %02x\n",cp->evalcode);
return(false);
} }
int64_t CCduration(int32_t &numblocks,uint256 txid) int64_t CCduration(int32_t &numblocks,uint256 txid)
@@ -599,3 +570,109 @@ bool komodo_txnotarizedconfirmed(uint256 txid)
return (true); return (true);
return (false); return (false);
} }
CPubKey check_signing_pubkey(CScript scriptSig)
{
bool found = false;
CPubKey pubkey;
auto findEval = [](CC *cond, struct CCVisitor _) {
bool r = false;
if (cc_typeId(cond) == CC_Secp256k1) {
*(CPubKey*)_.context=buf2pk(cond->publicKey);
r = true;
}
// false for a match, true for continue
return r ? 0 : 1;
};
CC *cond = GetCryptoCondition(scriptSig);
if (cond) {
CCVisitor visitor = { findEval, (uint8_t*)"", 0, &pubkey };
bool out = !cc_visit(cond, visitor);
cc_free(cond);
if (pubkey.IsValid()) {
return pubkey;
}
}
return CPubKey();
}
bool ProcessCC(struct CCcontract_info *cp,Eval* eval, std::vector<uint8_t> paramsNull,const CTransaction &ctx, unsigned int nIn)
{
CTransaction createTx; uint256 assetid,assetid2,hashBlock; uint8_t funcid; int32_t height,i,n,from_mempool = 0; int64_t amount; std::vector<uint8_t> origpubkey;
height = KOMODO_CONNECTING;
if ( KOMODO_CONNECTING < 0 ) // always comes back with > 0 for final confirmation
return(true);
if ( ASSETCHAINS_CC == 0 || (height & ~(1<<30)) < KOMODO_CCACTIVATE )
return eval->Invalid("CC are disabled or not active yet");
if ( (KOMODO_CONNECTING & (1<<30)) != 0 )
{
from_mempool = 1;
height &= ((1<<30) - 1);
}
//fprintf(stderr,"KOMODO_CONNECTING.%d mempool.%d vs CCactive.%d\n",height,from_mempool,KOMODO_CCACTIVATE);
// there is a chance CC tx is valid in mempool, but invalid when in block, so we cant filter duplicate requests. if any of the vins are spent, for example
//txid = ctx.GetHash();
//if ( txid == cp->prevtxid )
// return(true);
//fprintf(stderr,"process CC %02x\n",cp->evalcode);
CCclearvars(cp);
if ( paramsNull.size() != 0 ) // Don't expect params
return eval->Invalid("Cannot have params");
//else if ( ctx.vout.size() == 0 ) // spend can go to z-addresses
// return eval->Invalid("no-vouts");
else if ( (*cp->validate)(cp,eval,ctx,nIn) != 0 )
{
//fprintf(stderr,"done CC %02x\n",cp->evalcode);
//cp->prevtxid = txid;
return(true);
}
//fprintf(stderr,"invalid CC %02x\n",cp->evalcode);
return(false);
}
extern struct CCcontract_info CCinfos[0x100];
extern std::string MYCCLIBNAME;
bool CClib_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx,unsigned int nIn);
bool CClib_Dispatch(const CC *cond,Eval *eval,std::vector<uint8_t> paramsNull,const CTransaction &txTo,unsigned int nIn)
{
uint8_t evalcode; int32_t height,from_mempool; struct CCcontract_info *cp;
if ( ASSETCHAINS_CCLIB != MYCCLIBNAME )
{
fprintf(stderr,"-ac_cclib=%s vs myname %s\n",ASSETCHAINS_CCLIB.c_str(),MYCCLIBNAME.c_str());
return eval->Invalid("-ac_cclib name mismatches myname");
}
height = KOMODO_CONNECTING;
if ( KOMODO_CONNECTING < 0 ) // always comes back with > 0 for final confirmation
return(true);
if ( ASSETCHAINS_CC == 0 || (height & ~(1<<30)) < KOMODO_CCACTIVATE )
return eval->Invalid("CC are disabled or not active yet");
if ( (KOMODO_CONNECTING & (1<<30)) != 0 )
{
from_mempool = 1;
height &= ((1<<30) - 1);
}
evalcode = cond->code[0];
if ( evalcode >= EVAL_FIRSTUSER && evalcode <= EVAL_LASTUSER )
{
cp = &CCinfos[(int32_t)evalcode];
if ( cp->didinit == 0 )
{
if ( CClib_initcp(cp,evalcode) == 0 )
cp->didinit = 1;
else return eval->Invalid("unsupported CClib evalcode");
}
CCclearvars(cp);
if ( paramsNull.size() != 0 ) // Don't expect params
return eval->Invalid("Cannot have params");
else if ( CClib_validate(cp,height,eval,txTo,nIn) != 0 )
return(true);
return(false); //eval->Invalid("error in CClib_validate");
}
return eval->Invalid("cclib CC must have evalcode between 16 and 127");
}

33
src/cc/Makefile Normal file
View File

@@ -0,0 +1,33 @@
SHELL = /bin/sh
CC = gcc
CC_DARWIN = g++-6
CC_WIN = x86_64-w64-mingw32-gcc-posix
CFLAGS_DARWIN = -std=c++11 -arch x86_64 -I/usr/local/Cellar/gcc\@6/6.4.0_2/include/c++/6.4.0/ -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -c -Wl,-undefined -Wl,dynamic_lookup
CFLAGS = -std=c++11 -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared -c
CFLAGS_WIN = -std=c++11 -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared -c
DEBUGFLAGS = -O0 -D _DEBUG
RELEASEFLAGS = -O2 -D NDEBUG -combine -fwhole-program
$(info $(OS))
OS := $(shell uname -s)
$(info $(OS))
TARGET = ../cclib.so
TARGET_WIN = ../cclib.dll
SOURCES = cclib.cpp
#HEADERS = $(shell echo ../cryptoconditions/include/*.h)
all: $(TARGET)
$(TARGET): $(SOURCES)
$(info Building cclib to src/)
ifeq ($(OS),Darwin)
$(CC_DARWIN) $(CFLAGS_DARWIN) $(DEBUGFLAGS) -o $(TARGET) $(SOURCES)
else ifeq ($(OS),Linux)
$(CC) $(CFLAGS) $(DEBUGFLAGS) -o $(TARGET) $(SOURCES)
#else ifeq ($(WIN_HOST),True) - todo: pass ENV var from build.sh if WIN host
else
$(info WINDOWS)
$(CC_WIN) $(CFLAGS_WIN) $(DEBUGFLAGS) -o $(TARGET_WIN) $(SOURCES)
endif
clean:
rm -rf $(TARGET)

View File

@@ -153,8 +153,9 @@ bool AssetsValidate(struct CCcontract_info *cpAssets,Eval* eval,const CTransacti
return eval->Invalid("AssetValidate: invalid opreturn payload"); return eval->Invalid("AssetValidate: invalid opreturn payload");
// find dual-eval tokens unspendable addr: // find dual-eval tokens unspendable addr:
char tokensUnspendableAddr[64]; char tokensUnspendableAddr[64],origpubkeyCCaddr[64];
GetTokensCCaddress(cpAssets, tokensUnspendableAddr, GetUnspendable(cpAssets, NULL)); GetTokensCCaddress(cpAssets, tokensUnspendableAddr, GetUnspendable(cpAssets, NULL));
GetCCaddress(cpAssets, origpubkeyCCaddr, origpubkey);
// we need this for validating single-eval tokens' vins/vous: // we need this for validating single-eval tokens' vins/vous:
struct CCcontract_info *cpTokens, tokensC; struct CCcontract_info *cpTokens, tokensC;
@@ -258,7 +259,7 @@ bool AssetsValidate(struct CCcontract_info *cpAssets,Eval* eval,const CTransacti
if( (nValue = AssetValidateBuyvin(cpAssets, eval, totalunits, tmporigpubkey, assetsCCaddr, origaddr, tx, assetid)) == 0 ) if( (nValue = AssetValidateBuyvin(cpAssets, eval, totalunits, tmporigpubkey, assetsCCaddr, origaddr, tx, assetid)) == 0 )
return(false); return(false);
else if( numvouts < 3 ) else if( numvouts < 4 )
return eval->Invalid("not enough vouts for fillbuy"); return eval->Invalid("not enough vouts for fillbuy");
else if( tmporigpubkey != origpubkey ) else if( tmporigpubkey != origpubkey )
return eval->Invalid("mismatched origpubkeys for fillbuy"); return eval->Invalid("mismatched origpubkeys for fillbuy");
@@ -266,17 +267,19 @@ bool AssetsValidate(struct CCcontract_info *cpAssets,Eval* eval,const CTransacti
{ {
if( nValue != tx.vout[0].nValue + tx.vout[1].nValue ) if( nValue != tx.vout[0].nValue + tx.vout[1].nValue )
return eval->Invalid("locked value doesnt match vout0+1 fillbuy"); return eval->Invalid("locked value doesnt match vout0+1 fillbuy");
else if( tx.vout[3].scriptPubKey.IsPayToCryptoCondition() != 0 ) else if( tx.vout[4].scriptPubKey.IsPayToCryptoCondition() != 0 )
{ {
if( ConstrainVout(tx.vout[2], 1, assetsCCaddr, 0) == 0 ) // tokens on user cc addr if( ConstrainVout(tx.vout[2], 1, assetsCCaddr, 0) == 0 ) // tokens on user cc addr
return eval->Invalid("vout2 doesnt go to origpubkey fillbuy"); return eval->Invalid("vout2 doesnt go to origpubkey fillbuy");
else if ( inputs != tx.vout[2].nValue + tx.vout[3].nValue ) else if ( inputs != tx.vout[2].nValue + tx.vout[4].nValue )
return eval->Invalid("asset inputs doesnt match vout2+3 fillbuy"); return eval->Invalid("asset inputs doesnt match vout2+3 fillbuy");
} }
else if( ConstrainVout(tx.vout[2], 1, assetsCCaddr, inputs) == 0 ) // tokens on user cc addr else if( ConstrainVout(tx.vout[2], 1, assetsCCaddr, inputs) == 0 ) // tokens on user cc addr
return eval->Invalid("vout2 doesnt match inputs fillbuy"); return eval->Invalid("vout2 doesnt match inputs fillbuy");
else if( ConstrainVout(tx.vout[1],0,0,0) == 0 ) else if( ConstrainVout(tx.vout[1],0,0,0) == 0 )
return eval->Invalid("vout1 is CC for fillbuy"); return eval->Invalid("vout1 is CC for fillbuy");
else if( ConstrainVout(tx.vout[3], 1, origpubkeyCCaddr, 10000) == 0 )
return eval->Invalid("invalid marker for original pubkey");
else if( ValidateBidRemainder(remaining_price, tx.vout[0].nValue, nValue, tx.vout[1].nValue, tx.vout[2].nValue, totalunits) == false ) else if( ValidateBidRemainder(remaining_price, tx.vout[0].nValue, nValue, tx.vout[1].nValue, tx.vout[2].nValue, totalunits) == false )
return eval->Invalid("mismatched remainder for fillbuy"); return eval->Invalid("mismatched remainder for fillbuy");
else if( remaining_price != 0 ) else if( remaining_price != 0 )
@@ -345,7 +348,7 @@ bool AssetsValidate(struct CCcontract_info *cpAssets,Eval* eval,const CTransacti
if( (assetoshis = AssetValidateSellvin(cpAssets, eval, totalunits, tmporigpubkey, userTokensCCaddr, origaddr, tx, assetid)) == 0 ) if( (assetoshis = AssetValidateSellvin(cpAssets, eval, totalunits, tmporigpubkey, userTokensCCaddr, origaddr, tx, assetid)) == 0 )
return(false); return(false);
else if( numvouts < 3 ) else if( numvouts < 4 )
return eval->Invalid("not enough vouts for fillask"); return eval->Invalid("not enough vouts for fillask");
else if( tmporigpubkey != origpubkey ) else if( tmporigpubkey != origpubkey )
return eval->Invalid("mismatched origpubkeys for fillask"); return eval->Invalid("mismatched origpubkeys for fillask");
@@ -359,6 +362,8 @@ bool AssetsValidate(struct CCcontract_info *cpAssets,Eval* eval,const CTransacti
return eval->Invalid("normal vout1 for fillask"); return eval->Invalid("normal vout1 for fillask");
else if( ConstrainVout(tx.vout[2], 0, origaddr, 0) == 0 ) else if( ConstrainVout(tx.vout[2], 0, origaddr, 0) == 0 )
return eval->Invalid("normal vout1 for fillask"); return eval->Invalid("normal vout1 for fillask");
else if( ConstrainVout(tx.vout[3], 1, origpubkeyCCaddr, 10000) == 0 )
return eval->Invalid("invalid marker for original pubkey");
else if( remaining_price != 0 ) else if( remaining_price != 0 )
{ {
//char tokensUnspendableAddr[64]; //char tokensUnspendableAddr[64];

317
src/cc/cclib.cpp Normal file
View File

@@ -0,0 +1,317 @@
/******************************************************************************
* Copyright © 2014-2019 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include <assert.h>
#include <cryptoconditions.h>
#include "primitives/block.h"
#include "primitives/transaction.h"
#include "script/cc.h"
#include "cc/eval.h"
#include "cc/utils.h"
#include "cc/CCinclude.h"
#include "main.h"
#include "chain.h"
#include "core_io.h"
#include "crosschain.h"
#define FAUCET2SIZE COIN
struct CClib_rpcinfo
{
char *method,*help;
int32_t numrequiredargs,maxargs; // frontloaded with required
uint8_t funcid;
}
CClib_methods[] =
{
{ (char *)"faucet2_fund", (char *)"amount", 1, 1, 'F' },
{ (char *)"faucet2_get", (char *)"<no args>", 0, 0, 'G' },
};
std::string MYCCLIBNAME = (char *)"faucet2";
char *CClib_name() { return((char *)MYCCLIBNAME.c_str()); }
std::string CClib_rawtxgen(struct CCcontract_info *cp,uint8_t funcid,cJSON *params);
UniValue CClib_info(struct CCcontract_info *cp)
{
UniValue result(UniValue::VOBJ),a(UniValue::VARR); int32_t i; char str[2];
result.push_back(Pair("result","success"));
result.push_back(Pair("CClib",CClib_name()));
for (i=0; i<sizeof(CClib_methods)/sizeof(*CClib_methods); i++)
{
UniValue obj(UniValue::VOBJ);
if ( CClib_methods[i].funcid < ' ' || CClib_methods[i].funcid >= 128 )
obj.push_back(Pair("funcid",CClib_methods[i].funcid));
else
{
str[0] = CClib_methods[i].funcid;
str[1] = 0;
obj.push_back(Pair("funcid",str));
}
obj.push_back(Pair("name",CClib_methods[i].method));
obj.push_back(Pair("help",CClib_methods[i].help));
obj.push_back(Pair("params_required",CClib_methods[i].numrequiredargs));
obj.push_back(Pair("params_max",CClib_methods[i].maxargs));
a.push_back(obj);
}
result.push_back(Pair("methods",a));
return(result);
}
UniValue CClib(struct CCcontract_info *cp,char *method,cJSON *params)
{
UniValue result(UniValue::VOBJ); int32_t i; std::string rawtx;
for (i=0; i<sizeof(CClib_methods)/sizeof(*CClib_methods); i++)
{
if ( strcmp(method,CClib_methods[i].method) == 0 )
{
result.push_back(Pair("result","success"));
result.push_back(Pair("method",CClib_methods[i].method));
rawtx = CClib_rawtxgen(cp,CClib_methods[i].funcid,params);
result.push_back(Pair("rawtx",rawtx));
return(result);
}
}
result.push_back(Pair("result","error"));
result.push_back(Pair("method",CClib_methods[i].method));
result.push_back(Pair("error","method not found"));
return(result);
}
int64_t IsCClibvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
{
char destaddr[64];
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
{
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 )
return(tx.vout[v].nValue);
}
return(0);
}
bool CClibExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
{
static uint256 zerohash;
CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis;
numvins = tx.vin.size();
numvouts = tx.vout.size();
for (i=0; i<numvins; i++)
{
//fprintf(stderr,"vini.%d\n",i);
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) != 0 )
{
//fprintf(stderr,"vini.%d check mempool\n",i);
if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 )
return eval->Invalid("cant find vinTx");
else
{
//fprintf(stderr,"vini.%d check hash and vout\n",i);
if ( hashBlock == zerohash )
return eval->Invalid("cant faucet2 from mempool");
if ( (assetoshis= IsCClibvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
inputs += assetoshis;
}
}
}
for (i=0; i<numvouts; i++)
{
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
if ( (assetoshis= IsCClibvout(cp,tx,i)) != 0 )
outputs += assetoshis;
}
if ( inputs != outputs+FAUCET2SIZE+txfee )
{
fprintf(stderr,"inputs %llu vs outputs %llu\n",(long long)inputs,(long long)outputs);
return eval->Invalid("mismatched inputs != outputs + FAUCET2SIZE + txfee");
}
else return(true);
}
bool CClib_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx,unsigned int nIn)
{
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64];
std::vector<std::pair<CAddressIndexKey, CAmount> > txids;
numvins = tx.vin.size();
numvouts = tx.vout.size();
preventCCvins = preventCCvouts = -1;
if ( numvouts < 1 )
return eval->Invalid("no vouts");
else
{
for (i=0; i<numvins; i++)
{
if ( IsCCInput(tx.vin[0].scriptSig) == 0 )
{
fprintf(stderr,"faucetget invalid vini\n");
return eval->Invalid("illegal normal vini");
}
}
//fprintf(stderr,"check amounts\n");
if ( CClibExactAmounts(cp,eval,tx,1,10000) == false )
{
fprintf(stderr,"faucetget invalid amount\n");
return false;
}
else
{
preventCCvouts = 1;
if ( IsCClibvout(cp,tx,0) != 0 )
{
preventCCvouts++;
i = 1;
} else i = 0;
txid = tx.GetHash();
memcpy(hash,&txid,sizeof(hash));
fprintf(stderr,"check faucetget txid %s %02x/%02x\n",uint256_str(str,txid),hash[0],hash[31]);
if ( tx.vout[i].nValue != FAUCET2SIZE )
return eval->Invalid("invalid faucet output");
else if ( (hash[0] & 0xff) != 0 || (hash[31] & 0xff) != 0 )
return eval->Invalid("invalid faucetget txid");
Getscriptaddress(destaddr,tx.vout[i].scriptPubKey);
SetCCtxids(txids,destaddr);
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=txids.begin(); it!=txids.end(); it++)
{
//int height = it->first.blockHeight;
if ( CCduration(numblocks,it->first.txhash) > 0 && numblocks > 3 )
{
//fprintf(stderr,"would return error %s numblocks.%d ago\n",uint256_str(str,it->first.txhash),numblocks);
return eval->Invalid("faucet2 is only for brand new addresses");
}
}
retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
if ( retval != 0 )
fprintf(stderr,"faucet2get validated\n");
else fprintf(stderr,"faucet2get invalid\n");
return(retval);
}
}
}
int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
{
char coinaddr[64]; int64_t threshold,nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
threshold = total/(maxinputs+1);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( it->second.satoshis < threshold )
continue;
//char str[65]; fprintf(stderr,"check %s/v%d %.8f`\n",uint256_str(str,txid),vout,(double)it->second.satoshis/COIN);
// no need to prevent dup
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{
if ( (nValue= IsCClibvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 )
{
if ( total != 0 && maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
nValue = it->second.satoshis;
totalinputs += nValue;
n++;
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
break;
} else fprintf(stderr,"nValue too small or already spent in mempool\n");
} else fprintf(stderr,"couldnt get tx\n");
}
return(totalinputs);
}
std::string Faucet2Fund(struct CCcontract_info *cp,uint64_t txfee,int64_t funds)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CPubKey mypk,cclibpk; CScript opret;
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
cclibpk = GetUnspendable(cp,0);
if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 )
{
mtx.vout.push_back(MakeCC1vout(cp->evalcode,funds,cclibpk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
}
return("");
}
/*UniValue FaucetInfo()
{
UniValue result(UniValue::VOBJ); char numstr[64];
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CPubKey faucetpk; struct CCcontract_info *cp,C; int64_t funding;
result.push_back(Pair("result","success"));
result.push_back(Pair("name","Faucet"));
cp = CCinit(&C,EVAL_FAUCET);
faucetpk = GetUnspendable(cp,0);
funding = AddFaucetInputs(cp,mtx,faucetpk,0,0);
sprintf(numstr,"%.8f",(double)funding/COIN);
result.push_back(Pair("funding",numstr));
return(result);
}*/
std::string CClib_rawtxgen(struct CCcontract_info *cp,uint8_t funcid,cJSON *params)
{
CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CPubKey mypk,cclibpk; int64_t funds,txfee=0,inputs,CCchange=0,nValue=FAUCET2SIZE; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash;
if ( txfee == 0 )
txfee = 10000;
if ( funcid == 'F' )
{
if ( cJSON_GetArraySize(params) > 0 )
{
funds = (int64_t)jdouble(jitem(params,0),0)*COIN + 0.0000000049;
return(Faucet2Fund(cp,0,funds));
} else return("");
}
else if ( funcid != 'G' )
return("");
cclibpk = GetUnspendable(cp,0);
mypk = pubkey2pk(Mypubkey());
if ( (inputs= AddCClibInputs(cp,mtx,cclibpk,nValue+txfee,60)) > 0 )
{
if ( inputs > nValue )
CCchange = (inputs - nValue - txfee);
if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(EVAL_FIRSTUSER,CCchange,cclibpk));
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
fprintf(stderr,"start at %u\n",(uint32_t)time(NULL));
j = rand() & 0xfffffff;
for (i=0; i<1000000; i++,j++)
{
tmpmtx = mtx;
rawhex = FinalizeCCTx(-1LL,cp,tmpmtx,mypk,txfee,CScript() << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_FIRSTUSER << (uint8_t)'G' << j));
if ( (len= (int32_t)rawhex.size()) > 0 && len < 65536 )
{
len >>= 1;
decode_hex(buf,len,(char *)rawhex.c_str());
hash = bits256_doublesha256(0,buf,len);
if ( (hash.bytes[0] & 0xff) == 0 && (hash.bytes[31] & 0xff) == 0 )
{
fprintf(stderr,"found valid txid after %d iterations %u\n",i,(uint32_t)time(NULL));
return(rawhex);
}
//fprintf(stderr,"%02x%02x ",hash.bytes[0],hash.bytes[31]);
}
}
fprintf(stderr,"couldnt generate valid txid %u\n",(uint32_t)time(NULL));
return("");
} else fprintf(stderr,"cant find faucet inputs\n");
return("");
}

View File

@@ -422,8 +422,8 @@ int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, C
if ( (int32_t)it->first.index==0 && GetTransaction(it->first.txhash,tx,hashBlock,false) != 0 && (numvouts=tx.vout.size()) > 0) if ( (int32_t)it->first.index==0 && GetTransaction(it->first.txhash,tx,hashBlock,false) != 0 && (numvouts=tx.vout.size()) > 0)
{ {
if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,tokenid,tmp_txid,srcpub,destpub,param1,param2,param3)!=0 && if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,tokenid,tmp_txid,srcpub,destpub,param1,param2,param3)!=0 &&
(tmp_txid==openTx.GetHash() || tx.GetHash()==openTx.GetHash()) && (tmp_txid==openTx.GetHash() || tx.GetHash()==openTx.GetHash()) && IsChannelsMarkervout(cp,tx,marker==1?srcpub:destpub,marker)>0 &&
(totalinputs=IsChannelsvout(cp,tx,srcpub,destpub,0)+IsChannelsMarkervout(cp,tx,srcpub,marker))>0) (totalinputs=IsChannelsvout(cp,tx,srcpub,destpub,0))>0)
{ {
txid = it->first.txhash; txid = it->first.txhash;
break; break;
@@ -443,7 +443,7 @@ int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, C
tmp_txid==openTx.GetHash() && param1 < mindepth) tmp_txid==openTx.GetHash() && param1 < mindepth)
{ {
txid=hash; txid=hash;
totalinputs=txmempool.vout[0].nValue+txmempool.vout[1].nValue; totalinputs=txmempool.vout[0].nValue;
mindepth=param1; mindepth=param1;
} }
} }
@@ -502,6 +502,8 @@ std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64
if (tokenid!=zeroid && tokens>funds) mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS,tokens-funds,mypk)); if (tokenid!=zeroid && tokens>funds) mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS,tokens-funds,mypk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('O',tokenid,zeroid,mypk,destpub,numpayments,payment,hashchain))); return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('O',tokenid,zeroid,mypk,destpub,numpayments,payment,hashchain)));
} }
CCerror = strprintf("error adding funds");
fprintf(stderr,"%s\n",CCerror.c_str());
return(""); return("");
} }
@@ -520,30 +522,34 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
mypk = pubkey2pk(Mypubkey()); mypk = pubkey2pk(Mypubkey());
if (GetTransaction(opentxid,channelOpenTx,hashblock,false) == 0) if (GetTransaction(opentxid,channelOpenTx,hashblock,false) == 0)
{ {
fprintf(stderr, "invalid channel open txid\n"); CCerror = strprintf("invalid channel open txid");
return (""); fprintf(stderr,"%s\n",CCerror.c_str());
return("");
} }
if ((numvouts=channelOpenTx.vout.size()) > 0 && DecodeChannelsOpRet(channelOpenTx.vout[numvouts-1].scriptPubKey, tokenid, txid, srcpub, destpub, totalnumpayments, payment, hashchain)=='O') if ((numvouts=channelOpenTx.vout.size()) > 0 && DecodeChannelsOpRet(channelOpenTx.vout[numvouts-1].scriptPubKey, tokenid, txid, srcpub, destpub, totalnumpayments, payment, hashchain)=='O')
{ {
if (mypk != srcpub && mypk != destpub) if (mypk != srcpub && mypk != destpub)
{ {
fprintf(stderr,"this is not our channel\n"); CCerror = strprintf("this is not our channel");
fprintf(stderr,"%s\n",CCerror.c_str());
return(""); return("");
} }
else if (amount % payment != 0 || amount<payment) else if (amount % payment != 0 || amount<payment)
{ {
fprintf(stderr,"invalid amount, not a magnitude of payment size\n"); CCerror = strprintf("invalid amount, not a magnitude of payment size");
fprintf(stderr,"%s\n",CCerror.c_str());
return (""); return ("");
} }
} }
else else
{ {
fprintf(stderr, "invalid channel open tx\n"); CCerror = strprintf("invalid channel open tx");
fprintf(stderr,"%s\n",CCerror.c_str());
return (""); return ("");
} }
if (AddNormalinputs(mtx,mypk,2*txfee,3) > 0) if (AddNormalinputs(mtx,mypk,2*txfee,3) > 0)
{ {
if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid,mypk)) !=0 && (change=funds-amount-txfee)>=0) if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid,mypk)) !=0 && (change=funds-amount)>=0)
{ {
numpayments=amount/payment; numpayments=amount/payment;
if (GetTransaction(prevtxid,prevTx,hashblock,false) != 0 && (numvouts=prevTx.vout.size()) > 0 && if (GetTransaction(prevtxid,prevTx,hashblock,false) != 0 && (numvouts=prevTx.vout.size()) > 0 &&
@@ -552,11 +558,13 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
{ {
if (numpayments > prevdepth) if (numpayments > prevdepth)
{ {
fprintf(stderr,"not enough funds in channel for that amount\n"); CCerror = strprintf("not enough funds in channel for that amount");
fprintf(stderr,"%s\n",CCerror.c_str());
return (""); return ("");
} else if (numpayments == 0) } else if (numpayments == 0)
{ {
fprintf(stderr,"invalid amount\n"); CCerror = strprintf("invalid amount");
fprintf(stderr,"%s\n",CCerror.c_str());
return (""); return ("");
} }
if (secret!=zeroid) if (secret!=zeroid)
@@ -570,7 +578,8 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
endiancpy((uint8_t * ) & gensecret, hashdest, 32); endiancpy((uint8_t * ) & gensecret, hashdest, 32);
if (gensecret!=hashchain) if (gensecret!=hashchain)
{ {
fprintf(stderr,"invalid secret supplied\n"); CCerror = strprintf("invalid secret supplied");
fprintf(stderr,"%s\n",CCerror.c_str());
return(""); return("");
} }
} }
@@ -592,7 +601,8 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
} }
else else
{ {
fprintf(stderr,"invalid previous tx\n"); CCerror = strprintf("invalid previous tx");
fprintf(stderr,"%s\n",CCerror.c_str());
return(""); return("");
} }
if (tokenid!=zeroid) mtx.vout.push_back(MakeTokensCC1of2vout(EVAL_CHANNELS, change, srcpub, destpub)); if (tokenid!=zeroid) mtx.vout.push_back(MakeTokensCC1of2vout(EVAL_CHANNELS, change, srcpub, destpub));
@@ -605,11 +615,13 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
} }
else else
{ {
fprintf(stderr,"error adding CC inputs\n"); CCerror = strprintf("error adding CC inputs");
fprintf(stderr,"%s\n",CCerror.c_str());
return(""); return("");
} }
} }
fprintf(stderr,"error adding normal inputs\n"); CCerror = strprintf("error adding normal inputs");
fprintf(stderr,"%s\n",CCerror.c_str());
return(""); return("");
} }
@@ -629,36 +641,41 @@ std::string ChannelClose(uint64_t txfee,uint256 opentxid)
mypk = pubkey2pk(Mypubkey()); mypk = pubkey2pk(Mypubkey());
if (GetTransaction(opentxid,channelOpenTx,hashblock,false) == 0) if (GetTransaction(opentxid,channelOpenTx,hashblock,false) == 0)
{ {
fprintf(stderr, "invalid channel open txid\n"); CCerror = strprintf("invalid channel open txid");
fprintf(stderr,"%s\n",CCerror.c_str());
return (""); return ("");
} }
if ((numvouts=channelOpenTx.vout.size()) < 1 || DecodeChannelsOpRet(channelOpenTx.vout[numvouts-1].scriptPubKey,tokenid,tmp_txid,srcpub,destpub,numpayments,payment,hashchain)!='O') if ((numvouts=channelOpenTx.vout.size()) < 1 || DecodeChannelsOpRet(channelOpenTx.vout[numvouts-1].scriptPubKey,tokenid,tmp_txid,srcpub,destpub,numpayments,payment,hashchain)!='O')
{ {
fprintf(stderr, "invalid channel open tx\n"); CCerror = strprintf("invalid channel open tx");
fprintf(stderr,"%s\n",CCerror.c_str());
return (""); return ("");
} }
if (mypk != srcpub) if (mypk != srcpub)
{ {
fprintf(stderr,"cannot close, you are not channel owner\n"); CCerror = strprintf("cannot close, you are not channel owner");
fprintf(stderr,"%s\n",CCerror.c_str());
return(""); return("");
} }
if ( AddNormalinputs(mtx,mypk,2*txfee,3) > 0 ) if ( AddNormalinputs(mtx,mypk,2*txfee,3) > 0 )
{ {
if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid,mypk)) !=0 && funds-txfee>0) if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid,mypk)) !=0 && funds>0)
{ {
if (tokenid!=zeroid) mtx.vout.push_back(MakeTokensCC1of2vout(EVAL_CHANNELS, funds-txfee, mypk, destpub)); if (tokenid!=zeroid) mtx.vout.push_back(MakeTokensCC1of2vout(EVAL_CHANNELS, funds, mypk, destpub));
else mtx.vout.push_back(MakeCC1of2vout(EVAL_CHANNELS, funds-txfee, mypk, destpub)); else mtx.vout.push_back(MakeCC1of2vout(EVAL_CHANNELS, funds, mypk, destpub));
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,mypk)); mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,mypk));
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,destpub)); mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,destpub));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('C',tokenid,opentxid,mypk,destpub,(funds-txfee)/payment,payment,zeroid))); return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('C',tokenid,opentxid,mypk,destpub,funds/payment,payment,zeroid)));
} }
else else
{ {
fprintf(stderr,"error adding CC inputs\n"); CCerror = strprintf("error adding CC inputs");
fprintf(stderr,"%s\n",CCerror.c_str());
return(""); return("");
} }
} }
fprintf(stderr,"error adding normal inputs\n"); CCerror = strprintf("error adding normal inputs");
fprintf(stderr,"%s\n",CCerror.c_str());
return(""); return("");
} }
@@ -678,61 +695,72 @@ std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
mypk = pubkey2pk(Mypubkey()); mypk = pubkey2pk(Mypubkey());
if (GetTransaction(closetxid,channelCloseTx,hashblock,false) == 0) if (GetTransaction(closetxid,channelCloseTx,hashblock,false) == 0)
{ {
fprintf(stderr, "invalid channel close txid\n"); CCerror = strprintf("invalid channel close txid");
fprintf(stderr,"%s\n",CCerror.c_str());
return (""); return ("");
} }
if ((numvouts=channelCloseTx.vout.size()) < 1 || DecodeChannelsOpRet(channelCloseTx.vout[numvouts-1].scriptPubKey,tokenid,txid,srcpub,destpub,param1,param2,param3)!='C') if ((numvouts=channelCloseTx.vout.size()) < 1 || DecodeChannelsOpRet(channelCloseTx.vout[numvouts-1].scriptPubKey,tokenid,txid,srcpub,destpub,param1,param2,param3)!='C')
{ {
fprintf(stderr, "invalid channel close tx\n"); CCerror = strprintf("invalid channel close tx");
fprintf(stderr,"%s\n",CCerror.c_str());
return (""); return ("");
} }
if (txid!=opentxid) if (txid!=opentxid)
{ {
fprintf(stderr, "open and close txid are not from same channel\n"); CCerror = strprintf("open and close txid are not from same channel");
fprintf(stderr,"%s\n",CCerror.c_str());
return (""); return ("");
} }
if (GetTransaction(opentxid,channelOpenTx,hashblock,false) == 0) if (GetTransaction(opentxid,channelOpenTx,hashblock,false) == 0)
{ {
fprintf(stderr, "invalid channel open txid\n"); CCerror = strprintf("invalid channel open txid");
fprintf(stderr,"%s\n",CCerror.c_str());
return (""); return ("");
} }
if ((numvouts=channelOpenTx.vout.size()) < 1 || DecodeChannelsOpRet(channelOpenTx.vout[numvouts-1].scriptPubKey,tokenid,txid,srcpub,destpub,numpayments,payment,hashchain)!='O') if ((numvouts=channelOpenTx.vout.size()) < 1 || DecodeChannelsOpRet(channelOpenTx.vout[numvouts-1].scriptPubKey,tokenid,txid,srcpub,destpub,numpayments,payment,hashchain)!='O')
{ {
fprintf(stderr, "invalid channel open tx\n"); CCerror = strprintf("invalid channel open tx");
fprintf(stderr,"%s\n",CCerror.c_str());
return (""); return ("");
} }
if (mypk != srcpub) if (mypk != srcpub)
{ {
fprintf(stderr,"cannot refund, you are not the channel owenr\n"); CCerror = strprintf("cannot refund, you are not the channel owner");
fprintf(stderr,"%s\n",CCerror.c_str());
return(""); return("");
} }
if ( AddNormalinputs(mtx,mypk,2*txfee,3) > 0 ) if ( AddNormalinputs(mtx,mypk,2*txfee,3) > 0 )
{ {
if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid,mypk)) !=0 && funds-txfee>0) if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid,mypk)) !=0 && funds>0)
{ {
if ((GetTransaction(prevtxid,prevTx,hashblock,false) != 0) && (numvouts=prevTx.vout.size()) > 0 && if ((GetTransaction(prevtxid,prevTx,hashblock,false) != 0) && (numvouts=prevTx.vout.size()) > 0 &&
DecodeChannelsOpRet(prevTx.vout[numvouts-1].scriptPubKey, tokenid, txid, srcpub, destpub, param1, param2, param3) != 0) DecodeChannelsOpRet(prevTx.vout[numvouts-1].scriptPubKey, tokenid, txid, srcpub, destpub, param1, param2, param3) != 0)
{ {
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,mypk)); mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,mypk));
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,destpub)); mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,destpub));
if (tokenid!=zeroid) mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS,funds-txfee,mypk)); if (tokenid!=zeroid) mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS,funds,mypk));
else mtx.vout.push_back(CTxOut(funds-txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); else mtx.vout.push_back(CTxOut(funds,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('R',tokenid,opentxid,mypk,destpub,param1,payment,closetxid))); return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('R',tokenid,opentxid,mypk,destpub,funds/payment,payment,closetxid)));
} }
else else
{ {
fprintf(stderr,"previous tx is invalid\n"); CCerror = strprintf("previous tx is invalid");
fprintf(stderr,"%s\n",CCerror.c_str());
return(""); return("");
} }
} }
else else
{ {
fprintf(stderr,"error adding CC inputs\n"); CCerror = strprintf("error adding CC inputs");
fprintf(stderr,"%s\n",CCerror.c_str());
return(""); return("");
} }
} }
CCerror = strprintf("error adding normal inputs");
fprintf(stderr,"%s\n",CCerror.c_str());
return(""); return("");
} }
UniValue ChannelsList() UniValue ChannelsList()
{ {
UniValue result(UniValue::VOBJ); std::vector<std::pair<CAddressIndexKey, CAmount> > txids; struct CCcontract_info *cp,C; uint256 txid,hashBlock,tmp_txid,param3,tokenid; UniValue result(UniValue::VOBJ); std::vector<std::pair<CAddressIndexKey, CAmount> > txids; struct CCcontract_info *cp,C; uint256 txid,hashBlock,tmp_txid,param3,tokenid;

View File

@@ -27,6 +27,8 @@
#include "core_io.h" #include "core_io.h"
#include "crosschain.h" #include "crosschain.h"
bool CClib_Dispatch(const CC *cond,Eval *eval,std::vector<uint8_t> paramsNull,const CTransaction &txTo,unsigned int nIn);
char *CClib_name();
Eval* EVAL_TEST = 0; Eval* EVAL_TEST = 0;
struct CCcontract_info CCinfos[0x100]; struct CCcontract_info CCinfos[0x100];
@@ -65,13 +67,24 @@ bool Eval::Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn)
return Invalid("empty-eval"); return Invalid("empty-eval");
uint8_t ecode = cond->code[0]; uint8_t ecode = cond->code[0];
if ( ASSETCHAINS_CCDISABLES[ecode] != 0 )
{
fprintf(stderr,"%s evalcode.%d %02x\n",txTo.GetHash().GetHex().c_str(),ecode,ecode);
return Invalid("disabled-code, -ac_ccenables didnt include this ecode");
}
std::vector<uint8_t> vparams(cond->code+1, cond->code+cond->codeLength);
if ( ecode >= EVAL_FIRSTUSER && ecode <= EVAL_LASTUSER )
{
if ( ASSETCHAINS_CCLIB.size() > 0 && ASSETCHAINS_CCLIB == CClib_name() )
return CClib_Dispatch(cond,this,vparams,txTo,nIn);
else return Invalid("mismatched -ac_cclib vs CClib_name");
}
cp = &CCinfos[(int32_t)ecode]; cp = &CCinfos[(int32_t)ecode];
if ( cp->didinit == 0 ) if ( cp->didinit == 0 )
{ {
CCinit(cp,ecode); CCinit(cp,ecode);
cp->didinit = 1; cp->didinit = 1;
} }
std::vector<uint8_t> vparams(cond->code+1, cond->code+cond->codeLength);
switch ( ecode ) switch ( ecode )
{ {
case EVAL_IMPORTPAYOUT: case EVAL_IMPORTPAYOUT:

View File

@@ -59,6 +59,10 @@
EVAL(EVAL_TOKENS, 0xf2) EVAL(EVAL_TOKENS, 0xf2)
// evalcodes 0x10 to 0x7f are reserved for cclib dynamic CC
#define EVAL_FIRSTUSER 0x10
#define EVAL_LASTUSER 0x7f
typedef uint8_t EvalCode; typedef uint8_t EvalCode;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1
src/cc/makecclib Executable file
View File

@@ -0,0 +1 @@
gcc -std=c++11 -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared -c -o ../cclib.so cclib.cpp

View File

@@ -35,8 +35,14 @@
vout0 baton to next receiverpk (following the unspent baton back to original is the credit loop) vout0 baton to next receiverpk (following the unspent baton back to original is the credit loop)
'S' 'S'
vin0 'I' marker
vin1 baton
vins CC utxos from credit loop vins CC utxos from credit loop
'D' default/partial payment
'L' lockfunds
*/ */
// start of consensus code // start of consensus code
@@ -82,13 +88,13 @@ uint8_t DecodeMaramaraCoinbaseOpRet(const CScript scriptPubKey,CPubKey &pk,int32
} }
if ( vopret.size() > 2 && script[0] == EVAL_MARMARA ) if ( vopret.size() > 2 && script[0] == EVAL_MARMARA )
{ {
if ( script[1] == 'C' || script[1] == 'P' ) if ( script[1] == 'C' || script[1] == 'P' || script[1] == 'L' )
{ {
if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk; ss >> height; ss >> unlockht) != 0 ) if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk; ss >> height; ss >> unlockht) != 0 )
{ {
return(script[1]); return(script[1]);
} else fprintf(stderr,"DecodeMaramaraCoinbaseOpRet unmarshal error for %c\n",script[1]); } else fprintf(stderr,"DecodeMaramaraCoinbaseOpRet unmarshal error for %c\n",script[1]);
} else fprintf(stderr,"script[1] is %d != 'C' %d or 'P' %d\n",script[1],'C','P'); } //else fprintf(stderr,"script[1] is %d != 'C' %d or 'P' %d or 'L' %d\n",script[1],'C','P','L');
} else fprintf(stderr,"vopret.size() is %d\n",(int32_t)vopret.size()); } else fprintf(stderr,"vopret.size() is %d\n",(int32_t)vopret.size());
return(0); return(0);
} }
@@ -155,18 +161,25 @@ int32_t MarmaraGetbatontxid(std::vector<uint256> &creditloop,uint256 &batontxid,
if ( MarmaraGetcreatetxid(createtxid,txid) == 0 ) if ( MarmaraGetcreatetxid(createtxid,txid) == 0 )
{ {
txid = createtxid; txid = createtxid;
fprintf(stderr,"txid.%s -> createtxid %s\n",txid.GetHex().c_str(),createtxid.GetHex().c_str()); //fprintf(stderr,"txid.%s -> createtxid %s\n",txid.GetHex().c_str(),createtxid.GetHex().c_str());
while ( CCgetspenttxid(spenttxid,vini,height,txid,vout) == 0 ) while ( CCgetspenttxid(spenttxid,vini,height,txid,vout) == 0 )
{ {
creditloop.push_back(txid); creditloop.push_back(txid);
fprintf(stderr,"%d: %s\n",n,txid.GetHex().c_str()); //fprintf(stderr,"%d: %s\n",n,txid.GetHex().c_str());
n++; n++;
if ( (value= CCgettxout(spenttxid,vout,1)) > 0 ) if ( (value= CCgettxout(spenttxid,vout,1)) == 10000 )
{ {
batontxid = spenttxid; batontxid = spenttxid;
fprintf(stderr,"got baton %s %.8f\n",batontxid.GetHex().c_str(),(double)value/COIN); //fprintf(stderr,"got baton %s %.8f\n",batontxid.GetHex().c_str(),(double)value/COIN);
return(n); return(n);
} }
else if ( value > 0 )
{
batontxid = spenttxid;
fprintf(stderr,"n.%d got false baton %s/v%d %.8f\n",n,batontxid.GetHex().c_str(),vout,(double)value/COIN);
return(n);
}
// get funcid
txid = spenttxid; txid = spenttxid;
} }
} }
@@ -175,9 +188,16 @@ int32_t MarmaraGetbatontxid(std::vector<uint256> &creditloop,uint256 &batontxid,
CScript Marmara_scriptPubKey(int32_t height,CPubKey pk) CScript Marmara_scriptPubKey(int32_t height,CPubKey pk)
{ {
CTxOut ccvout; CTxOut ccvout; struct CCcontract_info *cp,C; CPubKey Marmarapk;
cp = CCinit(&C,EVAL_MARMARA);
Marmarapk = GetUnspendable(cp,0);
if ( height > 0 && (height & 1) == 0 && pk.size() == 33 ) if ( height > 0 && (height & 1) == 0 && pk.size() == 33 )
ccvout = MakeCC1vout(EVAL_MARMARA,0,pk); {
ccvout = MakeCC1of2vout(EVAL_MARMARA,0,Marmarapk,pk);
//char coinaddr[64];
//Getscriptaddress(coinaddr,ccvout.scriptPubKey);
//fprintf(stderr,"Marmara_scriptPubKey %s ht.%d -> %s\n",HexStr(pk).c_str(),height,coinaddr);
}
return(ccvout.scriptPubKey); return(ccvout.scriptPubKey);
} }
@@ -192,8 +212,9 @@ CScript MarmaraCoinbaseOpret(uint8_t funcid,int32_t height,CPubKey pk)
int32_t MarmaraValidateCoinbase(int32_t height,CTransaction tx) int32_t MarmaraValidateCoinbase(int32_t height,CTransaction tx)
{ {
struct CCcontract_info *cp,C; CPubKey pk; int32_t ht,unlockht; CTxOut ccvout; struct CCcontract_info *cp,C; CPubKey Marmarapk,pk; int32_t ht,unlockht; CTxOut ccvout;
cp = CCinit(&C,EVAL_MARMARA); cp = CCinit(&C,EVAL_MARMARA);
Marmarapk = GetUnspendable(cp,0);
if ( 0 ) if ( 0 )
{ {
int32_t d,histo[365*2+30]; int32_t d,histo[365*2+30];
@@ -221,19 +242,40 @@ int32_t MarmaraValidateCoinbase(int32_t height,CTransaction tx)
if ( ht == height && MarmaraUnlockht(height) == unlockht ) if ( ht == height && MarmaraUnlockht(height) == unlockht )
{ {
//fprintf(stderr,"ht.%d -> unlock.%d\n",ht,unlockht); //fprintf(stderr,"ht.%d -> unlock.%d\n",ht,unlockht);
ccvout = MakeCC1vout(EVAL_MARMARA,0,pk); ccvout = MakeCC1of2vout(EVAL_MARMARA,0,Marmarapk,pk);
if ( ccvout.scriptPubKey == tx.vout[0].scriptPubKey ) if ( ccvout.scriptPubKey == tx.vout[0].scriptPubKey )
return(0); return(0);
fprintf(stderr,"ht.%d mismatched CCvout scriptPubKey\n",height); char addr0[64],addr1[64];
Getscriptaddress(addr0,ccvout.scriptPubKey);
Getscriptaddress(addr1,tx.vout[0].scriptPubKey);
fprintf(stderr,"ht.%d mismatched CCvout scriptPubKey %s vs %s pk.%d %s\n",height,addr0,addr1,(int32_t)pk.size(),HexStr(pk).c_str());
} else fprintf(stderr,"ht.%d %d vs %d unlock.%d\n",height,MarmaraUnlockht(height),ht,unlockht); } else fprintf(stderr,"ht.%d %d vs %d unlock.%d\n",height,MarmaraUnlockht(height),ht,unlockht);
} else fprintf(stderr,"ht.%d error decoding coinbase opret\n",height); } else fprintf(stderr,"ht.%d error decoding coinbase opret\n",height);
} }
return(-1); return(-1);
} }
bool MarmaraPoScheck(char *destaddr,CScript opret,CTransaction staketx)
{
CPubKey Marmarapk,pk; int32_t height,unlockht; uint8_t funcid; char coinaddr[64]; struct CCcontract_info *cp,C;
//fprintf(stderr,"%s numvins.%d numvouts.%d %.8f opret[%d]\n",staketx.GetHash().ToString().c_str(),(int32_t)staketx.vin.size(),(int32_t)staketx.vout.size(),(double)staketx.vout[0].nValue/COIN,(int32_t)opret.size());
if ( staketx.vout.size() == 2 && opret == staketx.vout[1].scriptPubKey )
{
cp = CCinit(&C,EVAL_MARMARA);
funcid = DecodeMaramaraCoinbaseOpRet(opret,pk,height,unlockht);
Marmarapk = GetUnspendable(cp,0);
GetCCaddress1of2(cp,coinaddr,Marmarapk,pk);
//fprintf(stderr,"matched opret! funcid.%c ht.%d unlock.%d %s\n",funcid,height,unlockht,coinaddr);
return(strcmp(destaddr,coinaddr) == 0);
}
return(0);
}
bool MarmaraValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn) bool MarmaraValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
{ {
std::vector<uint8_t> vopret; CTransaction vinTx; uint256 hashBlock; int32_t numvins,numvouts,i,ht,unlockht,vht,vunlockht; uint8_t funcid,vfuncid,*script; CPubKey pk,vpk; std::vector<uint8_t> vopret; CTransaction vinTx; uint256 hashBlock; int32_t numvins,numvouts,i,ht,unlockht,vht,vunlockht; uint8_t funcid,vfuncid,*script; CPubKey pk,vpk;
if ( ASSETCHAINS_MARMARA == 0 )
return eval->Invalid("-ac_marmara must be set for marmara CC");
numvins = tx.vin.size(); numvins = tx.vin.size();
numvouts = tx.vout.size(); numvouts = tx.vout.size();
if ( numvouts < 1 ) if ( numvouts < 1 )
@@ -284,9 +326,17 @@ bool MarmaraValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
{ {
return(true); return(true);
} }
else if ( funcid == 'S' ) // collect -> automatically spend issuers locked funds, given 'I' else if ( funcid == 'S' ) // settlement -> automatically spend issuers locked funds, given 'I'
{ {
return(true); // iterate from issuer all remainder after maturity return(true);
}
else if ( funcid == 'D' ) // insufficient settlement
{
return(true);
}
else if ( funcid == 'C' ) // coinbase
{
return(true);
} }
// staking only for locked utxo // staking only for locked utxo
} }
@@ -298,9 +348,10 @@ bool MarmaraValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
int64_t AddMarmaraCoinbases(struct CCcontract_info *cp,CMutableTransaction &mtx,int32_t firstheight,CPubKey poolpk,int32_t maxinputs) int64_t AddMarmaraCoinbases(struct CCcontract_info *cp,CMutableTransaction &mtx,int32_t firstheight,CPubKey poolpk,int32_t maxinputs)
{ {
char coinaddr[64]; CPubKey pk; int64_t nValue,totalinputs = 0; uint256 txid,hashBlock; CTransaction vintx; int32_t unlockht,ht,vout,unlocks,n = 0; char coinaddr[64]; CPubKey Marmarapk,pk; int64_t nValue,totalinputs = 0; uint256 txid,hashBlock; CTransaction vintx; int32_t unlockht,ht,vout,unlocks,n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,poolpk); Marmarapk = GetUnspendable(cp,0);
GetCCaddress1of2(cp,coinaddr,Marmarapk,poolpk);
SetCCunspents(unspentOutputs,coinaddr); SetCCunspents(unspentOutputs,coinaddr);
unlocks = MarmaraUnlockht(firstheight); unlocks = MarmaraUnlockht(firstheight);
//fprintf(stderr,"check coinaddr.(%s)\n",coinaddr); //fprintf(stderr,"check coinaddr.(%s)\n",coinaddr);
@@ -332,13 +383,285 @@ int64_t AddMarmaraCoinbases(struct CCcontract_info *cp,CMutableTransaction &mtx,
return(totalinputs); return(totalinputs);
} }
int32_t MarmaraGetCreditloops(int64_t &totalamount,std::vector<uint256> &issuances,struct CCcontract_info *cp,int32_t firstheight,int32_t lastheight,int64_t minamount,int64_t maxamount,CPubKey refpk,std::string refcurrency) int64_t AddMarmarainputs(CMutableTransaction &mtx,std::vector<CPubKey> &pubkeys,char *coinaddr,int64_t total,int32_t maxinputs)
{
uint64_t threshold,nValue,totalinputs = 0; uint256 txid,hashBlock; CTransaction tx; int32_t numvouts,ht,unlockht,vout,i,n = 0; uint8_t funcid; CPubKey pk; std::vector<int64_t> vals;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
SetCCunspents(unspentOutputs,coinaddr);
threshold = total/(maxinputs+1);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( it->second.satoshis < threshold )
continue;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 && vout < numvouts && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(txid,vout) == 0 )
{
if ( (funcid= DecodeMaramaraCoinbaseOpRet(tx.vout[numvouts-1].scriptPubKey,pk,ht,unlockht)) == 'C' || funcid == 'P' || funcid == 'L' )
{
//char str[64]; fprintf(stderr,"(%s) %s/v%d %.8f ht.%d unlockht.%d\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN,ht,unlockht);
if ( total != 0 && maxinputs != 0 )
{
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
pubkeys.push_back(pk);
}
totalinputs += it->second.satoshis;
vals.push_back(it->second.satoshis);
n++;
if ( maxinputs != 0 && total == 0 )
continue;
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
break;
} else fprintf(stderr,"null funcid\n");
}
}
if ( maxinputs != 0 && total == 0 )
{
std::sort(vals.begin(),vals.end());
totalinputs = 0;
for (i=0; i<maxinputs && i<vals.size(); i++)
totalinputs += vals[i];
}
return(totalinputs);
}
UniValue MarmaraLock(uint64_t txfee,int64_t amount,int32_t height)
{
CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C; CPubKey Marmarapk,mypk,pk; int32_t unlockht,refunlockht,vout,ht,numvouts; int64_t nValue,val,inputsum=0,threshold,remains,change = 0; std::string rawtx,errorstr; char coinaddr[64]; uint256 txid,hashBlock; CTransaction tx; uint8_t funcid;
if ( txfee == 0 )
txfee = 10000;
if ( (height & 1) != 0 )
height++;
cp = CCinit(&C,EVAL_MARMARA);
mypk = pubkey2pk(Mypubkey());
Marmarapk = GetUnspendable(cp,0);
Getscriptaddress(coinaddr,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG);
if ( (val= CCaddress_balance(coinaddr)) < amount )
val -= txfee;
else val = amount;
if ( val > txfee )
inputsum = AddNormalinputs2(mtx,val,CC_MAXVINS/2);
//fprintf(stderr,"normal inputs %.8f val %.8f\n",(double)inputsum/COIN,(double)val/COIN);
mtx.vout.push_back(MakeCC1of2vout(EVAL_MARMARA,amount,Marmarapk,mypk));
if ( inputsum < amount+txfee )
{
refunlockht = MarmaraUnlockht(height);
result.push_back(Pair("normalfunds",ValueFromAmount(inputsum)));
result.push_back(Pair("height",height));
result.push_back(Pair("unlockht",refunlockht));
remains = (amount + txfee) - inputsum;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress1of2(cp,coinaddr,Marmarapk,mypk);
SetCCunspents(unspentOutputs,coinaddr);
threshold = remains / (MARMARA_VINS+1);
CCaddr1of2set(cp,Marmarapk,mypk,coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( (nValue= it->second.satoshis) < threshold )
continue;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 && vout < numvouts && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(txid,vout) == 0 )
{
if ( (funcid= DecodeMaramaraCoinbaseOpRet(tx.vout[numvouts-1].scriptPubKey,pk,ht,unlockht)) == 'C' || funcid == 'P' || funcid == 'L' )
{
if ( unlockht < refunlockht )
{
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
//fprintf(stderr,"merge CC vout %s/v%d %.8f unlockht.%d < ref.%d\n",txid.GetHex().c_str(),vout,(double)nValue/COIN,unlockht,refunlockht);
inputsum += nValue;
remains -= nValue;
if ( inputsum >= amount + txfee )
{
//fprintf(stderr,"inputsum %.8f >= amount %.8f, update amount\n",(double)inputsum/COIN,(double)amount/COIN);
amount = inputsum - txfee;
break;
}
}
}
}
}
}
if ( inputsum >= amount+txfee )
{
if ( inputsum > amount+txfee )
{
change = (inputsum - amount);
mtx.vout.push_back(CTxOut(change,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
}
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,MarmaraCoinbaseOpret('L',height,mypk));
if ( rawtx.size() == 0 )
errorstr = (char *)"couldnt finalize CCtx";
else
{
result.push_back(Pair("result",(char *)"success"));
result.push_back(Pair("rawtx",rawtx));
return(result);
}
} else errorstr = (char *)"insufficient funds";
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",errorstr));
return(result);
}
int32_t MarmaraSignature(uint8_t *utxosig,CMutableTransaction &mtx)
{
uint256 txid,hashBlock; uint8_t *ptr; int32_t i,siglen,vout,numvouts; CTransaction tx; std::string rawtx; CPubKey mypk; std::vector<CPubKey> pubkeys; struct CCcontract_info *cp,C; uint64_t txfee;
txfee = 10000;
vout = mtx.vin[0].prevout.n;
if ( GetTransaction(mtx.vin[0].prevout.hash,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 && vout < numvouts )
{
cp = CCinit(&C,EVAL_MARMARA);
mypk = pubkey2pk(Mypubkey());
pubkeys.push_back(mypk);
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,tx.vout[numvouts - 1].scriptPubKey,pubkeys);
if ( rawtx.size() > 0 )
{
siglen = mtx.vin[0].scriptSig.size();
ptr = &mtx.vin[0].scriptSig[0];
for (i=0; i<siglen; i++)
{
utxosig[i] = ptr[i];
//fprintf(stderr,"%02x",ptr[i]);
}
//fprintf(stderr," got signed rawtx.%s siglen.%d\n",rawtx.c_str(),siglen);
return(siglen);
}
}
return(0);
}
// jl777: decide on what unlockht settlement change should have -> from utxo making change
UniValue MarmaraSettlement(uint64_t txfee,uint256 refbatontxid)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
UniValue result(UniValue::VOBJ),a(UniValue::VARR); std::vector<uint256> creditloop; uint256 batontxid,createtxid,refcreatetxid,hashBlock; uint8_t funcid; int32_t numerrs=0,i,n,numvouts,matures,refmatures,height; int64_t amount,refamount,remaining,inputsum,change; CPubKey Marmarapk,mypk,pk; std::string currency,refcurrency,rawtx; CTransaction tx,batontx; char coinaddr[64],myCCaddr[64],destaddr[64],batonCCaddr[64],str[2],txidaddr[64]; std::vector<CPubKey> pubkeys; struct CCcontract_info *cp,C;
if ( txfee == 0 )
txfee = 10000;
cp = CCinit(&C,EVAL_MARMARA);
mypk = pubkey2pk(Mypubkey());
Marmarapk = GetUnspendable(cp,0);
remaining = change = 0;
height = chainActive.LastTip()->GetHeight();
if ( (n= MarmaraGetbatontxid(creditloop,batontxid,refbatontxid)) > 0 )
{
if ( GetTransaction(batontxid,batontx,hashBlock,false) != 0 && (numvouts= batontx.vout.size()) > 1 )
{
if ( (funcid= MarmaraDecodeLoopOpret(batontx.vout[numvouts-1].scriptPubKey,refcreatetxid,pk,refamount,refmatures,refcurrency)) != 0 )
{
if ( refcreatetxid != creditloop[0] )
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"invalid refcreatetxid, setting to creditloop[0]"));
return(result);
}
else if ( chainActive.LastTip()->GetHeight() < refmatures )
{
fprintf(stderr,"doesnt mature for another %d blocks\n",refmatures - chainActive.LastTip()->GetHeight());
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"cant settle immature creditloop"));
return(result);
}
else if ( (refmatures & 1) == 0 )
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"cant automatic settle even maturity heights"));
return(result);
}
else if ( n < 1 )
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"creditloop too short"));
return(result);
}
remaining = refamount;
GetCCaddress(cp,myCCaddr,Mypubkey());
Getscriptaddress(batonCCaddr,batontx.vout[0].scriptPubKey);
if ( strcmp(myCCaddr,batonCCaddr) == 0 )
{
mtx.vin.push_back(CTxIn(n == 1 ? batontxid : creditloop[1],1,CScript())); // issuance marker
pubkeys.push_back(Marmarapk);
mtx.vin.push_back(CTxIn(batontxid,0,CScript()));
pubkeys.push_back(mypk);
for (i=1; i<n; i++)
{
if ( GetTransaction(creditloop[i],tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
{
if ( (funcid= MarmaraDecodeLoopOpret(tx.vout[numvouts-1].scriptPubKey,createtxid,pk,amount,matures,currency)) != 0 )
{
GetCCaddress1of2(cp,coinaddr,Marmarapk,pk);
if ( (inputsum= AddMarmarainputs(mtx,pubkeys,coinaddr,remaining,MARMARA_VINS)) >= remaining )
{
change = (inputsum - remaining);
mtx.vout.push_back(CTxOut(amount,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
if ( change > txfee )
mtx.vout.push_back(MakeCC1of2vout(EVAL_MARMARA,change,Marmarapk,pk));
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,MarmaraLoopOpret('S',createtxid,mypk,0,refmatures,currency),pubkeys);
result.push_back(Pair("result",(char *)"success"));
result.push_back(Pair("rawtx",rawtx));
return(result);
} else remaining -= inputsum;
if ( mtx.vin.size() >= CC_MAXVINS - MARMARA_VINS )
break;
} else fprintf(stderr,"null funcid for creditloop[%d]\n",i);
} else fprintf(stderr,"couldnt get creditloop[%d]\n",i);
}
if ( refamount - remaining > 2*txfee )
{
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(CCtxidaddr(txidaddr,createtxid))) << OP_CHECKSIG)); // failure marker
if ( refamount-remaining > 3*txfee )
mtx.vout.push_back(CTxOut(refamount-remaining-2*txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,MarmaraLoopOpret('D',createtxid,mypk,-remaining,refmatures,currency),pubkeys);
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"insufficient funds"));
result.push_back(Pair("rawtx",rawtx));
result.push_back(Pair("remaining",ValueFromAmount(remaining)));
}
else
{
// jl777: maybe fund a txfee to report no funds avail
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"no funds available at all"));
}
}
else
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"this node does not have the baton"));
result.push_back(Pair("myCCaddr",myCCaddr));
result.push_back(Pair("batonCCaddr",batonCCaddr));
}
}
else
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"couldnt get batontxid opret"));
}
}
else
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"couldnt find batontxid"));
}
}
else
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"couldnt get creditloop"));
}
return(result);
}
int32_t MarmaraGetCreditloops(int64_t &totalamount,std::vector<uint256> &issuances,int64_t &totalclosed,std::vector<uint256> &closed,struct CCcontract_info *cp,int32_t firstheight,int32_t lastheight,int64_t minamount,int64_t maxamount,CPubKey refpk,std::string refcurrency)
{ {
char coinaddr[64]; CPubKey Marmarapk,senderpk; int64_t amount; uint256 createtxid,txid,hashBlock; CTransaction tx; int32_t numvouts,vout,matures,n=0; std::string currency; char coinaddr[64]; CPubKey Marmarapk,senderpk; int64_t amount; uint256 createtxid,txid,hashBlock; CTransaction tx; int32_t numvouts,vout,matures,n=0; std::string currency;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
Marmarapk = GetUnspendable(cp,0); Marmarapk = GetUnspendable(cp,0);
GetCCaddress(cp,coinaddr,Marmarapk); GetCCaddress(cp,coinaddr,Marmarapk);
SetCCunspents(unspentOutputs,coinaddr); SetCCunspents(unspentOutputs,coinaddr);
// do all txid, conditional on spent/unspent
//fprintf(stderr,"check coinaddr.(%s)\n",coinaddr); //fprintf(stderr,"check coinaddr.(%s)\n",coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{ {
@@ -364,21 +687,24 @@ int32_t MarmaraGetCreditloops(int64_t &totalamount,std::vector<uint256> &issuanc
return(n); return(n);
} }
UniValue MarmaraReceive(uint64_t txfee,CPubKey senderpk,int64_t amount,std::string currency,int32_t matures,uint256 batontxid) UniValue MarmaraReceive(uint64_t txfee,CPubKey senderpk,int64_t amount,std::string currency,int32_t matures,uint256 batontxid,bool automaticflag)
{ {
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
UniValue result(UniValue::VOBJ); CPubKey mypk; struct CCcontract_info *cp,C; std::string rawtx; char *errorstr=0; uint256 createtxid; int64_t batonamount; int32_t needbaton = 0; UniValue result(UniValue::VOBJ); CPubKey mypk; struct CCcontract_info *cp,C; std::string rawtx; char *errorstr=0; uint256 createtxid; int64_t batonamount; int32_t needbaton = 0;
cp = CCinit(&C,EVAL_MARMARA); cp = CCinit(&C,EVAL_MARMARA);
if ( txfee == 0 ) if ( txfee == 0 )
txfee = 10000; txfee = 10000;
// check for batonownership by senderpk and parameters match createtxid if ( automaticflag != 0 && (matures & 1) == 0 )
matures++;
else if ( automaticflag == 0 && (matures & 1) != 0 )
matures++;
mypk = pubkey2pk(Mypubkey()); mypk = pubkey2pk(Mypubkey());
memset(&createtxid,0,sizeof(createtxid)); memset(&createtxid,0,sizeof(createtxid));
if ( batontxid != zeroid && MarmaraGetcreatetxid(createtxid,batontxid) < 0 ) if ( batontxid != zeroid && MarmaraGetcreatetxid(createtxid,batontxid) < 0 )
errorstr = (char *)"cant get createtxid from batontxid"; errorstr = (char *)"cant get createtxid from batontxid";
else if ( currency != "MARMARA" ) else if ( currency != "MARMARA" )
errorstr = (char *)"for now, only MARMARA loops are supported"; errorstr = (char *)"for now, only MARMARA loops are supported";
else if ( amount < txfee ) else if ( amount <= txfee )
errorstr = (char *)"amount must be for more than txfee"; errorstr = (char *)"amount must be for more than txfee";
else if ( matures <= chainActive.LastTip()->GetHeight() ) else if ( matures <= chainActive.LastTip()->GetHeight() )
errorstr = (char *)"it must mature in the future"; errorstr = (char *)"it must mature in the future";
@@ -425,17 +751,14 @@ UniValue MarmaraIssue(uint64_t txfee,uint8_t funcid,CPubKey receiverpk,int64_t a
cp = CCinit(&C,EVAL_MARMARA); cp = CCinit(&C,EVAL_MARMARA);
if ( txfee == 0 ) if ( txfee == 0 )
txfee = 10000; txfee = 10000;
// make sure receiverpk is unique to creditloop
// make sure less than maxlength // make sure less than maxlength
Marmarapk = GetUnspendable(cp,0); Marmarapk = GetUnspendable(cp,0);
mypk = pubkey2pk(Mypubkey()); mypk = pubkey2pk(Mypubkey());
if ( MarmaraGetcreatetxid(createtxid,approvaltxid) < 0 ) if ( MarmaraGetcreatetxid(createtxid,approvaltxid) < 0 )
errorstr = (char *)"cant get createtxid from approvaltxid"; errorstr = (char *)"cant get createtxid from approvaltxid";
else if ( batontxid == zeroid )
errorstr = (char *)"null batontxid";
else if ( currency != "MARMARA" ) else if ( currency != "MARMARA" )
errorstr = (char *)"for now, only MARMARA loops are supported"; errorstr = (char *)"for now, only MARMARA loops are supported";
else if ( amount < txfee ) else if ( amount <= txfee )
errorstr = (char *)"amount must be for more than txfee"; errorstr = (char *)"amount must be for more than txfee";
else if ( matures <= chainActive.LastTip()->GetHeight() ) else if ( matures <= chainActive.LastTip()->GetHeight() )
errorstr = (char *)"it must mature in the future"; errorstr = (char *)"it must mature in the future";
@@ -479,69 +802,6 @@ UniValue MarmaraIssue(uint64_t txfee,uint8_t funcid,CPubKey receiverpk,int64_t a
return(result); return(result);
} }
UniValue MarmaraSettlement(uint64_t txfee,uint256 refbatontxid)
{
UniValue result(UniValue::VOBJ),a(UniValue::VARR); std::vector<uint256> creditloop; uint256 batontxid,createtxid,refcreatetxid,hashBlock; uint8_t funcid; int32_t numerrs=0,i,n,numvouts,matures,refmatures; int64_t amount,refamount; CPubKey Marmarapk,pk; std::string currency,refcurrency; CTransaction tx,batontx; char coinaddr[64],myCCaddr[64],destaddr[64],batonCCaddr[64],str[2]; struct CCcontract_info *cp,C;
if ( txfee == 0 )
txfee = 10000;
cp = CCinit(&C,EVAL_MARMARA);
Marmarapk = GetUnspendable(cp,0);
if ( (n= MarmaraGetbatontxid(creditloop,batontxid,refbatontxid)) > 0 )
{
if ( GetTransaction(batontxid,batontx,hashBlock,false) != 0 && (numvouts= batontx.vout.size()) > 1 )
{
if ( (funcid= MarmaraDecodeLoopOpret(batontx.vout[numvouts-1].scriptPubKey,refcreatetxid,pk,refamount,refmatures,refcurrency)) != 0 )
{
if ( refcreatetxid != creditloop[0] )
{
fprintf(stderr,"invalid refcreatetxid, setting to creditloop[0]\n");
refcreatetxid = creditloop[0];
numerrs++;
}
GetCCaddress(cp,myCCaddr,Mypubkey());
Getscriptaddress(batonCCaddr,batontx.vout[0].scriptPubKey);
if ( strcmp(myCCaddr,batonCCaddr) == 0 )
{
for (i=0; i<n; i++)
{
if ( GetTransaction(creditloop[i],tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
{
if ( (funcid= MarmaraDecodeLoopOpret(tx.vout[numvouts-1].scriptPubKey,createtxid,pk,amount,matures,currency)) != 0 )
{
GetCCaddress1of2(cp,coinaddr,Marmarapk,pk);
fprintf(stderr,"get locked funds of %s %.8f\n",coinaddr,(double)CCaddress_balance(coinaddr)/COIN);
} else fprintf(stderr,"null funcid for creditloop[%d]\n",i);
} else fprintf(stderr,"couldnt get creditloop[%d]\n",i);
}
}
else
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"this node does not have the baton"));
result.push_back(Pair("myCCaddr",myCCaddr));
result.push_back(Pair("batonCCaddr",batonCCaddr));
}
}
else
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"couldnt get batontxid opret"));
}
}
else
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"couldnt find batontxid"));
}
}
else
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"couldnt get creditloop"));
}
return(result);
}
UniValue MarmaraCreditloop(uint256 txid) UniValue MarmaraCreditloop(uint256 txid)
{ {
UniValue result(UniValue::VOBJ),a(UniValue::VARR); std::vector<uint256> creditloop; uint256 batontxid,createtxid,refcreatetxid,hashBlock; uint8_t funcid; int32_t numerrs=0,i,n,numvouts,matures,refmatures; int64_t amount,refamount; CPubKey pk; std::string currency,refcurrency; CTransaction tx; char coinaddr[64],myCCaddr[64],destaddr[64],batonCCaddr[64],str[2]; struct CCcontract_info *cp,C; UniValue result(UniValue::VOBJ),a(UniValue::VARR); std::vector<uint256> creditloop; uint256 batontxid,createtxid,refcreatetxid,hashBlock; uint8_t funcid; int32_t numerrs=0,i,n,numvouts,matures,refmatures; int64_t amount,refamount; CPubKey pk; std::string currency,refcurrency; CTransaction tx; char coinaddr[64],myCCaddr[64],destaddr[64],batonCCaddr[64],str[2]; struct CCcontract_info *cp,C;
@@ -555,35 +815,69 @@ UniValue MarmaraCreditloop(uint256 txid)
result.push_back(Pair("myaddress",coinaddr)); result.push_back(Pair("myaddress",coinaddr));
GetCCaddress(cp,myCCaddr,Mypubkey()); GetCCaddress(cp,myCCaddr,Mypubkey());
result.push_back(Pair("myCCaddress",myCCaddr)); result.push_back(Pair("myCCaddress",myCCaddr));
result.push_back(Pair("batontxid",batontxid.GetHex()));
if ( (funcid= MarmaraDecodeLoopOpret(tx.vout[numvouts-1].scriptPubKey,refcreatetxid,pk,refamount,refmatures,refcurrency)) != 0 ) if ( (funcid= MarmaraDecodeLoopOpret(tx.vout[numvouts-1].scriptPubKey,refcreatetxid,pk,refamount,refmatures,refcurrency)) != 0 )
{ {
str[0] = funcid, str[1] = 0; str[0] = funcid, str[1] = 0;
result.push_back(Pair("funcid",str)); result.push_back(Pair("funcid",str));
if ( refcreatetxid != creditloop[0] )
{
fprintf(stderr,"invalid refcreatetxid, setting to creditloop[0]\n");
refcreatetxid = creditloop[0];
numerrs++;
}
result.push_back(Pair("createtxid",refcreatetxid.GetHex()));
result.push_back(Pair("amount",ValueFromAmount(refamount)));
result.push_back(Pair("matures",refmatures));
result.push_back(Pair("currency",refcurrency)); result.push_back(Pair("currency",refcurrency));
result.push_back(Pair("batonpk",HexStr(pk))); if ( funcid == 'S' )
Getscriptaddress(coinaddr,CScript() << ParseHex(HexStr(pk)) << OP_CHECKSIG);
result.push_back(Pair("batonaddr",coinaddr));
GetCCaddress(cp,batonCCaddr,pk);
result.push_back(Pair("batonCCaddr",batonCCaddr));
Getscriptaddress(coinaddr,tx.vout[0].scriptPubKey);
if ( strcmp(coinaddr,batonCCaddr) != 0 )
{ {
result.push_back(Pair("vout0address",coinaddr)); refcreatetxid = creditloop[0];
numerrs++; result.push_back(Pair("settlement",batontxid.GetHex()));
result.push_back(Pair("createtxid",refcreatetxid.GetHex()));
result.push_back(Pair("remainder",ValueFromAmount(refamount)));
result.push_back(Pair("settled",refmatures));
result.push_back(Pair("pubkey",HexStr(pk)));
Getscriptaddress(coinaddr,CScript() << ParseHex(HexStr(pk)) << OP_CHECKSIG);
result.push_back(Pair("coinaddr",coinaddr));
result.push_back(Pair("collected",ValueFromAmount(tx.vout[0].nValue)));
Getscriptaddress(destaddr,tx.vout[0].scriptPubKey);
if ( strcmp(coinaddr,destaddr) != 0 )
{
result.push_back(Pair("destaddr",destaddr));
numerrs++;
}
refamount = -1;
}
else if ( funcid == 'D' )
{
refcreatetxid = creditloop[0];
result.push_back(Pair("settlement",batontxid.GetHex()));
result.push_back(Pair("createtxid",refcreatetxid.GetHex()));
result.push_back(Pair("remainder",ValueFromAmount(refamount)));
result.push_back(Pair("settled",refmatures));
Getscriptaddress(destaddr,tx.vout[0].scriptPubKey);
result.push_back(Pair("txidaddr",destaddr));
if ( tx.vout.size() > 1 )
result.push_back(Pair("collected",ValueFromAmount(tx.vout[1].nValue)));
}
else
{
result.push_back(Pair("batontxid",batontxid.GetHex()));
result.push_back(Pair("createtxid",refcreatetxid.GetHex()));
result.push_back(Pair("amount",ValueFromAmount(refamount)));
result.push_back(Pair("matures",refmatures));
if ( refcreatetxid != creditloop[0] )
{
fprintf(stderr,"invalid refcreatetxid, setting to creditloop[0]\n");
refcreatetxid = creditloop[0];
numerrs++;
}
result.push_back(Pair("batonpk",HexStr(pk)));
Getscriptaddress(coinaddr,CScript() << ParseHex(HexStr(pk)) << OP_CHECKSIG);
result.push_back(Pair("batonaddr",coinaddr));
GetCCaddress(cp,batonCCaddr,pk);
result.push_back(Pair("batonCCaddr",batonCCaddr));
Getscriptaddress(coinaddr,tx.vout[0].scriptPubKey);
if ( strcmp(coinaddr,batonCCaddr) != 0 )
{
result.push_back(Pair("vout0address",coinaddr));
numerrs++;
}
if ( strcmp(myCCaddr,coinaddr) == 0 )
result.push_back(Pair("ismine",1));
else result.push_back(Pair("ismine",0));
} }
if ( strcmp(myCCaddr,coinaddr) == 0 )
result.push_back(Pair("ismine",1));
else result.push_back(Pair("ismine",0));
for (i=0; i<n; i++) for (i=0; i<n; i++)
{ {
if ( GetTransaction(creditloop[i],tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 ) if ( GetTransaction(creditloop[i],tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
@@ -617,6 +911,13 @@ UniValue MarmaraCreditloop(uint256 txid)
obj.push_back(Pair("vout0address",destaddr)); obj.push_back(Pair("vout0address",destaddr));
numerrs++; numerrs++;
} }
if ( i == 0 && refamount < 0 )
{
refamount = amount;
refmatures = matures;
result.push_back(Pair("amount",ValueFromAmount(refamount)));
result.push_back(Pair("matures",refmatures));
}
if ( createtxid != refcreatetxid || amount != refamount || matures != refmatures || currency != refcurrency ) if ( createtxid != refcreatetxid || amount != refamount || matures != refmatures || currency != refcurrency )
{ {
numerrs++; numerrs++;
@@ -654,43 +955,6 @@ UniValue MarmaraCreditloop(uint256 txid)
return(result); return(result);
} }
UniValue MarmaraInfo(CPubKey refpk,int32_t firstheight,int32_t lastheight,int64_t minamount,int64_t maxamount,std::string currency)
{
UniValue result(UniValue::VOBJ),a(UniValue::VARR); int32_t i,n,matches; int64_t totalamount=0; std::vector<uint256> issuances; char coinaddr[64];
CPubKey Marmarapk; struct CCcontract_info *cp,C;
result.push_back(Pair("result","success"));
Getscriptaddress(coinaddr,CScript() << ParseHex(HexStr(Mypubkey())) << OP_CHECKSIG);
result.push_back(Pair("myaddress",coinaddr));
GetCCaddress(cp,coinaddr,Mypubkey());
result.push_back(Pair("myCCaddress",coinaddr));
if ( refpk.size() == 33 )
result.push_back(Pair("issuer",HexStr(refpk)));
if ( currency.size() == 0 )
currency = (char *)"MARMARA";
if ( firstheight <= lastheight )
firstheight = 0, lastheight = (1 << 30);
if ( minamount <= maxamount )
minamount = 0, maxamount = (1LL << 60);
result.push_back(Pair("firstheight",firstheight));
result.push_back(Pair("lastheight",lastheight));
result.push_back(Pair("minamount",ValueFromAmount(minamount)));
result.push_back(Pair("maxamount",ValueFromAmount(maxamount)));
result.push_back(Pair("currency",currency));
cp = CCinit(&C,EVAL_MARMARA);
Marmarapk = GetUnspendable(cp,0);
if ( (n= MarmaraGetCreditloops(totalamount,issuances,cp,firstheight,lastheight,minamount,maxamount,refpk,currency)) > 0 )
{
result.push_back(Pair("n",n));
matches = (int32_t)issuances.size();
result.push_back(Pair("matches",matches));
for (i=0; i<matches; i++)
a.push_back(issuances[i].GetHex());
result.push_back(Pair("issuances",a));
result.push_back(Pair("totalamount",ValueFromAmount(totalamount)));
}
return(result);
}
UniValue MarmaraPoolPayout(uint64_t txfee,int32_t firstheight,double perc,char *jsonstr) // [[pk0, shares0], [pk1, shares1], ...] UniValue MarmaraPoolPayout(uint64_t txfee,int32_t firstheight,double perc,char *jsonstr) // [[pk0, shares0], [pk1, shares1], ...]
{ {
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
@@ -777,3 +1041,57 @@ UniValue MarmaraPoolPayout(uint64_t txfee,int32_t firstheight,double perc,char *
return(result); return(result);
} }
// get all tx, constrain by vout, issuances[] and closed[]
UniValue MarmaraInfo(CPubKey refpk,int32_t firstheight,int32_t lastheight,int64_t minamount,int64_t maxamount,std::string currency)
{
CMutableTransaction mtx; std::vector<CPubKey> pubkeys;
UniValue result(UniValue::VOBJ),a(UniValue::VARR),b(UniValue::VARR); int32_t i,n,matches; int64_t totalclosed=0,totalamount=0; std::vector<uint256> issuances,closed; char coinaddr[64];
CPubKey Marmarapk; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_MARMARA);
Marmarapk = GetUnspendable(cp,0);
result.push_back(Pair("result","success"));
Getscriptaddress(coinaddr,CScript() << ParseHex(HexStr(Mypubkey())) << OP_CHECKSIG);
result.push_back(Pair("myaddress",coinaddr));
result.push_back(Pair("normal",ValueFromAmount(CCaddress_balance(coinaddr))));
GetCCaddress1of2(cp,coinaddr,Marmarapk,Mypubkey());
result.push_back(Pair("myCCactivated",coinaddr));
result.push_back(Pair("activated",ValueFromAmount(CCaddress_balance(coinaddr))));
result.push_back(Pair("activated16",ValueFromAmount(AddMarmarainputs(mtx,pubkeys,coinaddr,0,MARMARA_VINS))));
GetCCaddress(cp,coinaddr,Mypubkey());
result.push_back(Pair("myCCaddress",coinaddr));
result.push_back(Pair("CCutxos",ValueFromAmount(CCaddress_balance(coinaddr))));
if ( refpk.size() == 33 )
result.push_back(Pair("issuer",HexStr(refpk)));
if ( currency.size() == 0 )
currency = (char *)"MARMARA";
if ( firstheight <= lastheight )
firstheight = 0, lastheight = (1 << 30);
if ( minamount <= maxamount )
minamount = 0, maxamount = (1LL << 60);
result.push_back(Pair("firstheight",firstheight));
result.push_back(Pair("lastheight",lastheight));
result.push_back(Pair("minamount",ValueFromAmount(minamount)));
result.push_back(Pair("maxamount",ValueFromAmount(maxamount)));
result.push_back(Pair("currency",currency));
if ( (n= MarmaraGetCreditloops(totalamount,issuances,totalclosed,closed,cp,firstheight,lastheight,minamount,maxamount,refpk,currency)) > 0 )
{
result.push_back(Pair("n",n));
matches = (int32_t)issuances.size();
result.push_back(Pair("pending",matches));
for (i=0; i<matches; i++)
a.push_back(issuances[i].GetHex());
result.push_back(Pair("issuances",a));
result.push_back(Pair("totalamount",ValueFromAmount(totalamount)));
matches = (int32_t)closed.size();
result.push_back(Pair("numclosed",matches));
for (i=0; i<matches; i++)
b.push_back(closed[i].GetHex());
result.push_back(Pair("closed",b));
result.push_back(Pair("totalclosed",ValueFromAmount(totalclosed)));
}
return(result);
}

View File

@@ -92,11 +92,6 @@ static CBlock CreateGenesisBlock(uint32_t nTime, const uint256& nNonce, const st
void *chainparams_commandline(void *ptr); void *chainparams_commandline(void *ptr);
#include "komodo_defs.h" #include "komodo_defs.h"
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT;
extern uint32_t ASSETCHAIN_INIT, ASSETCHAINS_MAGIC;
extern int32_t VERUS_BLOCK_POSUNITS, ASSETCHAINS_LWMAPOS, ASSETCHAINS_SAPLING, ASSETCHAINS_OVERWINTER;
extern uint64_t ASSETCHAINS_SUPPLY, ASSETCHAINS_ALGO, ASSETCHAINS_EQUIHASH, ASSETCHAINS_VERUSHASH;
const arith_uint256 maxUint = UintToArith256(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); const arith_uint256 maxUint = UintToArith256(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"));

View File

@@ -799,6 +799,11 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block)
uint64_t signedmask,voutmask; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp; uint64_t signedmask,voutmask; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp;
uint8_t scriptbuf[10001],pubkeys[64][33],rmd160[20],scriptPubKey[35]; uint256 zero,btctxid,txhash; uint8_t scriptbuf[10001],pubkeys[64][33],rmd160[20],scriptPubKey[35]; uint256 zero,btctxid,txhash;
int32_t i,j,k,numnotaries,notarized,scriptlen,isratification,nid,numvalid,specialtx,notarizedheight,notaryid,len,numvouts,numvins,height,txn_count; int32_t i,j,k,numnotaries,notarized,scriptlen,isratification,nid,numvalid,specialtx,notarizedheight,notaryid,len,numvouts,numvins,height,txn_count;
if ( pindex == 0 )
{
fprintf(stderr,"komodo_connectblock null pindex\n");
return;
}
memset(&zero,0,sizeof(zero)); memset(&zero,0,sizeof(zero));
komodo_init(pindex->GetHeight()); komodo_init(pindex->GetHeight());
KOMODO_INITDONE = (uint32_t)time(NULL); KOMODO_INITDONE = (uint32_t)time(NULL);
@@ -942,12 +947,15 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block)
} }
} }
} }
if ( ((signedmask & 1) != 0 && numvalid >= KOMODO_MINRATIFY) || bitweight(signedmask) > (numnotaries/3) ) if ( ASSETCHAINS_SYMBOL[0] != 0 || height < 100000 )
{ {
memset(&txhash,0,sizeof(txhash)); if ( ((signedmask & 1) != 0 && numvalid >= KOMODO_MINRATIFY) || bitweight(signedmask) > (numnotaries/3) )
komodo_stateupdate(height,pubkeys,numvalid,0,txhash,0,0,0,0,0,0,0,0,0,0,zero,0); {
printf("RATIFIED! >>>>>>>>>> new notaries.%d newheight.%d from height.%d\n",numvalid,(((height+KOMODO_ELECTION_GAP/2)/KOMODO_ELECTION_GAP)+1)*KOMODO_ELECTION_GAP,height); memset(&txhash,0,sizeof(txhash));
} else printf("signedmask.%llx numvalid.%d wt.%d numnotaries.%d\n",(long long)signedmask,numvalid,bitweight(signedmask),numnotaries); komodo_stateupdate(height,pubkeys,numvalid,0,txhash,0,0,0,0,0,0,0,0,0,0,zero,0);
printf("RATIFIED! >>>>>>>>>> new notaries.%d newheight.%d from height.%d\n",numvalid,(((height+KOMODO_ELECTION_GAP/2)/KOMODO_ELECTION_GAP)+1)*KOMODO_ELECTION_GAP,height);
} else printf("signedmask.%llx numvalid.%d wt.%d numnotaries.%d\n",(long long)signedmask,numvalid,bitweight(signedmask),numnotaries);
}
} }
} }
} }

View File

@@ -557,9 +557,9 @@ uint64_t komodo_seed(int32_t height)
return(seed); return(seed);
} }
uint32_t komodo_txtime(uint64_t *valuep,uint256 hash, int32_t n, char *destaddr) uint32_t komodo_txtime(CScript &opret,uint64_t *valuep,uint256 hash, int32_t n, char *destaddr)
{ {
CTxDestination address; CTransaction tx; uint256 hashBlock; CTxDestination address; CTransaction tx; uint256 hashBlock; int32_t numvouts;
*valuep = 0; *valuep = 0;
if (!GetTransaction(hash, tx, if (!GetTransaction(hash, tx,
#ifndef KOMODO_ZCASH #ifndef KOMODO_ZCASH
@@ -570,10 +570,12 @@ uint32_t komodo_txtime(uint64_t *valuep,uint256 hash, int32_t n, char *destaddr)
//fprintf(stderr,"ERROR: %s/v%d locktime.%u\n",hash.ToString().c_str(),n,(uint32_t)tx.nLockTime); //fprintf(stderr,"ERROR: %s/v%d locktime.%u\n",hash.ToString().c_str(),n,(uint32_t)tx.nLockTime);
return(0); return(0);
} }
numvouts = tx.vout.size();
//fprintf(stderr,"%s/v%d locktime.%u\n",hash.ToString().c_str(),n,(uint32_t)tx.nLockTime); //fprintf(stderr,"%s/v%d locktime.%u\n",hash.ToString().c_str(),n,(uint32_t)tx.nLockTime);
if ( n < tx.vout.size() ) if ( n < numvouts )
{ {
*valuep = tx.vout[n].nValue; *valuep = tx.vout[n].nValue;
opret = tx.vout[numvouts-1].scriptPubKey;
if (ExtractDestination(tx.vout[n].scriptPubKey, address)) if (ExtractDestination(tx.vout[n].scriptPubKey, address))
strcpy(destaddr,CBitcoinAddress(address).ToString().c_str()); strcpy(destaddr,CBitcoinAddress(address).ToString().c_str());
} }
@@ -614,12 +616,12 @@ uint32_t komodo_txtime2(uint64_t *valuep,uint256 hash,int32_t n,char *destaddr)
int32_t komodo_WhoStaked(CBlock *pblock, CTxDestination &addressout) int32_t komodo_WhoStaked(CBlock *pblock, CTxDestination &addressout)
{ {
int32_t n,vout; uint32_t txtime; uint64_t value; char voutaddr[64],destaddr[64]; CTxDestination voutaddress; uint256 txid; int32_t n,vout; uint32_t txtime; uint64_t value; char voutaddr[64],destaddr[64]; CTxDestination voutaddress; uint256 txid; CScript opret;
if ( (n= pblock->vtx.size()) > 1 && pblock->vtx[n-1].vin.size() == 1 && pblock->vtx[n-1].vout.size() == 1 ) if ( (n= pblock->vtx.size()) > 1 && pblock->vtx[n-1].vin.size() == 1 && pblock->vtx[n-1].vout.size() == 1 )
{ {
txid = pblock->vtx[n-1].vin[0].prevout.hash; txid = pblock->vtx[n-1].vin[0].prevout.hash;
vout = pblock->vtx[n-1].vin[0].prevout.n; vout = pblock->vtx[n-1].vin[0].prevout.n;
txtime = komodo_txtime(&value,txid,vout,destaddr); txtime = komodo_txtime(opret,&value,txid,vout,destaddr);
if ( ExtractDestination(pblock->vtx[n-1].vout[0].scriptPubKey,voutaddress) ) if ( ExtractDestination(pblock->vtx[n-1].vout[0].scriptPubKey,voutaddress) )
{ {
strcpy(voutaddr,CBitcoinAddress(voutaddress).ToString().c_str()); strcpy(voutaddr,CBitcoinAddress(voutaddress).ToString().c_str());
@@ -634,23 +636,41 @@ int32_t komodo_WhoStaked(CBlock *pblock, CTxDestination &addressout)
return(0); return(0);
} }
int32_t komodo_isPoS(CBlock *pblock) bool MarmaraPoScheck(char *destaddr,CScript opret,CTransaction staketx);
int32_t komodo_isPoS(CBlock *pblock,int32_t height)
{ {
int32_t n,vout; uint32_t txtime; uint64_t value; char voutaddr[64],destaddr[64]; CTxDestination voutaddress; uint256 txid; int32_t n,vout,numvouts; uint32_t txtime; uint64_t value; char voutaddr[64],destaddr[64]; CTxDestination voutaddress; uint256 txid; CScript opret;
if ( ASSETCHAINS_STAKED != 0 ) if ( ASSETCHAINS_STAKED != 0 )
{ {
if ( (n= pblock->vtx.size()) > 1 && pblock->vtx[n-1].vin.size() == 1 && pblock->vtx[n-1].vout.size() == 1 ) n = pblock->vtx.size();
//fprintf(stderr,"ht.%d check for PoS numtx.%d numvins.%d numvouts.%d\n",height,n,(int32_t)pblock->vtx[n-1].vin.size(),(int32_t)pblock->vtx[n-1].vout.size());
if ( n > 1 && pblock->vtx[n-1].vin.size() == 1 && pblock->vtx[n-1].vout.size() == 1+(ASSETCHAINS_MARMARA!=0) )
{ {
txid = pblock->vtx[n-1].vin[0].prevout.hash; txid = pblock->vtx[n-1].vin[0].prevout.hash;
vout = pblock->vtx[n-1].vin[0].prevout.n; vout = pblock->vtx[n-1].vin[0].prevout.n;
txtime = komodo_txtime(&value,txid,vout,destaddr); txtime = komodo_txtime(opret,&value,txid,vout,destaddr);
if ( ExtractDestination(pblock->vtx[n-1].vout[0].scriptPubKey,voutaddress) ) if ( ExtractDestination(pblock->vtx[n-1].vout[0].scriptPubKey,voutaddress) )
{ {
strcpy(voutaddr,CBitcoinAddress(voutaddress).ToString().c_str()); strcpy(voutaddr,CBitcoinAddress(voutaddress).ToString().c_str());
if ( strcmp(destaddr,voutaddr) == 0 && pblock->vtx[n-1].vout[0].nValue == value ) //fprintf(stderr,"voutaddr.%s vs destaddr.%s\n",voutaddr,destaddr);
if ( pblock->vtx[n-1].vout[0].nValue == value && strcmp(destaddr,voutaddr) == 0 )
{ {
//fprintf(stderr,"is PoS block!\n"); if ( ASSETCHAINS_MARMARA == 0 )
return(1); return(1);
else
{
if ( pblock->vtx[n-1].vout[0].scriptPubKey.IsPayToCryptoCondition() != 0 && (numvouts= pblock->vtx[n-1].vout.size()) == 2 )
{
//fprintf(stderr,"validate proper %s %s signature and unlockht preservation\n",voutaddr,destaddr);
return(MarmaraPoScheck(destaddr,opret,pblock->vtx[n-1]));
}
else
{
fprintf(stderr,"reject ht.%d PoS block\n",height);
return(strcmp(ASSETCHAINS_SYMBOL,"MTST2") == 0); // allow until MTST3
}
}
} }
} }
} }
@@ -1190,7 +1210,7 @@ uint32_t komodo_segid32(char *coinaddr)
int8_t komodo_segid(int32_t nocache,int32_t height) int8_t komodo_segid(int32_t nocache,int32_t height)
{ {
CTxDestination voutaddress; CBlock block; CBlockIndex *pindex; uint64_t value; uint32_t txtime; char voutaddr[64],destaddr[64]; int32_t txn_count,vout; uint256 txid; int8_t segid = -1; CTxDestination voutaddress; CBlock block; CBlockIndex *pindex; uint64_t value; uint32_t txtime; char voutaddr[64],destaddr[64]; int32_t txn_count,vout; uint256 txid; CScript opret; int8_t segid = -1;
if ( height > 0 && (pindex= komodo_chainactive(height)) != 0 ) if ( height > 0 && (pindex= komodo_chainactive(height)) != 0 )
{ {
if ( nocache == 0 && pindex->segid >= -1 ) if ( nocache == 0 && pindex->segid >= -1 )
@@ -1202,7 +1222,7 @@ int8_t komodo_segid(int32_t nocache,int32_t height)
{ {
txid = block.vtx[txn_count-1].vin[0].prevout.hash; txid = block.vtx[txn_count-1].vin[0].prevout.hash;
vout = block.vtx[txn_count-1].vin[0].prevout.n; vout = block.vtx[txn_count-1].vin[0].prevout.n;
txtime = komodo_txtime(&value,txid,vout,destaddr); txtime = komodo_txtime(opret,&value,txid,vout,destaddr);
if ( ExtractDestination(block.vtx[txn_count-1].vout[0].scriptPubKey,voutaddress) ) if ( ExtractDestination(block.vtx[txn_count-1].vout[0].scriptPubKey,voutaddress) )
{ {
strcpy(voutaddr,CBitcoinAddress(voutaddress).ToString().c_str()); strcpy(voutaddr,CBitcoinAddress(voutaddress).ToString().c_str());
@@ -1444,12 +1464,14 @@ int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_
pindex = it != mapBlockIndex.end() ? it->second : NULL; pindex = it != mapBlockIndex.end() ? it->second : NULL;
if ( pindex != 0 && pindex->segid >= -1 ) if ( pindex != 0 && pindex->segid >= -1 )
{ {
//fprintf(stderr,"isPoSblock segid.%d\n",pindex->segid);
if ( pindex->segid == -1 ) if ( pindex->segid == -1 )
return(0); return(0);
else return(1); else return(1);
} }
txn_count = pblock->vtx.size(); txn_count = pblock->vtx.size();
if ( txn_count > 1 && pblock->vtx[txn_count-1].vin.size() == 1 && pblock->vtx[txn_count-1].vout.size() == 1 ) //fprintf(stderr,"checkblock n.%d vins.%d vouts.%d %.8f %.8f\n",txn_count,(int32_t)pblock->vtx[txn_count-1].vin.size(),(int32_t)pblock->vtx[txn_count-1].vout.size(),(double)pblock->vtx[txn_count-1].vout[0].nValue/COIN,(double)pblock->vtx[txn_count-1].vout[1].nValue/COIN);
if ( txn_count > 1 && pblock->vtx[txn_count-1].vin.size() == 1 && pblock->vtx[txn_count-1].vout.size() == 1 + (ASSETCHAINS_MARMARA!=0) )
{ {
it = mapBlockIndex.find(pblock->hashPrevBlock); it = mapBlockIndex.find(pblock->hashPrevBlock);
if ( it != mapBlockIndex.end() && (previndex = it->second) != NULL ) if ( it != mapBlockIndex.end() && (previndex = it->second) != NULL )
@@ -1459,7 +1481,7 @@ int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_
vout = pblock->vtx[txn_count-1].vin[0].prevout.n; vout = pblock->vtx[txn_count-1].vin[0].prevout.n;
if ( prevtime != 0 ) if ( prevtime != 0 )
{ {
if ( komodo_isPoS(pblock) != 0 ) if ( komodo_isPoS(pblock,height) != 0 )
{ {
eligible = komodo_stake(1,bnTarget,height,txid,vout,pblock->nTime,prevtime+27,(char *)""); eligible = komodo_stake(1,bnTarget,height,txid,vout,pblock->nTime,prevtime+27,(char *)"");
} }
@@ -1495,7 +1517,7 @@ int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_
} }
if ( slowflag == 0 && isPoS == 0 ) // maybe previous block is not seen yet, do the best approx if ( slowflag == 0 && isPoS == 0 ) // maybe previous block is not seen yet, do the best approx
{ {
if ( komodo_isPoS(pblock) != 0 ) if ( komodo_isPoS(pblock,height) != 0 )
isPoS = 1; isPoS = 1;
} }
if ( slowflag != 0 && isPoS != 0 ) if ( slowflag != 0 && isPoS != 0 )
@@ -1808,6 +1830,7 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
return(-1); return(-1);
} }
} }
//fprintf(stderr,"ASSETCHAINS_STAKED.%d ht.%d\n",(int32_t)ASSETCHAINS_STAKED,height);
if ( ASSETCHAINS_STAKED != 0 && height >= 2 ) // must PoS or have at least 16x better PoW if ( ASSETCHAINS_STAKED != 0 && height >= 2 ) // must PoS or have at least 16x better PoW
{ {
if ( (is_PoSblock= komodo_is_PoSblock(slowflag,height,pblock,bnTarget,bhash)) == 0 ) if ( (is_PoSblock= komodo_is_PoSblock(slowflag,height,pblock,bnTarget,bhash)) == 0 )
@@ -2064,6 +2087,9 @@ uint32_t komodo_eligible(arith_uint256 bnTarget,arith_uint256 ratio,struct komod
return(0); return(0);
} }
int32_t MarmaraSignature(uint8_t *utxosig,CMutableTransaction &txNew);
uint8_t DecodeMaramaraCoinbaseOpRet(const CScript scriptPubKey,CPubKey &pk,int32_t &height,int32_t &unlockht);
int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blocktimep,uint32_t *txtimep,uint256 *utxotxidp,int32_t *utxovoutp,uint64_t *utxovaluep,uint8_t *utxosig) int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blocktimep,uint32_t *txtimep,uint256 *utxotxidp,int32_t *utxovoutp,uint64_t *utxovaluep,uint8_t *utxosig)
{ {
static struct komodo_staking *array; static int32_t numkp,maxkp; static uint32_t lasttime; static struct komodo_staking *array; static int32_t numkp,maxkp; static uint32_t lasttime;
@@ -2112,31 +2138,60 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
maxkp = numkp = 0; maxkp = numkp = 0;
lasttime = 0; lasttime = 0;
} }
BOOST_FOREACH(const COutput& out, vecOutputs) if ( ASSETCHAINS_MARMARA == 0 )
{ {
if ( (tipindex= chainActive.Tip()) == 0 || tipindex->GetHeight()+1 > nHeight ) BOOST_FOREACH(const COutput& out, vecOutputs)
{ {
fprintf(stderr,"chain tip changed during staking loop t.%u counter.%d\n",(uint32_t)time(NULL),counter); if ( (tipindex= chainActive.Tip()) == 0 || tipindex->GetHeight()+1 > nHeight )
return(0);
}
counter++;
if ( out.nDepth < nMinDepth || out.nDepth > nMaxDepth )
{
fprintf(stderr,"komodo_staked invalid depth %d\n",(int32_t)out.nDepth);
continue;
}
CAmount nValue = out.tx->vout[out.i].nValue;
if ( nValue < COIN || !out.fSpendable )
continue;
const CScript& pk = out.tx->vout[out.i].scriptPubKey;
if ( ExtractDestination(pk,address) != 0 )
{
if ( IsMine(*pwalletMain,address) == 0 )
continue;
if ( GetTransaction(out.tx->GetHash(),tx,hashBlock,true) != 0 && (pindex= komodo_getblockindex(hashBlock)) != 0 )
{ {
array = komodo_addutxo(array,&numkp,&maxkp,(uint32_t)pindex->nTime,(uint64_t)nValue,out.tx->GetHash(),out.i,(char *)CBitcoinAddress(address).ToString().c_str(),hashbuf,(CScript)pk); fprintf(stderr,"chain tip changed during staking loop t.%u counter.%d\n",(uint32_t)time(NULL),counter);
//fprintf(stderr,"addutxo numkp.%d vs max.%d\n",numkp,maxkp); return(0);
}
counter++;
if ( out.nDepth < nMinDepth || out.nDepth > nMaxDepth )
{
fprintf(stderr,"komodo_staked invalid depth %d\n",(int32_t)out.nDepth);
continue;
}
CAmount nValue = out.tx->vout[out.i].nValue;
if ( nValue < COIN || !out.fSpendable )
continue;
const CScript& pk = out.tx->vout[out.i].scriptPubKey;
if ( ExtractDestination(pk,address) != 0 )
{
if ( IsMine(*pwalletMain,address) == 0 )
continue;
if ( GetTransaction(out.tx->GetHash(),tx,hashBlock,true) != 0 && (pindex= komodo_getblockindex(hashBlock)) != 0 )
{
array = komodo_addutxo(array,&numkp,&maxkp,(uint32_t)pindex->nTime,(uint64_t)nValue,out.tx->GetHash(),out.i,(char *)CBitcoinAddress(address).ToString().c_str(),hashbuf,(CScript)pk);
//fprintf(stderr,"addutxo numkp.%d vs max.%d\n",numkp,maxkp);
}
}
}
}
else
{
struct CCcontract_info *cp,C; uint256 txid; int32_t vout,ht,unlockht; CAmount nValue; char coinaddr[64]; CPubKey mypk,Marmarapk,pk;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
cp = CCinit(&C,EVAL_MARMARA);
mypk = pubkey2pk(Mypubkey());
Marmarapk = GetUnspendable(cp,0);
GetCCaddress1of2(cp,coinaddr,Marmarapk,mypk);
SetCCunspents(unspentOutputs,coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( (nValue= it->second.satoshis) < COIN )
continue;
if ( GetTransaction(txid,tx,hashBlock,true) != 0 && (pindex= komodo_getblockindex(hashBlock)) != 0 && myIsutxo_spentinmempool(txid,vout) == 0 )
{
const CScript &scriptPubKey = tx.vout[vout].scriptPubKey;
if ( DecodeMaramaraCoinbaseOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,pk,ht,unlockht) != 0 && pk == mypk )
{
array = komodo_addutxo(array,&numkp,&maxkp,(uint32_t)pindex->nTime,(uint64_t)nValue,txid,vout,coinaddr,hashbuf,(CScript)scriptPubKey);
}
// else fprintf(stderr,"SKIP addutxo %.8f numkp.%d vs max.%d\n",(double)nValue/COIN,numkp,maxkp);
} }
} }
} }
@@ -2176,7 +2231,7 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
} }
else else
{ {
fprintf(stderr,"ht.%d error validating winning blocktime %u -> %.8f eligible.%u test prior\n",nHeight,*blocktimep,(double)kp->nValue/COIN,eligible); //fprintf(stderr,"ht.%d error validating winning blocktime %u -> %.8f eligible.%u test prior\n",nHeight,*blocktimep,(double)kp->nValue/COIN,eligible);
continue; continue;
} }
eligible = besttime; eligible = besttime;
@@ -2218,16 +2273,26 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
txNew.vout[0].nValue = *utxovaluep - txfee; txNew.vout[0].nValue = *utxovaluep - txfee;
txNew.nLockTime = earliest; txNew.nLockTime = earliest;
CTransaction txNewConst(txNew); CTransaction txNewConst(txNew);
signSuccess = ProduceSignature(TransactionSignatureCreator(&keystore, &txNewConst, 0, *utxovaluep, SIGHASH_ALL), best_scriptPubKey, sigdata, consensusBranchId); if ( ASSETCHAINS_MARMARA == 0 )
if (!signSuccess)
fprintf(stderr,"failed to create signature\n");
else
{ {
signSuccess = ProduceSignature(TransactionSignatureCreator(&keystore, &txNewConst, 0, *utxovaluep, SIGHASH_ALL), best_scriptPubKey, sigdata, consensusBranchId);
UpdateTransaction(txNew,0,sigdata); UpdateTransaction(txNew,0,sigdata);
ptr = (uint8_t *)&sigdata.scriptSig[0]; ptr = (uint8_t *)&sigdata.scriptSig[0];
siglen = sigdata.scriptSig.size(); siglen = sigdata.scriptSig.size();
for (i=0; i<siglen; i++) for (i=0; i<siglen; i++)
utxosig[i] = ptr[i];//, fprintf(stderr,"%02x",ptr[i]); utxosig[i] = ptr[i];//, fprintf(stderr,"%02x",ptr[i]);
}
else
{
siglen = MarmaraSignature(utxosig,txNew);
if ( siglen > 0 )
signSuccess = true;
else signSuccess = false;
}
if (!signSuccess)
fprintf(stderr,"failed to create signature\n");
else
{
//fprintf(stderr," siglen.%d\n",siglen); //fprintf(stderr," siglen.%d\n",siglen);
//fprintf(stderr,"best %u from %u, gap %d lag.%d\n",earliest,*blocktimep,(int32_t)(earliest - *blocktimep),(int32_t)(time(NULL) - *blocktimep)); //fprintf(stderr,"best %u from %u, gap %d lag.%d\n",earliest,*blocktimep,(int32_t)(earliest - *blocktimep),(int32_t)(time(NULL) - *blocktimep));
*blocktimep = earliest; *blocktimep = earliest;

View File

@@ -30,7 +30,49 @@
#define KOMODO_SAPLING_DEADLINE 1550188800 // Feb 15th, 2019 #define KOMODO_SAPLING_DEADLINE 1550188800 // Feb 15th, 2019
#define _COINBASE_MATURITY 100 #define _COINBASE_MATURITY 100
#define SETBIT(bits,bitoffset) (((uint8_t *)bits)[(bitoffset) >> 3] |= (1 << ((bitoffset) & 7)))
#define GETBIT(bits,bitoffset) (((uint8_t *)bits)[(bitoffset) >> 3] & (1 << ((bitoffset) & 7)))
#define CLEARBIT(bits,bitoffset) (((uint8_t *)bits)[(bitoffset) >> 3] &= ~(1 << ((bitoffset) & 7)))
extern uint8_t ASSETCHAINS_TXPOW,ASSETCHAINS_PUBLIC; extern uint8_t ASSETCHAINS_TXPOW,ASSETCHAINS_PUBLIC;
int32_t MAX_BLOCK_SIZE(int32_t height); int32_t MAX_BLOCK_SIZE(int32_t height);
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT;
extern uint32_t ASSETCHAIN_INIT, ASSETCHAINS_MAGIC;
extern int32_t VERUS_BLOCK_POSUNITS, ASSETCHAINS_LWMAPOS, ASSETCHAINS_SAPLING, ASSETCHAINS_OVERWINTER;
extern uint64_t ASSETCHAINS_SUPPLY;
extern uint64_t ASSETCHAINS_TIMELOCKGTE;
extern uint32_t ASSETCHAINS_ALGO, ASSETCHAINS_VERUSHASH,ASSETCHAINS_EQUIHASH,KOMODO_INITDONE;
extern int32_t KOMODO_MININGTHREADS,KOMODO_LONGESTCHAIN,ASSETCHAINS_SEED,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,KOMODO_ON_DEMAND,KOMODO_PASSPORT_INITDONE;
extern uint64_t ASSETCHAINS_COMMISSION, ASSETCHAINS_STAKED;
extern bool VERUS_MINTBLOCKS;
extern uint64_t ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_TIMELOCKGTE, ASSETCHAINS_NONCEMASK[];
extern const char *ASSETCHAINS_ALGORITHMS[];
extern int32_t VERUS_MIN_STAKEAGE;
extern uint32_t ASSETCHAINS_VERUSHASH, ASSETCHAINS_LASTERA, ASSETCHAINS_NONCESHIFT[], ASSETCHAINS_HASHESPERROUND[];
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
extern std::string NOTARY_PUBKEY,ASSETCHAINS_OVERRIDE_PUBKEY,ASSETCHAINS_SCRIPTPUB;
extern uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_MARMARA;
extern char ASSETCHAINS_SYMBOL[65];
extern int32_t VERUS_BLOCK_POSUNITS, VERUS_CONSECUTIVE_POS_THRESHOLD, VERUS_NOPOS_THRESHHOLD;
extern int32_t KOMODO_CONNECTING,KOMODO_CCACTIVATE,KOMODO_DEALERNODE;
extern uint32_t ASSETCHAINS_CC;
extern char ASSETCHAINS_SYMBOL[];
extern std::string CCerror,ASSETCHAINS_CCLIB;
extern uint8_t ASSETCHAINS_CCDISABLES[256];
extern int32_t USE_EXTERNAL_PUBKEY;
extern std::string NOTARY_PUBKEY;
extern int32_t KOMODO_EXCHANGEWALLET;
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
extern int32_t VERUS_MIN_STAKEAGE;
extern std::string DONATION_PUBKEY;
extern uint8_t ASSETCHAINS_PRIVATE;
extern int32_t USE_EXTERNAL_PUBKEY;
#endif #endif

View File

@@ -1388,7 +1388,7 @@ void komodo_passport_iteration()
{ {
static long lastpos[34]; static char userpass[33][1024]; static uint32_t lasttime,callcounter,lastinterest; static long lastpos[34]; static char userpass[33][1024]; static uint32_t lasttime,callcounter,lastinterest;
int32_t maxseconds = 10; int32_t maxseconds = 10;
FILE *fp; uint8_t *filedata; long fpos,datalen,lastfpos; int32_t baseid,limit,n,ht,isrealtime,expired,refid,blocks,longest; struct komodo_state *sp,*refsp; char *retstr,fname[512],*base,symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; uint32_t buf[3],starttime; cJSON *infoobj,*result; uint64_t RTmask = 0; //CBlockIndex *pindex; FILE *fp; uint8_t *filedata; long fpos,datalen,lastfpos; int32_t baseid,limit,n,ht,isrealtime,expired,refid,blocks,longest; struct komodo_state *sp,*refsp; char *retstr,fname[512],*base,symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; uint32_t buf[3],starttime; uint64_t RTmask = 0; //CBlockIndex *pindex;
expired = 0; expired = 0;
while ( KOMODO_INITDONE == 0 ) while ( KOMODO_INITDONE == 0 )
{ {

View File

@@ -48,7 +48,7 @@ unsigned int WITNESS_CACHE_SIZE = _COINBASE_MATURITY+10;
int32_t KOMODO_MININGTHREADS = -1,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND,KOMODO_CONNECTING = -1,KOMODO_DEALERNODE,KOMODO_EXTRASATOSHI,ASSETCHAINS_FOUNDERS; int32_t KOMODO_MININGTHREADS = -1,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND,KOMODO_CONNECTING = -1,KOMODO_DEALERNODE,KOMODO_EXTRASATOSHI,ASSETCHAINS_FOUNDERS;
int32_t KOMODO_INSYNC,KOMODO_LASTMINED,prevKOMODO_LASTMINED,KOMODO_CCACTIVATE,JUMBLR_PAUSE = 1; int32_t KOMODO_INSYNC,KOMODO_LASTMINED,prevKOMODO_LASTMINED,KOMODO_CCACTIVATE,JUMBLR_PAUSE = 1;
std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY,ASSETCHAINS_SCRIPTPUB,ASSETCHAINS_SELFIMPORT; std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY,ASSETCHAINS_SCRIPTPUB,ASSETCHAINS_SELFIMPORT,ASSETCHAINS_CCLIB;
uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEYHASH[20],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE,ASSETCHAINS_TXPOW,ASSETCHAINS_MARMARA; uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEYHASH[20],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE,ASSETCHAINS_TXPOW,ASSETCHAINS_MARMARA;
bool VERUS_MINTBLOCKS; bool VERUS_MINTBLOCKS;
@@ -71,6 +71,7 @@ uint64_t ASSETCHAINS_TIMEUNLOCKFROM = 0, ASSETCHAINS_TIMEUNLOCKTO = 0;
uint32_t ASSETCHAINS_LASTERA = 1; uint32_t ASSETCHAINS_LASTERA = 1;
uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS],ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS],ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS],ASSETCHAINS_DECAY[ASSETCHAINS_MAX_ERAS]; uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS],ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS],ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS],ASSETCHAINS_DECAY[ASSETCHAINS_MAX_ERAS];
uint8_t ASSETCHAINS_CCDISABLES[256];
#define _ASSETCHAINS_EQUIHASH 0 #define _ASSETCHAINS_EQUIHASH 0
uint32_t ASSETCHAINS_NUMALGOS = 2; uint32_t ASSETCHAINS_NUMALGOS = 2;

View File

@@ -629,7 +629,7 @@ uint64_t jumblr_increment(uint8_t r,int32_t height,uint64_t total,uint64_t bigge
void jumblr_iteration() void jumblr_iteration()
{ {
static int32_t lastheight; static uint32_t lasttime; static int32_t lastheight; static uint32_t lasttime;
char *zaddr,*addr,*retstr,secretaddr[64]; cJSON *array; int32_t i,iter,height,acpublic,counter,chosen_one,n; uint64_t smallest,medium,biggest,amount=0,total=0; double fee; struct jumblr_item *ptr,*tmp; uint16_t r,s; char *zaddr,*addr,*retstr=0,secretaddr[64]; cJSON *array; int32_t i,iter,height,acpublic,counter,chosen_one,n; uint64_t smallest,medium,biggest,amount=0,total=0; double fee; struct jumblr_item *ptr,*tmp; uint16_t r,s;
acpublic = ASSETCHAINS_PUBLIC; acpublic = ASSETCHAINS_PUBLIC;
if ( ASSETCHAINS_SYMBOL[0] == 0 && GetTime() >= KOMODO_SAPLING_DEADLINE ) if ( ASSETCHAINS_SYMBOL[0] == 0 && GetTime() >= KOMODO_SAPLING_DEADLINE )
acpublic = 1; acpublic = 1;
@@ -648,7 +648,7 @@ void jumblr_iteration()
} }
free_json(array); free_json(array);
} }
free(retstr); free(retstr), retstr = 0;
} }
} }
height = (int32_t)chainActive.LastTip()->GetHeight(); height = (int32_t)chainActive.LastTip()->GetHeight();
@@ -691,7 +691,7 @@ void jumblr_iteration()
if ( amount > 0 && (retstr= jumblr_sendt_to_z(Jumblr_deposit,addr,dstr(amount))) != 0 ) if ( amount > 0 && (retstr= jumblr_sendt_to_z(Jumblr_deposit,addr,dstr(amount))) != 0 )
{ {
printf("sendt_to_z.(%s)\n",retstr); printf("sendt_to_z.(%s)\n",retstr);
free(retstr); free(retstr), retstr = 0;
} }
free(zaddr); free(zaddr);
} else printf("no zaddr from jumblr_zgetnewaddress\n"); } else printf("no zaddr from jumblr_zgetnewaddress\n");
@@ -723,7 +723,7 @@ void jumblr_iteration()
if ( (retstr= jumblr_sendz_to_z(ptr->dest,addr,dstr(total))) != 0 ) if ( (retstr= jumblr_sendz_to_z(ptr->dest,addr,dstr(total))) != 0 )
{ {
printf("n.%d counter.%d chosen_one.%d send z_to_z.(%s)\n",n,counter,chosen_one,retstr); printf("n.%d counter.%d chosen_one.%d send z_to_z.(%s)\n",n,counter,chosen_one,retstr);
free(retstr); free(retstr), retstr = 0;
} }
ptr->spent = (uint32_t)time(NULL); ptr->spent = (uint32_t)time(NULL);
free(zaddr); free(zaddr);
@@ -768,7 +768,7 @@ void jumblr_iteration()
if ( (retstr= jumblr_sendz_to_t(ptr->dest,secretaddr,dstr(total))) != 0 ) if ( (retstr= jumblr_sendz_to_t(ptr->dest,secretaddr,dstr(total))) != 0 )
{ {
printf("%s send z_to_t.(%s)\n",secretaddr,retstr); printf("%s send z_to_t.(%s)\n",secretaddr,retstr);
free(retstr); free(retstr), retstr = 0;
} else printf("null return from jumblr_sendz_to_t\n"); } else printf("null return from jumblr_sendz_to_t\n");
ptr->spent = (uint32_t)time(NULL); ptr->spent = (uint32_t)time(NULL);
break; break;

View File

@@ -1654,9 +1654,10 @@ extern int64_t MAX_MONEY;
void komodo_args(char *argv0) void komodo_args(char *argv0)
{ {
extern const char *Notaries_elected1[][2]; extern const char *Notaries_elected1[][2];
std::string name,addn; char *dirname,fname[512],arg0str[64],magicstr[9]; uint8_t magic[4],extrabuf[8192],*extraptr=0; FILE *fp; uint64_t val; uint16_t port; int32_t i,baseid,len,n,extralen = 0; std::string name,addn; char *dirname,fname[512],arg0str[64],magicstr[9]; uint8_t magic[4],extrabuf[8192],disablebits[32],*extraptr=0; FILE *fp; uint64_t val; uint16_t port; int32_t i,nonz,baseid,len,n,extralen = 0; uint64_t ccenables[256];
IS_KOMODO_NOTARY = GetBoolArg("-notary", false); IS_KOMODO_NOTARY = GetBoolArg("-notary", false);
memset(ccenables,0,sizeof(ccenables));
memset(disablebits,0,sizeof(disablebits));
if ( GetBoolArg("-gen", false) != 0 ) if ( GetBoolArg("-gen", false) != 0 )
{ {
KOMODO_MININGTHREADS = GetArg("-genproclimit",-1); KOMODO_MININGTHREADS = GetArg("-genproclimit",-1);
@@ -1779,6 +1780,33 @@ void komodo_args(char *argv0)
ASSETCHAINS_BEAMPORT = GetArg("-ac_beam",0); ASSETCHAINS_BEAMPORT = GetArg("-ac_beam",0);
ASSETCHAINS_CODAPORT = GetArg("-ac_coda",0); ASSETCHAINS_CODAPORT = GetArg("-ac_coda",0);
ASSETCHAINS_MARMARA = GetArg("-ac_marmara",0); ASSETCHAINS_MARMARA = GetArg("-ac_marmara",0);
if ( ASSETCHAINS_CC != 0 )
{
ASSETCHAINS_CCLIB = GetArg("-ac_cclib","");
Split(GetArg("-ac_ccenable",""), ccenables, 0);
for (i=nonz=0; i<0x100; i++)
{
if ( ccenables[i] != 0 )
{
nonz++;
fprintf(stderr,"%d ",(uint8_t)(ccenables[i] & 0xff));
}
}
fprintf(stderr,"nonz.%d ccenables[]\n",nonz);
if ( nonz > 0 )
{
for (i=0; i<256; i++)
{
ASSETCHAINS_CCDISABLES[i] = 1;
SETBIT(disablebits,i);
}
for (i=0; i<256; i++)
{
CLEARBIT(disablebits,(ccenables[i] & 0xff));
ASSETCHAINS_CCDISABLES[ccenables[i] & 0xff] = 0;
}
}
}
if ( ASSETCHAINS_BEAMPORT != 0 && ASSETCHAINS_CODAPORT != 0 ) if ( ASSETCHAINS_BEAMPORT != 0 && ASSETCHAINS_CODAPORT != 0 )
{ {
fprintf(stderr,"can only have one of -ac_beam or -ac_coda\n"); fprintf(stderr,"can only have one of -ac_beam or -ac_coda\n");
@@ -1863,7 +1891,7 @@ void komodo_args(char *argv0)
fprintf(stderr,"-ac_script and -ac_marmara are mutually exclusive\n"); fprintf(stderr,"-ac_script and -ac_marmara are mutually exclusive\n");
exit(0); exit(0);
} }
if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 || ASSETCHAINS_REWARD[0] != 0 || ASSETCHAINS_HALVING[0] != 0 || ASSETCHAINS_DECAY[0] != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 || ASSETCHAINS_FOUNDERS != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1 || ASSETCHAINS_SELFIMPORT.size() > 0 || ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF|| ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH || ASSETCHAINS_LWMAPOS != 0 || ASSETCHAINS_LASTERA > 0 || ASSETCHAINS_BEAMPORT != 0 || ASSETCHAINS_CODAPORT != 0 || ASSETCHAINS_MARMARA != 0 ) if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 || ASSETCHAINS_REWARD[0] != 0 || ASSETCHAINS_HALVING[0] != 0 || ASSETCHAINS_DECAY[0] != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 || ASSETCHAINS_FOUNDERS != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1 || ASSETCHAINS_SELFIMPORT.size() > 0 || ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF|| ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH || ASSETCHAINS_LWMAPOS != 0 || ASSETCHAINS_LASTERA > 0 || ASSETCHAINS_BEAMPORT != 0 || ASSETCHAINS_CODAPORT != 0 || ASSETCHAINS_MARMARA != 0 || nonz > 0 || ASSETCHAINS_CCLIB.size() > 0 )
{ {
fprintf(stderr,"perc %.4f%% ac_pub=[%02x%02x%02x...] acsize.%d\n",dstr(ASSETCHAINS_COMMISSION)*100,ASSETCHAINS_OVERRIDE_PUBKEY33[0],ASSETCHAINS_OVERRIDE_PUBKEY33[1],ASSETCHAINS_OVERRIDE_PUBKEY33[2],(int32_t)ASSETCHAINS_SCRIPTPUB.size()); fprintf(stderr,"perc %.4f%% ac_pub=[%02x%02x%02x...] acsize.%d\n",dstr(ASSETCHAINS_COMMISSION)*100,ASSETCHAINS_OVERRIDE_PUBKEY33[0],ASSETCHAINS_OVERRIDE_PUBKEY33[1],ASSETCHAINS_OVERRIDE_PUBKEY33[2],(int32_t)ASSETCHAINS_SCRIPTPUB.size());
extraptr = extrabuf; extraptr = extrabuf;
@@ -1939,6 +1967,20 @@ void komodo_args(char *argv0)
extraptr[extralen++] = 'c'; extraptr[extralen++] = 'c';
if ( ASSETCHAINS_MARMARA != 0 ) if ( ASSETCHAINS_MARMARA != 0 )
extraptr[extralen++] = ASSETCHAINS_MARMARA; extraptr[extralen++] = ASSETCHAINS_MARMARA;
if ( nonz > 0 )
{
memcpy(&extraptr[extralen],disablebits,sizeof(disablebits));
extralen += sizeof(disablebits);
}
if ( ASSETCHAINS_CCLIB.size() > 1 )
{
for (i=0; i<ASSETCHAINS_CCLIB.size(); i++)
{
extraptr[extralen++] = ASSETCHAINS_CCLIB[i];
fprintf(stderr,"%c",ASSETCHAINS_CCLIB[i]);
}
fprintf(stderr," <- CCLIB name\n");
}
} }
addn = GetArg("-seednode",""); addn = GetArg("-seednode","");

View File

@@ -3497,6 +3497,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
CDiskBlockPos pos; CDiskBlockPos pos;
if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40)) if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
return error("ConnectBlock(): FindUndoPos failed"); return error("ConnectBlock(): FindUndoPos failed");
if ( pindex->pprev == 0 )
fprintf(stderr,"ConnectBlock: unexpected null pprev\n");
if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart())) if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart()))
return AbortNode(state, "Failed to write undo data"); return AbortNode(state, "Failed to write undo data");
@@ -3804,7 +3806,7 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) {
CValidationState stateDummy; CValidationState stateDummy;
// don't keep staking or invalid transactions // don't keep staking or invalid transactions
if (tx.IsCoinBase() || ((i == (block.vtx.size() - 1)) && (ASSETCHAINS_STAKED && komodo_isPoS((CBlock *)&block) != 0)) || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL)) if (tx.IsCoinBase() || ((i == (block.vtx.size() - 1)) && (ASSETCHAINS_STAKED && komodo_isPoS((CBlock *)&block,pindexDelete->GetHeight()) != 0)) || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
{ {
mempool.remove(tx, removed, true); mempool.remove(tx, removed, true);
} }
@@ -3835,7 +3837,7 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) {
{ {
CTransaction &tx = block.vtx[i]; CTransaction &tx = block.vtx[i];
//if ((i == (block.vtx.size() - 1)) && ((ASSETCHAINS_LWMAPOS && block.IsVerusPOSBlock()) || (ASSETCHAINS_STAKED != 0 && (komodo_isPoS((CBlock *)&block) != 0)))) //if ((i == (block.vtx.size() - 1)) && ((ASSETCHAINS_LWMAPOS && block.IsVerusPOSBlock()) || (ASSETCHAINS_STAKED != 0 && (komodo_isPoS((CBlock *)&block) != 0))))
if ((i == (block.vtx.size() - 1)) && (ASSETCHAINS_STAKED != 0 && (komodo_isPoS((CBlock *)&block) != 0))) if ((i == (block.vtx.size() - 1)) && (ASSETCHAINS_STAKED != 0 && (komodo_isPoS((CBlock *)&block,pindexDelete->GetHeight()) != 0)))
{ {
EraseFromWallets(tx.GetHash()); EraseFromWallets(tx.GetHash());
} }
@@ -4732,7 +4734,7 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
CValidationState state; CValidationState state;
CTransaction Tx; CTransaction Tx;
const CTransaction &tx = (CTransaction)block.vtx[i]; const CTransaction &tx = (CTransaction)block.vtx[i];
if (tx.IsCoinBase() || !tx.vjoinsplit.empty() || !tx.vShieldedSpend.empty() || ((i == (block.vtx.size() - 1)) && (ASSETCHAINS_STAKED && komodo_isPoS((CBlock *)&block) != 0))) if (tx.IsCoinBase() || !tx.vjoinsplit.empty() || !tx.vShieldedSpend.empty() || ((i == (block.vtx.size() - 1)) && (ASSETCHAINS_STAKED && komodo_isPoS((CBlock *)&block,height) != 0)))
continue; continue;
Tx = tx; Tx = tx;
if ( myAddtomempool(Tx, &state, true) == false ) // happens with out of order tx in block on resync if ( myAddtomempool(Tx, &state, true) == false ) // happens with out of order tx in block on resync

View File

@@ -39,8 +39,7 @@
#endif #endif
#include <unistd.h> #include <unistd.h>
extern uint64_t ASSETCHAINS_TIMELOCKGTE; #include "komodo_defs.h"
extern uint32_t ASSETCHAINS_ALGO, ASSETCHAINS_VERUSHASH;
int64_t komodo_block_unlocktime(uint32_t nHeight); int64_t komodo_block_unlocktime(uint32_t nHeight);
void AtomicTimer::start() void AtomicTimer::start()

View File

@@ -132,17 +132,8 @@ void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams,
#include "komodo_defs.h" #include "komodo_defs.h"
extern CCriticalSection cs_metrics; extern CCriticalSection cs_metrics;
extern int32_t KOMODO_MININGTHREADS,KOMODO_LONGESTCHAIN,ASSETCHAINS_SEED,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAIN_INIT,KOMODO_INITDONE,KOMODO_ON_DEMAND,KOMODO_INITDONE,KOMODO_PASSPORT_INITDONE;
extern uint64_t ASSETCHAINS_COMMISSION, ASSETCHAINS_STAKED;
extern bool VERUS_MINTBLOCKS;
extern uint64_t ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_TIMELOCKGTE, ASSETCHAINS_NONCEMASK[];
extern const char *ASSETCHAINS_ALGORITHMS[];
extern int32_t VERUS_MIN_STAKEAGE, ASSETCHAINS_ALGO, ASSETCHAINS_EQUIHASH, ASSETCHAINS_VERUSHASH, ASSETCHAINS_LASTERA, ASSETCHAINS_LWMAPOS, ASSETCHAINS_NONCESHIFT[], ASSETCHAINS_HASHESPERROUND[];
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
extern std::string NOTARY_PUBKEY,ASSETCHAINS_OVERRIDE_PUBKEY,ASSETCHAINS_SCRIPTPUB;
void vcalc_sha256(char deprecated[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uint8_t *src,int32_t len); void vcalc_sha256(char deprecated[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uint8_t *src,int32_t len);
extern uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_MARMARA;
uint32_t Mining_start,Mining_height; uint32_t Mining_start,Mining_height;
int32_t My_notaryid = -1; int32_t My_notaryid = -1;
int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,uint32_t timestamp); int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,uint32_t timestamp);
@@ -158,6 +149,7 @@ int32_t komodo_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33);
int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex); int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex);
CScript Marmara_scriptPubKey(int32_t height,CPubKey pk); CScript Marmara_scriptPubKey(int32_t height,CPubKey pk);
CScript MarmaraCoinbaseOpret(uint8_t funcid,int32_t height,CPubKey pk); CScript MarmaraCoinbaseOpret(uint8_t funcid,int32_t height,CPubKey pk);
bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey);
CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32_t gpucount, bool isStake) CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32_t gpucount, bool isStake)
{ {
@@ -486,7 +478,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
{ {
LEAVE_CRITICAL_SECTION(cs_main); LEAVE_CRITICAL_SECTION(cs_main);
LEAVE_CRITICAL_SECTION(mempool.cs); LEAVE_CRITICAL_SECTION(mempool.cs);
uint64_t txfees,utxovalue; uint32_t txtime; uint256 utxotxid; int32_t i,siglen,numsigs,utxovout; uint8_t utxosig[128],*ptr; uint64_t txfees,utxovalue; uint32_t txtime; uint256 utxotxid; int32_t i,siglen,numsigs,utxovout; uint8_t utxosig[512],*ptr;
CMutableTransaction txStaked = CreateNewContextualCMutableTransaction(Params().GetConsensus(), stakeHeight); CMutableTransaction txStaked = CreateNewContextualCMutableTransaction(Params().GetConsensus(), stakeHeight);
if (ASSETCHAINS_LWMAPOS != 0) if (ASSETCHAINS_LWMAPOS != 0)
@@ -520,7 +512,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
pblocktemplate->vTxSigOps.push_back(GetLegacySigOpCount(txStaked)); pblocktemplate->vTxSigOps.push_back(GetLegacySigOpCount(txStaked));
nFees += txfees; nFees += txfees;
pblock->nTime = blocktime; pblock->nTime = blocktime;
//printf("staking PoS ht.%d t%u lag.%u\n",(int32_t)chainActive.LastTip()->GetHeight()+1,blocktime,(uint32_t)(GetAdjustedTime() - (blocktime-13))); printf("staking PoS ht.%d t%u lag.%u\n",(int32_t)chainActive.LastTip()->GetHeight()+1,blocktime,(uint32_t)(GetAdjustedTime() - (blocktime-13)));
} else return(0); //fprintf(stderr,"no utxos eligible for staking\n"); } else return(0); //fprintf(stderr,"no utxos eligible for staking\n");
} }
// Create coinbase tx // Create coinbase tx
@@ -540,11 +532,11 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
txNew.vout[0].nValue += 5000; txNew.vout[0].nValue += 5000;
pblock->vtx[0] = txNew; pblock->vtx[0] = txNew;
//fprintf(stderr,"ht.%d cmp.%d [%d %d %d %d %d]\n",nHeight,nHeight > 1 && ASSETCHAINS_SYMBOL[0] != 0 && (ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1) && ASSETCHAINS_COMMISSION != 0 && (commission= komodo_commission((CBlock*)&pblocktemplate->block,(int32_t)nHeight)) != 0,nHeight > 1,ASSETCHAINS_SYMBOL[0] != 0, (ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1), ASSETCHAINS_COMMISSION != 0,(commission= komodo_commission((CBlock*)&pblocktemplate->block,(int32_t)nHeight)) != 0);
// check if coinbase transactions must be time locked at current subsidy and prepend the time lock
// to transaction if so, cast for GTE operator
if ( ASSETCHAINS_MARMARA != 0 && nHeight > 0 && (nHeight & 1) == 0 ) if ( ASSETCHAINS_MARMARA != 0 && nHeight > 0 && (nHeight & 1) == 0 )
{ {
char checkaddr[64];
Getscriptaddress(checkaddr,txNew.vout[0].scriptPubKey);
//`fprintf(stderr,"set mining coinbase -> %s\n",checkaddr);
txNew.vout.resize(2); txNew.vout.resize(2);
txNew.vout[1].nValue = 0; txNew.vout[1].nValue = 0;
txNew.vout[1].scriptPubKey = MarmaraCoinbaseOpret('C',nHeight,pk); txNew.vout[1].scriptPubKey = MarmaraCoinbaseOpret('C',nHeight,pk);
@@ -1605,11 +1597,11 @@ void static BitcoinMiner()
int32_t percPoS,z; bool fNegative,fOverflow; int32_t percPoS,z; bool fNegative,fOverflow;
HASHTarget_POW = komodo_PoWtarget(&percPoS,HASHTarget,Mining_height,ASSETCHAINS_STAKED); HASHTarget_POW = komodo_PoWtarget(&percPoS,HASHTarget,Mining_height,ASSETCHAINS_STAKED);
HASHTarget.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow); HASHTarget.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow);
if ( ASSETCHAINS_STAKED < 100 ) if ( ASSETCHAINS_STAKED < 100 && KOMODO_MININGTHREADS == 0 )
{ {
for (z=31; z>=0; z--) for (z=31; z>=0; z--)
fprintf(stderr,"%02x",((uint8_t *)&HASHTarget_POW)[z]); fprintf(stderr,"%02x",((uint8_t *)&HASHTarget_POW)[z]);
fprintf(stderr," PoW for staked coin PoS %d%% vs target %d%%\n",percPoS,(int32_t)ASSETCHAINS_STAKED); fprintf(stderr," PoW for staked coin PoS %d%% vs target %d%% ht.%d\n",percPoS,(int32_t)ASSETCHAINS_STAKED,Mining_height);
} }
} }
while (true) while (true)

View File

@@ -37,9 +37,8 @@
#endif // ENABLE_RUST #endif // ENABLE_RUST
uint32_t komodo_chainactive_timestamp(); uint32_t komodo_chainactive_timestamp();
extern uint32_t ASSETCHAINS_ALGO, ASSETCHAINS_EQUIHASH, ASSETCHAINS_STAKED; #include "komodo_defs.h"
extern char ASSETCHAINS_SYMBOL[65];
extern int32_t ASSETCHAINS_LWMAPOS,VERUS_BLOCK_POSUNITS, VERUS_CONSECUTIVE_POS_THRESHOLD, VERUS_NOPOS_THRESHHOLD;
unsigned int lwmaGetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params); unsigned int lwmaGetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params);
unsigned int lwmaCalculateNextWorkRequired(const CBlockIndex* pindexLast, const Consensus::Params& params); unsigned int lwmaCalculateNextWorkRequired(const CBlockIndex* pindexLast, const Consensus::Params& params);

View File

@@ -24,8 +24,8 @@
#include "tinyformat.h" #include "tinyformat.h"
#include "utilstrencodings.h" #include "utilstrencodings.h"
#include "crypto/common.h" #include "crypto/common.h"
#include "komodo_defs.h"
extern uint32_t ASSETCHAINS_ALGO, ASSETCHAINS_VERUSHASH;
// default hash algorithm for block // default hash algorithm for block
uint256 (CBlockHeader::*CBlockHeader::hashFunction)() const = &CBlockHeader::GetSHA256DHash; uint256 (CBlockHeader::*CBlockHeader::hashFunction)() const = &CBlockHeader::GetSHA256DHash;

View File

@@ -48,10 +48,8 @@
using namespace std; using namespace std;
extern int32_t ASSETCHAINS_ALGO, ASSETCHAINS_EQUIHASH, ASSETCHAINS_LWMAPOS; #include "komodo_defs.h"
extern uint64_t ASSETCHAINS_STAKED;
extern int32_t KOMODO_MININGTHREADS;
extern bool VERUS_MINTBLOCKS;
arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc); arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc);
/** /**

View File

@@ -77,7 +77,8 @@ int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heig
extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT; extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT;
extern uint32_t ASSETCHAINS_CC; extern uint32_t ASSETCHAINS_CC;
extern uint32_t ASSETCHAINS_MAGIC; extern uint32_t ASSETCHAINS_MAGIC;
extern uint64_t ASSETCHAINS_COMMISSION,ASSETCHAINS_STAKED,ASSETCHAINS_SUPPLY,ASSETCHAINS_LASTERA; extern uint64_t ASSETCHAINS_COMMISSION,ASSETCHAINS_STAKED,ASSETCHAINS_SUPPLY;
extern uint32_t ASSETCHAINS_LASTERA;
extern int32_t ASSETCHAINS_LWMAPOS,ASSETCHAINS_SAPLING; extern int32_t ASSETCHAINS_LWMAPOS,ASSETCHAINS_SAPLING;
extern uint64_t ASSETCHAINS_ENDSUBSIDY[],ASSETCHAINS_REWARD[],ASSETCHAINS_HALVING[],ASSETCHAINS_DECAY[]; extern uint64_t ASSETCHAINS_ENDSUBSIDY[],ASSETCHAINS_REWARD[],ASSETCHAINS_HALVING[],ASSETCHAINS_DECAY[];
extern std::string NOTARY_PUBKEY; extern uint8_t NOTARY_PUBKEY33[]; extern std::string NOTARY_PUBKEY; extern uint8_t NOTARY_PUBKEY33[];
@@ -224,7 +225,7 @@ UniValue getinfo(const UniValue& params, bool fHelp)
} }
} }
if (ASSETCHAINS_LASTERA > 0) if (ASSETCHAINS_LASTERA > 0)
obj.push_back(Pair("eras", ASSETCHAINS_LASTERA + 1)); obj.push_back(Pair("eras", (int64_t)(ASSETCHAINS_LASTERA + 1)));
obj.push_back(Pair("reward", acReward)); obj.push_back(Pair("reward", acReward));
obj.push_back(Pair("halving", acHalving)); obj.push_back(Pair("halving", acHalving));
obj.push_back(Pair("decay", acDecay)); obj.push_back(Pair("decay", acDecay));

View File

@@ -458,10 +458,15 @@ static const CRPCCommand vRPCCommands[] =
{ "marmara", "marmarainfo", &marmara_info, true }, { "marmara", "marmarainfo", &marmara_info, true },
{ "marmara", "marmaracreditloop", &marmara_creditloop, true }, { "marmara", "marmaracreditloop", &marmara_creditloop, true },
{ "marmara", "marmarasettlement", &marmara_settlement, true }, { "marmara", "marmarasettlement", &marmara_settlement, true },
{ "marmara", "marmaralock", &marmara_lock, true },
// Payments // Payments
{ "payments", "paymentsaddress", &paymentsaddress, true }, { "payments", "paymentsaddress", &paymentsaddress, true },
{ "CClib", "cclibaddress", &cclibaddress, true },
{ "CClib", "cclibinfo", &cclibinfo, true },
{ "CClib", "cclib", &cclib, true },
// Gateways // Gateways
{ "gateways", "gatewaysaddress", &gatewaysaddress, true }, { "gateways", "gatewaysaddress", &gatewaysaddress, true },
{ "gateways", "gatewayslist", &gatewayslist, true }, { "gateways", "gatewayslist", &gatewayslist, true },
@@ -532,6 +537,9 @@ static const CRPCCommand vRPCCommands[] =
{ "util", "reconsiderblock", &reconsiderblock, true }, { "util", "reconsiderblock", &reconsiderblock, true },
/* Not shown in help */ /* Not shown in help */
{ "hidden", "setmocktime", &setmocktime, true }, { "hidden", "setmocktime", &setmocktime, true },
{ "hidden", "test_ac", &test_ac, true },
{ "hidden", "test_heirmarker", &test_heirmarker, true },
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
/* Wallet */ /* Wallet */
{ "wallet", "resendwallettransactions", &resendwallettransactions, true}, { "wallet", "resendwallettransactions", &resendwallettransactions, true},

View File

@@ -285,7 +285,11 @@ extern UniValue marmara_transfer(const UniValue& params, bool fHelp);
extern UniValue marmara_info(const UniValue& params, bool fHelp); extern UniValue marmara_info(const UniValue& params, bool fHelp);
extern UniValue marmara_creditloop(const UniValue& params, bool fHelp); extern UniValue marmara_creditloop(const UniValue& params, bool fHelp);
extern UniValue marmara_settlement(const UniValue& params, bool fHelp); extern UniValue marmara_settlement(const UniValue& params, bool fHelp);
extern UniValue marmara_lock(const UniValue& params, bool fHelp);
extern UniValue paymentsaddress(const UniValue& params, bool fHelp); extern UniValue paymentsaddress(const UniValue& params, bool fHelp);
extern UniValue cclibaddress(const UniValue& params, bool fHelp);
extern UniValue cclibinfo(const UniValue& params, bool fHelp);
extern UniValue cclib(const UniValue& params, bool fHelp);
extern UniValue gatewaysaddress(const UniValue& params, bool fHelp); extern UniValue gatewaysaddress(const UniValue& params, bool fHelp);
extern UniValue gatewayslist(const UniValue& params, bool fHelp); extern UniValue gatewayslist(const UniValue& params, bool fHelp);
extern UniValue gatewaysinfo(const UniValue& params, bool fHelp); extern UniValue gatewaysinfo(const UniValue& params, bool fHelp);
@@ -467,4 +471,8 @@ extern UniValue paxprices(const UniValue& params, bool fHelp);
extern UniValue paxdeposit(const UniValue& params, bool fHelp); extern UniValue paxdeposit(const UniValue& params, bool fHelp);
extern UniValue paxwithdraw(const UniValue& params, bool fHelp); extern UniValue paxwithdraw(const UniValue& params, bool fHelp);
// test rpc:
extern UniValue test_ac(const UniValue& params, bool fHelp);
extern UniValue test_heirmarker(const UniValue& params, bool fHelp);
#endif // BITCOIN_RPCSERVER_H #endif // BITCOIN_RPCSERVER_H

View File

@@ -340,39 +340,39 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
switch (whichTypeRet) switch (whichTypeRet)
{ {
case TX_NONSTANDARD: case TX_NONSTANDARD:
case TX_NULL_DATA: case TX_NULL_DATA:
return false;
case TX_PUBKEY:
keyID = CPubKey(vSolutions[0]).GetID();
return Sign1(keyID, creator, scriptPubKey, ret, consensusBranchId);
case TX_PUBKEYHASH:
keyID = CKeyID(uint160(vSolutions[0]));
if (!Sign1(keyID, creator, scriptPubKey, ret, consensusBranchId))
return false; return false;
else case TX_PUBKEY:
{ keyID = CPubKey(vSolutions[0]).GetID();
CPubKey vch; return Sign1(keyID, creator, scriptPubKey, ret, consensusBranchId);
creator.KeyStore().GetPubKey(keyID, vch); case TX_PUBKEYHASH:
ret.push_back(ToByteVector(vch)); keyID = CKeyID(uint160(vSolutions[0]));
} if (!Sign1(keyID, creator, scriptPubKey, ret, consensusBranchId))
return true; return false;
case TX_SCRIPTHASH: else
if (creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptRet)) { {
ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end())); CPubKey vch;
creator.KeyStore().GetPubKey(keyID, vch);
ret.push_back(ToByteVector(vch));
}
return true; return true;
} case TX_SCRIPTHASH:
return false; if (creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptRet)) {
ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
return true;
}
return false;
case TX_CRYPTOCONDITION: case TX_CRYPTOCONDITION:
return SignStepCC(creator, scriptPubKey, vSolutions, ret, consensusBranchId); return SignStepCC(creator, scriptPubKey, vSolutions, ret, consensusBranchId);
case TX_MULTISIG: case TX_MULTISIG:
ret.push_back(valtype()); // workaround CHECKMULTISIG bug ret.push_back(valtype()); // workaround CHECKMULTISIG bug
return (SignN(vSolutions, creator, scriptPubKey, ret, consensusBranchId)); return (SignN(vSolutions, creator, scriptPubKey, ret, consensusBranchId));
default: default:
return false; return false;
} }
} }
@@ -431,13 +431,13 @@ void UpdateTransaction(CMutableTransaction& tx, unsigned int nIn, const Signatur
} }
bool SignSignature( bool SignSignature(
const CKeyStore &keystore, const CKeyStore &keystore,
const CScript& fromPubKey, const CScript& fromPubKey,
CMutableTransaction& txTo, CMutableTransaction& txTo,
unsigned int nIn, unsigned int nIn,
const CAmount& amount, const CAmount& amount,
int nHashType, int nHashType,
uint32_t consensusBranchId) uint32_t consensusBranchId)
{ {
assert(nIn < txTo.vin.size()); assert(nIn < txTo.vin.size());
@@ -451,12 +451,12 @@ bool SignSignature(
} }
bool SignSignature( bool SignSignature(
const CKeyStore &keystore, const CKeyStore &keystore,
const CTransaction& txFrom, const CTransaction& txFrom,
CMutableTransaction& txTo, CMutableTransaction& txTo,
unsigned int nIn, unsigned int nIn,
int nHashType, int nHashType,
uint32_t consensusBranchId) uint32_t consensusBranchId)
{ {
assert(nIn < txTo.vin.size()); assert(nIn < txTo.vin.size());
CTxIn& txin = txTo.vin[nIn]; CTxIn& txin = txTo.vin[nIn];
@@ -467,8 +467,8 @@ bool SignSignature(
} }
static vector<valtype> CombineMultisig(const CScript& scriptPubKey, const BaseSignatureChecker& checker, static vector<valtype> CombineMultisig(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
const vector<valtype>& vSolutions, const vector<valtype>& vSolutions,
const vector<valtype>& sigs1, const vector<valtype>& sigs2, uint32_t consensusBranchId) const vector<valtype>& sigs1, const vector<valtype>& sigs2, uint32_t consensusBranchId)
{ {
// Combine all the signatures we've got: // Combine all the signatures we've got:
set<valtype> allsigs; set<valtype> allsigs;
@@ -523,102 +523,102 @@ static vector<valtype> CombineMultisig(const CScript& scriptPubKey, const BaseSi
namespace namespace
{ {
struct Stacks struct Stacks
{ {
std::vector<valtype> script; std::vector<valtype> script;
Stacks() {} Stacks() {}
explicit Stacks(const std::vector<valtype>& scriptSigStack_) : script(scriptSigStack_) {} explicit Stacks(const std::vector<valtype>& scriptSigStack_) : script(scriptSigStack_) {}
explicit Stacks(const SignatureData& data, uint32_t consensusBranchId) { explicit Stacks(const SignatureData& data, uint32_t consensusBranchId) {
EvalScript(script, data.scriptSig, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), consensusBranchId); EvalScript(script, data.scriptSig, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), consensusBranchId);
} }
SignatureData Output() const { SignatureData Output() const {
SignatureData result; SignatureData result;
result.scriptSig = PushAll(script); result.scriptSig = PushAll(script);
return result; return result;
} }
}; };
} }
static Stacks CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker, static Stacks CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
const txnouttype txType, const vector<valtype>& vSolutions, const txnouttype txType, const vector<valtype>& vSolutions,
Stacks sigs1, Stacks sigs2, uint32_t consensusBranchId) Stacks sigs1, Stacks sigs2, uint32_t consensusBranchId)
{ {
switch (txType) switch (txType)
{ {
case TX_NONSTANDARD: case TX_NONSTANDARD:
case TX_NULL_DATA: case TX_NULL_DATA:
// Don't know anything about this, assume bigger one is correct: // Don't know anything about this, assume bigger one is correct:
if (sigs1.script.size() >= sigs2.script.size()) if (sigs1.script.size() >= sigs2.script.size())
return sigs1; return sigs1;
return sigs2;
case TX_PUBKEY:
case TX_PUBKEYHASH:
case TX_CRYPTOCONDITION:
// Signatures are bigger than placeholders or empty scripts:
if (sigs1.script.empty() || sigs1.script[0].empty())
return sigs2; return sigs2;
return sigs1; case TX_PUBKEY:
case TX_SCRIPTHASH: case TX_PUBKEYHASH:
if (sigs1.script.empty() || sigs1.script.back().empty()) case TX_CRYPTOCONDITION:
return sigs2; // Signatures are bigger than placeholders or empty scripts:
else if (sigs2.script.empty() || sigs2.script.back().empty()) if (sigs1.script.empty() || sigs1.script[0].empty())
return sigs2;
return sigs1; return sigs1;
else case TX_SCRIPTHASH:
{ if (sigs1.script.empty() || sigs1.script.back().empty())
// Recur to combine: return sigs2;
valtype spk = sigs1.script.back(); else if (sigs2.script.empty() || sigs2.script.back().empty())
CScript pubKey2(spk.begin(), spk.end()); return sigs1;
else
{
// Recur to combine:
valtype spk = sigs1.script.back();
CScript pubKey2(spk.begin(), spk.end());
txnouttype txType2; txnouttype txType2;
vector<vector<unsigned char> > vSolutions2; vector<vector<unsigned char> > vSolutions2;
Solver(pubKey2, txType2, vSolutions2); Solver(pubKey2, txType2, vSolutions2);
sigs1.script.pop_back(); sigs1.script.pop_back();
sigs2.script.pop_back(); sigs2.script.pop_back();
Stacks result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2, consensusBranchId); Stacks result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2, consensusBranchId);
result.script.push_back(spk); result.script.push_back(spk);
return result; return result;
} }
case TX_MULTISIG: case TX_MULTISIG:
return Stacks(CombineMultisig(scriptPubKey, checker, vSolutions, sigs1.script, sigs2.script, consensusBranchId)); return Stacks(CombineMultisig(scriptPubKey, checker, vSolutions, sigs1.script, sigs2.script, consensusBranchId));
default: default:
return Stacks(); return Stacks();
} }
} }
SignatureData CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker, SignatureData CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
const SignatureData& scriptSig1, const SignatureData& scriptSig2, const SignatureData& scriptSig1, const SignatureData& scriptSig2,
uint32_t consensusBranchId) uint32_t consensusBranchId)
{ {
txnouttype txType; txnouttype txType;
vector<vector<unsigned char> > vSolutions; vector<vector<unsigned char> > vSolutions;
Solver(scriptPubKey, txType, vSolutions); Solver(scriptPubKey, txType, vSolutions);
return CombineSignatures( return CombineSignatures(
scriptPubKey, checker, txType, vSolutions, scriptPubKey, checker, txType, vSolutions,
Stacks(scriptSig1, consensusBranchId), Stacks(scriptSig1, consensusBranchId),
Stacks(scriptSig2, consensusBranchId), Stacks(scriptSig2, consensusBranchId),
consensusBranchId).Output(); consensusBranchId).Output();
} }
namespace { namespace {
/** Dummy signature checker which accepts all signatures. */ /** Dummy signature checker which accepts all signatures. */
class DummySignatureChecker : public BaseSignatureChecker class DummySignatureChecker : public BaseSignatureChecker
{
public:
DummySignatureChecker() {}
bool CheckSig(
const std::vector<unsigned char>& scriptSig,
const std::vector<unsigned char>& vchPubKey,
const CScript& scriptCode,
uint32_t consensusBranchId) const
{ {
return true; public:
} DummySignatureChecker() {}
};
const DummySignatureChecker dummyChecker; bool CheckSig(
const std::vector<unsigned char>& scriptSig,
const std::vector<unsigned char>& vchPubKey,
const CScript& scriptCode,
uint32_t consensusBranchId) const
{
return true;
}
};
const DummySignatureChecker dummyChecker;
} }
const BaseSignatureChecker& DummySignatureCreator::Checker() const const BaseSignatureChecker& DummySignatureCreator::Checker() const
@@ -627,12 +627,12 @@ const BaseSignatureChecker& DummySignatureCreator::Checker() const
} }
bool DummySignatureCreator::CreateSig( bool DummySignatureCreator::CreateSig(
std::vector<unsigned char>& vchSig, std::vector<unsigned char>& vchSig,
const CKeyID& keyid, const CKeyID& keyid,
const CScript& scriptCode, const CScript& scriptCode,
uint32_t consensusBranchId, uint32_t consensusBranchId,
CKey *key, CKey *key,
void *extraData) const void *extraData) const
{ {
// Create a dummy signature that is a valid DER-encoding // Create a dummy signature that is a valid DER-encoding
vchSig.assign(72, '\000'); vchSig.assign(72, '\000');
@@ -647,3 +647,4 @@ bool DummySignatureCreator::CreateSig(
vchSig[6 + 33 + 32] = SIGHASH_ALL; vchSig[6 + 33 + 32] = SIGHASH_ALL;
return true; return true;
} }

View File

@@ -57,6 +57,7 @@
#include <numeric> #include <numeric>
#include "komodo_defs.h"
using namespace std; using namespace std;
@@ -67,8 +68,6 @@ const std::string ADDR_TYPE_SPROUT = "sprout";
const std::string ADDR_TYPE_SAPLING = "sapling"; const std::string ADDR_TYPE_SAPLING = "sapling";
extern UniValue TxJoinSplitToJSON(const CTransaction& tx); extern UniValue TxJoinSplitToJSON(const CTransaction& tx);
extern uint8_t ASSETCHAINS_PRIVATE;
extern int32_t USE_EXTERNAL_PUBKEY;
uint32_t komodo_segid32(char *coinaddr); uint32_t komodo_segid32(char *coinaddr);
int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); int32_t komodo_dpowconfs(int32_t height,int32_t numconfs);
int32_t komodo_isnotaryvout(char *coinaddr); // from ac_private chains only int32_t komodo_isnotaryvout(char *coinaddr); // from ac_private chains only
@@ -5094,8 +5093,8 @@ int32_t komodo_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33)
if (!EnsureWalletIsAvailable(0)) if (!EnsureWalletIsAvailable(0))
return 0; return 0;
const CKeyStore& keystore = *pwalletMain;
assert(pwalletMain != NULL); assert(pwalletMain != NULL);
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
utxovalue = 0; utxovalue = 0;
memset(&utxotxid,0,sizeof(utxotxid)); memset(&utxotxid,0,sizeof(utxotxid));
@@ -5172,7 +5171,6 @@ int32_t verus_staked(CBlock *pBlock, CMutableTransaction &txNew, uint32_t &nBits
int32_t ensure_CCrequirements() int32_t ensure_CCrequirements()
{ {
extern uint8_t NOTARY_PUBKEY33[];
CCerror = ""; CCerror = "";
if ( NOTARY_PUBKEY33[0] == 0 ) if ( NOTARY_PUBKEY33[0] == 0 )
return(-1); return(-1);
@@ -5262,8 +5260,6 @@ UniValue setpubkey(const UniValue& params, bool fHelp)
char Raddress[18]; char Raddress[18];
uint8_t pubkey33[33]; uint8_t pubkey33[33];
extern uint8_t NOTARY_PUBKEY33[];
extern std::string NOTARY_PUBKEY;
if ( NOTARY_PUBKEY33[0] == 0 ) { if ( NOTARY_PUBKEY33[0] == 0 ) {
if (strlen(params[0].get_str().c_str()) == 66) { if (strlen(params[0].get_str().c_str()) == 66) {
decode_hex(pubkey33,33,(char *)params[0].get_str().c_str()); decode_hex(pubkey33,33,(char *)params[0].get_str().c_str());
@@ -5327,6 +5323,43 @@ UniValue channelsaddress(const UniValue& params, bool fHelp)
return(result); return(result);
} }
UniValue cclibaddress(const UniValue& params, bool fHelp)
{
struct CCcontract_info *cp,C; std::vector<unsigned char> pubkey;
cp = CCinit(&C,EVAL_FIRSTUSER);
if ( fHelp || params.size() > 1 )
throw runtime_error("cclibaddress [pubkey]\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
if ( params.size() == 1 )
pubkey = ParseHex(params[0].get_str().c_str());
return(CCaddress(cp,(char *)"CClib",pubkey));
}
UniValue cclibinfo(const UniValue& params, bool fHelp)
{
struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_FIRSTUSER);
if ( fHelp || params.size() > 0 )
throw runtime_error("cclibinfo\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
return(CClib_info(cp));
}
UniValue cclib(const UniValue& params, bool fHelp)
{
struct CCcontract_info *cp,C; char *method; cJSON *jsonparams;
cp = CCinit(&C,EVAL_FIRSTUSER);
if ( fHelp || params.size() > 2 )
throw runtime_error("cclib method [JSON params]\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
method = (char *)params[0].get_str().c_str();
jsonparams = cJSON_Parse(params[1].get_str().c_str());
return(CClib(cp,method,jsonparams));
}
UniValue oraclesaddress(const UniValue& params, bool fHelp) UniValue oraclesaddress(const UniValue& params, bool fHelp)
{ {
struct CCcontract_info *cp,C; std::vector<unsigned char> pubkey; struct CCcontract_info *cp,C; std::vector<unsigned char> pubkey;
@@ -5558,8 +5591,9 @@ UniValue marmara_receive(const UniValue& params, bool fHelp)
UniValue result(UniValue::VOBJ); uint256 batontxid; std::vector<uint8_t> senderpub; int64_t amount; int32_t matures; std::string currency; UniValue result(UniValue::VOBJ); uint256 batontxid; std::vector<uint8_t> senderpub; int64_t amount; int32_t matures; std::string currency;
if ( fHelp || (params.size() != 5 && params.size() != 4) ) if ( fHelp || (params.size() != 5 && params.size() != 4) )
{ {
// automatic flag -> lsb of matures
// 1st marmarareceive 028076d42eb20efc10007fafb5ca66a2052523c0d2221e607adf958d1a332159f6 7.5 MARMARA 1440 // 1st marmarareceive 028076d42eb20efc10007fafb5ca66a2052523c0d2221e607adf958d1a332159f6 7.5 MARMARA 1440
// after marmarareceive 039433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775 7.5 MARMARA 3903 bf6b4d42aa3ce974c853d73b06c78597dd3b5fb493d5d0d944f72c2017f561ad // after marmarareceive 039433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775 7.5 MARMARA 1168 d72d87aa0d50436de695c93e2bf3d7273c63c92ef6307913aa01a6ee6a16548b
throw runtime_error("marmarareceive senderpk amount currency matures batontxid\n"); throw runtime_error("marmarareceive senderpk amount currency matures batontxid\n");
} }
if ( ensure_CCrequirements() < 0 ) if ( ensure_CCrequirements() < 0 )
@@ -5578,7 +5612,7 @@ UniValue marmara_receive(const UniValue& params, bool fHelp)
matures = atol(params[3].get_str().c_str()); matures = atol(params[3].get_str().c_str());
batontxid = Parseuint256((char *)params[4].get_str().c_str()); batontxid = Parseuint256((char *)params[4].get_str().c_str());
} else matures = atol(params[3].get_str().c_str()) + chainActive.LastTip()->GetHeight() + 1; } else matures = atol(params[3].get_str().c_str()) + chainActive.LastTip()->GetHeight() + 1;
return(MarmaraReceive(0,pubkey2pk(senderpub),amount,currency,matures,batontxid)); return(MarmaraReceive(0,pubkey2pk(senderpub),amount,currency,matures,batontxid,true));
} }
UniValue marmara_issue(const UniValue& params, bool fHelp) UniValue marmara_issue(const UniValue& params, bool fHelp)
@@ -5586,7 +5620,9 @@ UniValue marmara_issue(const UniValue& params, bool fHelp)
UniValue result(UniValue::VOBJ); uint256 approvaltxid; std::vector<uint8_t> receiverpub; int64_t amount; int32_t matures; std::string currency; UniValue result(UniValue::VOBJ); uint256 approvaltxid; std::vector<uint8_t> receiverpub; int64_t amount; int32_t matures; std::string currency;
if ( fHelp || params.size() != 5 ) if ( fHelp || params.size() != 5 )
{ {
// marmaraissue 039433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775 7.5 MARMARA 3903 010ff7f9256cefe3b5dee3d72c0eeae9fc6f34884e6f32ffe5b60916df54a9be // marmaraissue 039433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775 7.5 MARMARA 1168 32da4cb3e886ee42de90b4a15042d71169077306badf909099c5c5c692df3f27
// marmaraissue 039433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775 700 MARMARA 2629 11fe8bf1de80c2ef69124d08907f259aef7f41e3a632ca2d48ad072a8c8f3078 -> 335df3a5dd6b92a3d020c9465d4d76e0d8242126106b83756dcecbad9813fdf3
throw runtime_error("marmaraissue receiverpk amount currency matures approvaltxid\n"); throw runtime_error("marmaraissue receiverpk amount currency matures approvaltxid\n");
} }
if ( ensure_CCrequirements() < 0 ) if ( ensure_CCrequirements() < 0 )
@@ -5609,7 +5645,7 @@ UniValue marmara_transfer(const UniValue& params, bool fHelp)
UniValue result(UniValue::VOBJ); uint256 approvaltxid,batontxid; std::vector<uint8_t> receiverpub; int64_t amount; int32_t matures; std::string currency; std::vector<uint256> creditloop; UniValue result(UniValue::VOBJ); uint256 approvaltxid,batontxid; std::vector<uint8_t> receiverpub; int64_t amount; int32_t matures; std::string currency; std::vector<uint256> creditloop;
if ( fHelp || params.size() != 5 ) if ( fHelp || params.size() != 5 )
{ {
// marmaratransfer 028076d42eb20efc10007fafb5ca66a2052523c0d2221e607adf958d1a332159f6 7.5 MARMARA 3903 748a4c80e6f6b725340fb0f52738f38a11c422d59b3034c8366b3d7b33c99a1e // marmaratransfer 028076d42eb20efc10007fafb5ca66a2052523c0d2221e607adf958d1a332159f6 7.5 MARMARA 1168 1506c774e4b2804a6e25260920840f4cfca8d1fb400e69fe6b74b8e593dbedc5
throw runtime_error("marmaratransfer receiverpk amount currency matures approvaltxid\n"); throw runtime_error("marmaratransfer receiverpk amount currency matures approvaltxid\n");
} }
if ( ensure_CCrequirements() < 0 ) if ( ensure_CCrequirements() < 0 )
@@ -5679,7 +5715,7 @@ UniValue marmara_settlement(const UniValue& params, bool fHelp)
if ( fHelp || params.size() != 1 ) if ( fHelp || params.size() != 1 )
{ {
// marmarasettlement 010ff7f9256cefe3b5dee3d72c0eeae9fc6f34884e6f32ffe5b60916df54a9be // marmarasettlement 010ff7f9256cefe3b5dee3d72c0eeae9fc6f34884e6f32ffe5b60916df54a9be
// marmarasettlement cc23bf81733556dc06db2fd9c9f4178cad44bdc237d6e62101cf0cdafb5195f7 // marmarasettlement ff3e259869196f3da9b5ea3f9e088a76c4fc063cf36ab586b652e121d441a603
throw runtime_error("marmarasettlement batontxid\n"); throw runtime_error("marmarasettlement batontxid\n");
} }
if ( ensure_CCrequirements() < 0 ) if ( ensure_CCrequirements() < 0 )
@@ -5689,6 +5725,20 @@ UniValue marmara_settlement(const UniValue& params, bool fHelp)
return(result); return(result);
} }
UniValue marmara_lock(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); int64_t amount; int32_t height;
if ( fHelp || params.size() > 2 || params.size() == 0 )
{
throw runtime_error("marmaralock amount unlockht\n");
}
amount = atof(params[0].get_str().c_str()) * COIN + 0.00000000499999;
if ( params.size() == 2 )
height = atol(params[1].get_str().c_str());
else height = chainActive.LastTip()->GetHeight() + 1;
return(MarmaraLock(0,amount,height));
}
UniValue channelslist(const UniValue& params, bool fHelp) UniValue channelslist(const UniValue& params, bool fHelp)
{ {
if ( fHelp || params.size() > 0 ) if ( fHelp || params.size() > 0 )
@@ -7312,7 +7362,7 @@ UniValue heirfund(const UniValue& params, bool fHelp)
{ {
UniValue result(UniValue::VOBJ); UniValue result(UniValue::VOBJ);
uint256 tokenid = zeroid; uint256 tokenid = zeroid;
uint64_t txfee; int64_t txfee;
int64_t amount; int64_t amount;
int64_t inactivitytime; int64_t inactivitytime;
std::string hex; std::string hex;
@@ -7323,21 +7373,34 @@ UniValue heirfund(const UniValue& params, bool fHelp)
return NullUniValue; return NullUniValue;
if (fHelp || params.size() != 5 && params.size() != 6) if (fHelp || params.size() != 5 && params.size() != 6)
throw runtime_error("heirfundtokens fee funds heirname heirpubkey inactivitytime [tokenid]\n"); throw runtime_error("heirfund txfee funds heirname heirpubkey inactivitytime [tokenid]\n");
if (ensure_CCrequirements() < 0) if (ensure_CCrequirements() < 0)
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain; const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
txfee = atoll((char*)params[0].get_str().c_str()); txfee = atoll(params[0].get_str().c_str());
amount = atoll((char*)params[1].get_str().c_str()); if (txfee < 0)
throw runtime_error("incorrect txfee param\n");
if(params.size() == 6) // tokens in satoshis:
amount = atoll(params[1].get_str().c_str());
else // coins:
amount = atof(params[1].get_str().c_str()) * COIN;
if( amount <= 0 )
throw runtime_error("incorrect amount\n");
name = params[2].get_str(); name = params[2].get_str();
pubkey = ParseHex(params[3].get_str().c_str()); pubkey = ParseHex(params[3].get_str().c_str());
if( !pubkey2pk(pubkey).IsValid() ) if( !pubkey2pk(pubkey).IsValid() )
throw runtime_error("incorrect pubkey\n"); throw runtime_error("incorrect pubkey\n");
inactivitytime = atof((char*)params[4].get_str().c_str()); inactivitytime = atoll(params[4].get_str().c_str());
if (inactivitytime <= 0)
throw runtime_error("incorrect inactivity time param\n");
if (params.size() == 6) { if (params.size() == 6) {
tokenid = Parseuint256((char*)params[5].get_str().c_str()); tokenid = Parseuint256((char*)params[5].get_str().c_str());
if(tokenid == zeroid) if(tokenid == zeroid)
@@ -7356,7 +7419,7 @@ UniValue heiradd(const UniValue& params, bool fHelp)
{ {
UniValue result; UniValue result;
uint256 fundingtxid; uint256 fundingtxid;
uint64_t txfee; int64_t txfee;
int64_t amount; int64_t amount;
int64_t inactivitytime; int64_t inactivitytime;
std::string hex; std::string hex;
@@ -7367,18 +7430,20 @@ UniValue heiradd(const UniValue& params, bool fHelp)
return NullUniValue; return NullUniValue;
if (fHelp || params.size() != 3) if (fHelp || params.size() != 3)
throw runtime_error("heiraddtokens fee funds fundingtxid\n"); throw runtime_error("heiradd txfee funds fundingtxid\n");
if (ensure_CCrequirements() < 0) if (ensure_CCrequirements() < 0)
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain; const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
txfee = atoll((char*)params[0].get_str().c_str()); txfee = atoll(params[0].get_str().c_str());
amount = atoll((char*)params[1].get_str().c_str()); if (txfee < 0)
throw runtime_error("incorrect txfee param\n");
fundingtxid = Parseuint256((char*)params[2].get_str().c_str()); fundingtxid = Parseuint256((char*)params[2].get_str().c_str());
result = HeirAddCaller(fundingtxid, txfee, amount); result = HeirAddCaller(fundingtxid, txfee, params[1].get_str());
return result; return result;
} }
@@ -7387,7 +7452,6 @@ UniValue heirclaim(const UniValue& params, bool fHelp)
UniValue result; // result(UniValue::VOBJ); UniValue result; // result(UniValue::VOBJ);
uint256 fundingtxid; uint256 fundingtxid;
int64_t txfee; int64_t txfee;
int64_t amount;
int64_t inactivitytime; int64_t inactivitytime;
std::string hex; std::string hex;
std::vector<unsigned char> pubkey; std::vector<unsigned char> pubkey;
@@ -7398,18 +7462,20 @@ UniValue heirclaim(const UniValue& params, bool fHelp)
return NullUniValue; return NullUniValue;
if (fHelp || params.size() != 3) if (fHelp || params.size() != 3)
throw runtime_error("heirclaimtokens fee funds fundingtxid\n"); throw runtime_error("heirclaim txfee funds fundingtxid\n");
if (ensure_CCrequirements() < 0) if (ensure_CCrequirements() < 0)
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain; const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
txfee = atoll((char*)params[0].get_str().c_str()); txfee = atoll(params[0].get_str().c_str());
amount = atoll((char*)params[1].get_str().c_str()); if (txfee < 0)
throw runtime_error("incorrect txfee param\n");
fundingtxid = Parseuint256((char*)params[2].get_str().c_str()); fundingtxid = Parseuint256((char*)params[2].get_str().c_str());
result = HeirClaimCaller(fundingtxid, txfee, amount); result = HeirClaimCaller(fundingtxid, txfee, params[1].get_str());
return result; return result;
} }
@@ -7531,3 +7597,79 @@ void RegisterWalletRPCCommands(CRPCTable &tableRPC)
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]); tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
} }
UniValue test_ac(const UniValue& params, bool fHelp)
{
// make fake token tx:
struct CCcontract_info *cp, C;
if (fHelp || (params.size() != 4))
throw runtime_error("incorrect params\n");
if (ensure_CCrequirements() < 0)
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
std::vector<unsigned char> pubkey1;
std::vector<unsigned char> pubkey2;
pubkey1 = ParseHex(params[0].get_str().c_str());
pubkey2 = ParseHex(params[1].get_str().c_str());
CPubKey pk1 = pubkey2pk(pubkey1);
CPubKey pk2 = pubkey2pk(pubkey2);
if(!pk1.IsValid() || !pk2.IsValid())
throw runtime_error("invalid pubkey\n");
int64_t txfee = 10000;
int64_t amount = atoll(params[2].get_str().c_str()) * COIN;
uint256 fundingtxid = Parseuint256((char *)params[3].get_str().c_str());
CPubKey myPubkey = pubkey2pk(Mypubkey());
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
int64_t normalInputs = AddNormalinputs(mtx, myPubkey, txfee + amount, 60);
if( normalInputs < txfee + amount)
throw runtime_error("not enough normals\n");
mtx.vout.push_back(MakeCC1of2vout(EVAL_HEIR, amount, pk1, pk2));
CScript opret;
fundingtxid = revuint256(fundingtxid);
opret << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_HEIR << (uint8_t)'A' << fundingtxid << (uint8_t)0);
cp = CCinit(&C, EVAL_HEIR);
return(FinalizeCCTx(0, cp, mtx, myPubkey, txfee, opret));
}
UniValue test_heirmarker(const UniValue& params, bool fHelp)
{
// make fake token tx:
struct CCcontract_info *cp, C;
if (fHelp || (params.size() != 1))
throw runtime_error("incorrect params\n");
if (ensure_CCrequirements() < 0)
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
uint256 fundingtxid = Parseuint256((char *)params[0].get_str().c_str());
CPubKey myPubkey = pubkey2pk(Mypubkey());
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
int64_t normalInputs = AddNormalinputs(mtx, myPubkey, 10000, 60);
if (normalInputs < 10000)
throw runtime_error("not enough normals\n");
mtx.vin.push_back(CTxIn(fundingtxid, 1));
mtx.vout.push_back(MakeCC1vout(EVAL_HEIR, 10000, myPubkey));
CScript opret;
fundingtxid = revuint256(fundingtxid);
opret << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_HEIR << (uint8_t)'C' << fundingtxid << (uint8_t)0);
cp = CCinit(&C, EVAL_HEIR);
return(FinalizeCCTx(0, cp, mtx, myPubkey, 10000, opret));
}

View File

@@ -59,13 +59,7 @@ bool fSendFreeTransactions = false;
bool fPayAtLeastCustomFee = true; bool fPayAtLeastCustomFee = true;
#include "komodo_defs.h" #include "komodo_defs.h"
extern int32_t USE_EXTERNAL_PUBKEY;
extern std::string NOTARY_PUBKEY;
extern int32_t KOMODO_EXCHANGEWALLET;
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
extern int32_t VERUS_MIN_STAKEAGE;
CBlockIndex *komodo_chainactive(int32_t height); CBlockIndex *komodo_chainactive(int32_t height);
extern std::string DONATION_PUBKEY;
/** /**
* Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation)

View File

@@ -42,6 +42,21 @@ PREFIX="$(pwd)/depends/$TRIPLET"
make "$@" -C ./depends/ V=1 NO_QT=1 NO_PROTON=1 make "$@" -C ./depends/ V=1 NO_QT=1 NO_PROTON=1
#BUILD CCLIB
WD=$PWD
cd src/cc
echo $PWD
if make "$@"; then
echo CCLIB BUILD SUCCESSFUL
else
echo CCLIB BUILD FAILED
exit 1
fi
cd $WD
./autogen.sh ./autogen.sh
CPPFLAGS="-I$PREFIX/include -arch x86_64" LDFLAGS="-L$PREFIX/lib -arch x86_64 -Wl,-no_pie" \ CPPFLAGS="-I$PREFIX/include -arch x86_64" LDFLAGS="-L$PREFIX/lib -arch x86_64 -Wl,-no_pie" \
CXXFLAGS='-arch x86_64 -I/usr/local/Cellar/gcc\@6/6.4.0_2/include/c++/6.4.0/ -I$PREFIX/include -fwrapv -fno-strict-aliasing -Werror -g -Wl,-undefined -Wl,dynamic_lookup' \ CXXFLAGS='-arch x86_64 -I/usr/local/Cellar/gcc\@6/6.4.0_2/include/c++/6.4.0/ -I$PREFIX/include -fwrapv -fno-strict-aliasing -Werror -g -Wl,-undefined -Wl,dynamic_lookup' \

View File

@@ -101,6 +101,21 @@ eval "$MAKE" --version
as --version as --version
ld -v ld -v
#BUILD CCLIB
WD=$PWD
cd src/cc
echo $PWD
if make "$@"; then
echo CCLIB BUILD SUCCESSFUL
else
echo CCLIB BUILD FAILED
exit 1
fi
cd $WD
HOST="$HOST" BUILD="$BUILD" NO_PROTON="$PROTON_ARG" "$MAKE" "$@" -C ./depends/ V=1 HOST="$HOST" BUILD="$BUILD" NO_PROTON="$PROTON_ARG" "$MAKE" "$@" -C ./depends/ V=1
./autogen.sh ./autogen.sh