Merge remote-tracking branch 'origin/ztxstats' into ztxstats

This commit is contained in:
Duke Leto
2019-08-08 13:27:47 -04:00
99 changed files with 7178 additions and 1099 deletions
+338
View File
@@ -0,0 +1,338 @@
{
"REVS": {
"ac_supply": "1300000"
}
,
"SUPERNET": {
"ac_supply": "816061"
}
,
"DEX": {
"ac_supply": "999999"
}
,
"PANGEA": {
"ac_supply": "999999"
}
,
"JUMBLR": {
"ac_supply": "999999"
}
,
"BET": {
"ac_supply": "999999"
}
,
"CRYPTO": {
"ac_supply": "999999"
}
,
"HODL": {
"ac_supply": "9999999"
}
,
"MSHARK": {
"ac_supply": "1400000"
}
,
"BOTS": {
"ac_supply": "999999"
}
,
"MGW": {
"ac_supply": "999999"
}
,
"COQUICASH": {
"ac_supply": "72000000",
"ac_reward": "7200000000",
"ac_staked": "50",
"ac_halving": "420000",
"ac_cc": "2",
"ac_ccenable": "227,235,236,241",
"addnode": [
"78.47.108.168"
]
}
,
"WLC": {
"ac_supply": "210000000"
}
,
"KV": {
"ac_supply": "1000000"
}
,
"CEAL": {
"ac_supply": "366666666"
}
,
"MESH": {
"ac_supply": "1000007"
}
,
"AXO": {
"ac_supply": "200000000",
"ac_ccactivate": "130000"
}
,
"ETOMIC": {
"ac_supply": "100000000"
}
,
"BTCH": {
"ac_supply": "20998641"
}
,
"PIZZA": {
"ac_supply": "100000000"
}
,
"BEER": {
"ac_supply": "100000000"
}
,
"NINJA": {
"ac_supply": "100000000"
}
,
"OOT": {
"ac_supply": "216000000",
"ac_sapling": "5000000"
}
,
"BNTN": {
"ac_supply": "500000000"
}
,
"CHAIN": {
"ac_supply": "999999"
}
,
"PRLPAY": {
"ac_supply": "500000000"
}
,
"DSEC": {
"ac_supply": "7000000"
}
,
"GLXT": {
"ac_supply": "10000000000"
}
,
"EQL": {
"ac_supply": "500000000",
"ac_ccactivate": "205000"
}
,
"ZILLA": {
"ac_supply": "11000000",
"ac_sapling": "5000000",
"addnode": [
"51.68.215.104"
]
}
,
"RFOX": {
"ac_supply": "1000000000",
"ac_reward": "100000000"
}
,
"SEC": {
"ac_supply": "1000000000",
"ac_cc": "333"
}
,
"CCL": {
"ac_supply": "200000000",
"ac_end": "1",
"ac_cc": "2",
"addressindex": "1",
"spentindex": "1",
"addnode": [
"142.93.136.89",
"195.201.22.89"
]
}
,
"PIRATE": {
"ac_supply": "0",
"ac_reward": "25600000000",
"ac_halving": "77777",
"ac_private": "1",
"addnode": [
"136.243.102.225"
]
}
,
"PGT": {
"ac_supply": "10000000",
"ac_end": "1",
"addnode": [
"190.114.254.104"
]
}
,
"DION": {
"ac_supply": "3900000000",
"ac_reward": "22260000000",
"ac_staked": "100",
"ac_cc": "1",
"ac_end": "4300000000",
"addnode": [
"51.75.124.34"
]
}
,
"KMDICE": {
"ac_supply": "10500000",
"ac_reward": "2500000000",
"ac_halving": "210000",
"ac_cc": "2",
"addressindex": "1",
"spentindex": "1",
"addnode": [
"144.76.217.232"
]
}
,
"KSB": {
"ac_supply": "1000000000",
"ac_end": "1",
"ac_public": "1",
"addnode": [
"37.187.225.231"
]
}
,
"OUR": {
"ac_reward": "1478310502",
"ac_halving": "525600",
"ac_cc": "42",
"ac_supply": "100000000",
"ac_perc": "77700",
"ac_staked": "93",
"ac_pubkey": "02652a3f3e00b3a1875a918314f0bac838d6dd189a346fa623f5efe9541ac0b98c",
"ac_public": "1",
"addnode": [
"51.255.195.65",
"217.182.129.38",
"37.187.225.231"
]
}
,
"ILN": {
"ac_supply": "10000000000",
"ac_cc": "2",
"addnode": ["51.75.122.83"]
}
,
"RICK": {
"ac_supply": "90000000000",
"ac_reward": "100000000",
"ac_cc": "3",
"addnode": ["138.201.136.145"]
}
,
"MORTY": {
"ac_supply": "90000000000",
"ac_reward": "100000000",
"ac_cc": "3",
"addnode": ["138.201.136.145"]
}
,
"KOIN": {
"ac_supply": "125000000",
"addnode": ["3.0.32.10"]
}
,
"ZEXO": {
"ac_reward": "1478310502",
"ac_halving": "525600",
"ac_cc": "42",
"ac_ccenable": "236",
"ac_supply": "100000000",
"ac_perc": "77700",
"ac_staked": "93",
"ac_pubkey": "02713bd85e054db923694b6b7a85306264edf4d6bd6d331814f2b40af444b3ebbc",
"ac_public": "1",
"addnode": [
"195.201.20.230",
"80.240.17.222"
]
}
,
"K64": {
"ac_reward": "0",
"ac_supply": "64000777",
"ac_staked": "10",
"addnode": ["18.197.20.21"]
}
,
"HUSH3": {
"ac_sapling": "1",
"ac_founders": "1",
"ac_reward": "0,1125000000,562500000",
"ac_end": "128,340000,5422111",
"ac_blocktime": "150",
"ac_supply": "6178674",
"ac_halving": "129,340000,840000",
"ac_cc": "2",
"ac_cclib": "hush3",
"ac_ccenable": "228,234,235,236,241",
"ac_perc": "11111111",
"ac_eras": "3",
"ac_script": "76a9145eb10cf64f2bab1b457f1f25e658526155928fac88ac",
"clientname": "GoldenSandtrout",
"addnode": [
"188.165.212.101",
"136.243.227.142",
"5.9.224.250"
]
}
}
+31 -8
View File
@@ -44,9 +44,16 @@
"ac_supply": "999999"
},
{
"ac_name": "COQUI",
"ac_name": "COQUICASH",
"ac_supply": "72000000",
"ac_ccactivate": "200000"
"ac_reward": "7200000000",
"ac_staked": "50",
"ac_halving": "420000",
"ac_cc": "2",
"ac_ccenable": "227,235,236,241",
"addnode": [
"78.47.108.168"
]
},
{
"ac_name": "WLC",
@@ -235,12 +242,6 @@
"ac_cc": "3",
"addnode": ["138.201.136.145"]
},
{
"ac_name": "VOTE2019",
"ac_supply": "123651638",
"ac_public": "1",
"addnode": ["95.213.238.98"]
},
{
"ac_name": "KOIN",
"ac_supply": "125000000",
@@ -268,5 +269,27 @@
"ac_supply": "64000777",
"ac_staked": "10",
"addnode": ["18.197.20.21"]
},
{
"ac_name": "HUSH3",
"ac_sapling": "1",
"ac_founders": "1",
"ac_reward": "0,1125000000,562500000",
"ac_end": "128,340000,5422111",
"ac_blocktime": "150",
"ac_supply": "6178674",
"ac_halving": "129,340000,840000",
"ac_cc": "2",
"ac_cclib": "hush3",
"ac_ccenable": "228,234,235,236,241",
"ac_perc": "11111111",
"ac_eras": "3",
"ac_script": "76a9145eb10cf64f2bab1b457f1f25e658526155928fac88ac",
"clientname": "GoldenSandtrout",
"addnode": [
"188.165.212.101",
"136.243.227.142",
"5.9.224.250"
]
}
]
+27 -26
View File
@@ -4,37 +4,37 @@ delay=60
source pubkey.txt
echo $pubkey
./komodod -pubkey=$pubkey -ac_name=REVS -ac_supply=1300000 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=SUPERNET -ac_supply=816061 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=DEX -ac_supply=999999 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=PANGEA -ac_supply=999999 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=JUMBLR -ac_supply=999999 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=BET -ac_supply=999999 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=CRYPTO -ac_supply=999999 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=HODL -ac_supply=9999999 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=MSHARK -ac_supply=1400000 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=BOTS -ac_supply=999999 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=MGW -ac_supply=999999 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=COQUI -ac_supply=72000000 -ac_ccactivate=200000 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=WLC -ac_supply=210000000 -addnode=148.251.190.89 $1 &
./komodod -pubkey=$pubkey -ac_name=KV -ac_supply=1000000 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=CEAL -ac_supply=366666666 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=MESH -ac_supply=1000007 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=AXO -ac_supply=200000000 -ac_ccactivate=130000 -addnode=78.47.196.146 &
./komodod -pubkey=$pubkey -ac_name=ETOMIC -ac_supply=100000000 -addnode=78.47.196.146 &
./komodod -pubkey=$pubkey -ac_name=BTCH -ac_supply=20998641 -addnode=78.47.196.146 &
./komodod -pubkey=$pubkey -ac_name=BEER -ac_supply=100000000 -addnode=78.47.196.146 &
./komodod -pubkey=$pubkey -ac_name=PIZZA -ac_supply=100000000 -addnode=78.47.196.146 &
./komodod -pubkey=$pubkey -ac_name=NINJA -ac_supply=100000000 -addnode=78.47.196.146 &
./komodod -pubkey=$pubkey -ac_name=OOT -ac_supply=216000000 -ac_sapling=5000000 -addnode=174.138.107.226 &
./komodod -pubkey=$pubkey -ac_name=BNTN -ac_supply=500000000 -addnode=94.130.169.205 &
./komodod -pubkey=$pubkey -ac_name=CHAIN -ac_supply=999999 -addnode=78.47.146.222 &
./komodod -pubkey=$pubkey -ac_name=REVS -ac_supply=1300000 -addnode=95.213.238.98 $1 &
./komodod -pubkey=$pubkey -ac_name=SUPERNET -ac_supply=816061 -addnode=95.213.238.98 $1 &
./komodod -pubkey=$pubkey -ac_name=DEX -ac_supply=999999 -addnode=95.213.238.98 $1 &
./komodod -pubkey=$pubkey -ac_name=PANGEA -ac_supply=999999 -addnode=95.213.238.98 $1 &
./komodod -pubkey=$pubkey -ac_name=JUMBLR -ac_supply=999999 -addnode=95.213.238.98 $1 &
./komodod -pubkey=$pubkey -ac_name=BET -ac_supply=999999 -addnode=95.213.238.98 $1 &
./komodod -pubkey=$pubkey -ac_name=CRYPTO -ac_supply=999999 -addnode=95.213.238.98 $1 &
./komodod -pubkey=$pubkey -ac_name=HODL -ac_supply=9999999 -addnode=95.213.238.98 $1 &
./komodod -pubkey=$pubkey -ac_name=MSHARK -ac_supply=1400000 -addnode=95.213.238.98 $1 &
./komodod -pubkey=$pubkey -ac_name=BOTS -ac_supply=999999 -addnode=95.213.238.98 $1 &
./komodod -pubkey=$pubkey -ac_name=MGW -ac_supply=999999 -addnode=95.213.238.98 $1 &
./komodod -pubkey=$pubkey -ac_name=COQUI -ac_supply=72000000 -ac_ccactivate=200000 -addnode=95.213.238.98 $1 &
./komodod -pubkey=$pubkey -ac_name=WLC -ac_supply=210000000 -addnode=95.213.238.98 $1 &
./komodod -pubkey=$pubkey -ac_name=KV -ac_supply=1000000 -addnode=95.213.238.98 $1 &
./komodod -pubkey=$pubkey -ac_name=CEAL -ac_supply=366666666 -addnode=95.213.238.98 $1 &
./komodod -pubkey=$pubkey -ac_name=MESH -ac_supply=1000007 -addnode=95.213.238.98 $1 &
./komodod -pubkey=$pubkey -ac_name=AXO -ac_supply=200000000 -ac_ccactivate=130000 -addnode=95.213.238.98 &
./komodod -pubkey=$pubkey -ac_name=ETOMIC -ac_supply=100000000 -addnode=95.213.238.98 &
./komodod -pubkey=$pubkey -ac_name=BTCH -ac_supply=20998641 -addnode=95.213.238.98 &
./komodod -pubkey=$pubkey -ac_name=BEER -ac_supply=100000000 -addnode=95.213.238.98 &
./komodod -pubkey=$pubkey -ac_name=PIZZA -ac_supply=100000000 -addnode=95.213.238.98 &
./komodod -pubkey=$pubkey -ac_name=NINJA -ac_supply=100000000 -addnode=95.213.238.98 &
./komodod -pubkey=$pubkey -ac_name=OOT -ac_supply=216000000 -ac_sapling=5000000 -addnode=95.213.238.98 &
./komodod -pubkey=$pubkey -ac_name=BNTN -ac_supply=500000000 -addnode=95.213.238.98 &
./komodod -pubkey=$pubkey -ac_name=CHAIN -ac_supply=999999 -addnode=95.213.238.98 &
./komodod -pubkey=$pubkey -ac_name=PRLPAY -ac_supply=500000000 -addnode=13.250.226.125 &
./komodod -pubkey=$pubkey -ac_name=DSEC -ac_supply=7000000 -addnode=185.148.147.30 &
./komodod -pubkey=$pubkey -ac_name=GLXT -ac_supply=10000000000 -addnode=13.230.224.15 &
./komodod -pubkey=$pubkey -ac_name=EQL -ac_supply=500000000 -ac_ccactivate=205000 -addnode=46.101.124.153 &
./komodod -pubkey=$pubkey -ac_name=ZILLA -ac_supply=11000000 -ac_sapling=5000000 -addnode=51.68.215.104 &
./komodod -pubkey=$pubkey -ac_name=RFOX -ac_supply=1000000000 -ac_reward=100000000 -addnode=78.47.196.146 &
./komodod -pubkey=$pubkey -ac_name=RFOX -ac_supply=1000000000 -ac_reward=100000000 -addnode=95.213.238.98 &
~/VerusCoin/src/komodod -pubkey=$pubkey -ac_name=VRSC -ac_algo=verushash -ac_cc=1 -ac_veruspos=50 -ac_supply=0 -ac_eras=3 -ac_reward=0,38400000000,2400000000 -ac_halving=1,43200,1051920 -ac_decay=100000000,0,0 -ac_end=10080,226080,0 -ac_timelockgte=19200000000 -ac_timeunlockfrom=129600 -ac_timeunlockto=1180800 -addnode=185.25.48.236 -addnode=185.64.105.111 &
./komodod -pubkey=$pubkey -ac_name=SEC -ac_cc=333 -ac_supply=1000000000 -addnode=185.148.145.43 &
./komodod -pubkey=$pubkey -ac_name=CCL -ac_supply=200000000 -ac_end=1 -ac_cc=2 -addressindex=1 -spentindex=1 -addnode=142.93.136.89 -addnode=195.201.22.89 &
@@ -52,3 +52,4 @@ echo $pubkey
./komodod -pubkey=$pubkey -ac_name=KOIN -ac_supply=125000000 -addnode=3.0.32.10 &
./komodod -pubkey=$pubkey -ac_name=ZEXO -ac_supply=100000000 -ac_reward=1478310502 -ac_halving=525600 -ac_cc=42 -ac_ccenable=236 -ac_perc=77700 -ac_staked=93 -ac_pubkey=02713bd85e054db923694b6b7a85306264edf4d6bd6d331814f2b40af444b3ebbc -ac_public=1 -addnode=80.240.17.222 &
./komodod -pubkey=$pubkey -ac_name=K64 -ac_supply=64000777 -ac_reward=0 -ac_staked=10 -addnode=18.197.20.211 &
./komodod -pubkey=$pubkey -ac_name=HUSH3 -ac_sapling=1 -ac_reward=0,1125000000,562500000 -ac_halving=129,340000,840000 -ac_end=128,340000,5422111 -ac_eras=3 -ac_blocktime=150 -ac_cc=2 -ac_ccenable=228,234,235,236,241 -ac_founders=1 -ac_supply=6178674 -ac_perc=11111111 -clientname=GoldenSandtrout -addnode=188.165.212.101 -addnode=136.243.227.142 -addnode=5.9.224.250 -ac_cclib=hush3 -ac_script=76a9145eb10cf64f2bab1b457f1f25e658526155928fac88ac &
+17 -2
View File
@@ -65,11 +65,25 @@ void komodo_passport_iteration();
uint64_t komodo_interestsum();
int32_t komodo_longestchain();
void komodo_cbopretupdate(int32_t forceflag);
CBlockIndex *komodo_chainactive(int32_t height);
void WaitForShutdown(boost::thread_group* threadGroup)
{
int32_t i; bool fShutdown = ShutdownRequested();
int32_t i,height; CBlockIndex *pindex; bool fShutdown = ShutdownRequested(); const uint256 zeroid;
// Tell the main threads to shutdown.
if (komodo_currentheight()>KOMODO_EARLYTXID_HEIGHT && KOMODO_EARLYTXID!=zeroid && ((height=tx_height(KOMODO_EARLYTXID))==0 || height>KOMODO_EARLYTXID_HEIGHT))
{
fprintf(stderr,"error: earlytx must be before block height %d or tx does not exist\n",KOMODO_EARLYTXID_HEIGHT);
StartShutdown();
}
if ( ASSETCHAINS_STAKED == 0 && ASSETCHAINS_ADAPTIVEPOW == 0 && (pindex= komodo_chainactive(1)) != 0 )
{
if ( pindex->nTime > ADAPTIVEPOW_CHANGETO_DEFAULTON )
{
ASSETCHAINS_ADAPTIVEPOW = 1;
fprintf(stderr,"default activate adaptivepow\n");
} else fprintf(stderr,"height1 time %u vs %u\n",pindex->nTime,ADAPTIVEPOW_CHANGETO_DEFAULTON);
} //else fprintf(stderr,"cant find height 1\n");
if ( ASSETCHAINS_CBOPRET != 0 )
komodo_pricesinit();
while (!fShutdown)
@@ -77,7 +91,8 @@ void WaitForShutdown(boost::thread_group* threadGroup)
//fprintf(stderr,"call passport iteration\n");
if ( ASSETCHAINS_SYMBOL[0] == 0 )
{
komodo_passport_iteration();
if ( KOMODO_NSPV <= 0 )
komodo_passport_iteration();
for (i=0; i<10; i++)
{
fShutdown = ShutdownRequested();
-1
View File
@@ -28,7 +28,6 @@ std::string ImportGatewayWithdraw(uint64_t txfee,uint256 bindtxid,std::string re
std::string ImportGatewayPartialSign(uint64_t txfee,uint256 lasttxid,std::string refcoin, std::string hex);
std::string ImportGatewayCompleteSigning(uint64_t txfee,uint256 lasttxid,std::string refcoin,std::string hex);
std::string ImportGatewayMarkDone(uint64_t txfee,uint256 completetxid,std::string refcoin);
UniValue ImportGatewayPendingDeposits(uint256 bindtxid,std::string refcoin);
UniValue ImportGatewayPendingWithdraws(uint256 bindtxid,std::string refcoin);
UniValue ImportGatewayProcessedWithdraws(uint256 bindtxid,std::string refcoin);
UniValue ImportGatewayExternalAddress(uint256 bindtxid,CPubKey pubkey);
+10 -1
View File
@@ -22,6 +22,15 @@
bool PegsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
// CCcustom
UniValue PegsInfo();
std::string PegsCreate(uint64_t txfee,int64_t amount,std::vector<uint256> bindtxids);
std::string PegsFund(uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount);
std::string PegsGet(uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount);
std::string PegsRedeem(uint64_t txfee,uint256 pegstxid, uint256 tokenid);
std::string PegsLiquidate(uint64_t txfee,uint256 pegstxid, uint256 tokenid, uint256 liquidatetxid);
std::string PegsExchange(uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount);
UniValue PegsAccountHistory(uint256 pegstxid);
UniValue PegsAccountInfo(uint256 pegstxid);
UniValue PegsWorstAccounts(uint256 pegstxid);
UniValue PegsInfo(uint256 pegstxid);
#endif
+6 -6
View File
@@ -39,7 +39,7 @@ UniValue AssetOrders(uint256 refassetid, CPubKey pk, uint8_t additionalEvalCode)
txid = it->first.txhash;
LOGSTREAM("ccassets", CCLOG_DEBUG2, stream << "addOrders() checking txid=" << txid.GetHex() << std::endl);
if ( GetTransaction(txid, ordertx, hashBlock, false) != 0 )
if ( myGetTransaction(txid, ordertx, hashBlock) != 0 )
{
// for logging: funcid = DecodeAssetOpRet(vintx.vout[vintx.vout.size() - 1].scriptPubKey, evalCode, assetid, assetid2, price, origpubkey);
if (ordertx.vout.size() > 0 && (funcid = DecodeAssetTokenOpRet(ordertx.vout[ordertx.vout.size()-1].scriptPubKey, evalCode, assetid, assetid2, price, origpubkey)) != 0)
@@ -273,7 +273,7 @@ std::string CreateBuyOffer(int64_t txfee, int64_t bidamount, uint256 assetid, in
fprintf(stderr,"negative bidamount %lld, pricetotal %lld\n", (long long)bidamount, (long long)pricetotal);
return("");
}
if (GetTransaction(assetid, vintx, hashBlock, false) == 0)
if (myGetTransaction(assetid, vintx, hashBlock) == 0)
{
fprintf(stderr,"cant find assetid\n");
return("");
@@ -470,7 +470,7 @@ std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid)
if (AddNormalinputs(mtx, mypk, txfee, 3) > 0)
{
mask = ~((1LL << mtx.vin.size()) - 1);
if (GetTransaction(bidtxid, vintx, hashBlock, false) != 0)
if (myGetTransaction(bidtxid, vintx, hashBlock) != 0)
{
std::vector<uint8_t> vopretNonfungible;
GetNonfungibleData(assetid, vopretNonfungible);
@@ -520,7 +520,7 @@ std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid)
if (AddNormalinputs(mtx, mypk, txfee, 3) > 0)
{
mask = ~((1LL << mtx.vin.size()) - 1);
if (GetTransaction(asktxid, vintx, hashBlock, false) != 0)
if (myGetTransaction(asktxid, vintx, hashBlock) != 0)
{
std::vector<uint8_t> vopretNonfungible;
GetNonfungibleData(assetid, vopretNonfungible);
@@ -594,7 +594,7 @@ std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t f
if (AddNormalinputs(mtx, mypk, 2*txfee, 3) > 0)
{
mask = ~((1LL << mtx.vin.size()) - 1);
if (GetTransaction(bidtxid, vintx, hashBlock, false) != 0)
if (myGetTransaction(bidtxid, vintx, hashBlock) != 0)
{
bidamount = vintx.vout[bidvout].nValue;
SetAssetOrigpubkey(origpubkey, origprice, vintx);
@@ -697,7 +697,7 @@ std::string FillSell(int64_t txfee, uint256 assetid, uint256 assetid2, uint256 a
//if (AddNormalinputs(mtx, mypk, 2*txfee, 3) > 0)
//{
//mask = ~((1LL << mtx.vin.size()) - 1);
if (GetTransaction(asktxid, vintx, hashBlock, false) != 0)
if (myGetTransaction(asktxid, vintx, hashBlock) != 0)
{
orig_assetoshis = vintx.vout[askvout].nValue;
SetAssetOrigpubkey(origpubkey, total_nValue, vintx);
+11 -3
View File
@@ -52,9 +52,11 @@ one other technical note is that komodod has the insight-explorer extensions bui
#include "../utlist.h"
#include "../uthash.h"
#include "merkleblock.h"
#include "../komodo_nSPV_defs.h"
#define CC_BURNPUBKEY "02deaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddeaddead"
#define CC_MAXVINS 1024
#define CC_REQUIREMENTS_MSG (KOMODO_NSPV!=0?"to use CC contracts you need to nspv_login first\n":"to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n")
#define SMALLVAL 0.000000000000001
#define SATOSHIDEN ((uint64_t)100000000L)
@@ -79,6 +81,7 @@ one other technical note is that komodod has the insight-explorer extensions bui
OPRETID_CHANNELSDATA = 0x14,
OPRETID_HEIRDATA = 0x15,
OPRETID_ROGUEGAMEDATA = 0x16,
OPRETID_PEGSDATA = 0x17,
// non cc contract data:
OPRETID_FIRSTNONCCDATA = 0x80,
@@ -126,7 +129,7 @@ struct CCcontract_info
// the same for tokens 1of2 keys cc
char tokens1of2addr[64];
CPubKey tokens1of2pk[2];
CPubKey tokens1of2pk[2]; uint8_t tokens1of2priv[32];
// this is for spending from two additional 'unspendable' CC addresses of other eval codes
// (that is, for spending from several cc contract 'unspendable' addresses):
@@ -150,6 +153,7 @@ struct oracleprice_info
};
typedef std::vector<uint8_t> vscript_t;
extern struct NSPV_CCmtxinfo NSPV_U;
#ifdef ENABLE_WALLET
extern CWallet* pwalletMain;
@@ -172,12 +176,14 @@ static const uint256 zeroid;
static uint256 ignoretxid;
static int32_t ignorevin;
bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock);
bool NSPV_myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, int32_t &txheight, int32_t &currentheight);
int32_t is_hexstr(char *str,int32_t n);
bool myAddtomempool(CTransaction &tx, CValidationState *pstate = NULL, bool fSkipExpiry = false);
int32_t CCgettxout(uint256 txid,int32_t vout,int32_t mempoolflag,int32_t lockflag);
int64_t CCgettxout(uint256 txid,int32_t vout,int32_t mempoolflag,int32_t lockflag);
bool myIsutxo_spentinmempool(uint256 &spenttxid,int32_t &spentvini,uint256 txid,int32_t vout);
bool mytxid_inmempool(uint256 txid);
int32_t myIsutxo_spent(uint256 &spenttxid,uint256 txid,int32_t vout);
int32_t myGet_mempool_txs(std::vector<CTransaction> &txs,uint8_t evalcode,uint8_t funcid);
int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex);
int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp);
int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *endianedp);
@@ -249,7 +255,7 @@ CC *MakeTokensCCcond1(uint8_t evalcode, CPubKey pk);
CC *MakeTokensCCcond1(uint8_t evalcode, uint8_t evalcode2, CPubKey pk);
bool GetTokensCCaddress(struct CCcontract_info *cp, char *destaddr, CPubKey pk);
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, uint8_t *priv, char *coinaddr);
int32_t CClib_initcp(struct CCcontract_info *cp,uint8_t evalcode);
bool IsCCInput(CScript const& scriptSig);
@@ -286,9 +292,11 @@ 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,bool CCflag = true);
void SetCCtxids(std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex,char *coinaddr,bool CCflag = true);
int64_t NSPV_AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int32_t maxinputs,struct NSPV_CCmtxinfo *ptr);
int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int32_t maxinputs);
int64_t AddNormalinputs2(CMutableTransaction &mtx,int64_t total,int32_t maxinputs);
int64_t CCutxovalue(char *coinaddr,uint256 utxotxid,int32_t utxovout,int32_t CCflag);
bool NSPV_SignTx(CMutableTransaction &mtx,int32_t vini,int64_t utxovalue,const CScript scriptPubKey,uint32_t nTime);
// curve25519 and sha256
bits256 curve25519_shared(bits256 privkey,bits256 otherpub);
+26 -6
View File
@@ -397,6 +397,21 @@ int64_t IsTokensvout(bool goDeeper, bool checkPubkeys /*<--not used, always true
}
}
//special check for tx when spending from 1of2 CC address and one of pubkeys is global CC pubkey
struct CCcontract_info *cpEvalCode1,CEvalCode1;
cpEvalCode1 = CCinit(&CEvalCode1,evalCode1);
CPubKey pk=GetUnspendable(cpEvalCode1,0);
testVouts.push_back( std::make_pair(MakeTokensCC1of2vout(evalCode1, tx.vout[v].nValue, voutPubkeys[0], pk), std::string("dual-eval1 pegscc cc1of2 pk[0] globalccpk")) );
if (voutPubkeys.size() == 2) testVouts.push_back( std::make_pair(MakeTokensCC1of2vout(evalCode1, tx.vout[v].nValue, voutPubkeys[1], pk), std::string("dual-eval1 pegscc cc1of2 pk[1] globalccpk")) );
if (evalCode2!=0)
{
struct CCcontract_info *cpEvalCode2,CEvalCode2;
cpEvalCode2 = CCinit(&CEvalCode2,evalCode2);
CPubKey pk=GetUnspendable(cpEvalCode2,0);
testVouts.push_back( std::make_pair(MakeTokensCC1of2vout(evalCode2, tx.vout[v].nValue, voutPubkeys[0], pk), std::string("dual-eval2 pegscc cc1of2 pk[0] globalccpk")) );
if (voutPubkeys.size() == 2) testVouts.push_back( std::make_pair(MakeTokensCC1of2vout(evalCode2, tx.vout[v].nValue, voutPubkeys[1], pk), std::string("dual-eval2 pegscc cc1of2 pk[1] globalccpk")) );
}
// maybe it is single-eval or dual/three-eval token change?
std::vector<CPubKey> vinPubkeys, vinPubkeysUnfiltered;
ExtractTokensCCVinPubkeys(tx, vinPubkeysUnfiltered);
@@ -639,7 +654,7 @@ int64_t AddTokenCCInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, C
if (ivin != mtx.vin.size()) // that is, the tx.vout is already added to mtx.vin (in some previous calls)
continue;
if (GetTransaction(vintxid, vintx, hashBlock, false) != 0)
if (myGetTransaction(vintxid, vintx, hashBlock) != 0)
{
Getscriptaddress(destaddr, vintx.vout[vout].scriptPubKey);
if (strcmp(destaddr, tokenaddr) != 0 &&
@@ -855,7 +870,12 @@ std::string TokenTransfer(int64_t txfee, uint256 tokenid, vscript_t destpubkey,
if (txfee == 0)
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if (AddNormalinputs(mtx, mypk, txfee, 3) > 0)
/*if ( cp->tokens1of2addr[0] == 0 )
{
GetTokensCCaddress(cp, cp->tokens1of2addr, mypk);
fprintf(stderr,"set tokens1of2addr <- %s\n",cp->tokens1of2addr);
}*/
if (AddNormalinputs(mtx, mypk, txfee, 3) > 0)
{
mask = ~((1LL << mtx.vin.size()) - 1); // seems, mask is not used anymore
@@ -905,7 +925,7 @@ int64_t GetTokenBalance(CPubKey pk, uint256 tokenid)
// CCerror = strprintf("obsolete, cannot return correct value without eval");
// return 0;
if (GetTransaction(tokenid, tokentx, hashBlock, false) == 0)
if (myGetTransaction(tokenid, tokentx, hashBlock) == 0)
{
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "cant find tokenid" << std::endl);
CCerror = strprintf("cant find tokenid");
@@ -930,14 +950,14 @@ UniValue TokenInfo(uint256 tokenid)
cpTokens = CCinit(&tokensCCinfo, EVAL_TOKENS);
if( !GetTransaction(tokenid, tokenbaseTx, hashBlock, false) )
if( !myGetTransaction(tokenid, tokenbaseTx, hashBlock) )
{
fprintf(stderr, "TokenInfo() cant find tokenid\n");
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "cant find tokenid"));
return(result);
}
if (hashBlock.IsNull()) {
if ( KOMODO_NSPV <= 0 && hashBlock.IsNull()) {
result.push_back(Pair("result", "error"));
result.push_back(Pair("error", "the transaction is still in mempool"));
return(result);
@@ -1016,7 +1036,7 @@ UniValue TokenList()
cp = CCinit(&C, EVAL_TOKENS);
auto addTokenId = [&](uint256 txid) {
if (GetTransaction(txid, vintx, hashBlock, false) != 0) {
if (myGetTransaction(txid, vintx, hashBlock) != 0) {
if (vintx.vout.size() > 0 && DecodeTokenCreateOpRet(vintx.vout[vintx.vout.size() - 1].scriptPubKey, origpubkey, name, description) != 0) {
result.push_back(txid.GetHex());
}
+82 -33
View File
@@ -17,6 +17,7 @@
#include "key_io.h"
std::vector<CPubKey> NULL_pubkeys;
struct NSPV_CCmtxinfo NSPV_U;
/*
FinalizeCCTx is a very useful function that will properly sign both CC and normal inputs, adds normal change and the opreturn.
@@ -45,7 +46,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
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;
int32_t i,flag,utxovout,n,err = 0;
int32_t i,flag,mgret,utxovout,n,err = 0;
char myaddr[64], destaddr[64], unspendable[64], mytokensaddr[64], mysingletokensaddr[64], unspendabletokensaddr[64],CC1of2CCaddr[64];
uint8_t *privkey, myprivkey[32], unspendablepriv[32], /*tokensunspendablepriv[32],*/ *msg32 = 0;
CC *mycond=0, *othercond=0, *othercond2=0,*othercond4=0, *othercond3=0, *othercond1of2=NULL, *othercond1of2tokens = NULL, *cond=0, *condCC2=0,*mytokenscond = NULL, *mysingletokenscond = NULL, *othertokenscond = NULL;
@@ -96,12 +97,20 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
//This is a must to avoid hardfork change of validation in every CC, because there could be maximum one normal vin at the begining with current validation.
for (i=0; i<n; i++)
{
if ( GetTransaction(mtx.vin[i].prevout.hash,vintx,hashBlock,false) != 0 )
if (i==0 && mtx.vin[i].prevout.n==10e8)
continue;
if ( myGetTransaction(mtx.vin[i].prevout.hash,vintx,hashBlock) != 0 && mtx.vin[i].prevout.n < vintx.vout.size() )
{
if ( vintx.vout[mtx.vin[i].prevout.n].scriptPubKey.IsPayToCryptoCondition() == 0 && ccvins==0)
normalvins++;
else ccvins++;
}
}
else
{
fprintf(stderr,"vin.%d vout.%d is bigger than vintx.%d\n",i,mtx.vin[i].prevout.n,(int32_t)vintx.vout.size());
memset(myprivkey,0,32);
return("");
}
}
if (normalvins>1 && ccvins)
{
@@ -114,7 +123,8 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
memset(utxovalues,0,sizeof(utxovalues));
for (i=0; i<n; i++)
{
if ( GetTransaction(mtx.vin[i].prevout.hash,vintx,hashBlock,false) != 0 )
if (i==0 && mtx.vin[i].prevout.n==10e8) continue;
if ( (mgret= myGetTransaction(mtx.vin[i].prevout.hash,vintx,hashBlock)) != 0 )
{
utxovout = mtx.vin[i].prevout.n;
utxovalues[i] = vintx.vout[utxovout].nValue;
@@ -129,7 +139,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
{
mask |= (1LL << i);
}
} else fprintf(stderr,"FinalizeCCTx couldnt find %s\n",mtx.vin[i].prevout.hash.ToString().c_str());
} else fprintf(stderr,"FinalizeCCTx couldnt find %s mgret.%d\n",mtx.vin[i].prevout.hash.ToString().c_str(),mgret);
}
nmask = (1LL << n) - 1;
if ( 0 && (mask & nmask) != (CCmask & nmask) )
@@ -145,22 +155,37 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
n = mtx.vin.size();
for (i=0; i<n; i++)
{
if ( GetTransaction(mtx.vin[i].prevout.hash,vintx,hashBlock,false) != 0 )
if (i==0 && mtx.vin[i].prevout.n==10e8)
continue;
if ( (mgret= myGetTransaction(mtx.vin[i].prevout.hash,vintx,hashBlock)) != 0 )
{
utxovout = mtx.vin[i].prevout.n;
if ( vintx.vout[utxovout].scriptPubKey.IsPayToCryptoCondition() == 0 )
{
if ( SignTx(mtx,i,vintx.vout[utxovout].nValue,vintx.vout[utxovout].scriptPubKey) == 0 )
fprintf(stderr,"signing error for vini.%d of %llx\n",i,(long long)vinimask);
if ( KOMODO_NSPV <= 0 )
{
if ( SignTx(mtx,i,vintx.vout[utxovout].nValue,vintx.vout[utxovout].scriptPubKey) == 0 )
fprintf(stderr,"signing error for vini.%d of %llx\n",i,(long long)vinimask);
}
else
{
{
char addr[64];
Getscriptaddress(addr,vintx.vout[utxovout].scriptPubKey);
fprintf(stderr,"vout[%d] %.8f -> %s\n",utxovout,dstr(vintx.vout[utxovout].nValue),addr);
}
if ( NSPV_SignTx(mtx,i,vintx.vout[utxovout].nValue,vintx.vout[utxovout].scriptPubKey,0) == 0 )
fprintf(stderr,"NSPV signing error for vini.%d of %llx\n",i,(long long)vinimask);
}
}
else
{
Getscriptaddress(destaddr,vintx.vout[utxovout].scriptPubKey);
//fprintf(stderr,"FinalizeCCTx() vin.%d is CC %.8f -> (%s) vs %s\n",i,(double)utxovalues[i]/COIN,destaddr,cp->unspendableaddr2);
//fprintf(stderr,"FinalizeCCTx() vin.%d is CC %.8f -> (%s) vs %s\n",i,(double)utxovalues[i]/COIN,destaddr,mysingletokensaddr);
//std::cerr << "FinalizeCCtx() searching destaddr=" << destaddr << " for vin[" << i << "] satoshis=" << utxovalues[i] << std::endl;
if( strcmp(destaddr, myaddr) == 0 )
{
//fprintf(stderr, "FinalizeCCTx() matched cc myaddr (%s)\n", myaddr);
//fprintf(stderr, "FinalizeCCTx() matched cc myaddr (%s)\n", myaddr);
privkey = myprivkey;
cond = mycond;
}
@@ -168,30 +193,30 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
{
privkey = myprivkey;
cond = mytokenscond;
//fprintf(stderr,"FinalizeCCTx() matched dual-eval TokensCC1vout my token addr.(%s)\n",mytokensaddr);
//fprintf(stderr,"FinalizeCCTx() matched dual-eval TokensCC1vout my token addr.(%s)\n",mytokensaddr);
}
else if (strcmp(destaddr, mysingletokensaddr) == 0) // if this is TokensCC1vout
{
privkey = myprivkey;
cond = mysingletokenscond;
//fprintf(stderr, "FinalizeCCTx() matched single-eval token CC1vout my token addr.(%s)\n", mytokensaddr);
//fprintf(stderr, "FinalizeCCTx() matched single-eval token CC1vout my token addr.(%s)\n", mytokensaddr);
}
else if ( strcmp(destaddr,unspendable) == 0 )
{
privkey = unspendablepriv;
cond = othercond;
//fprintf(stderr,"FinalizeCCTx evalcode(%d) matched unspendable CC addr.(%s)\n",cp->evalcode,unspendable);
//fprintf(stderr,"FinalizeCCTx evalcode(%d) matched unspendable CC addr.(%s)\n",cp->evalcode,unspendable);
}
else if (strcmp(destaddr, unspendabletokensaddr) == 0)
{
privkey = unspendablepriv;
cond = othertokenscond;
//fprintf(stderr,"FinalizeCCTx() matched unspendabletokensaddr dual/three-eval CC addr.(%s)\n",unspendabletokensaddr);
//fprintf(stderr,"FinalizeCCTx() matched unspendabletokensaddr dual/three-eval CC addr.(%s)\n",unspendabletokensaddr);
}
// check if this is the 2nd additional evalcode + 'unspendable' cc addr:
else if ( strcmp(destaddr, cp->unspendableaddr2) == 0)
{
//fprintf(stderr,"FinalizeCCTx() matched %s unspendable2!\n",cp->unspendableaddr2);
//fprintf(stderr,"FinalizeCCTx() matched %s unspendable2!\n",cp->unspendableaddr2);
privkey = cp->unspendablepriv2;
if( othercond2 == 0 )
othercond2 = MakeCCcond1(cp->unspendableEvalcode2, cp->unspendablepk2);
@@ -200,7 +225,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
// check if this is 3rd additional evalcode + 'unspendable' cc addr:
else if ( strcmp(destaddr,cp->unspendableaddr3) == 0 )
{
//fprintf(stderr,"FinalizeCCTx() matched %s unspendable3!\n",cp->unspendableaddr3);
//fprintf(stderr,"FinalizeCCTx() matched %s unspendable3!\n",cp->unspendableaddr3);
privkey = cp->unspendablepriv3;
if( othercond3 == 0 )
othercond3 = MakeCCcond1(cp->unspendableEvalcode3, cp->unspendablepk3);
@@ -209,7 +234,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
// check if this is spending from 1of2 cc coins addr:
else if (strcmp(cp->coins1of2addr, destaddr) == 0)
{
//fprintf(stderr,"FinalizeCCTx() matched %s unspendable1of2!\n",cp->coins1of2addr);
//fprintf(stderr,"FinalizeCCTx() matched %s unspendable1of2!\n",cp->coins1of2addr);
privkey = cp->coins1of2priv;//myprivkey;
if (othercond1of2 == 0)
othercond1of2 = MakeCCcond1of2(cp->evalcode, cp->coins1of2pk[0], cp->coins1of2pk[1]);
@@ -217,7 +242,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
}
else if ( strcmp(CC1of2CCaddr,destaddr) == 0 )
{
//fprintf(stderr,"FinalizeCCTx() matched %s CC1of2CCaddr!\n",CC1of2CCaddr);
//fprintf(stderr,"FinalizeCCTx() matched %s CC1of2CCaddr!\n",CC1of2CCaddr);
privkey = unspendablepriv;
if (condCC2 == 0)
condCC2 = MakeCCcond1of2(cp->evalcode,unspendablepk,unspendablepk);
@@ -226,8 +251,8 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
// check if this is spending from 1of2 cc tokens addr:
else if (strcmp(cp->tokens1of2addr, destaddr) == 0)
{
//fprintf(stderr,"FinalizeCCTx() matched %s cp->tokens1of2addr!\n", cp->tokens1of2addr);
privkey = myprivkey;
//fprintf(stderr,"FinalizeCCTx() matched %s cp->tokens1of2addr!\n", cp->tokens1of2addr);
privkey = cp->tokens1of2priv;//myprivkey;
if (othercond1of2tokens == 0)
// NOTE: if additionalEvalcode2 is not set then it is dual-eval cc else three-eval cc
// TODO: verify evalcodes order if additionalEvalcode2 is not 0
@@ -251,32 +276,38 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
cond = othercond4;
flag = 1;
}
}
} //else privkey = myprivkey;
if ( flag == 0 )
{
fprintf(stderr,"CC signing error: vini.%d has unknown CC address.(%s)\n",i,destaddr);
memset(myprivkey,0,32);
return("");
}
}
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 ( 0 )
{
int32_t z;
for (z=0; z<32; z++)
fprintf(stderr,"%02x",privkey[z]);
fprintf(stderr," privkey, ");
for (z=0; z<32; z++)
fprintf(stderr,"%02x",((uint8_t *)sighash.begin())[z]);
fprintf(stderr," sighash [%d] %.8f %x\n",i,(double)utxovalues[i]/COIN,consensusBranchId);
}
if ( cc_signTreeSecp256k1Msg32(cond,privkey,sighash.begin()) != 0 )
{
//int32_t z;
//for (z=0; z<32; z++)
// fprintf(stderr,"%02x",((uint8_t *)sighash.begin())[z]);
//fprintf(stderr," sighash, ");
//for (z=0; z<32; z++)
// fprintf(stderr,"%02x",privkey[z]);
//fprintf(stderr," signed with privkey\n");
mtx.vin[i].scriptSig = CCSig(cond);
mtx.vin[i].scriptSig = CCSig(cond);
}
else
{
fprintf(stderr,"vini.%d has CC signing error address.(%s)\n",i,destaddr);
fprintf(stderr,"vini.%d has CC signing error address.(%s) %s\n",i,destaddr,EncodeHexTx(mtx).c_str());
memset(myprivkey,0,sizeof(myprivkey));
return("");
}
}
} else fprintf(stderr,"FinalizeCCTx couldnt find %s\n",mtx.vin[i].prevout.hash.ToString().c_str());
} else fprintf(stderr,"FinalizeCCTx2 couldnt find %s mgret.%d\n",mtx.vin[i].prevout.hash.ToString().c_str(),mgret);
}
if ( mycond != 0 )
cc_free(mycond);
@@ -300,15 +331,24 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
cc_free(mysingletokenscond);
if ( othertokenscond != 0 )
cc_free(othertokenscond);
memset(myprivkey,0,sizeof(myprivkey));
std::string strHex = EncodeHexTx(mtx);
if ( strHex.size() > 0 )
return(strHex);
else return("0");
}
void NSPV_CCunspents(std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs,char *coinaddr,bool ccflag);
void NSPV_CCtxids(std::vector<std::pair<CAddressIndexKey, CAmount> > &txids,char *coinaddr,bool ccflag);
void SetCCunspents(std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs,char *coinaddr,bool ccflag)
{
int32_t type=0,i,n; char *ptr; std::string addrstr; uint160 hashBytes; std::vector<std::pair<uint160, int> > addresses;
if ( KOMODO_NSPV > 0 )
{
NSPV_CCunspents(unspentOutputs,coinaddr,ccflag);
return;
}
n = (int32_t)strlen(coinaddr);
addrstr.resize(n+1);
ptr = (char *)addrstr.data();
@@ -328,6 +368,11 @@ void SetCCunspents(std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValu
void SetCCtxids(std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex,char *coinaddr,bool ccflag)
{
int32_t type=0,i,n; char *ptr; std::string addrstr; uint160 hashBytes; std::vector<std::pair<uint160, int> > addresses;
if ( KOMODO_NSPV > 0 )
{
NSPV_CCtxids(addressIndex,coinaddr,ccflag);
return;
}
n = (int32_t)strlen(coinaddr);
addrstr.resize(n+1);
ptr = (char *)addrstr.data();
@@ -357,7 +402,7 @@ int64_t CCutxovalue(char *coinaddr,uint256 utxotxid,int32_t utxovout,int32_t CCf
return(0);
}
int32_t CCgettxout(uint256 txid,int32_t vout,int32_t mempoolflag,int32_t lockflag)
int64_t CCgettxout(uint256 txid,int32_t vout,int32_t mempoolflag,int32_t lockflag)
{
CCoins coins;
//fprintf(stderr,"CCgettxoud %s/v%d\n",txid.GetHex().c_str(),vout);
@@ -510,6 +555,8 @@ int32_t CC_vinselect(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *
int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int32_t maxinputs)
{
int32_t abovei,belowi,ind,vout,i,n = 0; 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;
if ( KOMODO_NSPV > 0 )
return(NSPV_AddNormalinputs(mtx,mypk,total,maxinputs,&NSPV_U));
#ifdef ENABLE_WALLET
assert(pwalletMain != NULL);
const CKeyStore& keystore = *pwalletMain;
@@ -605,6 +652,8 @@ int64_t AddNormalinputs2(CMutableTransaction &mtx,int64_t total,int32_t maxinput
{
int32_t abovei,belowi,ind,vout,i,n = 0; int64_t sum,threshold,above,below; int64_t remains,nValue,totalinputs = 0; char coinaddr[64]; uint256 txid,hashBlock; CTransaction tx; struct CC_utxo *utxos,*up;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
if ( KOMODO_NSPV > 0 )
return(NSPV_AddNormalinputs(mtx,pubkey2pk(Mypubkey()),total,maxinputs,&NSPV_U));
utxos = (struct CC_utxo *)calloc(CC_MAXVINS,sizeof(*utxos));
if ( maxinputs > CC_MAXVINS )
maxinputs = CC_MAXVINS;
+102 -23
View File
@@ -18,6 +18,7 @@
*/
#include "CCinclude.h"
#include "komodo_structs.h"
#include "key_io.h"
#ifdef TESTMODE
#define MIN_NON_NOTARIZED_CONFIRMS 2
@@ -187,7 +188,7 @@ void CCaddr3set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *
}
// set pubkeys, myprivkey and 1of2 cc addr for spending from 1of2 cryptocondition vout:
void CCaddr1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2,uint8_t *priv,char *coinaddr)
void CCaddr1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2, uint8_t *priv, char *coinaddr)
{
cp->coins1of2pk[0] = pk1;
cp->coins1of2pk[1] = pk2;
@@ -197,20 +198,25 @@ void CCaddr1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2,uint8_t
// set pubkeys, myprivkey and 1of2 cc addr for spending from 1of2 token cryptocondition vout
// to get tokenaddr use GetTokensCCaddress()
void CCaddrTokens1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2, char *tokenaddr)
void CCaddrTokens1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2, uint8_t *priv, char *tokenaddr)
{
cp->tokens1of2pk[0] = pk1;
cp->tokens1of2pk[1] = pk2;
memcpy(cp->tokens1of2priv,priv,32);
strcpy(cp->tokens1of2addr, tokenaddr);
}
bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey)
{
CTxDestination address; txnouttype whichType;
if ( ExtractDestination(scriptPubKey,address) != 0 )
destaddr[0] = 0;
if ( scriptPubKey.begin() != 0 )
{
strcpy(destaddr,(char *)CBitcoinAddress(address).ToString().c_str());
return(true);
if ( ExtractDestination(scriptPubKey,address) != 0 )
{
strcpy(destaddr,(char *)CBitcoinAddress(address).ToString().c_str());
return(true);
}
}
//fprintf(stderr,"ExtractDestination failed\n");
return(false);
@@ -437,9 +443,28 @@ std::vector<uint8_t> Mypubkey()
return(pubkey);
}
extern char NSPV_wifstr[],NSPV_pubkeystr[];
extern uint32_t NSPV_logintime;
#define NSPV_AUTOLOGOUT 777
bool Myprivkey(uint8_t myprivkey[])
{
char coinaddr[64],checkaddr[64]; std::string strAddress; char *dest; int32_t i,n; CBitcoinAddress address; CKeyID keyID; CKey vchSecret; uint8_t buf33[33];
if ( KOMODO_NSPV > 0 )
{
if ( NSPV_logintime == 0 || time(NULL) > NSPV_logintime+NSPV_AUTOLOGOUT )
{
fprintf(stderr,"need to be logged in to get myprivkey\n");
return false;
}
vchSecret = DecodeSecret(NSPV_wifstr);
memcpy(myprivkey,vchSecret.begin(),32);
//for (i=0; i<32; i++)
// fprintf(stderr,"%02x",myprivkey[i]);
//fprintf(stderr," myprivkey %s\n",NSPV_wifstr);
memset((uint8_t *)vchSecret.begin(),0,32);
return true;
}
if ( Getscriptaddress(coinaddr,CScript() << Mypubkey() << OP_CHECKSIG) != 0 )
{
n = (int32_t)strlen(coinaddr);
@@ -454,6 +479,7 @@ bool Myprivkey(uint8_t myprivkey[])
if ( pwalletMain->GetKey(keyID,vchSecret) != 0 )
{
memcpy(myprivkey,vchSecret.begin(),32);
memset((uint8_t *)vchSecret.begin(),0,32);
if ( 0 )
{
for (i=0; i<32; i++)
@@ -559,9 +585,13 @@ uint256 CCOraclesReverseScan(char const *logcategory,uint256 &txid,int32_t heigh
return(zeroid);
}
int32_t NSPV_coinaddr_inmempool(char const *logcategory,char *coinaddr,uint8_t CCflag);
int32_t myIs_coinaddr_inmempoolvout(char const *logcategory,char *coinaddr)
{
int32_t i,n; char destaddr[64];
if ( KOMODO_NSPV > 0 )
return(NSPV_coinaddr_inmempool(logcategory,coinaddr,1));
BOOST_FOREACH(const CTxMemPoolEntry &e,mempool.mapTx)
{
const CTransaction &tx = e.GetTx();
@@ -582,6 +612,32 @@ int32_t myIs_coinaddr_inmempoolvout(char const *logcategory,char *coinaddr)
return(0);
}
extern struct NSPV_mempoolresp NSPV_mempoolresult;
extern bool NSPV_evalcode_inmempool(uint8_t evalcode,uint8_t funcid);
int32_t myGet_mempool_txs(std::vector<CTransaction> &txs,uint8_t evalcode,uint8_t funcid)
{
int i=0;
if ( KOMODO_NSPV > 0 )
{
CTransaction tx; uint256 hashBlock;
NSPV_evalcode_inmempool(evalcode,funcid);
for (int i=0;i<NSPV_mempoolresult.numtxids;i++)
{
if (myGetTransaction(NSPV_mempoolresult.txids[i],tx,hashBlock)!=0) txs.push_back(tx);
}
return (NSPV_mempoolresult.numtxids);
}
BOOST_FOREACH(const CTxMemPoolEntry &e,mempool.mapTx)
{
txs.push_back(e.GetTx());
i++;
}
return(i);
}
int32_t CCCointxidExists(char const *logcategory,uint256 cointxid)
{
char txidaddr[64]; std::string coin; int32_t numvouts; uint256 hashBlock;
@@ -611,33 +667,56 @@ uint256 BitcoinGetProofMerkleRoot(const std::vector<uint8_t> &proofData, std::ve
bool komodo_txnotarizedconfirmed(uint256 txid)
{
char str[65];
uint32_t confirms,notarized=0,txheight;
int32_t confirms,notarized=0,txheight=0,currentheight=0;;
CTransaction tx;
uint256 hashBlock;
CBlockIndex *pindex;
char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp;
if ( myGetTransaction(txid,tx,hashBlock) == 0 )
if (KOMODO_NSPV!=0)
{
fprintf(stderr,"komodo_txnotarizedconfirmed cant find txid %s\n",txid.ToString().c_str());
return(0);
if ( NSPV_myGetTransaction(txid,tx,hashBlock,txheight,currentheight) == 0 )
{
fprintf(stderr,"komodo_txnotarizedconfirmed cant find txid %s\n",txid.ToString().c_str());
return(0);
}
else if (txheight<=0)
{
fprintf(stderr,"komodo_txnotarizedconfirmed no txheight.%d for txid %s\n",txheight,txid.ToString().c_str());
return(0);
}
else if (txheight>currentheight)
{
fprintf(stderr,"komodo_txnotarizedconfirmed backwards heights for txid %s hts.(%d %d)\n",txid.ToString().c_str(),txheight,currentheight);
return(0);
}
confirms=1 + currentheight - txheight;
}
else if ( hashBlock == zeroid )
else
{
fprintf(stderr,"komodo_txnotarizedconfirmed no hashBlock for txid %s\n",txid.ToString().c_str());
return(0);
if ( myGetTransaction(txid,tx,hashBlock) == 0 )
{
fprintf(stderr,"komodo_txnotarizedconfirmed cant find txid %s\n",txid.ToString().c_str());
return(0);
}
else if ( hashBlock == zeroid )
{
fprintf(stderr,"komodo_txnotarizedconfirmed no hashBlock for txid %s\n",txid.ToString().c_str());
return(0);
}
else if ( (pindex= komodo_blockindex(hashBlock)) == 0 || (txheight= pindex->GetHeight()) <= 0 )
{
fprintf(stderr,"komodo_txnotarizedconfirmed no txheight.%d %p for txid %s\n",txheight,pindex,txid.ToString().c_str());
return(0);
}
else if ( (pindex= chainActive.LastTip()) == 0 || pindex->GetHeight() < txheight )
{
fprintf(stderr,"komodo_txnotarizedconfirmed backwards heights for txid %s hts.(%d %d)\n",txid.ToString().c_str(),txheight,(int32_t)pindex->GetHeight());
return(0);
}
confirms=1 + pindex->GetHeight() - txheight;
}
else if ( (pindex= komodo_blockindex(hashBlock)) == 0 || (txheight= pindex->GetHeight()) <= 0 )
{
fprintf(stderr,"komodo_txnotarizedconfirmed no txheight.%d %p for txid %s\n",txheight,pindex,txid.ToString().c_str());
return(0);
}
else if ( (pindex= chainActive.LastTip()) == 0 || pindex->GetHeight() < txheight )
{
fprintf(stderr,"komodo_txnotarizedconfirmed backwards heights for txid %s hts.(%d %d)\n",txid.ToString().c_str(),txheight,(int32_t)pindex->GetHeight());
return(0);
}
confirms=1 + pindex->GetHeight() - txheight;
if ((sp= komodo_stateptr(symbol,dest)) != 0 && (notarized=sp->NOTARIZED_HEIGHT) > 0 && txheight > sp->NOTARIZED_HEIGHT) notarized=0;
#ifdef TESTMODE
notarized=0;
+1 -1
View File
@@ -131,7 +131,7 @@ int64_t AddAuctionInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPu
// prevent dup
if ( it->second.satoshis < 1000000 )
continue;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
if ( myGetTransaction(txid,vintx,hashBlock) != 0 )
{
if ( (nValue= IsAuctionvout(cp,vintx,(int32_t)it->first.index)) > 0 )
{
+2 -2
View File
@@ -520,7 +520,7 @@ int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK
if ( it->second.satoshis < threshold || it->second.satoshis == txfee )
continue;
// no need to prevent dup
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
if ( myGetTransaction(txid,vintx,hashBlock) != 0 )
{
if ( (nValue= IsCClibvout(cp,vintx,vout,cmpaddr)) >= 1000000 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
@@ -550,7 +550,7 @@ int64_t AddCClibtxfee(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKe
//char str[65]; fprintf(stderr,"%s check %s/v%d %.8f vs %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN,(double)threshold/COIN);
if ( it->second.satoshis < txfee )
continue;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
if ( myGetTransaction(txid,vintx,hashBlock) != 0 )
{
if ( (nValue= IsCClibvout(cp,vintx,vout,coinaddr)) != 0 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
+37 -34
View File
@@ -416,7 +416,7 @@ int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, C
else marker=2;
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
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 && myGetTransaction(it->first.txhash,tx,hashBlock) != 0 && (numvouts=tx.vout.size()) > 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()) && IsChannelsMarkervout(cp,tx,marker==1?srcpub:destpub,marker)>0 &&
@@ -431,12 +431,14 @@ int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, C
{
txid=zeroid;
int32_t mindepth=CHANNELS_MAXPAYMENTS;
BOOST_FOREACH(const CTxMemPoolEntry &e, mempool.mapTx)
std::vector<CTransaction> tmp_txs;
myGet_mempool_txs(tmp_txs,EVAL_CHANNELS,'P');
for (std::vector<CTransaction>::const_iterator it=tmp_txs.begin(); it!=tmp_txs.end(); it++)
{
const CTransaction &txmempool = e.GetTx();
const CTransaction &txmempool = *it;
const uint256 &hash = txmempool.GetHash();
if ((numvouts=txmempool.vout.size()) > 0 && DecodeChannelsOpRet(txmempool.vout[numvouts-1].scriptPubKey,tokenid,tmp_txid,srcpub,destpub,param1,param2,param3) != 0 &&
if ((numvouts=txmempool.vout.size()) > 0 && DecodeChannelsOpRet(txmempool.vout[numvouts-1].scriptPubKey,tokenid,tmp_txid,srcpub,destpub,param1,param2,param3)=='P' &&
tmp_txid==openTx.GetHash() && param1 < mindepth)
{
txid=hash;
@@ -451,8 +453,9 @@ int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, C
mtx.vin.push_back(CTxIn(txid,0,CScript()));
mtx.vin.push_back(CTxIn(txid,marker,CScript()));
Myprivkey(myprivkey);
if (tokenid!=zeroid) CCaddrTokens1of2set(cp,srcpub,destpub,coinaddr);
if (tokenid!=zeroid) CCaddrTokens1of2set(cp,srcpub,destpub,myprivkey,coinaddr);
else CCaddr1of2set(cp,srcpub,destpub,myprivkey,coinaddr);
memset(myprivkey,0,32);
return totalinputs;
}
else return 0;
@@ -517,7 +520,7 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if (GetTransaction(opentxid,channelOpenTx,hashblock,false) == 0)
if (myGetTransaction(opentxid,channelOpenTx,hashblock) == 0)
{
CCerror = strprintf("invalid channel open txid");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
@@ -555,7 +558,7 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid,mypk)) !=0 && (change=funds-amount)>=0)
{
numpayments=amount/payment;
if (GetTransaction(prevtxid,prevTx,hashblock,false) != 0 && (numvouts=prevTx.vout.size()) > 0 &&
if (myGetTransaction(prevtxid,prevTx,hashblock) != 0 && (numvouts=prevTx.vout.size()) > 0 &&
((funcid = DecodeChannelsOpRet(prevTx.vout[numvouts-1].scriptPubKey, tokenid, txid, srcpub, destpub, prevdepth, param2, param3)) != 0) &&
(funcid == 'P' || funcid=='O'))
{
@@ -642,7 +645,7 @@ std::string ChannelClose(uint64_t txfee,uint256 opentxid)
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if (GetTransaction(opentxid,channelOpenTx,hashblock,false) == 0)
if (myGetTransaction(opentxid,channelOpenTx,hashblock) == 0)
{
CCerror = strprintf("invalid channel open txid");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
@@ -702,7 +705,7 @@ std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if (GetTransaction(closetxid,channelCloseTx,hashblock,false) == 0)
if (myGetTransaction(closetxid,channelCloseTx,hashblock) == 0)
{
CCerror = strprintf("invalid channel close txid");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
@@ -726,7 +729,7 @@ std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
return ("");
}
if (GetTransaction(opentxid,channelOpenTx,hashblock,false) == 0)
if (myGetTransaction(opentxid,channelOpenTx,hashblock) == 0)
{
CCerror = strprintf("invalid channel open txid");
LOGSTREAM("channelscc",CCLOG_INFO, stream << CCerror << std::endl);
@@ -754,7 +757,7 @@ std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
{
if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid,mypk)) !=0 && funds>0)
{
if ((GetTransaction(prevtxid,prevTx,hashblock,false) != 0) && (numvouts=prevTx.vout.size()) > 0 &&
if ((myGetTransaction(prevtxid,prevTx,hashblock) != 0) && (numvouts=prevTx.vout.size()) > 0 &&
DecodeChannelsOpRet(prevTx.vout[numvouts-1].scriptPubKey, tokenid, txid, srcpub, destpub, param1, param2, param3) != 0)
{
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,CC_MARKER_VALUE,mypk));
@@ -799,7 +802,7 @@ UniValue ChannelsList()
txid = it->first.txhash;
vout = (int32_t)it->first.index;
nValue = (int64_t)it->second;
if ( (vout == 1 || vout == 2) && nValue == CC_MARKER_VALUE && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 )
if ( (vout == 1 || vout == 2) && nValue == CC_MARKER_VALUE && myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 0 )
{
if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,tokenid,tmp_txid,srcpub,destpub,param1,param2,param3) == 'O')
{
@@ -814,18 +817,18 @@ UniValue ChannelsList()
UniValue ChannelsInfo(uint256 channeltxid)
{
UniValue result(UniValue::VOBJ),array(UniValue::VARR); CTransaction tx,opentx; uint256 txid,tmp_txid,hashBlock,param3,opentxid,hashchain,prevtxid,tokenid;
UniValue result(UniValue::VOBJ),array(UniValue::VARR); CTransaction tx,opentx; uint256 txid,tmp_txid,hashBlock,param3,opentxid,hashchain,tokenid;
struct CCcontract_info *cp,C; char CCaddr[65],addr[65],str[512]; int32_t vout,numvouts,param1,numpayments;
int64_t param2,payment; CPubKey srcpub,destpub,mypk;
std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex; std::vector<uint256> txids;
std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex; std::vector<CTransaction> txs;
cp = CCinit(&C,EVAL_CHANNELS);
mypk = pubkey2pk(Mypubkey());
if (GetTransaction(channeltxid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 &&
if (myGetTransaction(channeltxid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 0 &&
(DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,tokenid,opentxid,srcpub,destpub,param1,param2,param3) == 'O'))
{
GetCCaddress(cp,CCaddr,mypk);
GetCCaddress1of2(cp,CCaddr,srcpub,destpub);
Getscriptaddress(addr,CScript() << ParseHex(HexStr(destpub)) << OP_CHECKSIG);
result.push_back(Pair("result","success"));
result.push_back(Pair("Channel CC address",CCaddr));
@@ -841,40 +844,41 @@ UniValue ChannelsInfo(uint256 channeltxid)
{
result.push_back(Pair("Denomination (satoshi)",i64tostr(param2)));
result.push_back(Pair("Amount (satoshi)",i64tostr(param1*param2)));
}
}
GetCCaddress(cp,CCaddr,mypk);
SetCCtxids(addressIndex,CCaddr,true);
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++)
{
if (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 && (tmp_txid==channeltxid || tx.GetHash()==channeltxid))
txids.push_back(it->first.txhash);
if (myGetTransaction(it->first.txhash,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 0 && it->second==CC_MARKER_VALUE &&
DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,tokenid,tmp_txid,srcpub,destpub,param1,param2,param3)!=0 && (tmp_txid==channeltxid || tx.GetHash()==channeltxid))
txs.push_back(tx);
}
BOOST_FOREACH(const CTxMemPoolEntry &e, mempool.mapTx)
std::vector<CTransaction> tmp_txs;
myGet_mempool_txs(tmp_txs,EVAL_CHANNELS,'P');
for (std::vector<CTransaction>::const_iterator it=tmp_txs.begin(); it!=tmp_txs.end(); it++)
{
const CTransaction &txmempool = e.GetTx();
const uint256 &hash = txmempool.GetHash();
const CTransaction &txmempool = *it;
if ((numvouts=txmempool.vout.size()) > 0 && DecodeChannelsOpRet(txmempool.vout[numvouts-1].scriptPubKey,tokenid,tmp_txid,srcpub,destpub,param1,param2,param3) == 'P' && tmp_txid==channeltxid)
txids.push_back(hash);
txs.push_back(txmempool);
}
prevtxid=zeroid;
for (std::vector<uint256>::const_iterator it=txids.begin(); it!=txids.end(); it++)
for (std::vector<CTransaction>::const_iterator it=txs.begin(); it!=txs.end(); it++)
{
txid=*it;
if (txid!=prevtxid && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 )
tx=*it;
if ((numvouts= tx.vout.size()) > 0 )
{
UniValue obj(UniValue::VOBJ);
if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,tokenid,tmp_txid,srcpub,destpub,param1,param2,param3) == 'O' && tx.GetHash()==channeltxid)
{
obj.push_back(Pair("Open",txid.GetHex().data()));
obj.push_back(Pair("Open",tx.GetHash().GetHex().data()));
}
else if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,tokenid,opentxid,srcpub,destpub,param1,param2,param3) == 'P' && opentxid==channeltxid)
{
if (GetTransaction(opentxid,opentx,hashBlock,false) != 0 && (numvouts=opentx.vout.size()) > 0 &&
if (myGetTransaction(opentxid,opentx,hashBlock) != 0 && (numvouts=opentx.vout.size()) > 0 &&
DecodeChannelsOpRet(opentx.vout[numvouts-1].scriptPubKey,tokenid,tmp_txid,srcpub,destpub,numpayments,payment,hashchain) == 'O')
{
Getscriptaddress(str,tx.vout[3].scriptPubKey);
obj.push_back(Pair("Payment",txid.GetHex().data()));
obj.push_back(Pair("Payment",tx.GetHash().GetHex().data()));
obj.push_back(Pair("Number of payments",param2));
obj.push_back(Pair("Amount",param2*payment));
obj.push_back(Pair("Destination",str));
@@ -884,18 +888,17 @@ UniValue ChannelsInfo(uint256 channeltxid)
}
else if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,tokenid,opentxid,srcpub,destpub,param1,param2,param3) == 'C' && opentxid==channeltxid)
{
obj.push_back(Pair("Close",txid.GetHex().data()));
obj.push_back(Pair("Close",tx.GetHash().GetHex().data()));
}
else if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,tokenid,opentxid,srcpub,destpub,param1,param2,param3) == 'R' && opentxid==channeltxid)
{
Getscriptaddress(str,tx.vout[2].scriptPubKey);
obj.push_back(Pair("Refund",txid.GetHex().data()));
obj.push_back(Pair("Refund",tx.GetHash().GetHex().data()));
obj.push_back(Pair("Amount",param1*param2));
obj.push_back(Pair("Destination",str));
}
array.push_back(obj);
}
prevtxid=txid;
}
result.push_back(Pair("Transactions",array));
}
+6 -6
View File
@@ -206,12 +206,12 @@ void OS_nonportable_randombytes(uint8_t *x,long xlen);
int32_t OS_nonportable_init();
#endif
void OS_portable_init();
void OS_init();
void OS_portable_init(void);
void OS_init(void);
int32_t sortds(double *buf,uint32_t num,int32_t size);
int32_t revsortds(double *buf,uint32_t num,int32_t size);
double OS_portable_milliseconds();
double OS_portable_milliseconds(void);
void OS_portable_randombytes(uint8_t *x,long xlen);
int32_t OS_portable_truncate(char *fname,long filesize);
char *OS_portable_path(char *str);
@@ -256,7 +256,7 @@ int32_t OS_removefile(char *fname,int32_t scrubflag);
void *OS_mapfile(char *fname,long *filesizep,int32_t enablewrite);
int32_t OS_releasemap(void *ptr,unsigned long filesize);
double OS_milliseconds();
double OS_milliseconds(void);
void OS_randombytes(uint8_t *x,long xlen);
//int32_t OS_syncmap(struct OS_mappedptr *mp,long len);
@@ -313,7 +313,7 @@ void sort64s(uint64_t *buf,uint32_t num,int32_t size);
void revsort64s(uint64_t *buf,uint32_t num,int32_t size);
int decode_base32(uint8_t *token,uint8_t *tokenstr,int32_t len);
int init_base32(char *tokenstr,uint8_t *token,int32_t len);
char *OS_mvstr();
char *OS_mvstr(void);
long _stripwhite(char *buf,int accept);
int32_t is_DST(int32_t datenum);
@@ -381,7 +381,7 @@ double dxblend(double *destp,double val,double decay);
uint64_t calc_ipbits(char *ip_port);
void expand_ipbits(char *ipaddr,uint64_t ipbits);
void escape_code(char *escaped,char *str);
void SaM_PrepareIndices();
void SaM_PrepareIndices(void);
// iguana_serdes.c
#ifndef IGUANA_LOG2PACKETSIZE
+4 -1
View File
@@ -40,7 +40,10 @@ long stripquotes(char *str)
return(0);
len = strlen(str);
if ( str[0] == '"' && str[len-1] == '"' )
str[len-1] = 0, offset = 1;
{
str[len-1] = 0;
offset = 1;
}
else offset = 0;
return(offset);
}
+17 -14
View File
@@ -1041,6 +1041,7 @@ int32_t itemvalid(char *refcoin,int64_t *refundedp,int64_t *waitingp,struct clai
*refundedp = *waitingp = 0;
if ( item->refundvalue < 0 )
return(-1);
// change "kmd" -> %s, tolowerstr(refcoin)
sprintf(url,"https://kmd.explorer.dexstats.info/insight-api-komodo/addr/%s",item->destaddr);
if ( (retstr= send_curl(url,"/tmp/itemvalid")) != 0 )
{
@@ -1061,7 +1062,7 @@ int32_t itemvalid(char *refcoin,int64_t *refundedp,int64_t *waitingp,struct clai
}
free_json(curljson);
}
//printf("%s\n",retstr);
printf("%s\n",retstr);
free(retstr);
}
if ( item->approved != 0 )
@@ -1086,18 +1087,19 @@ void scan_claims(int32_t issueflag,char *refcoin,int32_t batchid)
else if ( batchid == 2 )
{
batchmin = 1;//777 * SATOSHIDEN;
batchmax = 77777 * SATOSHIDEN;
batchmax = 5000 * SATOSHIDEN;
}
else if ( batchid == 3 )
{
batchmin = 77777 * SATOSHIDEN;
batchmax = 1000000 * SATOSHIDEN;
batchmin = 1;//117777 * SATOSHIDEN;
batchmax = 10000000 * SATOSHIDEN;
}
for (i=0; i<NUM_CLAIMS; i++)
{
item = &CLAIMS[i];
if ( item->refundvalue < batchmin || item->refundvalue >= batchmax )
continue;
printf("check.%d %s %.8f vs refund %.8f -> %s\n",batchid,item->oldaddr,dstr(item->total),dstr(item->refundvalue),item->destaddr);
if ( itemvalid(refcoin,&refunded,&waiting,item) < 0 )
{
if ( refunded != 0 )
@@ -1170,7 +1172,7 @@ int32_t update_claimvalue(int32_t *disputedp,char *addr,int64_t amount,bits256 t
item = &CLAIMS[i];
item->refundvalue = amount;
if ( bits256_nonz(item->txid) != 0 )
printf("disputed.%d %s claimed %.8f vs %.8f\n",item->disputed,addr,dstr(item->total),dstr(amount));
printf("disputed.%d (%s) %s claimed %.8f vs %.8f\n",item->disputed,item->username,addr,dstr(item->total),dstr(amount));
item->txid = txid;
if ( item->disputed != 0 )
*disputedp = 1;
@@ -1183,6 +1185,7 @@ int32_t update_claimvalue(int32_t *disputedp,char *addr,int64_t amount,bits256 t
int64_t update_claimstats(char *username,char *oldaddr,char *destaddr,int64_t amount)
{
int32_t i; struct claimitem *item;
printf("claim user.(%s) (%s) -> (%s) %.8f\n",username,oldaddr,destaddr,dstr(amount));
for (i=0; i<NUM_CLAIMS; i++)
{
if ( strcmp(oldaddr,CLAIMS[i].oldaddr) == 0 )
@@ -1191,7 +1194,7 @@ int64_t update_claimstats(char *username,char *oldaddr,char *destaddr,int64_t am
if ( strcmp(destaddr,item->destaddr) != 0 )//|| strcmp(username,item->username) != 0 )
{
item->disputed++;
printf("disputed.%d claim.%-4d: (%36s -> %36s %s) vs. (%36s -> %36s %s) \n",item->disputed,i,oldaddr,destaddr,username,item->oldaddr,item->destaddr,item->username);
printf("disputed.%d claim.%-4d: (%36s -> [%36s] %s) vs. (%36s -> [%36s] %s) \n",item->disputed,i,oldaddr,destaddr,username,item->oldaddr,item->destaddr,item->username);
}
item->numutxos++;
item->total += amount;
@@ -1258,14 +1261,14 @@ int64_t sum_of_vins(char *refcoin,int32_t *totalvinsp,int32_t *uniqaddrsp,bits25
return(total);
}
void reconcile_claims(char *fname)
void reconcile_claims(char *refcoin,char *fname)
{
FILE *fp; double amount; int32_t i,n,numlines = 0; char buf[1024],fields[16][256],*str; int64_t total = 0;
if ( (fp= fopen(fname,"rb")) != 0 )
{
while ( fgets(buf,sizeof(buf),fp) > 0 )
{
//printf("%d.(%s)\n",numlines,buf);
printf("%d.(%s)\n",numlines,buf);
str = buf;
n = i = 0;
memset(fields,0,sizeof(fields));
@@ -1277,7 +1280,7 @@ void reconcile_claims(char *fname)
i = 0;
if ( n > 1 )
{
//printf("(%16s) ",fields[n]);
printf("(%16s) ",fields[n]);
}
n++;
if ( *str == '\n' || *str == '\r' )
@@ -1287,8 +1290,8 @@ void reconcile_claims(char *fname)
str++;
else fields[n][i++] = *str++;
}
//printf("%s\n",fields[0]);
total += update_claimstats(fields[1],fields[3],fields[6],atof(fields[4])*SATOSHIDEN + 0.0000000049);
printf("%s\n",fields[1]);
total += update_claimstats(fields[1],fields[3],fields[5 + (strcmp("KMD",refcoin)==0)],atof(fields[4])*SATOSHIDEN + 0.0000000049);
numlines++;
}
fclose(fp);
@@ -1326,7 +1329,7 @@ int32_t main(int32_t argc,char **argv)
if ( 1 )//strcmp(coinstr,"KMD") == 0 )
{
sprintf(buf,"%s-Claims.csv",coinstr);
reconcile_claims(buf);
reconcile_claims(coinstr,buf);
for (i=0; i<NUM_CLAIMS; i++)
{
if ( CLAIMS[i].disputed != 0 )
@@ -1393,8 +1396,8 @@ int32_t main(int32_t argc,char **argv)
}
//scan_claims(0,coinstr,0);
//scan_claims(0,coinstr,1);
scan_claims(0,coinstr,2);
//scan_claims(0,coinstr,3);
//scan_claims(0,coinstr,2);
scan_claims(1,coinstr,3);
}
else if ( (retjson= get_listunspent(coinstr,acstr)) != 0 )
{
+1
View File
@@ -587,6 +587,7 @@ uint256 DiceHashEntropy(uint256 &entropy,uint256 _txidpriv,int32_t vout,int32_t
fprintf(stderr,"%02x",ssecret2.bytes[i]);
fprintf(stderr," ssecret2 dont match\n");
}
memset(tmp256.bytes,0,32);
//char str[65],str2[65];
//fprintf(stderr,"generated house hentropy.%s <- entropy.%s\n",uint256_str(str,hentropy),uint256_str(str2,entropy));
return(hentropy);
+77 -29
View File
@@ -3148,6 +3148,8 @@ UniValue dilithium_keypair(uint64_t txfee,struct CCcontract_info *cp,cJSON *para
if ( externalflag == 0 )
result.push_back(Pair("warning","test mode using privkey for -pubkey, only for testing. there is no point using quantum secure signing if you are using a privkey with a known secp256k1 pubkey!!"));
result.push_back(Pair("result","success"));
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(result);
}
@@ -3194,9 +3196,23 @@ UniValue dilithium_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *par
if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,dilithiumpk));
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,dilithium_registeropret(handle,mypk,bigpub));
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(musig_rawtxresult(result,rawtx));
} else return(cclib_error(result,"couldnt find enough funds"));
} else return(cclib_error(result,"not enough parameters"));
}
else
{
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(cclib_error(result,"couldnt find enough funds"));
}
}
else
{
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(cclib_error(result,"not enough parameters"));
}
} else return(cclib_error(result,"not dilithiumpk funds"));
}
@@ -3222,9 +3238,23 @@ UniValue dilithium_sign(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
result.push_back(Pair("signature",dilithium_hexstr(str,sm,smlen)));
calc_rmd160_sha256(rmd160,sm,smlen);
result.push_back(Pair("sighash",dilithium_hexstr(str,rmd160,20)));
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(result);
} else return(cclib_error(result,"unexpected signed message len"));
} else return(cclib_error(result,"not enough parameters"));
}
else
{
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(cclib_error(result,"unexpected signed message len"));
}
}
else
{
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(cclib_error(result,"not enough parameters"));
}
}
UniValue dilithium_verify(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
@@ -3289,7 +3319,7 @@ UniValue dilithium_send(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
UniValue dilithium_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey mypk,destpub33; CTransaction vintx; uint256 prevhash,hashBlock,destpubtxid; int32_t i,smlen,n,numvouts; char str[129],*scriptstr; CTxOut vout; std::string handle; uint8_t pk[CRYPTO_PUBLICKEYBYTES],pk2[CRYPTO_PUBLICKEYBYTES],sk[CRYPTO_SECRETKEYBYTES],msg[32],seed[32]; std::vector<uint8_t> sig;
UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey mypk,destpub33; CTransaction vintx; uint256 prevhash,hashBlock,destpubtxid; int32_t i,smlen,n,numvouts; char str[129],*scriptstr,*retstr=""; CTxOut vout; std::string handle; uint8_t pk[CRYPTO_PUBLICKEYBYTES],pk2[CRYPTO_PUBLICKEYBYTES],sk[CRYPTO_SECRETKEYBYTES],msg[32],seed[32]; std::vector<uint8_t> sig;
if ( txfee == 0 )
txfee = DILITHIUM_TXFEE;
mypk = pubkey2pk(Mypubkey());
@@ -3317,23 +3347,31 @@ UniValue dilithium_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params
if ( dilithium_sendopretdecode(destpubtxid,vintx.vout[numvouts-1].scriptPubKey) == 'x' )
{
if ( dilithium_bigpubget(handle,destpub33,pk2,destpubtxid) < 0 )
return(cclib_error(result,"couldnt get bigpub"));
retstr = (char *)"couldnt get bigpub";
else if ( memcmp(pk,pk2,sizeof(pk)) != 0 )
return(cclib_error(result,"dilithium bigpub mismatch"));
retstr = (char *)"dilithium bigpub mismatch";
else if ( destpub33 != mypk )
return(cclib_error(result,"destpub33 is not for this -pubkey"));
retstr = (char *)"destpub33 is not for this -pubkey";
else if ( _dilithium_sign(&sig[0],&smlen,msg,32,sk) < 0 )
return(cclib_error(result,"dilithium signing error"));
retstr = (char *)"dilithium signing error";
else if ( smlen != 32+CRYPTO_BYTES )
return(cclib_error(result,"siglen error"));
mtx.vin.push_back(CTxIn(prevhash,0));
mtx.vout.push_back(vout);
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,dilithium_spendopret(destpubtxid,sig));
return(dilithium_rawtxresult(result,rawtx));
} else return(cclib_error(result,"couldnt decode send opret"));
} else return(cclib_error(result,"couldnt find vin0"));
} else return(cclib_error(result,"script or bad destpubtxid is not hex"));
} else return(cclib_error(result,"need to have exactly 2 params sendtxid, scriptPubKey"));
retstr = (char *)"siglen error";
else
{
mtx.vin.push_back(CTxIn(prevhash,0));
mtx.vout.push_back(vout);
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,dilithium_spendopret(destpubtxid,sig));
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(dilithium_rawtxresult(result,rawtx));
}
} else retstr = (char *)"couldnt decode send opret";
} else retstr = (char *)"couldnt find vin0";
} else retstr = (char *)"script or bad destpubtxid is not hex";
} else retstr = (char *)"need to have exactly 2 params sendtxid, scriptPubKey";
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(cclib_error(result,retstr));
}
int64_t dilithium_inputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 destpubtxid,int64_t total,int32_t maxinputs,char *cmpaddr)
@@ -3354,7 +3392,7 @@ int64_t dilithium_inputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPu
//char str[65]; fprintf(stderr,"%s check %s/v%d %.8f vs %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN,(double)threshold/COIN);
if ( it->second.satoshis < threshold || it->second.satoshis == DILITHIUM_TXFEE )
continue;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 && (numvouts= vintx.vout.size()) > 1 )
if ( myGetTransaction(txid,vintx,hashBlock) != 0 && (numvouts= vintx.vout.size()) > 1 )
{
if ( (nValue= IsCClibvout(cp,vintx,vout,cmpaddr)) > DILITHIUM_TXFEE && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
@@ -3377,7 +3415,7 @@ int64_t dilithium_inputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPu
UniValue dilithium_Qsend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey mypk,destpub33; CTransaction tx,vintx; uint256 prevhash,mypubtxid,hashBlock,destpubtxid; int64_t amount,inputsum,outputsum,change; int32_t i,smlen,n,numvouts; char str[129],myCCaddr[64],*scriptstr; CTxOut vout; std::string handle; uint8_t pk[CRYPTO_PUBLICKEYBYTES],pk2[CRYPTO_PUBLICKEYBYTES],sk[CRYPTO_SECRETKEYBYTES],msg[32],seed[32]; std::vector<uint8_t> sig; std::vector<uint256> voutpubtxids;
UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey mypk,destpub33; CTransaction tx,vintx; uint256 prevhash,mypubtxid,hashBlock,destpubtxid; int64_t amount,inputsum,outputsum,change; int32_t i,smlen,n,numvouts; char str[129],myCCaddr[64],*scriptstr,*retstr=""; CTxOut vout; std::string handle; uint8_t pk[CRYPTO_PUBLICKEYBYTES],pk2[CRYPTO_PUBLICKEYBYTES],sk[CRYPTO_SECRETKEYBYTES],msg[32],seed[32]; std::vector<uint8_t> sig; std::vector<uint256> voutpubtxids;
if ( txfee == 0 )
txfee = DILITHIUM_TXFEE;
mypk = pubkey2pk(Mypubkey());
@@ -3402,6 +3440,8 @@ UniValue dilithium_Qsend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params
if ( dilithium_bigpubget(handle,destpub33,pk2,prevhash) < 0 )
{
result.push_back(Pair("destpubtxid",prevhash.GetHex().c_str()));
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(cclib_error(result,"couldnt find bigpub at destpubtxid"));
}
else
@@ -3437,19 +3477,27 @@ UniValue dilithium_Qsend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params
//fprintf(stderr," msg\n");
sig.resize(32+CRYPTO_BYTES);
if ( dilithium_bigpubget(handle,destpub33,pk2,mypubtxid) < 0 )
return(cclib_error(result,"couldnt get bigpub"));
retstr = (char *)"couldnt get bigpub";
else if ( memcmp(pk,pk2,sizeof(pk)) != 0 )
return(cclib_error(result,"dilithium bigpub mismatch"));
retstr = (char *)"dilithium bigpub mismatch";
else if ( destpub33 != mypk )
return(cclib_error(result,"destpub33 is not for this -pubkey"));
retstr = (char *)"destpub33 is not for this -pubkey";
else if ( _dilithium_sign(&sig[0],&smlen,msg,32,sk) < 0 )
return(cclib_error(result,"dilithium signing error"));
retstr = (char *)"dilithium signing error";
else if ( smlen != 32+CRYPTO_BYTES )
return(cclib_error(result,"siglen error"));
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,dilithium_Qsendopret(mypubtxid,sig,voutpubtxids));
return(dilithium_rawtxresult(result,rawtx));
} else return(cclib_error(result,"Q couldnt find enough Q or x inputs"));
} else return(cclib_error(result,"need to have exactly 2 params sendtxid, scriptPubKey"));
retstr = (char *)"siglen error";
else
{
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,dilithium_Qsendopret(mypubtxid,sig,voutpubtxids));
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(dilithium_rawtxresult(result,rawtx));
}
} else retstr = (char *)"Q couldnt find enough Q or x inputs";
} else retstr = (char *)"need to have exactly 2 params sendtxid, scriptPubKey";
memset(seed,0,32);
memset(sk,0,sizeof(sk));
return(cclib_error(result,retstr));
}
bool dilithium_Qvalidate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx)
+1 -1
View File
@@ -129,7 +129,7 @@ bool Eval::GetTxUnconfirmed(const uint256 &hash, CTransaction &txOut, uint256 &h
{
return(myGetTransaction(hash, txOut,hashBlock));
/*if (!myGetTransaction(hash, txOut,hashBlock)) {
return(GetTransaction(hash, txOut,hashBlock));
return(myGetTransaction(hash, txOut,hashBlock));
} else return(true);*/
}
+4 -2
View File
@@ -35,6 +35,7 @@ int64_t IsFaucetvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v
{
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 )
return(tx.vout[v].nValue);
//else fprintf(stderr,"dest.%s vs (%s)\n",destaddr,cp->unspendableCCaddr);
}
return(0);
}
@@ -159,7 +160,7 @@ int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub
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 ( myGetTransaction(txid,vintx,hashBlock) != 0 )
{
if ( (nValue= IsFaucetvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
@@ -170,7 +171,7 @@ int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub
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,"vout.%d nValue %.8f too small or already spent in mempool\n",vout,(double)nValue/COIN);
} else fprintf(stderr,"couldnt get tx\n");
}
return(totalinputs);
@@ -221,6 +222,7 @@ std::string FaucetFund(uint64_t txfee,int64_t funds)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CPubKey mypk,faucetpk; CScript opret; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_FAUCET);
if ( txfee == 0 )
txfee = 10000;
+1 -1
View File
@@ -133,7 +133,7 @@ int64_t AddFSMInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey
// prevent dup
if ( it->second.satoshis < 1000000 )
continue;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
if ( myGetTransaction(txid,vintx,hashBlock) != 0 )
{
if ( (nValue= IsFSMvout(cp,vintx,(int32_t)it->first.index)) > 0 )
{
+13 -10
View File
@@ -411,7 +411,7 @@ UniValue games_rng(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
int32_t games_eventsign(uint32_t &timestamp,std::vector<uint8_t> &sig,std::vector<uint8_t> payload,CPubKey pk)
{
static secp256k1_context *ctx;
size_t siglen = 74; secp256k1_pubkey pubkey; secp256k1_ecdsa_signature signature; int32_t len,verifyflag = 1; uint8_t privkey[32]; uint256 hash; uint32_t t;
size_t siglen = 74; secp256k1_pubkey pubkey; secp256k1_ecdsa_signature signature; int32_t len,verifyflag = 1,retval=-100; uint8_t privkey[32]; uint256 hash; uint32_t t;
if ( ctx == 0 )
ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
if ( ctx != 0 )
@@ -439,10 +439,9 @@ int32_t games_eventsign(uint32_t &timestamp,std::vector<uint8_t> &sig,std::vecto
{
if ( siglen != sig.size() )
sig.resize(siglen);
return(0);
}
else return(-3);
} else return(-2);
retval = 0;
} else retval = -3;
} else retval = -2;
}
else
{
@@ -451,12 +450,14 @@ int32_t games_eventsign(uint32_t &timestamp,std::vector<uint8_t> &sig,std::vecto
if ( secp256k1_ecdsa_signature_parse_der(ctx,&signature,&sig[0],sig.size()) > 0 )
{
if ( secp256k1_ecdsa_verify(ctx,&signature,(uint8_t *)&hash,&pubkey) > 0 )
return(0);
else return(-4);
} else return(-3);
} else return(-2);
retval = 0;
else retval = -4;
} else retval = -3;
} else retval = -2;
}
} else return(-1);
} else retval = -1;
memset(privkey,0,sizeof(privkey));
return(retval);
}
int32_t games_event(uint32_t timestamp,uint256 gametxid,int32_t eventid,std::vector<uint8_t> payload)
@@ -1339,6 +1340,7 @@ UniValue games_keystrokes(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
CCaddr1of2set(cp,gamespk,mypk,mypriv,destaddr);
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,games_keystrokesopret(gametxid,batontxid,mypk,keystrokes));
//fprintf(stderr,"KEYSTROKES.(%s)\n",rawtx.c_str());
memset(mypriv,0,sizeof(mypriv));
return(games_rawtxresult(result,rawtx,1));
} else return(cclib_error(result,"keystrokes tx was too late"));
} else return(cclib_error(result,"couldnt find batontxid"));
@@ -1612,6 +1614,7 @@ UniValue games_finish(uint64_t txfee,struct CCcontract_info *cp,cJSON *params,ch
GetOpReturnData(opret, vopretNonfungible);
rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, EncodeTokenCreateOpRet('c', Mypubkey(), std::string(seedstr), gametxid.GetHex(), vopretNonfungible));
}
memset(mypriv,0,sizeof(mypriv));
return(games_rawtxresult(result,rawtx,1));
}
result.push_back(Pair("result","success"));
+37 -36
View File
@@ -499,10 +499,11 @@ int32_t GatewaysBindExists(struct CCcontract_info *cp,CPubKey gatewayspk,uint256
}
}
}
BOOST_FOREACH(const CTxMemPoolEntry &e, mempool.mapTx)
std::vector<CTransaction> tmp_txs;
myGet_mempool_txs(tmp_txs,EVAL_GATEWAYS,'B');
for (std::vector<CTransaction>::const_iterator it=tmp_txs.begin(); it!=tmp_txs.end(); it++)
{
const CTransaction &txmempool = e.GetTx();
const uint256 &hash = txmempool.GetHash();
const CTransaction &txmempool = *it;
if ((numvouts=txmempool.vout.size()) > 0 && DecodeGatewaysOpRet(tx.vout[numvouts-1].scriptPubKey)=='B')
if (DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) == 'B' &&
@@ -823,7 +824,7 @@ int64_t AddGatewaysInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; std::string refcoin,tmprefcoin; CPubKey withdrawpub,destpub;
uint256 tokenid,txid,oracletxid,tmpbindtxid,tmptokenid,deposittxid,hashBlock;
if ( GetTransaction(bindtxid,bindtx,hashBlock,false) != 0 )
if ( myGetTransaction(bindtxid,bindtx,hashBlock) != 0 )
{
if ((numvouts=bindtx.vout.size())!=0 && DecodeGatewaysBindOpRet(depositaddr,bindtx.vout[numvouts-1].scriptPubKey,tokenid,refcoin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) == 'B')
{
@@ -839,7 +840,7 @@ int64_t AddGatewaysInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
if ( myGetTransaction(txid,vintx,hashBlock) != 0 )
{
funcid=DecodeGatewaysOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey);
if ((vout==0 && funcid=='B' && bindtxid==txid && total != 0 && maxinputs != 0) ||
@@ -932,7 +933,7 @@ std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if ( GetTransaction(oracletxid,oracletx,hashBlock,false) == 0 || (numvouts= oracletx.vout.size()) <= 0 )
if ( myGetTransaction(oracletxid,oracletx,hashBlock) == 0 || (numvouts= oracletx.vout.size()) <= 0 )
{
CCerror = strprintf("cant find oracletxid %s",uint256_str(str,oracletxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
@@ -982,7 +983,7 @@ std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std::
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
LOGSTREAM("gatewayscc",CCLOG_DEBUG1, stream << "GatewaysDeposit ht." << height << " " << refcoin << " " << (double)amount/COIN << " numpks." << (int32_t)pubkeys.size() << std::endl);
if ( GetTransaction(bindtxid,bindtx,hashBlock,false) == 0 || (numvouts= bindtx.vout.size()) <= 0 )
if ( myGetTransaction(bindtxid,bindtx,hashBlock) == 0 || (numvouts= bindtx.vout.size()) <= 0 )
{
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
@@ -1059,7 +1060,7 @@ std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,ui
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
gatewayspk = GetUnspendable(cp,0);
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
if ( myGetTransaction(bindtxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
{
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
@@ -1077,7 +1078,7 @@ std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,ui
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if ( GetTransaction(deposittxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
if ( myGetTransaction(deposittxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
{
CCerror = strprintf("cant find deposittxid %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
@@ -1138,7 +1139,7 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin
mypk = pubkey2pk(Mypubkey());
gatewayspk = GetUnspendable(cp, 0);
if( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
if( myGetTransaction(bindtxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
{
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
@@ -1164,7 +1165,7 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin
vout = (int32_t)it->first.index;
nValue = (int64_t)it->second.satoshis;
K=0;
if ( vout == 0 && nValue == 10000 && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size())>0 &&
if ( vout == 0 && nValue == CC_MARKER_VALUE && myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size())>0 &&
(funcid=DecodeGatewaysOpRet(tx.vout[numvouts-1].scriptPubKey))!=0 && (funcid=='W' || funcid=='P'))
{
if (funcid=='W' && DecodeGatewaysWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,tmptokenid,tmpbindtxid,coin,withdrawpub,tmpamount)=='W'
@@ -1176,7 +1177,7 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin
}
else if (funcid=='P' && DecodeGatewaysPartialOpRet(tx.vout[numvouts-1].scriptPubKey,withdrawtxid,coin,K,signerpk,hex)=='P' &&
GetTransaction(withdrawtxid,tx,hashBlock,false)!=0 && (numvouts=tx.vout.size())>0 && DecodeGatewaysWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,tmptokenid,tmpbindtxid,coin,withdrawpub,tmpamount)=='W'
myGetTransaction(withdrawtxid,tx,hashBlock)!=0 && (numvouts=tx.vout.size())>0 && DecodeGatewaysWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,tmptokenid,tmpbindtxid,coin,withdrawpub,tmpamount)=='W'
&& refcoin==coin && tmptokenid==tokenid && tmpbindtxid==bindtxid)
{
CCerror = strprintf("unable to create withdraw, another withdraw pending");
@@ -1220,7 +1221,7 @@ std::string GatewaysPartialSign(uint64_t txfee,uint256 lasttxid,std::string refc
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
gatewayspk = GetUnspendable(cp,0);
if (GetTransaction(lasttxid,tx,hashBlock,false)==0 || (numvouts= tx.vout.size())<=0
if (myGetTransaction(lasttxid,tx,hashBlock)==0 || (numvouts= tx.vout.size())<=0
|| (funcid=DecodeGatewaysOpRet(tx.vout[numvouts-1].scriptPubKey))==0 || (funcid!='W' && funcid!='P'))
{
CCerror = strprintf("can't find last tx %s",uint256_str(str,lasttxid));
@@ -1242,7 +1243,7 @@ std::string GatewaysPartialSign(uint64_t txfee,uint256 lasttxid,std::string refc
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (GetTransaction(bindtxid,tmptx,hashBlock,false)==0 || (numvouts=tmptx.vout.size())<=0)
else if (myGetTransaction(bindtxid,tmptx,hashBlock)==0 || (numvouts=tmptx.vout.size())<=0)
{
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
@@ -1264,7 +1265,7 @@ std::string GatewaysPartialSign(uint64_t txfee,uint256 lasttxid,std::string refc
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (GetTransaction(withdrawtxid,tmptx,hashBlock,false)==0 || (numvouts= tmptx.vout.size())<=0)
else if (myGetTransaction(withdrawtxid,tmptx,hashBlock)==0 || (numvouts= tmptx.vout.size())<=0)
{
CCerror = strprintf("can't find withdraw tx %s",uint256_str(str,withdrawtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
@@ -1283,7 +1284,7 @@ std::string GatewaysPartialSign(uint64_t txfee,uint256 lasttxid,std::string refc
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (GetTransaction(bindtxid,tmptx,hashBlock,false)==0 || (numvouts=tmptx.vout.size())<=0)
else if (myGetTransaction(bindtxid,tmptx,hashBlock)==0 || (numvouts=tmptx.vout.size())<=0)
{
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
@@ -1320,7 +1321,7 @@ std::string GatewaysCompleteSigning(uint64_t txfee,uint256 lasttxid,std::string
gatewayspk = GetUnspendable(cp,0);
if ( txfee == 0 )
txfee = 10000;
if (GetTransaction(lasttxid,tx,hashBlock,false)==0 || (numvouts= tx.vout.size())<=0
if (myGetTransaction(lasttxid,tx,hashBlock)==0 || (numvouts= tx.vout.size())<=0
|| (funcid=DecodeGatewaysOpRet(tx.vout[numvouts-1].scriptPubKey))==0 || (funcid!='W' && funcid!='P'))
{
CCerror = strprintf("invalid last txid %s",uint256_str(str,lasttxid));
@@ -1336,7 +1337,7 @@ std::string GatewaysCompleteSigning(uint64_t txfee,uint256 lasttxid,std::string
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (GetTransaction(bindtxid,tmptx,hashBlock,false)==0 || (numvouts=tmptx.vout.size())<=0)
else if (myGetTransaction(bindtxid,tmptx,hashBlock)==0 || (numvouts=tmptx.vout.size())<=0)
{
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
@@ -1364,7 +1365,7 @@ std::string GatewaysCompleteSigning(uint64_t txfee,uint256 lasttxid,std::string
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (GetTransaction(withdrawtxid,tmptx,hashBlock,false)==0 || (numvouts=tmptx.vout.size())==0)
else if (myGetTransaction(withdrawtxid,tmptx,hashBlock)==0 || (numvouts=tmptx.vout.size())==0)
{
CCerror = strprintf("invalid withdraw txid %s",uint256_str(str,withdrawtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
@@ -1382,7 +1383,7 @@ std::string GatewaysCompleteSigning(uint64_t txfee,uint256 lasttxid,std::string
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (GetTransaction(bindtxid,tmptx,hashBlock,false)==0 || (numvouts=tmptx.vout.size())<=0)
else if (myGetTransaction(bindtxid,tmptx,hashBlock)==0 || (numvouts=tmptx.vout.size())<=0)
{
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
@@ -1418,7 +1419,7 @@ std::string GatewaysMarkDone(uint64_t txfee,uint256 completetxid,std::string ref
mypk = pubkey2pk(Mypubkey());
if ( txfee == 0 )
txfee = 10000;
if (GetTransaction(completetxid,tx,hashBlock,false)==0 || (numvouts= tx.vout.size())<=0)
if (myGetTransaction(completetxid,tx,hashBlock)==0 || (numvouts= tx.vout.size())<=0)
{
CCerror = strprintf("invalid completesigning txid %s",uint256_str(str,completetxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
@@ -1436,7 +1437,7 @@ std::string GatewaysMarkDone(uint64_t txfee,uint256 completetxid,std::string ref
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (GetTransaction(withdrawtxid,tx,hashBlock,false)==0 || (numvouts= tx.vout.size())==0)
else if (myGetTransaction(withdrawtxid,tx,hashBlock)==0 || (numvouts= tx.vout.size())==0)
{
CCerror = strprintf("invalid withdraw txid %s",uint256_str(str,withdrawtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
@@ -1448,7 +1449,7 @@ std::string GatewaysMarkDone(uint64_t txfee,uint256 completetxid,std::string ref
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (GetTransaction(bindtxid,tx,hashBlock,false)==0 || (numvouts=tx.vout.size())<=0)
else if (myGetTransaction(bindtxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0)
{
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
@@ -1485,7 +1486,7 @@ UniValue GatewaysPendingDeposits(uint256 bindtxid,std::string refcoin)
mypk = pubkey2pk(Mypubkey());
gatewayspk = GetUnspendable(cp,0);
_GetCCaddress(coinaddr,EVAL_GATEWAYS,mypk);
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
if ( myGetTransaction(bindtxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error",strprintf("cant find bindtxid %s",uint256_str(str,bindtxid))));
@@ -1503,7 +1504,7 @@ UniValue GatewaysPendingDeposits(uint256 bindtxid,std::string refcoin)
txid = it->first.txhash;
vout = (int32_t)it->first.index;
nValue = (int64_t)it->second.satoshis;
if ( vout == 0 && nValue == 10000 && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts=tx.vout.size())>0 &&
if ( vout == 0 && nValue == CC_MARKER_VALUE && myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts=tx.vout.size())>0 &&
DecodeGatewaysDepositOpRet(tx.vout[numvouts-1].scriptPubKey,tmpbindtxid,coin,publishers,txids,height,cointxid,claimvout,hex,proof,destpub,amount) == 'D'
&& tmpbindtxid==bindtxid && refcoin == coin && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0)
{
@@ -1540,7 +1541,7 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
gatewayspk = GetUnspendable(cp,0);
_GetCCaddress(coinaddr,EVAL_GATEWAYS,gatewayspk);
GetTokensCCaddress(cp,tokensaddr,gatewayspk);
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
if ( myGetTransaction(bindtxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error",strprintf("cant find bindtxid %s",uint256_str(str,bindtxid))));
@@ -1567,7 +1568,7 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
vout = (int32_t)it->first.index;
nValue = (int64_t)it->second.satoshis;
K=0;
if ( vout == 0 && nValue == 10000 && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size())>0 &&
if ( vout == 0 && nValue == CC_MARKER_VALUE && myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size())>0 &&
(funcid=DecodeGatewaysOpRet(tx.vout[numvouts-1].scriptPubKey))!=0 && (funcid=='W' || funcid=='P') && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0)
{
if (funcid=='W')
@@ -1576,7 +1577,7 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
}
else if (funcid=='P')
{
if (DecodeGatewaysPartialOpRet(tx.vout[numvouts-1].scriptPubKey,withdrawtxid,coin,K,signerpk,hex)!='P' || GetTransaction(withdrawtxid,tx,hashBlock,false)==0
if (DecodeGatewaysPartialOpRet(tx.vout[numvouts-1].scriptPubKey,withdrawtxid,coin,K,signerpk,hex)!='P' || myGetTransaction(withdrawtxid,tx,hashBlock)==0
|| (numvouts=tx.vout.size())<=0 || DecodeGatewaysWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,tmptokenid,tmpbindtxid,coin,withdrawpub,amount)!='W'
|| refcoin!=coin || tmptokenid!=tokenid || tmpbindtxid!=bindtxid)
continue;
@@ -1628,7 +1629,7 @@ UniValue GatewaysProcessedWithdraws(uint256 bindtxid,std::string refcoin)
mypk = pubkey2pk(Mypubkey());
gatewayspk = GetUnspendable(cp,0);
_GetCCaddress(coinaddr,EVAL_GATEWAYS,gatewayspk);
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
if ( myGetTransaction(bindtxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error",strprintf("cant find bindtxid %s",uint256_str(str,bindtxid))));
@@ -1654,10 +1655,10 @@ UniValue GatewaysProcessedWithdraws(uint256 bindtxid,std::string refcoin)
txid = it->first.txhash;
vout = (int32_t)it->first.index;
nValue = (int64_t)it->second.satoshis;
if ( vout == 0 && nValue == 10000 && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size())>0 &&
if ( vout == 0 && nValue == CC_MARKER_VALUE && myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size())>0 &&
DecodeGatewaysCompleteSigningOpRet(tx.vout[numvouts-1].scriptPubKey,withdrawtxid,coin,K,hex) == 'S' && refcoin == coin && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0)
{
if (GetTransaction(withdrawtxid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size())>0
if (myGetTransaction(withdrawtxid,tx,hashBlock) != 0 && (numvouts= tx.vout.size())>0
&& DecodeGatewaysWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,tmptokenid,bindtxid,coin,withdrawpub,amount) == 'W' || refcoin!=coin || tmptokenid!=tokenid)
{
UniValue obj(UniValue::VOBJ);
@@ -1689,7 +1690,7 @@ UniValue GatewaysList()
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++)
{
txid = it->first.txhash;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
if ( myGetTransaction(txid,vintx,hashBlock) != 0 )
{
if ( vintx.vout.size() > 0 && DecodeGatewaysBindOpRet(depositaddr,vintx.vout[vintx.vout.size()-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 0 )
{
@@ -1706,7 +1707,7 @@ UniValue GatewaysExternalAddress(uint256 bindtxid,CPubKey pubkey)
std::string coin; int64_t numvouts,totalsupply; char str[65],addr[65],depositaddr[65]; uint8_t M,N,taddr,prefix,prefix2,wiftype; std::vector<CPubKey> msigpubkeys;
cp = CCinit(&C,EVAL_GATEWAYS);
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
if ( myGetTransaction(bindtxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error",strprintf("cant find bindtxid %s",uint256_str(str,bindtxid))));
@@ -1730,7 +1731,7 @@ UniValue GatewaysDumpPrivKey(uint256 bindtxid,CKey key)
std::string coin,priv; int64_t numvouts,totalsupply; char str[65],addr[65],depositaddr[65]; uint8_t M,N,taddr,prefix,prefix2,wiftype; std::vector<CPubKey> msigpubkeys;
cp = CCinit(&C,EVAL_GATEWAYS);
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
if ( myGetTransaction(bindtxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error",strprintf("cant find bindtxid %s",uint256_str(str,bindtxid))));
@@ -1759,7 +1760,7 @@ UniValue GatewaysInfo(uint256 bindtxid)
cp = CCinit(&C,EVAL_GATEWAYS);
Gatewayspk = GetUnspendable(cp,0);
GetTokensCCaddress(cp,gatewaystokens,Gatewayspk);
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
if ( myGetTransaction(bindtxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error",strprintf("cant find bindtxid %s",uint256_str(str,bindtxid))));
@@ -1771,7 +1772,7 @@ UniValue GatewaysInfo(uint256 bindtxid)
result.push_back(Pair("error",strprintf("invalid bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str())));
return(result);
}
if ( GetTransaction(bindtxid,tx,hashBlock,false) != 0 )
if ( myGetTransaction(bindtxid,tx,hashBlock) != 0 )
{
result.push_back(Pair("result","success"));
result.push_back(Pair("name","Gateways"));
+4 -3
View File
@@ -531,7 +531,7 @@ template <class Helper> int64_t Add1of2AddressInputs(struct CCcontract_info* cp,
//std::cerr << "Add1of2AddressInputs() txid=" << txid.GetHex() << std::endl;
if (GetTransaction(txid, heirtx, hashBlock, false) != 0) {
if (myGetTransaction(txid, heirtx, hashBlock) != 0) {
uint256 tokenid;
uint256 fundingTxidInOpret;
uint8_t hasHeirSpendingBegunDummy;
@@ -579,7 +579,7 @@ template <class Helper> int64_t LifetimeHeirContractFunds(struct CCcontract_info
CTransaction heirtx;
// TODO: check all funding tx should contain unspendable markers
if (GetTransaction(txid, heirtx, hashBlock, false) && heirtx.vout.size() > 0) {
if (myGetTransaction(txid, heirtx, hashBlock) && heirtx.vout.size() > 0) {
uint256 tokenid;
uint256 fundingTxidInOpret;
uint8_t hasHeirSpendingBegunDummy;
@@ -967,6 +967,7 @@ template <typename Helper>UniValue _HeirClaim(uint256 fundingtxid, int64_t txfee
std::string rawhextx = FinalizeCCTx(0, cp, mtx, myPubkey, txfee,
Helper::makeClaimOpRet(tokenid, voutTokenPubkeys, fundingtxid, (myPubkey == heirPubkey) ? 1 : hasHeirSpendingBegun)); // forward isHeirSpending to the next latest tx
memset(myprivkey,0,sizeof(myprivkey));
if (!rawhextx.empty()) {
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", rawhextx));
@@ -1232,7 +1233,7 @@ void _HeirList(struct CCcontract_info *cp, UniValue &result)
//std::cerr << "HeirList() checking txid=" << txid.GetHex() << " vout=" << vout << '\n';
CTransaction fundingtx;
if (GetTransaction(txid, fundingtx, hashBlock, false)) {
if (myGetTransaction(txid, fundingtx, hashBlock)) {
CPubKey ownerPubkey, heirPubkey;
std::string heirName, memo;
int64_t inactivityTimeSec;
+5 -2
View File
@@ -56,6 +56,7 @@ public:
uint8_t mypriv[32];
Myprivkey(mypriv);
CCaddr1of2set(cp, ownerPubkey, heirPubkey,mypriv, coinaddr);
memset(mypriv,0,sizeof(mypriv));
}
};
@@ -98,8 +99,10 @@ public:
}
static void CCaddrCoinsOrTokens1of2set(struct CCcontract_info *cp, CPubKey ownerPubkey, CPubKey heirPubkey, char *coinaddr) {
CCaddrTokens1of2set(cp, ownerPubkey, heirPubkey, coinaddr);
uint8_t mypriv[32];
Myprivkey(mypriv);
CCaddrTokens1of2set(cp, ownerPubkey, heirPubkey, mypriv, coinaddr);
memset(mypriv,0,sizeof(mypriv));
}
};
+2 -2
View File
@@ -1,6 +1,6 @@
How this works:
- earlytxid must be a transaction included in the chain before block 100. The chain MUST not have any other of these type of tx before block 100, or someone may be able to change it and mess things up.
- When it gets to block 100, it takes the txid specified by the -earlytxid param (does not affect magic)
- earlytxid must be a transaction included in the chain before block KOMODO_EARLYTXID_HEIGHT. The chain MUST not have any other of these type of tx before block KOMODO_EARLYTXID_HEIGHT, or someone may be able to change it and mess things up.
- When it gets to block KOMODO_EARLYTXID_HEIGHT, it takes the txid specified by the -earlytxid param (does not affect magic)
- Looks up the transaction searches for the opreturn, then permenantly appends it to the end of ac_script in RAM.
- After every daemon restart, the first time the daemon mines a block, or receives a block that pays ac_script it will look up the op_return and save it again.
- this enables it to always reach consensus but doesnt need to constantly keep looking up the tx in the chain.
+13 -6
View File
@@ -367,7 +367,7 @@ int32_t CheckGATEWAYimport(CTransaction importTx,CTransaction burnTx,std::string
return(-1);
}
// check for valid burn from external coin blockchain and if valid return(0);
if (GetTransaction(bindtxid, bindtx, hashBlock, false) == 0 || (numvouts = bindtx.vout.size()) <= 0)
if (myGetTransaction(bindtxid, bindtx, hashBlock) == 0 || (numvouts = bindtx.vout.size()) <= 0)
{
LOGSTREAM("importgateway", CCLOG_INFO, stream << "CheckGATEWAYimport cant find bindtxid=" << bindtxid.GetHex() << std::endl);
return(-1);
@@ -397,7 +397,7 @@ int32_t CheckGATEWAYimport(CTransaction importTx,CTransaction burnTx,std::string
LOGSTREAM("importgateway", CCLOG_INFO, stream << "CheckGATEWAYimport bindtx not yet confirmed/notarized" << std::endl);
return(-1);
}
else if (GetTransaction(oracletxid, oracletx, hashBlock, false) == 0 || (numvouts = oracletx.vout.size()) <= 0)
else if (myGetTransaction(oracletxid, oracletx, hashBlock) == 0 || (numvouts = oracletx.vout.size()) <= 0)
{
LOGSTREAM("importgateway", CCLOG_INFO, stream << "CheckGATEWAYimport cant find oracletxid=" << oracletxid.GetHex() << std::endl);
return(-1);
@@ -417,7 +417,7 @@ int32_t CheckGATEWAYimport(CTransaction importTx,CTransaction burnTx,std::string
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
if ( GetTransaction(txid,regtx,hashBlock,false) != 0 && regtx.vout.size() > 0
if ( myGetTransaction(txid,regtx,hashBlock) != 0 && regtx.vout.size() > 0
&& DecodeOraclesOpRet(regtx.vout[regtx.vout.size()-1].scriptPubKey,tmporacletxid,regpk,datafee) == 'R' && oracletxid == tmporacletxid )
{
pubkeys.push_back(regpk);
@@ -681,7 +681,7 @@ bool Eval::ImportCoin(const std::vector<uint8_t> params, const CTransaction &imp
return Invalid("invalid-params");
// Control all aspects of this transaction
// It should not be at all malleable
if (MakeImportCoinTransaction(proof, burnTx, payouts, importTx.nExpiryHeight).GetHash() != importTx.GetHash()) // ExistsImportTombstone prevents from duplication
if (ASSETCHAINS_SELFIMPORT!="PEGSCC" && MakeImportCoinTransaction(proof, burnTx, payouts, importTx.nExpiryHeight).GetHash() != importTx.GetHash()) // ExistsImportTombstone prevents from duplication
return Invalid("non-canonical");
// burn params
if (!UnmarshalBurnTx(burnTx, targetSymbol, &targetCcid, payoutsHash, rawproof))
@@ -736,10 +736,17 @@ bool Eval::ImportCoin(const std::vector<uint8_t> params, const CTransaction &imp
else if ( UnmarshalBurnTx(burnTx,srcaddr,receipt)==0 || CheckCODAimport(importTx,burnTx,payouts,srcaddr,receipt) < 0 )
return Invalid("CODA-import-failure");
}
else if ( targetSymbol == "PEGSCC" )
{
if ( ASSETCHAINS_SELFIMPORT != "PEGSCC" )
return Invalid("PEGSCC-import-when-not PEGSCC");
// else if ( CheckPUBKEYimport(merkleBranchProof,rawproof,burnTx,payouts) < 0 )
// return Invalid("PEGSCC-import-failure");
}
else if ( targetSymbol == "PUBKEY" )
{
if ( ASSETCHAINS_SELFIMPORT != "PUBKEY" )
return Invalid("PUBKEY-import-when-notPUBKEY");
return Invalid("PUBKEY-import-when-not PUBKEY");
else if ( CheckPUBKEYimport(merkleBranchProof,rawproof,burnTx,payouts) < 0 )
return Invalid("PUBKEY-import-failure");
}
@@ -747,7 +754,7 @@ bool Eval::ImportCoin(const std::vector<uint8_t> params, const CTransaction &imp
{
if ( targetSymbol != ASSETCHAINS_SELFIMPORT )
return Invalid("invalid-gateway-import-coin");
else if ( UnmarshalBurnTx(burnTx,bindtxid,publishers,txids,burntxid,height,burnvout,rawburntx,destpub,amount)==0 || CheckGATEWAYimport(importTx,burnTx,targetSymbol,rawproof,bindtxid,publishers,txids,burntxid,height,burnvout,rawburntx,destpub,amount) < 0 )
else if ( UnmarshalBurnTx(burnTx,bindtxid,publishers,txids,burntxid,height,burnvout,rawburntx,destpub,amount)==0 || CheckGATEWAYimport(importTx,burnTx,targetSymbol,rawproof,bindtxid,publishers,txids,burntxid,height,burnvout,rawburntx,destpub,amount) < 0 )
return Invalid("GATEWAY-import-failure");
}
}
+75 -87
View File
@@ -278,10 +278,11 @@ int32_t ImportGatewayBindExists(struct CCcontract_info *cp,CPubKey importgateway
}
}
}
BOOST_FOREACH(const CTxMemPoolEntry &e, mempool.mapTx)
std::vector<CTransaction> tmp_txs;
myGet_mempool_txs(tmp_txs,EVAL_IMPORTGATEWAY,'B');
for (std::vector<CTransaction>::const_iterator it=tmp_txs.begin(); it!=tmp_txs.end(); it++)
{
const CTransaction &txmempool = e.GetTx();
const uint256 &hash = txmempool.GetHash();
const CTransaction &txmempool = *it;
if ((numvouts=txmempool.vout.size()) > 0 && DecodeImportGatewayOpRet(tx.vout[numvouts-1].scriptPubKey)=='B')
if (DecodeImportGatewayBindOpRet(burnaddr,tx.vout[numvouts-1].scriptPubKey,coin,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) == 'B')
@@ -525,7 +526,7 @@ std::string ImportGatewayBind(uint64_t txfee,std::string coin,uint256 oracletxid
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if ( GetTransaction(oracletxid,oracletx,hashBlock,false) == 0 || (numvouts= oracletx.vout.size()) <= 0 )
if ( myGetTransaction(oracletxid,oracletx,hashBlock) == 0 || (numvouts= oracletx.vout.size()) <= 0 )
{
CCerror = strprintf("cant find oracletxid %s",uint256_str(str,oracletxid));
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
@@ -568,7 +569,7 @@ std::string ImportGatewayDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,
if (KOMODO_EARLYTXID!=zeroid && bindtxid!=KOMODO_EARLYTXID)
{
CCerror = strprintf("CheckGATEWAYimport invalid import gateway. On this chain only valid import gateway is %s",KOMODO_EARLYTXID.GetHex());
CCerror = strprintf("invalid import gateway. On this chain only valid import gateway is %s",KOMODO_EARLYTXID.GetHex());
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
@@ -581,7 +582,7 @@ std::string ImportGatewayDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,
return std::string("");
}
LOGSTREAM("importgateway",CCLOG_DEBUG1, stream << "ImportGatewayDeposit ht." << height << " " << refcoin << " " << (double)amount/COIN << " numpks." << (int32_t)pubkeys.size() << std::endl);
if ( GetTransaction(bindtxid,bindtx,hashBlock,false) == 0 || (numvouts= bindtx.vout.size()) <= 0 )
if ( myGetTransaction(bindtxid,bindtx,hashBlock) == 0 || (numvouts= bindtx.vout.size()) <= 0 )
{
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
@@ -645,13 +646,19 @@ std::string ImportGatewayWithdraw(uint64_t txfee,uint256 bindtxid,std::string re
std::vector<CPubKey> msigpubkeys; char burnaddr[64],str[65],coinaddr[64]; struct CCcontract_info *cp,C;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
if (KOMODO_EARLYTXID!=zeroid && bindtxid!=KOMODO_EARLYTXID)
{
CCerror = strprintf("invalid import gateway. On this chain only valid import gateway is %s",KOMODO_EARLYTXID.GetHex());
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
cp = CCinit(&C,EVAL_IMPORTGATEWAY);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
importgatewaypk = GetUnspendable(cp, 0);
if( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
if( myGetTransaction(bindtxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
{
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
@@ -677,7 +684,7 @@ std::string ImportGatewayWithdraw(uint64_t txfee,uint256 bindtxid,std::string re
vout = (int32_t)it->first.index;
nValue = (int64_t)it->second.satoshis;
K=0;
if ( vout == 0 && nValue == 10000 && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size())>0 &&
if ( vout == 0 && nValue == CC_MARKER_VALUE && myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size())>0 &&
(funcid=DecodeImportGatewayOpRet(tx.vout[numvouts-1].scriptPubKey))!=0 && (funcid=='W' || funcid=='P'))
{
if (funcid=='W' && DecodeImportGatewayWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,tmpbindtxid,coin,withdrawpub,tmpamount)=='W'
@@ -689,7 +696,7 @@ std::string ImportGatewayWithdraw(uint64_t txfee,uint256 bindtxid,std::string re
}
else if (funcid=='P' && DecodeImportGatewayPartialOpRet(tx.vout[numvouts-1].scriptPubKey,withdrawtxid,coin,K,signerpk,hex)=='P' &&
GetTransaction(withdrawtxid,tx,hashBlock,false)!=0 && (numvouts=tx.vout.size())>0 && DecodeImportGatewayWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,tmpbindtxid,coin,withdrawpub,tmpamount)=='W'
myGetTransaction(withdrawtxid,tx,hashBlock)!=0 && (numvouts=tx.vout.size())>0 && DecodeImportGatewayWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,tmpbindtxid,coin,withdrawpub,tmpamount)=='W'
&& refcoin==coin && tmpbindtxid==bindtxid)
{
CCerror = strprintf("unable to create withdraw, another withdraw pending");
@@ -701,7 +708,7 @@ std::string ImportGatewayWithdraw(uint64_t txfee,uint256 bindtxid,std::string re
if( AddNormalinputs(mtx, mypk, txfee+CC_MARKER_VALUE+amount, 64) > 0 )
{
mtx.vout.push_back(MakeCC1vout(EVAL_IMPORTGATEWAY,CC_MARKER_VALUE,importgatewaypk));
mtx.vout.push_back(MakeCC1vout(EVAL_IMPORTGATEWAY,amount,importgatewaypk));
mtx.vout.push_back(MakeCC1vout(EVAL_IMPORTGATEWAY,amount,CCtxidaddr(str,bindtxid)));
return(FinalizeCCTx(0, cp, mtx, mypk, txfee,EncodeImportGatewayWithdrawOpRet('W',bindtxid,refcoin,withdrawpub,amount)));
}
CCerror = strprintf("cant find enough normal inputs");
@@ -722,7 +729,7 @@ std::string ImportGatewayPartialSign(uint64_t txfee,uint256 lasttxid,std::string
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
importgatewaypk = GetUnspendable(cp,0);
if (GetTransaction(lasttxid,tx,hashBlock,false)==0 || (numvouts= tx.vout.size())<=0
if (myGetTransaction(lasttxid,tx,hashBlock)==0 || (numvouts= tx.vout.size())<=0
|| (funcid=DecodeImportGatewayOpRet(tx.vout[numvouts-1].scriptPubKey))==0 || (funcid!='W' && funcid!='P'))
{
CCerror = strprintf("can't find last tx %s",uint256_str(str,lasttxid));
@@ -738,13 +745,19 @@ std::string ImportGatewayPartialSign(uint64_t txfee,uint256 lasttxid,std::string
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (KOMODO_EARLYTXID!=zeroid && bindtxid!=KOMODO_EARLYTXID)
{
CCerror = strprintf("invalid import gateway. On this chain only valid import gateway is %s",KOMODO_EARLYTXID.GetHex());
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (komodo_txnotarizedconfirmed(withdrawtxid)==false)
{
CCerror = strprintf("gatewayswithdraw tx not yet confirmed/notarized");
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (GetTransaction(bindtxid,tmptx,hashBlock,false)==0 || (numvouts=tmptx.vout.size())<=0)
else if (myGetTransaction(bindtxid,tmptx,hashBlock)==0 || (numvouts=tmptx.vout.size())<=0)
{
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
@@ -766,7 +779,7 @@ std::string ImportGatewayPartialSign(uint64_t txfee,uint256 lasttxid,std::string
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (GetTransaction(withdrawtxid,tmptx,hashBlock,false)==0 || (numvouts= tmptx.vout.size())<=0)
else if (myGetTransaction(withdrawtxid,tmptx,hashBlock)==0 || (numvouts= tmptx.vout.size())<=0)
{
CCerror = strprintf("can't find withdraw tx %s",uint256_str(str,withdrawtxid));
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
@@ -779,13 +792,19 @@ std::string ImportGatewayPartialSign(uint64_t txfee,uint256 lasttxid,std::string
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (KOMODO_EARLYTXID!=zeroid && bindtxid!=KOMODO_EARLYTXID)
{
CCerror = strprintf("invalid import gateway. On this chain only valid import gateway is %s",KOMODO_EARLYTXID.GetHex());
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (komodo_txnotarizedconfirmed(withdrawtxid)==false)
{
CCerror = strprintf("gatewayswithdraw tx not yet confirmed/notarized");
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (GetTransaction(bindtxid,tmptx,hashBlock,false)==0 || (numvouts=tmptx.vout.size())<=0)
else if (myGetTransaction(bindtxid,tmptx,hashBlock)==0 || (numvouts=tmptx.vout.size())<=0)
{
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
@@ -822,7 +841,7 @@ std::string ImportGatewayCompleteSigning(uint64_t txfee,uint256 lasttxid,std::st
importgatewaypk = GetUnspendable(cp,0);
if ( txfee == 0 )
txfee = 10000;
if (GetTransaction(lasttxid,tx,hashBlock,false)==0 || (numvouts= tx.vout.size())<=0
if (myGetTransaction(lasttxid,tx,hashBlock)==0 || (numvouts= tx.vout.size())<=0
|| (funcid=DecodeImportGatewayOpRet(tx.vout[numvouts-1].scriptPubKey))==0 || (funcid!='W' && funcid!='P'))
{
CCerror = strprintf("invalid last txid %s",uint256_str(str,lasttxid));
@@ -838,18 +857,30 @@ std::string ImportGatewayCompleteSigning(uint64_t txfee,uint256 lasttxid,std::st
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (GetTransaction(bindtxid,tmptx,hashBlock,false)==0 || (numvouts=tmptx.vout.size())<=0)
else if (myGetTransaction(bindtxid,tmptx,hashBlock)==0 || (numvouts=tmptx.vout.size())<=0)
{
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (KOMODO_EARLYTXID!=zeroid && bindtxid!=KOMODO_EARLYTXID)
{
CCerror = strprintf("invalid import gateway. On this chain only valid import gateway is %s",KOMODO_EARLYTXID.GetHex());
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (komodo_txnotarizedconfirmed(withdrawtxid)==false)
{
CCerror = strprintf("gatewayswithdraw tx not yet confirmed/notarized");
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (GetTransaction(bindtxid,tmptx,hashBlock,false)==0 || (numvouts=tmptx.vout.size())<=0)
{
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (DecodeImportGatewayBindOpRet(burnaddr,tmptx.vout[numvouts-1].scriptPubKey,coin,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B'
|| refcoin!=coin)
{
@@ -866,7 +897,7 @@ std::string ImportGatewayCompleteSigning(uint64_t txfee,uint256 lasttxid,std::st
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (GetTransaction(withdrawtxid,tmptx,hashBlock,false)==0 || (numvouts=tmptx.vout.size())==0)
else if (myGetTransaction(withdrawtxid,tmptx,hashBlock)==0 || (numvouts=tmptx.vout.size())==0)
{
CCerror = strprintf("invalid withdraw txid %s",uint256_str(str,withdrawtxid));
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
@@ -878,13 +909,19 @@ std::string ImportGatewayCompleteSigning(uint64_t txfee,uint256 lasttxid,std::st
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (KOMODO_EARLYTXID!=zeroid && bindtxid!=KOMODO_EARLYTXID)
{
CCerror = strprintf("invalid import gateway. On this chain only valid import gateway is %s",KOMODO_EARLYTXID.GetHex());
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (komodo_txnotarizedconfirmed(withdrawtxid)==false)
{
CCerror = strprintf("gatewayswithdraw tx not yet confirmed/notarized");
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (GetTransaction(bindtxid,tmptx,hashBlock,false)==0 || (numvouts=tmptx.vout.size())<=0)
else if (myGetTransaction(bindtxid,tmptx,hashBlock)==0 || (numvouts=tmptx.vout.size())<=0)
{
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
@@ -920,7 +957,7 @@ std::string ImportGatewayMarkDone(uint64_t txfee,uint256 completetxid,std::strin
mypk = pubkey2pk(Mypubkey());
if ( txfee == 0 )
txfee = 10000;
if (GetTransaction(completetxid,tx,hashBlock,false)==0 || (numvouts= tx.vout.size())<=0)
if (myGetTransaction(completetxid,tx,hashBlock)==0 || (numvouts= tx.vout.size())<=0)
{
CCerror = strprintf("invalid completesigning txid %s",uint256_str(str,completetxid));
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
@@ -938,7 +975,7 @@ std::string ImportGatewayMarkDone(uint64_t txfee,uint256 completetxid,std::strin
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (GetTransaction(withdrawtxid,tx,hashBlock,false)==0 || (numvouts= tx.vout.size())==0)
else if (myGetTransaction(withdrawtxid,tx,hashBlock)==0 || (numvouts= tx.vout.size())==0)
{
CCerror = strprintf("invalid withdraw txid %s",uint256_str(str,withdrawtxid));
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
@@ -950,7 +987,13 @@ std::string ImportGatewayMarkDone(uint64_t txfee,uint256 completetxid,std::strin
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (GetTransaction(bindtxid,tx,hashBlock,false)==0 || (numvouts=tx.vout.size())<=0)
else if (KOMODO_EARLYTXID!=zeroid && bindtxid!=KOMODO_EARLYTXID)
{
CCerror = strprintf("invalid import gateway. On this chain only valid import gateway is %s",KOMODO_EARLYTXID.GetHex());
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
else if (myGetTransaction(bindtxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0)
{
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
@@ -974,61 +1017,6 @@ std::string ImportGatewayMarkDone(uint64_t txfee,uint256 completetxid,std::strin
return("");
}
UniValue ImportGatewayPendingDeposits(uint256 bindtxid,std::string refcoin)
{
UniValue result(UniValue::VOBJ),pending(UniValue::VARR); CTransaction tx; std::string coin,hex,pub;
CPubKey mypk,importgatewaypk,destpub; std::vector<CPubKey> pubkeys,publishers; std::vector<uint256> txids;
uint256 tmpbindtxid,hashBlock,txid,oracletxid,burntxid; uint8_t M,N,taddr,prefix,prefix2,wiftype;
char burnaddr[65],coinaddr[65],str[65],destaddr[65],txidaddr[65]; std::vector<uint8_t> proof;
int32_t numvouts,vout,claimvout,height; int64_t nValue,amount; struct CCcontract_info *cp,C;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
cp = CCinit(&C,EVAL_IMPORTGATEWAY);
mypk = pubkey2pk(Mypubkey());
importgatewaypk = GetUnspendable(cp,0);
_GetCCaddress(coinaddr,EVAL_IMPORTGATEWAY,mypk);
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
{
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if ( DecodeImportGatewayBindOpRet(burnaddr,tx.vout[numvouts-1].scriptPubKey,coin,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin != coin)
{
CCerror = strprintf("invalid bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str());
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
SetCCunspents(unspentOutputs,coinaddr,true);
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;
nValue = (int64_t)it->second.satoshis;
if ( vout == 0 && nValue == 10000 && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts=tx.vout.size())>0 &&
DecodeImportGatewayDepositOpRet(tx.vout[numvouts-1].scriptPubKey,tmpbindtxid,coin,publishers,txids,height,burntxid,claimvout,hex,proof,destpub,amount) == 'D'
&& tmpbindtxid==bindtxid && refcoin == coin && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0)
{
UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("burntxid",uint256_str(str,burntxid)));
obj.push_back(Pair("deposittxid",uint256_str(str,txid)));
CCtxidaddr(txidaddr,txid);
obj.push_back(Pair("deposittxidaddr",txidaddr));
_GetCCaddress(destaddr,EVAL_TOKENS,destpub);
obj.push_back(Pair("depositaddr",burnaddr));
obj.push_back(Pair("tokens_destination_address",destaddr));
pub=HexStr(destpub);
obj.push_back(Pair("claim_pubkey",pub));
obj.push_back(Pair("amount",(double)amount/COIN));
obj.push_back(Pair("confirmed_or_notarized",komodo_txnotarizedconfirmed(txid)));
pending.push_back(obj);
}
}
result.push_back(Pair("coin",refcoin));
result.push_back(Pair("pending",pending));
return(result);
}
UniValue ImportGatewayPendingWithdraws(uint256 bindtxid,std::string refcoin)
{
UniValue result(UniValue::VOBJ),pending(UniValue::VARR); CTransaction tx; std::string coin,hex; CPubKey mypk,importgatewaypk,withdrawpub,signerpk;
@@ -1041,7 +1029,7 @@ UniValue ImportGatewayPendingWithdraws(uint256 bindtxid,std::string refcoin)
mypk = pubkey2pk(Mypubkey());
importgatewaypk = GetUnspendable(cp,0);
_GetCCaddress(coinaddr,EVAL_IMPORTGATEWAY,importgatewaypk);
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
if ( myGetTransaction(bindtxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
{
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
@@ -1068,7 +1056,7 @@ UniValue ImportGatewayPendingWithdraws(uint256 bindtxid,std::string refcoin)
vout = (int32_t)it->first.index;
nValue = (int64_t)it->second.satoshis;
K=0;
if ( vout == 0 && nValue == 10000 && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size())>0 &&
if ( vout == 0 && nValue == CC_MARKER_VALUE && myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size())>0 &&
(funcid=DecodeImportGatewayOpRet(tx.vout[numvouts-1].scriptPubKey))!=0 && (funcid=='W' || funcid=='P') && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0)
{
if (funcid=='W')
@@ -1077,7 +1065,7 @@ UniValue ImportGatewayPendingWithdraws(uint256 bindtxid,std::string refcoin)
}
else if (funcid=='P')
{
if (DecodeImportGatewayPartialOpRet(tx.vout[numvouts-1].scriptPubKey,withdrawtxid,coin,K,signerpk,hex)!='P' || GetTransaction(withdrawtxid,tx,hashBlock,false)==0
if (DecodeImportGatewayPartialOpRet(tx.vout[numvouts-1].scriptPubKey,withdrawtxid,coin,K,signerpk,hex)!='P' || myGetTransaction(withdrawtxid,tx,hashBlock)==0
|| (numvouts=tx.vout.size())<=0 || DecodeImportGatewayWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,tmpbindtxid,coin,withdrawpub,amount)!='W'
|| refcoin!=coin || tmpbindtxid!=bindtxid)
continue;
@@ -1129,7 +1117,7 @@ UniValue ImportGatewayProcessedWithdraws(uint256 bindtxid,std::string refcoin)
mypk = pubkey2pk(Mypubkey());
importgatewaypk = GetUnspendable(cp,0);
_GetCCaddress(coinaddr,EVAL_IMPORTGATEWAY,importgatewaypk);
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
if ( myGetTransaction(bindtxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
{
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
@@ -1155,10 +1143,10 @@ UniValue ImportGatewayProcessedWithdraws(uint256 bindtxid,std::string refcoin)
txid = it->first.txhash;
vout = (int32_t)it->first.index;
nValue = (int64_t)it->second.satoshis;
if ( vout == 0 && nValue == 10000 && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size())>0 &&
if ( vout == 0 && nValue == CC_MARKER_VALUE && myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size())>0 &&
DecodeImportGatewayCompleteSigningOpRet(tx.vout[numvouts-1].scriptPubKey,withdrawtxid,coin,K,hex) == 'S' && refcoin == coin && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0)
{
if (GetTransaction(withdrawtxid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size())>0
if (myGetTransaction(withdrawtxid,tx,hashBlock) != 0 && (numvouts= tx.vout.size())>0
&& DecodeImportGatewayWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,bindtxid,coin,withdrawpub,amount) == 'W' || refcoin!=coin)
{
UniValue obj(UniValue::VOBJ);
@@ -1192,7 +1180,7 @@ UniValue ImportGatewayList()
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++)
{
txid = it->first.txhash;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
if ( myGetTransaction(txid,vintx,hashBlock) != 0 )
{
if ( vintx.vout.size() > 0 && DecodeImportGatewayBindOpRet(burnaddr,vintx.vout[vintx.vout.size()-1].scriptPubKey,coin,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 0 )
{
@@ -1209,7 +1197,7 @@ UniValue ImportGatewayExternalAddress(uint256 bindtxid,CPubKey pubkey)
std::string coin; int64_t numvouts; char str[65],addr[65],burnaddr[65]; uint8_t M,N,taddr,prefix,prefix2,wiftype; std::vector<CPubKey> msigpubkeys;
cp = CCinit(&C,EVAL_IMPORTGATEWAY);
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
if ( myGetTransaction(bindtxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
{
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
@@ -1233,7 +1221,7 @@ UniValue ImportGatewayDumpPrivKey(uint256 bindtxid,CKey key)
std::string coin,priv; int64_t numvouts; char str[65],addr[65],burnaddr[65]; uint8_t M,N,taddr,prefix,prefix2,wiftype; std::vector<CPubKey> msigpubkeys;
cp = CCinit(&C,EVAL_IMPORTGATEWAY);
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
if ( myGetTransaction(bindtxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
{
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
@@ -1262,7 +1250,7 @@ UniValue ImportGatewayInfo(uint256 bindtxid)
cp = CCinit(&C,EVAL_IMPORTGATEWAY);
ImportGatewaypk = GetUnspendable(cp,0);
GetTokensCCaddress(cp,gatewaystokens,ImportGatewaypk);
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
if ( myGetTransaction(bindtxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
{
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
@@ -1274,7 +1262,7 @@ UniValue ImportGatewayInfo(uint256 bindtxid)
LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl);
return("");
}
if ( GetTransaction(bindtxid,tx,hashBlock,false) != 0 )
if ( myGetTransaction(bindtxid,tx,hashBlock) != 0 )
{
result.push_back(Pair("result","success"));
result.push_back(Pair("name","ImportGateway"));
+1 -1
View File
@@ -48,7 +48,7 @@ bits320 crecip(const bits320 z);
bits256 curve25519(bits256 mysecret,bits256 basepoint);
void OS_randombytes(unsigned char *x,long xlen);
bits256 rand256(int32_t privkeyflag);
bits256 curve25519_basepoint9();
bits256 curve25519_basepoint9(void);
bits256 curve25519_keypair(bits256 *pubkeyp);
void vcalc_sha256(char hashstr[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uint8_t *src,int32_t len);
+4 -4
View File
@@ -173,7 +173,7 @@ int64_t AddLottoInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK
// prevent dup
if ( it->second.satoshis < COIN )
continue;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
if ( myGetTransaction(txid,vintx,hashBlock) != 0 )
{
if ( (nValue= IsLottovout(cp,vintx,(int32_t)it->first.index)) > 0 )
{
@@ -214,7 +214,7 @@ int64_t LottoPlanFunds(uint64_t refsbits,struct CCcontract_info *cp,CPubKey pk,u
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 )
if ( myGetTransaction(txid,tx,hashBlock) != 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 )
{
// need to implement this! if ( (funcid= DecodeLottoOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) == 'F' || funcid == 'T' )
{
@@ -233,7 +233,7 @@ int64_t LottoPlanFunds(uint64_t refsbits,struct CCcontract_info *cp,CPubKey pk,u
UniValue LottoInfo(uint256 lottoid)
{
UniValue result(UniValue::VOBJ); uint256 hashBlock,hentropy; CTransaction vintx; uint64_t lockedfunds,sbits; int32_t ticketsize,odds,firstheight,period; CPubKey lottopk; struct CCcontract_info *cp,C; char str[67],numstr[65];
if ( GetTransaction(lottoid,vintx,hashBlock,false) == 0 )
if ( myGetTransaction(lottoid,vintx,hashBlock) == 0 )
{
fprintf(stderr,"cant find lottoid\n");
result.push_back(Pair("result","error"));
@@ -270,7 +270,7 @@ UniValue LottoList()
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++)
{
txid = it->first.txhash;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
if ( myGetTransaction(txid,vintx,hashBlock) != 0 )
{
if ( vintx.vout.size() > 0 && DecodeLottoFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,sbits,ticketsize,odds,firstheight,period,hentropy) == 'F' )
{
+10 -9
View File
@@ -360,7 +360,7 @@ int64_t AddMarmaraCoinbases(struct CCcontract_info *cp,CMutableTransaction &mtx,
txid = it->first.txhash;
vout = (int32_t)it->first.index;
//fprintf(stderr,"txid.%s/v%d\n",txid.GetHex().c_str(),vout);
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
if ( myGetTransaction(txid,vintx,hashBlock) != 0 )
{
if ( vintx.IsCoinBase() != 0 && vintx.vout.size() == 2 && vintx.vout[1].nValue == 0 )
{
@@ -399,7 +399,7 @@ int64_t AddMarmarainputs(CMutableTransaction &mtx,std::vector<CPubKey> &pubkeys,
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(ignoretxid,ignorevin,txid,vout) == 0 )
if ( myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 0 && vout < numvouts && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
if ( (funcid= DecodeMaramaraCoinbaseOpRet(tx.vout[numvouts-1].scriptPubKey,pk,ht,unlockht)) == 'C' || funcid == 'P' || funcid == 'L' )
{
@@ -468,7 +468,7 @@ UniValue MarmaraLock(uint64_t txfee,int64_t amount,int32_t height)
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(ignoretxid,ignorevin,txid,vout) == 0 )
if ( myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 0 && vout < numvouts && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
if ( (funcid= DecodeMaramaraCoinbaseOpRet(tx.vout[numvouts-1].scriptPubKey,pk,ht,unlockht)) == 'C' || funcid == 'P' || funcid == 'L' )
{
@@ -488,6 +488,7 @@ UniValue MarmaraLock(uint64_t txfee,int64_t amount,int32_t height)
}
}
}
memset(mypriv,0,sizeof(mypriv));
}
if ( inputsum >= amount+txfee )
{
@@ -516,7 +517,7 @@ 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 )
if ( myGetTransaction(mtx.vin[0].prevout.hash,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 1 && vout < numvouts )
{
cp = CCinit(&C,EVAL_MARMARA);
mypk = pubkey2pk(Mypubkey());
@@ -553,7 +554,7 @@ UniValue MarmaraSettlement(uint64_t txfee,uint256 refbatontxid)
height = chainActive.LastTip()->GetHeight();
if ( (n= MarmaraGetbatontxid(creditloop,batontxid,refbatontxid)) > 0 )
{
if ( GetTransaction(batontxid,batontx,hashBlock,false) != 0 && (numvouts= batontx.vout.size()) > 1 )
if ( myGetTransaction(batontxid,batontx,hashBlock) != 0 && (numvouts= batontx.vout.size()) > 1 )
{
if ( (funcid= MarmaraDecodeLoopOpret(batontx.vout[numvouts-1].scriptPubKey,refcreatetxid,pk,refamount,refmatures,refcurrency)) != 0 )
{
@@ -593,7 +594,7 @@ UniValue MarmaraSettlement(uint64_t txfee,uint256 refbatontxid)
pubkeys.push_back(mypk);
for (i=1; i<n; i++)
{
if ( GetTransaction(creditloop[i],tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
if ( myGetTransaction(creditloop[i],tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 1 )
{
if ( (funcid= MarmaraDecodeLoopOpret(tx.vout[numvouts-1].scriptPubKey,createtxid,pk,amount,matures,currency)) != 0 )
{
@@ -674,7 +675,7 @@ int32_t MarmaraGetCreditloops(int64_t &totalamount,std::vector<uint256> &issuanc
txid = it->first.txhash;
vout = (int32_t)it->first.index;
//fprintf(stderr,"txid.%s/v%d\n",txid.GetHex().c_str(),vout);
if ( vout == 1 && GetTransaction(txid,tx,hashBlock,false) != 0 )
if ( vout == 1 && myGetTransaction(txid,tx,hashBlock) != 0 )
{
if ( tx.IsCoinBase() == 0 && (numvouts= tx.vout.size()) > 2 && tx.vout[numvouts - 1].nValue == 0 )
{
@@ -814,7 +815,7 @@ UniValue MarmaraCreditloop(uint256 txid)
cp = CCinit(&C,EVAL_MARMARA);
if ( (n= MarmaraGetbatontxid(creditloop,batontxid,txid)) > 0 )
{
if ( GetTransaction(batontxid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
if ( myGetTransaction(batontxid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 1 )
{
result.push_back(Pair("result",(char *)"success"));
Getscriptaddress(coinaddr,CScript() << ParseHex(HexStr(Mypubkey())) << OP_CHECKSIG);
@@ -886,7 +887,7 @@ UniValue MarmaraCreditloop(uint256 txid)
}
for (i=0; i<n; i++)
{
if ( GetTransaction(creditloop[i],tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
if ( myGetTransaction(creditloop[i],tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 1 )
{
if ( (funcid= MarmaraDecodeLoopOpret(tx.vout[numvouts-1].scriptPubKey,createtxid,pk,amount,matures,currency)) != 0 )
{
+2
View File
@@ -482,10 +482,12 @@ UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
MUSIG[musiglocation]->numcommits = 1;
result.push_back(Pair("commitment",str));
result.push_back(Pair("result","success"));
memset(privkey,0,sizeof(privkey));
return(result);
}
else
{
memset(privkey,0,sizeof(privkey));
memset(session,0,sizeof(session));
return(cclib_error(result,"couldnt initialize session"));
}
+26 -19
View File
@@ -193,6 +193,7 @@ CPubKey OracleBatonPk(char *batonaddr,struct CCcontract_info *cp)
//fprintf(stderr,"batonpk.(%s) -> %s\n",(char *)HexStr(batonpk).c_str(),batonaddr);
strcpy(cp->unspendableaddr2,batonaddr);
} else fprintf(stderr,"error creating pubkey\n");
memset(priv,0,sizeof(priv));
return(batonpk);
}
@@ -246,9 +247,11 @@ int64_t OracleDatafee(CScript &scriptPubKey,uint256 oracletxid,CPubKey publisher
static uint256 myIs_baton_spentinmempool(uint256 batontxid,int32_t batonvout)
{
BOOST_FOREACH(const CTxMemPoolEntry &e,mempool.mapTx)
std::vector<CTransaction> tmp_txs;
myGet_mempool_txs(tmp_txs,EVAL_ORACLES,'D');
for (std::vector<CTransaction>::const_iterator it=tmp_txs.begin(); it!=tmp_txs.end(); it++)
{
const CTransaction &tx = e.GetTx();
const CTransaction &tx = *it;
if ( tx.vout.size() > 0 && tx.vin.size() > 1 && batontxid == tx.vin[1].prevout.hash && batonvout == tx.vin[1].prevout.n )
{
const uint256 &txid = tx.GetHash();
@@ -759,7 +762,7 @@ int64_t AddOracleInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,uint
txid = it->first.txhash;
vout = (int32_t)it->first.index;
//char str[65]; fprintf(stderr,"oracle check %s/v%d\n",uint256_str(str,txid),vout);
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 && (numvouts=vintx.vout.size()-1)>0)
if ( myGetTransaction(txid,vintx,hashBlock) != 0 && (numvouts=vintx.vout.size()-1)>0)
{
if ((funcid=DecodeOraclesOpRet(vintx.vout[numvouts].scriptPubKey,tmporacletxid,tmppk,tmpnum))!=0 && (funcid=='S' || funcid=='D'))
{
@@ -795,7 +798,7 @@ int64_t LifetimeOraclesFunds(struct CCcontract_info *cp,uint256 oracletxid,CPubK
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++)
{
txid = it->first.txhash;
if ( GetTransaction(txid,subtx,hashBlock,false) != 0 )
if ( myGetTransaction(txid,subtx,hashBlock) != 0 )
{
if ( subtx.vout.size() > 0 && DecodeOraclesOpRet(subtx.vout[subtx.vout.size()-1].scriptPubKey,subtxid,pk,num) == 'S' && subtxid == oracletxid && pk == publisher )
{
@@ -818,7 +821,7 @@ int64_t AddMyOraclesFunds(struct CCcontract_info *cp,CMutableTransaction &mtx,CP
txid = it->first.txhash;
vout = (int32_t)it->first.index;
nValue = it->second.satoshis;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 && (numvouts=vintx.vout.size())>0)
if ( myGetTransaction(txid,vintx,hashBlock) != 0 && (numvouts=vintx.vout.size())>0)
{
if ((funcid=DecodeOraclesOpRet(vintx.vout[numvouts-1].scriptPubKey,tmporacletxid,tmppk,tmpamount))!=0 && funcid=='F' && tmppk==pk
&& tmporacletxid==oracletxid && tmpamount==nValue && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout)==0)
@@ -829,9 +832,11 @@ int64_t AddMyOraclesFunds(struct CCcontract_info *cp,CMutableTransaction &mtx,CP
} else fprintf(stderr,"couldnt find transaction\n");
}
BOOST_FOREACH(const CTxMemPoolEntry &e, mempool.mapTx)
std::vector<CTransaction> tmp_txs;
myGet_mempool_txs(tmp_txs,EVAL_ORACLES,'F');
for (std::vector<CTransaction>::const_iterator it=tmp_txs.begin(); it!=tmp_txs.end(); it++)
{
const CTransaction &txmempool = e.GetTx();
const CTransaction &txmempool = *it;
const uint256 &hash = txmempool.GetHash();
nValue=txmempool.vout[0].nValue;
@@ -986,7 +991,7 @@ std::string OracleData(int64_t txfee,uint256 oracletxid,std::vector <uint8_t> da
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
}
if ( GetTransaction(oracletxid,tx,hashBlock,false) != 0 && (numvouts=tx.vout.size()) > 0 )
if ( myGetTransaction(oracletxid,tx,hashBlock) != 0 && (numvouts=tx.vout.size()) > 0 )
{
if ( DecodeOraclesCreateOpRet(tx.vout[numvouts-1].scriptPubKey,name,description,format) == 'C' )
{
@@ -1061,11 +1066,11 @@ UniValue OracleDataSample(uint256 reforacletxid,uint256 txid)
CPubKey pk; std::string name,description,format; int32_t numvouts; std::vector<uint8_t> data; char str[67], *formatstr = 0;
result.push_back(Pair("result","success"));
if ( GetTransaction(reforacletxid,oracletx,hashBlock,false) != 0 && (numvouts=oracletx.vout.size()) > 0 )
if ( myGetTransaction(reforacletxid,oracletx,hashBlock) != 0 && (numvouts=oracletx.vout.size()) > 0 )
{
if ( DecodeOraclesCreateOpRet(oracletx.vout[numvouts-1].scriptPubKey,name,description,format) == 'C' )
{
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts=tx.vout.size()) > 0 )
if ( myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts=tx.vout.size()) > 0 )
{
if ( DecodeOraclesData(tx.vout[numvouts-1].scriptPubKey,oracletxid,btxid,pk,data) == 'D' && reforacletxid == oracletxid )
{
@@ -1094,13 +1099,15 @@ UniValue OracleDataSamples(uint256 reforacletxid,char* batonaddr,int32_t num)
std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex; int64_t nValue;
result.push_back(Pair("result","success"));
if ( GetTransaction(reforacletxid,oracletx,hashBlock,false) != 0 && (numvouts=oracletx.vout.size()) > 0 )
if ( myGetTransaction(reforacletxid,oracletx,hashBlock) != 0 && (numvouts=oracletx.vout.size()) > 0 )
{
if ( DecodeOraclesCreateOpRet(oracletx.vout[numvouts-1].scriptPubKey,name,description,format) == 'C' )
{
BOOST_FOREACH(const CTxMemPoolEntry &e, mempool.mapTx)
std::vector<CTransaction> tmp_txs;
myGet_mempool_txs(tmp_txs,EVAL_ORACLES,'D');
for (std::vector<CTransaction>::const_iterator it=tmp_txs.begin(); it!=tmp_txs.end(); it++)
{
const CTransaction &txmempool = e.GetTx();
const CTransaction &txmempool = *it;
const uint256 &hash = txmempool.GetHash();
if ((numvouts=txmempool.vout.size())>0 && DecodeOraclesData(txmempool.vout[numvouts-1].scriptPubKey,oracletxid,btxid,pk,data) == 'D' && reforacletxid == oracletxid )
{
@@ -1122,7 +1129,7 @@ UniValue OracleDataSamples(uint256 reforacletxid,char* batonaddr,int32_t num)
txid=it->first.txhash;
vout = (int32_t)it->first.index;
nValue = (int64_t)it->second;
if (vout==1 && nValue==10000 && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts=tx.vout.size()) > 0 )
if (vout==1 && nValue==10000 && myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts=tx.vout.size()) > 0 )
{
if ( DecodeOraclesData(tx.vout[numvouts-1].scriptPubKey,oracletxid,btxid,pk,data) == 'D' && reforacletxid == oracletxid )
{
@@ -1155,14 +1162,14 @@ UniValue OracleInfo(uint256 origtxid)
cp = CCinit(&C,EVAL_ORACLES);
CCtxidaddr(markeraddr,origtxid);
if ( GetTransaction(origtxid,tx,hashBlock,false) == 0 )
if ( myGetTransaction(origtxid,tx,hashBlock) == 0 )
{
fprintf(stderr,"cant find oracleid\n");
result.push_back(Pair("result","error"));
result.push_back(Pair("error","cant find oracleid"));
return(result);
}
if ( GetTransaction(origtxid,tx,hashBlock,false) != 0 )
if ( myGetTransaction(origtxid,tx,hashBlock) != 0 )
{
if ( tx.vout.size() > 0 && DecodeOraclesCreateOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,name,description,format) == 'C' )
{
@@ -1177,7 +1184,7 @@ UniValue OracleInfo(uint256 origtxid)
{
txid = it->first.txhash;
height = (int32_t)it->second.blockHeight;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 &&
if ( myGetTransaction(txid,tx,hashBlock) != 0 && tx.vout.size() > 0 &&
DecodeOraclesOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,oracletxid,pk,datafee) == 'R' && oracletxid == origtxid )
{
if (publishers.find(pk)==publishers.end() || height>publishers[pk].second)
@@ -1189,7 +1196,7 @@ UniValue OracleInfo(uint256 origtxid)
}
for (std::map<CPubKey,std::pair<uint256,int32_t>>::iterator it = publishers.begin(); it != publishers.end(); ++it)
{
if ( GetTransaction(it->second.first,tx,hashBlock,false) != 0 && DecodeOraclesOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,oracletxid,pk,datafee) == 'R')
if ( myGetTransaction(it->second.first,tx,hashBlock) != 0 && DecodeOraclesOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,oracletxid,pk,datafee) == 'R')
{
UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("publisher",pubkey33_str(str,(uint8_t *)pk.begin())));
@@ -1222,7 +1229,7 @@ UniValue OraclesList()
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++)
{
txid = it->first.txhash;
if ( GetTransaction(txid,createtx,hashBlock,false) != 0 )
if ( myGetTransaction(txid,createtx,hashBlock) != 0 )
{
if ( createtx.vout.size() > 0 && DecodeOraclesCreateOpRet(createtx.vout[createtx.vout.size()-1].scriptPubKey,name,description,format) == 'C' )
{
+3 -1
View File
@@ -314,6 +314,8 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
fIsMerge = true;
else if ( DecodePaymentsReleaseOpRet(ccopret,createtxid,amountReleased) != 'R' )
return(eval->Invalid("could not decode ccopret"));
if ( tx.vout.back().scriptPubKey.IsOpReturn() )
fHasOpret = true;
mpz_set_si(mpzCheckamount,amountReleased);
} else return(eval->Invalid("could not decode ccopret"));
@@ -557,7 +559,7 @@ int64_t AddPaymentsInputs(bool fLockedBlocks,int8_t GetBalance,struct CCcontract
txid = it->first.txhash;
vout = (int32_t)it->first.index;
//fprintf(stderr,"iter.%d %s/v%d %s\n",iter,txid.GetHex().c_str(),vout,coinaddr);
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
if ( myGetTransaction(txid,vintx,hashBlock) != 0 )
{
if ( (nValue= IsPaymentsvout(cp,vintx,vout,coinaddr,ccopret)) > PAYMENTS_TXFEE && nValue >= threshold && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
+1182 -53
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -590,7 +590,7 @@ int64_t AddPricesInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, ch
vout = (int32_t)it->first.index;
//if (vout == exclvout && txid == excltxid) // exclude vout which is added directly to vins outside this function
// continue;
if (GetTransaction(txid, vintx, hashBlock, false) != 0 && vout < vintx.vout.size())
if (myGetTransaction(txid, vintx, hashBlock) != 0 && vout < vintx.vout.size())
{
vscript_t vopret;
uint8_t funcId = PricesCheckOpret(vintx, vopret);
@@ -2161,7 +2161,7 @@ UniValue PricesList(uint32_t filter, CPubKey mypk)
std::vector<uint16_t> vec;
CTransaction vintx;
if (GetTransaction(txid, vintx, hashBlock, false) != 0)
if (myGetTransaction(txid, vintx, hashBlock) != 0)
{
// TODO: forget old tx
+6 -6
View File
@@ -357,7 +357,7 @@ int64_t AddRewardsInputs(CScript &scriptPubKey,uint64_t maxseconds,struct CCcont
break;
if ( j != mtx.vin.size() )
continue;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
if ( myGetTransaction(txid,tx,hashBlock) != 0 && tx.vout.size() > 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
if ( (funcid= DecodeRewardsOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) != 0 )
{
@@ -409,7 +409,7 @@ int64_t RewardsPlanFunds(uint64_t &lockedfunds,uint64_t refsbits,struct CCcontra
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 )
if ( myGetTransaction(txid,tx,hashBlock) != 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 )
{
if ( (funcid= DecodeRewardsOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) == 'F' || funcid == 'A' || funcid == 'U' || funcid == 'L' )
{
@@ -439,7 +439,7 @@ bool RewardsPlanExists(struct CCcontract_info *cp,uint64_t refsbits,CPubKey rewa
{
//int height = it->first.blockHeight;
txid = it->first.txhash;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && ConstrainVout(tx.vout[0],1,CCaddr,0) != 0 )
if ( myGetTransaction(txid,tx,hashBlock) != 0 && tx.vout.size() > 0 && ConstrainVout(tx.vout[0],1,CCaddr,0) != 0 )
{
//char str[65]; fprintf(stderr,"rewards plan %s\n",uint256_str(str,txid));
if ( DecodeRewardsFundingOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) == 'F' )
@@ -455,7 +455,7 @@ bool RewardsPlanExists(struct CCcontract_info *cp,uint64_t refsbits,CPubKey rewa
UniValue RewardsInfo(uint256 rewardsid)
{
UniValue result(UniValue::VOBJ); uint256 hashBlock; CTransaction vintx; uint64_t lockedfunds,APR,minseconds,maxseconds,mindeposit,sbits,funding; CPubKey rewardspk; struct CCcontract_info *cp,C; char str[67],numstr[65];
if ( GetTransaction(rewardsid,vintx,hashBlock,false) == 0 )
if ( myGetTransaction(rewardsid,vintx,hashBlock) == 0 )
{
fprintf(stderr,"cant find fundingtxid\n");
result.push_back(Pair("result","error"));
@@ -498,7 +498,7 @@ UniValue RewardsList()
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++)
{
txid = it->first.txhash;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
if ( myGetTransaction(txid,vintx,hashBlock) != 0 )
{
if ( vintx.vout.size() > 0 && DecodeRewardsFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) != 0 )
{
@@ -657,7 +657,7 @@ std::string RewardsUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint2
CCerror = "locktxid/v0 is spent";
return("");
}
if ( GetTransaction(locktxid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && tx.vout[1].scriptPubKey.IsPayToCryptoCondition() == 0 )
if ( myGetTransaction(locktxid,tx,hashBlock) != 0 && tx.vout.size() > 0 && tx.vout[1].scriptPubKey.IsPayToCryptoCondition() == 0 )
{
scriptPubKey = tx.vout[1].scriptPubKey;
mtx.vin.push_back(CTxIn(locktxid,0,CScript()));
+2
View File
@@ -963,6 +963,7 @@ UniValue rogue_keystrokes(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
CCaddr1of2set(cp,roguepk,mypk,mypriv,destaddr);
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,rogue_keystrokesopret(gametxid,batontxid,mypk,keystrokes));
//fprintf(stderr,"KEYSTROKES.(%s)\n",rawtx.c_str());
memset(mypriv,0,32);
return(rogue_rawtxresult(result,rawtx,1));
} else return(cclib_error(result,"keystrokes tx was too late"));
} else return(cclib_error(result,"couldnt find batontxid"));
@@ -1330,6 +1331,7 @@ UniValue rogue_finishgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
GetOpReturnData(opret, vopretNonfungible);
rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee, EncodeTokenCreateOpRet('c', Mypubkey(), std::string(seedstr), gametxid.GetHex(), vopretNonfungible));
}
memset(mypriv,0,32);
return(rogue_rawtxresult(result,rawtx,1));
}
result.push_back(Pair("result","success"));
+3 -3
View File
@@ -2730,7 +2730,7 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params
decode_hex((uint8_t *)&txid,32,txidstr);
txid = revuint256(txid);
result.push_back(Pair("txid",txid.GetHex()));
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
if ( myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 1 )
{
if ( sudoku_genopreturndecode(unsolved,tx.vout[numvouts-1].scriptPubKey) == 'G' )
{
@@ -2780,7 +2780,7 @@ UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
//char str[65]; fprintf(stderr,"%s check %s/v%d %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN);
if ( it->second.satoshis != txfee || vout != 0 )
continue;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
if ( myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 1 )
{
if ( (nValue= IsCClibvout(cp,tx,vout,coinaddr)) == txfee && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
@@ -2861,7 +2861,7 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params
result.push_back(Pair("txid",txid.GetHex()));
if ( CCgettxout(txid,0,1,0) < 0 )
result.push_back(Pair("error","already solved"));
else if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
else if ( myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 1 )
{
Getscriptaddress(checkaddr,tx.vout[1].scriptPubKey);
if ( strcmp(checkaddr,CCaddr) != 0 )
+7 -13
View File
@@ -572,18 +572,6 @@ extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
const CScript &CCoinsViewCache::GetSpendFor(const CCoins *coins, const CTxIn& input)
{
assert(coins);
/*if (coins->nHeight < 6400 && !strcmp(ASSETCHAINS_SYMBOL, "VRSC"))
{
std::string hc = input.prevout.hash.ToString();
if (LaunchMap().lmap.count(hc))
{
CTransactionExceptionData &txData = LaunchMap().lmap[hc];
if ((txData.voutMask & (((uint64_t)1) << (uint64_t)input.prevout.n)) != 0)
{
return txData.scriptPubKey;
}
}
}*/
return coins->vout[input.prevout.n].scriptPubKey;
}
@@ -604,6 +592,11 @@ CAmount CCoinsViewCache::GetValueIn(int32_t nHeight,int64_t *interestp,const CTr
return 0;
for (unsigned int i = 0; i < tx.vin.size(); i++)
{
if (tx.IsPegsImport() && i==0)
{
nResult = GetCoinImportValue(tx);
continue;
}
value = GetOutputFor(tx.vin[i]).nValue;
nResult += value;
#ifdef KOMODO_ENABLE_INTEREST
@@ -675,6 +668,7 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
{
if (!tx.IsMint()) {
for (unsigned int i = 0; i < tx.vin.size(); i++) {
if (tx.IsPegsImport() && i==0) continue;
const COutPoint &prevout = tx.vin[i].prevout;
const CCoins* coins = AccessCoins(prevout.hash);
if (!coins || !coins->IsAvailable(prevout.n)) {
@@ -696,7 +690,7 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const
// use the maximum priority for all (partially or fully) shielded transactions.
// (Note that coinbase transactions cannot contain JoinSplits, or Sapling shielded Spends or Outputs.)
if (tx.vjoinsplit.size() > 0 || tx.vShieldedSpend.size() > 0 || tx.vShieldedOutput.size() > 0 || tx.IsCoinImport()) {
if (tx.vjoinsplit.size() > 0 || tx.vShieldedSpend.size() > 0 || tx.vShieldedOutput.size() > 0 || tx.IsCoinImport() || tx.IsPegsImport()) {
return MAX_PRIORITY;
}
-31
View File
@@ -463,37 +463,6 @@ public:
friend class CCoinsViewCache;
};
class CTransactionExceptionData
{
public:
CScript scriptPubKey;
uint64_t voutMask;
CTransactionExceptionData() : scriptPubKey(), voutMask() {}
};
/*class CLaunchMap
{
public:
std::unordered_map<std::string, CTransactionExceptionData> lmap;
CLaunchMap() : lmap()
{
//printf("txid: %s -> addr: %s\n", whitelist_ids[i], whitelist_addrs[i]);
CBitcoinAddress bcaddr(whitelist_address);
CKeyID key;
if (bcaddr.GetKeyID_NoCheck(key))
{
std::vector<unsigned char> address = std::vector<unsigned char>(key.begin(), key.end());
for (int i = 0; i < WHITELIST_COUNT; i++)
{
std::string hash = uint256S(whitelist_ids[i]).ToString();
lmap[hash].scriptPubKey << OP_DUP << OP_HASH160 << address << OP_EQUALVERIFY << OP_CHECKSIG;
lmap[hash].voutMask = whitelist_masks[i];
}
}
}
};
static CLaunchMap launchMap = CLaunchMap();*/
/** CCoinsView that adds a memory cache for transactions to another CCoinsView */
class CCoinsViewCache : public CCoinsViewBacked
{
+6 -1
View File
@@ -18,6 +18,8 @@
******************************************************************************/
#include "consensus/upgrades.h"
extern int32_t KOMODO_NSPV;
#define NSPV_BRANCHID 0x76b809bb
/**
* General information about each network upgrade.
@@ -97,7 +99,10 @@ int CurrentEpoch(int nHeight, const Consensus::Params& params) {
return Consensus::BASE_SPROUT;
}
uint32_t CurrentEpochBranchId(int nHeight, const Consensus::Params& params) {
uint32_t CurrentEpochBranchId(int nHeight, const Consensus::Params& params)
{
if ( KOMODO_NSPV > 0 )
return(NSPV_BRANCHID);
return NetworkUpgradeInfo[CurrentEpoch(nHeight, params)].nBranchId;
}
+5 -1
View File
@@ -272,9 +272,13 @@ int cc_verify(const struct CC *cond, const unsigned char *msg, size_t msgLength,
unsigned char msgHash[32];
if (doHashMsg) sha256(msg, msgLength, msgHash);
else memcpy(msgHash, msg, 32);
int32_t z;
for (z=0; z<32; z++)
fprintf(stderr,"%02x",msgHash[z]);
fprintf(stderr," msgHash msglen.%d\n",msgLength);
if (!cc_secp256k1VerifyTreeMsg32(cond, msgHash)) {
fprintf(stderr,"cc_verify error C\n");
fprintf(stderr," cc_verify error C\n");
return 0;
}
+14 -4
View File
@@ -157,7 +157,11 @@ static int secp256k1Sign(CC *cond, CCVisitor visitor) {
int rc = secp256k1_ecdsa_sign(ec_ctx_sign, &sig, visitor.msg, signing->sk, NULL, NULL);
unlockSign();
if (rc != 1) return 0;
if (rc != 1)
{
fprintf(stderr,"secp256k1Sign rc.%d\n",rc);
return 0;
}
if (!cond->signature) cond->signature = calloc(1, SECP256K1_SIG_SIZE);
secp256k1_ecdsa_signature_serialize_compact(ec_ctx_verify, cond->signature, &sig);
@@ -188,16 +192,22 @@ int cc_signTreeSecp256k1Msg32(CC *cond, const unsigned char *privateKey, const u
}
// serialize pubkey
unsigned char *publicKey = calloc(1, SECP256K1_PK_SIZE);
//unsigned char *publicKey = calloc(1, SECP256K1_PK_SIZE);
unsigned char publicKey[SECP256K1_PK_SIZE];
size_t ol = SECP256K1_PK_SIZE;
secp256k1_ec_pubkey_serialize(ec_ctx_verify, publicKey, &ol, &spk, SECP256K1_EC_COMPRESSED);
{
int32_t z;
for (z=0; z<33; z++)
fprintf(stderr,"%02x",publicKey[z]);
fprintf(stderr," pubkey\n");
}
// sign
CCSecp256k1SigningData signing = {publicKey, privateKey, 0};
CCVisitor visitor = {&secp256k1Sign, msg32, 32, &signing};
cc_visit(cond, visitor);
free(publicKey);
//free(publicKey);
return signing.nSigned;
}
Executable
+7
View File
@@ -0,0 +1,7 @@
#!/bin/bash
#set working directory to the location of this script
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
../komodo-cli -ac_name=HUSH3 "$@"
+11 -11
View File
@@ -166,7 +166,7 @@ TEST(checktransaction_tests, BadTxnsOversize) {
// ... but fails contextual ones!
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-oversize", false)).Times(1);
EXPECT_FALSE(ContextualCheckTransaction(tx, state, 1, 100));
EXPECT_FALSE(ContextualCheckTransaction(0,tx, state, 1, 100));
}
{
@@ -188,7 +188,7 @@ TEST(checktransaction_tests, BadTxnsOversize) {
MockCValidationState state;
EXPECT_TRUE(CheckTransactionWithoutProofVerification(tx, state));
EXPECT_TRUE(ContextualCheckTransaction(tx, state, 1, 100));
EXPECT_TRUE(ContextualCheckTransaction(0,tx, state, 1, 100));
// Revert to default
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_SAPLING, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT);
@@ -508,9 +508,9 @@ TEST(checktransaction_tests, bad_txns_invalid_joinsplit_signature) {
MockCValidationState state;
// during initial block download, DoS ban score should be zero, else 100
EXPECT_CALL(state, DoS(0, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false)).Times(1);
ContextualCheckTransaction(tx, state, 0, 100, []() { return true; });
ContextualCheckTransaction(0,tx, state, 0, 100, []() { return true; });
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false)).Times(1);
ContextualCheckTransaction(tx, state, 0, 100, []() { return false; });
ContextualCheckTransaction(0,tx, state, 0, 100, []() { return false; });
}
TEST(checktransaction_tests, non_canonical_ed25519_signature) {
@@ -522,7 +522,7 @@ TEST(checktransaction_tests, non_canonical_ed25519_signature) {
{
CTransaction tx(mtx);
MockCValidationState state;
EXPECT_TRUE(ContextualCheckTransaction(tx, state, 0, 100));
EXPECT_TRUE(ContextualCheckTransaction(0,tx, state, 0, 100));
}
// Copied from libsodium/crypto_sign/ed25519/ref10/open.c
@@ -544,9 +544,9 @@ TEST(checktransaction_tests, non_canonical_ed25519_signature) {
MockCValidationState state;
// during initial block download, DoS ban score should be zero, else 100
EXPECT_CALL(state, DoS(0, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false)).Times(1);
ContextualCheckTransaction(tx, state, 0, 100, []() { return true; });
ContextualCheckTransaction(0,tx, state, 0, 100, []() { return true; });
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false)).Times(1);
ContextualCheckTransaction(tx, state, 0, 100, []() { return false; });
ContextualCheckTransaction(0,tx, state, 0, 100, []() { return false; });
}
TEST(checktransaction_tests, OverwinterConstructors) {
@@ -801,7 +801,7 @@ TEST(checktransaction_tests, OverwinterVersionNumberHigh) {
UNSAFE_CTransaction tx(mtx);
MockCValidationState state;
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-tx-overwinter-version-too-high", false)).Times(1);
ContextualCheckTransaction(tx, state, 1, 100);
ContextualCheckTransaction(0,tx, state, 1, 100);
// Revert to default
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT);
@@ -837,9 +837,9 @@ TEST(checktransaction_tests, OverwinterNotActive) {
MockCValidationState state;
// during initial block download, DoS ban score should be zero, else 100
EXPECT_CALL(state, DoS(0, false, REJECT_INVALID, "tx-overwinter-not-active", false)).Times(1);
ContextualCheckTransaction(tx, state, 1, 100, []() { return true; });
ContextualCheckTransaction(0,tx, state, 1, 100, []() { return true; });
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "tx-overwinter-not-active", false)).Times(1);
ContextualCheckTransaction(tx, state, 1, 100, []() { return false; });
ContextualCheckTransaction(0,tx, state, 1, 100, []() { return false; });
}
// This tests a transaction without the fOverwintered flag set, against the Overwinter consensus rule set.
@@ -856,7 +856,7 @@ TEST(checktransaction_tests, OverwinterFlagNotSet) {
CTransaction tx(mtx);
MockCValidationState state;
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "tx-overwinter-flag-not-set", false)).Times(1);
ContextualCheckTransaction(tx, state, 1, 100);
ContextualCheckTransaction(0,tx, state, 1, 100);
// Revert to default
UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT);
+2 -2
View File
@@ -51,7 +51,7 @@ TEST(TransactionBuilder, Invoke)
EXPECT_EQ(tx1.valueBalance, -40000);
CValidationState state;
EXPECT_TRUE(ContextualCheckTransaction(tx1, state, 2, 0));
EXPECT_TRUE(ContextualCheckTransaction(0,tx1, state, 2, 0));
EXPECT_EQ(state.GetRejectReason(), "");
// Prepare to spend the note that was just created
@@ -85,7 +85,7 @@ TEST(TransactionBuilder, Invoke)
EXPECT_EQ(tx2.vShieldedOutput.size(), 2);
EXPECT_EQ(tx2.valueBalance, 10000);
EXPECT_TRUE(ContextualCheckTransaction(tx2, state, 3, 0));
EXPECT_TRUE(ContextualCheckTransaction(0,tx2, state, 3, 0));
EXPECT_EQ(state.GetRejectReason(), "");
// Revert to default
Executable
+10
View File
@@ -0,0 +1,10 @@
#!/bin/bash
# Copyright (c) 2019 Hush developers
# set working directory to the location of this script
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
NAME=HUSHT
./komodo-tx -ac_name=$NAME "$@"
+4 -1
View File
@@ -2,7 +2,10 @@
# Copyright (c) 2019 Hush developers
# set working directory to the location of this script
DIR="$( cd "$( dirname "$( readlink -f "${BASH_SOURCE[0]}" )" )" && pwd )"
# readlink -f does not always exist
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
DIR="$( cd "$( dirname "$( readlink "${BASH_SOURCE[0]}" )" )" && pwd )"
cd $DIR
NAME=HUSH3
+52 -5
View File
@@ -75,6 +75,18 @@ CTransaction MakeImportCoinTransaction(const ImportProof proof, const CTransacti
return CTransaction(mtx);
}
CTransaction MakePegsImportCoinTransaction(const ImportProof proof, const CTransaction burnTx, const std::vector<CTxOut> payouts, uint32_t nExpiryHeightOverride)
{
CMutableTransaction mtx; uint256 accounttxid,pegstxid,tokenid; CScript opret; CScript scriptSig;
mtx=MakeImportCoinTransaction(proof,burnTx,payouts);
// for spending markers in import tx - to track account state
accounttxid=burnTx.vin[0].prevout.hash;
mtx.vin.push_back(CTxIn(accounttxid,0,CScript()));
mtx.vin.push_back(CTxIn(accounttxid,1,CScript()));
return (mtx);
}
CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, const std::string targetSymbol, const std::vector<CTxOut> payouts, const std::vector<uint8_t> rawproof)
{
@@ -123,13 +135,30 @@ CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, std::string targetSymb
return CTxOut(value, CScript() << OP_RETURN << opret);
}
CTxOut MakeBurnOutput(CAmount value,uint32_t targetCCid,std::string targetSymbol,const std::vector<CTxOut> payouts,std::vector<uint8_t> rawproof,uint256 pegstxid,
uint256 tokenid,CPubKey srcpub,int64_t amount,std::pair<int64_t,int64_t> account)
{
std::vector<uint8_t> opret;
opret = E_MARSHAL(ss << (uint8_t)EVAL_IMPORTCOIN;
ss << VARINT(targetCCid);
ss << targetSymbol;
ss << SerializeHash(payouts);
ss << rawproof;
ss << pegstxid;
ss << tokenid;
ss << srcpub;
ss << amount;
ss << account);
return CTxOut(value, CScript() << OP_RETURN << opret);
}
bool UnmarshalImportTx(const CTransaction importTx, ImportProof &proof, CTransaction &burnTx, std::vector<CTxOut> &payouts)
{
if (importTx.vout.size() < 1)
return false;
if (importTx.vin.size() != 1 || importTx.vin[0].scriptSig != (CScript() << E_MARSHAL(ss << EVAL_IMPORTCOIN))) {
if ((!importTx.IsPegsImport() && importTx.vin.size() != 1) || importTx.vin[0].scriptSig != (CScript() << E_MARSHAL(ss << EVAL_IMPORTCOIN))) {
LOGSTREAM("importcoin", CCLOG_INFO, stream << "UnmarshalImportTx() incorrect import tx vin" << std::endl);
return false;
}
@@ -263,17 +292,35 @@ bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &bindtxid,std::vector<CPu
ss >> amount));
}
bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &pegstxid,uint256 &tokenid,CPubKey &srcpub, int64_t &amount,std::pair<int64_t,int64_t> &account)
{
std::vector<uint8_t> burnOpret,rawproof; bool isEof=true;
uint32_t targetCCid; uint256 payoutsHash; std::string targetSymbol;
uint8_t evalCode;
if (burnTx.vout.size() == 0) return false;
GetOpReturnData(burnTx.vout.back().scriptPubKey, burnOpret);
return (E_UNMARSHAL(burnOpret, ss >> evalCode;
ss >> VARINT(targetCCid);
ss >> targetSymbol;
ss >> payoutsHash;
ss >> rawproof;
ss >> pegstxid;
ss >> tokenid;
ss >> srcpub;
ss >> amount;
ss >> account));
}
/*
* Required by main
*/
CAmount GetCoinImportValue(const CTransaction &tx)
{
ImportProof proof;
CTransaction burnTx;
std::vector<CTxOut> payouts;
ImportProof proof; CTransaction burnTx; std::vector<CTxOut> payouts;
bool isNewImportTx = false;
if ((isNewImportTx = UnmarshalImportTx(tx, proof, burnTx, payouts))) {
if (burnTx.vout.size() > 0) {
vscript_t vburnOpret;
+4
View File
@@ -95,16 +95,20 @@ public:
CAmount GetCoinImportValue(const CTransaction &tx);
CTransaction MakeImportCoinTransaction(const ImportProof proof, const CTransaction burnTx, const std::vector<CTxOut> payouts, uint32_t nExpiryHeightOverride = 0);
CTransaction MakePegsImportCoinTransaction(const ImportProof proof, const CTransaction burnTx, const std::vector<CTxOut> payouts, uint32_t nExpiryHeightOverride = 0);
CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, const std::string targetSymbol, const std::vector<CTxOut> payouts, const std::vector<uint8_t> rawproof);
CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, std::string targetSymbol, const std::vector<CTxOut> payouts,std::vector<uint8_t> rawproof,
uint256 bindtxid,std::vector<CPubKey> publishers,std::vector<uint256>txids,uint256 burntxid,int32_t height,int32_t burnvout,std::string rawburntx,CPubKey destpub, int64_t amount);
CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, std::string targetSymbol, const std::vector<CTxOut> payouts,std::vector<uint8_t> rawproof,std::string srcaddr,
std::string receipt);
CTxOut MakeBurnOutput(CAmount value,uint32_t targetCCid,std::string targetSymbol,const std::vector<CTxOut> payouts,std::vector<uint8_t> rawproof,uint256 pegstxid,
uint256 tokenid,CPubKey srcpub,int64_t amount,std::pair<int64_t,int64_t> account);
bool UnmarshalBurnTx(const CTransaction burnTx, std::string &targetSymbol, uint32_t *targetCCid, uint256 &payoutsHash,std::vector<uint8_t> &rawproof);
bool UnmarshalBurnTx(const CTransaction burnTx, std::string &srcaddr, std::string &receipt);
bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &bindtxid,std::vector<CPubKey> &publishers,std::vector<uint256> &txids,uint256& burntxid,int32_t &height,int32_t &burnvout,std::string &rawburntx,CPubKey &destpub, int64_t &amount);
bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &pegstxid,uint256 &tokenid,CPubKey &srcpub,int64_t &amount,std::pair<int64_t,int64_t> &account);
bool UnmarshalImportTx(const CTransaction importTx, ImportProof &proof, CTransaction &burnTx,std::vector<CTxOut> &payouts);
bool VerifyCoinImport(const CScript& scriptSig, TransactionSignatureChecker& checker, CValidationState &state);
+80 -23
View File
@@ -91,12 +91,10 @@
using namespace std;
#include "komodo_defs.h"
extern void ThreadSendAlert();
extern bool komodo_dailysnapshot(int32_t height);
extern int32_t KOMODO_LOADINGBLOCKS;
extern bool VERUS_MINTBLOCKS;
extern char ASSETCHAINS_SYMBOL[];
extern int32_t KOMODO_SNAPSHOT_INTERVAL;
ZCJoinSplit* pzcashParams = NULL;
@@ -745,6 +743,19 @@ bool InitSanityCheck(void)
return true;
}
void NoParamsShutdown(void)
{
//TODO: error message incorrect about location
LogPrintf("Could not find Sapling params anywhere! Exiting...");
uiInterface.ThreadSafeMessageBox(strprintf(
_("Cannot find the Sapling network parameters in the following directory:\n"
"%s\n"
"Please run 'zcash-fetch-params' or './zcutil/fetch-params.sh' and then restart."),
ZC_GetParamsDir()),
"", CClientUIInterface::MSG_ERROR);
StartShutdown();
return;
}
static void ZC_LoadParams(
const CChainParams& chainparams
@@ -753,21 +764,37 @@ static void ZC_LoadParams(
struct timeval tv_start, tv_end;
float elapsed;
// First check the global installation location
boost::filesystem::path sapling_spend = ZC_GetParamsDir() / "sapling-spend.params";
boost::filesystem::path sapling_output = ZC_GetParamsDir() / "sapling-output.params";
if (!(
boost::filesystem::exists(sapling_spend) &&
boost::filesystem::exists(sapling_output)
)) {
uiInterface.ThreadSafeMessageBox(strprintf(
_("Cannot find the Zcash network parameters in the following directory:\n"
"%s\n"
"Please run 'zcash-fetch-params' or './zcutil/fetch-params.sh' and then restart."),
ZC_GetParamsDir()),
"", CClientUIInterface::MSG_ERROR);
StartShutdown();
return;
// NOTE: This means that sapling params do not need to be installed, just findable
if (!( boost::filesystem::exists(sapling_spend) && boost::filesystem::exists(sapling_output))) {
// Not globally installed, use local copies if they exist
// First check ., then .., then ../hush3
sapling_spend = "sapling-spend.params";
sapling_output = "sapling-output.params";
// This is the most common case, for binaries distributed with params
if (!( boost::filesystem::exists(sapling_spend) && boost::filesystem::exists(sapling_output))) {
// Not in PWD, try ..
sapling_spend = boost::filesystem::path("..") / "sapling-spend.params";
sapling_output = boost::filesystem::path("..") / "sapling-output.params";
// Try .. in case this binary has no params
if (!( boost::filesystem::exists(sapling_spend) && boost::filesystem::exists(sapling_output))) {
// Not in .., try ../hush3 (the case of SilentDragon installed in same directory as hush3)
sapling_spend = boost::filesystem::path("..") / "hush3" / "sapling-spend.params";
sapling_output = boost::filesystem::path("..") / "hush3" / "sapling-output.params";
// This will catch the case of any external software (i.e. GUI wallets) needing params and installed in same dir as hush3.git
if (!( boost::filesystem::exists(sapling_spend) && boost::filesystem::exists(sapling_output))) {
// No Sapling params, at least we tried
NoParamsShutdown();
return;
}
}
}
}
//LogPrintf("Loading verifying key from %s\n", vk_path.string().c_str());
@@ -971,13 +998,15 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// Make sure enough file descriptors are available
int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1);
nMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS);
//fprintf(stderr,"nMaxConnections %d\n",nMaxConnections);
nMaxConnections = std::max(std::min(nMaxConnections, (int)(FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS)), 0);
int nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS);
//fprintf(stderr,"nMaxConnections %d FD_SETSIZE.%d nBind.%d expr.%d \n",nMaxConnections,FD_SETSIZE,nBind,(int)(FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS));
if (nFD < MIN_CORE_FILEDESCRIPTORS)
return InitError(_("Not enough file descriptors available."));
if (nFD - MIN_CORE_FILEDESCRIPTORS < nMaxConnections)
nMaxConnections = nFD - MIN_CORE_FILEDESCRIPTORS;
fprintf(stderr,"nMaxConnections %d\n",nMaxConnections);
// if using block pruning, then disable txindex
// also disable the wallet (for now, until SPV support is implemented in wallet)
if (GetArg("-prune", 0)) {
@@ -1059,6 +1088,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
RegisterAllCoreRPCCommands(tableRPC);
#ifdef ENABLE_WALLET
bool fDisableWallet = GetBoolArg("-disablewallet", false);
if ( KOMODO_NSPV > 0 )
{
fDisableWallet = true;
nLocalServices = 0;
}
if (!fDisableWallet)
RegisterWalletRPCCommands(tableRPC);
#endif
@@ -1135,9 +1169,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// Option to startup with mocktime set (used for regression testing):
SetMockTime(GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op
if (GetBoolArg("-peerbloomfilters", true))
nLocalServices |= NODE_BLOOM;
if ( KOMODO_NSPV <= 0 )
{
if (GetBoolArg("-peerbloomfilters", true))
nLocalServices |= NODE_BLOOM;
}
nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE);
#ifdef ENABLE_MINING
@@ -1297,9 +1333,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
libsnark::inhibit_profiling_info = true;
libsnark::inhibit_profiling_counters = true;
// Initialize Zcash circuit parameters
ZC_LoadParams(chainparams);
if ( KOMODO_NSPV <= 0 )
{
// Initialize Zcash circuit parameters
ZC_LoadParams(chainparams);
}
/* Start the RPC server already. It will be started in "warmup" mode
* and not really process calls already (but it will signify connections
* that the server is there and will be ready later). Warmup mode will
@@ -1476,6 +1514,18 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
}
#endif
if ( KOMODO_NSPV > 0 )
{
std::vector<boost::filesystem::path> vImportFiles;
threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles));
StartNode(threadGroup, scheduler);
pcoinsTip = new CCoinsViewCache(pcoinscatcher);
InitBlockIndex();
SetRPCWarmupFinished();
uiInterface.InitMessage(_("Done loading"));
pwalletMain = new CWallet("tmptmp.wallet");
return !fRequestShutdown;
}
// ********************************************************* Step 7: load block chain
fReindex = GetBoolArg("-reindex", false);
@@ -1888,7 +1938,14 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
PruneAndFlush();
}
}
if ( KOMODO_NSPV >= 0 )
{
if ( GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX) != 0 )
nLocalServices |= NODE_ADDRINDEX;
if ( GetBoolArg("-spentindex", DEFAULT_SPENTINDEX) != 0 )
nLocalServices |= NODE_SPENTINDEX;
fprintf(stderr,"nLocalServices %llx %d, %d\n",(long long)nLocalServices,GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX),GetBoolArg("-spentindex", DEFAULT_SPENTINDEX));
}
// ********************************************************* Step 10: import blocks
if (mapArgs.count("-blocknotify"))
+16
View File
@@ -207,6 +207,22 @@ CKey DecodeSecret(const std::string& str)
return key;
}
CKey DecodeCustomSecret(const std::string& str, uint8_t secret_key)
{
CKey key;
std::vector<unsigned char> data;
if (DecodeBase58Check(str, data)) {
const std::vector<unsigned char>& privkey_prefix = std::vector<unsigned char>(1, secret_key);
if ((data.size() == 32 + privkey_prefix.size() || (data.size() == 33 + privkey_prefix.size() && data.back() == 1)) &&
std::equal(privkey_prefix.begin(), privkey_prefix.end(), data.begin())) {
bool compressed = data.size() == 33 + privkey_prefix.size();
key.Set(data.begin() + privkey_prefix.size(), data.begin() + privkey_prefix.size() + 32, compressed);
}
}
memory_cleanse(data.data(), data.size());
return key;
}
std::string EncodeSecret(const CKey& key)
{
assert(key.IsValid());
+1
View File
@@ -17,6 +17,7 @@
#include <string>
CKey DecodeSecret(const std::string& str);
CKey DecodeCustomSecret(const std::string& str, uint8_t secret_key);
std::string EncodeSecret(const CKey& key);
std::string EncodeCustomSecret(const CKey& key,uint8_t secret_key);
+2
View File
@@ -47,6 +47,8 @@ using namespace std;
#include "komodo_interest.h"
CKey NSPV_key;
char NSPV_pubkeystr[67],NSPV_wifstr[64];
uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight)
{
return(0);
+48 -23
View File
@@ -1256,28 +1256,25 @@ CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams);
uint64_t komodo_commission(const CBlock *pblock,int32_t height)
{
static bool didinit = false,ishush3 = false;
// LABS fungible chains, cannot have any block reward!
if ( is_STAKED(ASSETCHAINS_SYMBOL) == 2 )
return(0);
int32_t i,j,n=0,txn_count,halvings; int64_t nSubsidy; uint64_t commission,total = 0;
txn_count = pblock->vtx.size();
if (!didinit) {
ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false;
didinit = true;
}
int32_t i,j,n=0,txn_count; int64_t nSubsidy; uint64_t commission,total = 0;
if ( ASSETCHAINS_FOUNDERS != 0 )
{
// prod values
// NOTE: ac_end specifies the first block with 0 reward, not the last block with a reward!
// TODO: BR_END will change slightly based on magicExtra UTXO, up to 10 blocks, and do
// to the fact that -ac_supply only takes integer arguments another max of 5 blocks,
// so could change by at most 15 blocks after mainnet launch
int32_t starting_commission = 125000000, HALVING1 = 340000, INTERVAL = 840000, TRANSITION = 129, BR_END = 5422111;
// testnet values
//int64_t starting_commission = 125000000, HALVING1 = 34, INTERVAL = 84, TRANSITION = 29;
nSubsidy = GetBlockSubsidy(height,Params().GetConsensus());
//fprintf(stderr,"ht.%d nSubsidy %.8f prod %llu\n",height,(double)nSubsidy/COIN,(long long)(nSubsidy * ASSETCHAINS_COMMISSION));
commission = ((nSubsidy * ASSETCHAINS_COMMISSION) / COIN);
//fprintf(stderr,"ORIG ht.%d nSubsidy %.8f prod %llu\n",height,(double)nSubsidy/COIN,(long long)(nSubsidy * ASSETCHAINS_COMMISSION));
if ((strcmp(ASSETCHAINS_SYMBOL, "HUSH3") != 0) || (strcmp(ASSETCHAINS_SYMBOL, "HUSH3T") != 0)) {
if (ishush3) {
int32_t starting_commission = 125000000, HALVING1 = 340000, INTERVAL = 840000, TRANSITION = 129, BR_END = 5422111;
// HUSH supply curve cannot be exactly represented via KMD AC CLI args, so we do it ourselves.
// You specify the BR, and the FR % gets added so 10% of 12.5 is 1.25
// but to tell the AC params, I need to say "11% of 11.25" is 1.25
@@ -1298,13 +1295,13 @@ uint64_t komodo_commission(const CBlock *pblock,int32_t height)
} else if (height < HALVING1+5*INTERVAL) {
commission = starting_commission / 32;
} else if (height < HALVING1+6*INTERVAL) { // Block 5380000
// Block reward will go to zero between 7th+8th halvings
// Block reward will go to zero between 7th+8th halvings, ac_end may need adjusting
commission = starting_commission / 64;
} else if (height < HALVING1+7*INTERVAL) {
// Block reward will be zero before this is ever reached
commission = starting_commission / 128; // Block 6220000
}
}
//fprintf(stderr,"AFTER ht.%d nSubsidy %.8f prod %llu\n",height,(double)nSubsidy/COIN,(long long)(nSubsidy * ASSETCHAINS_COMMISSION));
if ( ASSETCHAINS_FOUNDERS > 1 )
{
@@ -1419,6 +1416,32 @@ uint32_t komodo_stakehash(uint256 *hashp,char *address,uint8_t *hashbuf,uint256
return(addrhash.uints[0]);
}
arith_uint256 komodo_adaptivepow_target(int32_t height,arith_uint256 bnTarget,uint32_t nTime)
{
arith_uint256 origtarget,easy; int32_t diff,tipdiff; int64_t mult; bool fNegative,fOverflow; CBlockIndex *tipindex;
if ( height > 10 && (tipindex= komodo_chainactive(height - 1)) != 0 ) // disable offchain diffchange
{
diff = (nTime - tipindex->GetMedianTimePast());
tipdiff = (nTime - tipindex->nTime);
if ( tipdiff > 13*ASSETCHAINS_BLOCKTIME )
diff = tipdiff;
if ( diff >= 13 * ASSETCHAINS_BLOCKTIME && (height < 30 || tipdiff > 2*ASSETCHAINS_BLOCKTIME) )
{
mult = diff - 12 * ASSETCHAINS_BLOCKTIME;
mult = (mult / ASSETCHAINS_BLOCKTIME) * ASSETCHAINS_BLOCKTIME + ASSETCHAINS_BLOCKTIME / 2;
origtarget = bnTarget;
bnTarget = bnTarget * arith_uint256(mult * mult);
easy.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow);
if ( bnTarget < origtarget || bnTarget > easy ) // deal with overflow
{
bnTarget = easy;
fprintf(stderr,"tipdiff.%d diff.%d height.%d miner overflowed mult.%lld, set to mindiff\n",tipdiff,diff,height,(long long)mult);
} else fprintf(stderr,"tipdiff.%d diff.%d height.%d miner elapsed %d, adjust by factor of %lld\n",tipdiff,diff,height,diff,(long long)mult);
} //else fprintf(stderr,"height.%d tipdiff.%d diff %d, vs %d\n",height,tipdiff,diff,13*ASSETCHAINS_BLOCKTIME);
} else fprintf(stderr,"adaptive cant find height.%d\n",height);
return(bnTarget);
}
arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc)
{
int32_t oldflag = 0,dispflag = 0;
@@ -2091,7 +2114,7 @@ uint64_t komodo_checknotarypay(CBlock *pblock,int32_t height)
total += txout.nValue;
//fprintf(stderr, "MATCHED AmountPaid.%lu notaryid.%i\n",AmountToPay,NotarisationNotaries[n-1]);
}
else fprintf(stderr, "NOT MATCHED AmountPaid.%lu AmountToPay.%lu notaryid.%i\n", pblock->vtx[0].vout[n].nValue, AmountToPay, NotarisationNotaries[n-1]);
else fprintf(stderr, "NOT MATCHED AmountPaid.%llu AmountToPay.%llu notaryid.%i\n", (long long)pblock->vtx[0].vout[n].nValue, (long long)AmountToPay, NotarisationNotaries[n-1]);
}
n++;
}
@@ -2112,7 +2135,7 @@ bool komodo_appendACscriptpub()
{
CTransaction tx; uint256 blockhash;
// get transaction and check that it occured before height 100.
if ( myGetTransaction(KOMODO_EARLYTXID,tx,blockhash) && mapBlockIndex[blockhash]->GetHeight() < 100 )
if ( myGetTransaction(KOMODO_EARLYTXID,tx,blockhash) && mapBlockIndex[blockhash]->GetHeight() < KOMODO_EARLYTXID_HEIGHT )
{
for (int i = 0; i < tx.vout.size(); i++)
{
@@ -2147,15 +2170,15 @@ void GetKomodoEarlytxidScriptPub()
StartShutdown();
return;
}
if ( chainActive.Height() < 100 )
if ( chainActive.Height() < KOMODO_EARLYTXID_HEIGHT )
{
fprintf(stderr, "Cannot fetch -earlytxid before block 100.\n");
fprintf(stderr, "Cannot fetch -earlytxid before block %d.\n",KOMODO_EARLYTXID_HEIGHT);
StartShutdown();
return;
}
CTransaction tx; uint256 blockhash; int32_t i;
// get transaction and check that it occured before height 100.
if ( myGetTransaction(KOMODO_EARLYTXID,tx,blockhash) && mapBlockIndex[blockhash]->GetHeight() < 100 )
if ( myGetTransaction(KOMODO_EARLYTXID,tx,blockhash) && mapBlockIndex[blockhash]->GetHeight() < KOMODO_EARLYTXID_HEIGHT )
{
for (i = 0; i < tx.vout.size(); i++)
if ( tx.vout[i].scriptPubKey[0] == OP_RETURN )
@@ -2179,7 +2202,7 @@ int64_t komodo_checkcommission(CBlock *pblock,int32_t height)
checktoshis = komodo_commission(pblock,height);
if ( checktoshis >= 10000 && pblock->vtx[0].vout.size() < 2 )
{
fprintf(stderr,"komodo_checkcommission vsize.%d height.%d commission %.8f\n",(int32_t)pblock->vtx[0].vout.size(),height,(double)checktoshis/COIN);
//fprintf(stderr,"komodo_checkcommission vsize.%d height.%d commission %.8f\n",(int32_t)pblock->vtx[0].vout.size(),height,(double)checktoshis/COIN);
return(-1);
}
else if ( checktoshis != 0 )
@@ -2196,7 +2219,7 @@ int64_t komodo_checkcommission(CBlock *pblock,int32_t height)
if ( ASSETCHAINS_SCRIPTPUB.size() > 1 )
{
static bool didinit = false;
if ( !didinit && height > 100 && KOMODO_EARLYTXID != zeroid && komodo_appendACscriptpub() )
if ( !didinit && height > KOMODO_EARLYTXID_HEIGHT && KOMODO_EARLYTXID != zeroid && komodo_appendACscriptpub() )
{
fprintf(stderr, "appended CC_op_return to ASSETCHAINS_SCRIPTPUB.%s\n", ASSETCHAINS_SCRIPTPUB.c_str());
didinit = true;
@@ -2263,6 +2286,8 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
if ( height == 0 )
return(0);
}
//if ( ASSETCHAINS_ADAPTIVEPOW > 0 )
// bnTarget = komodo_adaptivepow_target(height,bnTarget,pblock->nTime);
if ( ASSETCHAINS_LWMAPOS != 0 && bhash > bnTarget )
{
// if proof of stake is active, check if this is a valid PoS block before we fail
@@ -2387,7 +2412,7 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
numSN = komodo_notaries(notarypubkeys, height, pblock->nTime);
if ( pblock->vtx[1].vin.size() < numSN/5 )
{
fprintf(stderr, "ht.%i does not meet minsigs.%i sigs.%li\n",height,numSN/5,pblock->vtx[1].vin.size());
fprintf(stderr, "ht.%i does not meet minsigs.%i sigs.%lld\n",height,numSN/5,(long long)pblock->vtx[1].vin.size());
return(-1);
}
}
+11 -3
View File
@@ -15,10 +15,14 @@
#ifndef KOMODO_DEFS_H
#define KOMODO_DEFS_H
#include "arith_uint256.h"
#include "komodo_nk.h"
#define KOMODO_EARLYTXID_HEIGHT 100
#define ADAPTIVEPOW_CHANGETO_DEFAULTON 1572480000
#define ASSETCHAINS_MINHEIGHT 128
#define ASSETCHAINS_MAX_ERAS 3
#define ASSETCHAINS_MAX_ERAS 7
#define KOMODO_ELECTION_GAP 2000
#define ROUNDROBIN_DELAY 61
#define KOMODO_ASSETCHAIN_MAXLEN 65
@@ -261,6 +265,7 @@ static const char *notaries_elected[NUM_KMD_SEASONS][NUM_KMD_NOTARIES][2] =
//#endif
extern uint8_t ASSETCHAINS_TXPOW,ASSETCHAINS_PUBLIC;
extern int8_t ASSETCHAINS_ADAPTIVEPOW;
int32_t MAX_BLOCK_SIZE(int32_t height);
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT;
@@ -271,10 +276,10 @@ extern uint64_t ASSETCHAINS_SUPPLY, ASSETCHAINS_FOUNDERS_REWARD;
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,ASSETCHAINS_STAKED;
extern int32_t KOMODO_MININGTHREADS,KOMODO_LONGESTCHAIN,ASSETCHAINS_SEED,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,KOMODO_ON_DEMAND,KOMODO_PASSPORT_INITDONE,ASSETCHAINS_STAKED,KOMODO_NSPV;
extern uint64_t ASSETCHAINS_COMMISSION, ASSETCHAINS_LASTERA,ASSETCHAINS_CBOPRET;
extern bool VERUS_MINTBLOCKS;
extern uint64_t ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_NOTARY_PAY[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_TIMELOCKGTE, ASSETCHAINS_NONCEMASK[],ASSETCHAINS_NK[2];
extern uint64_t ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS+1], ASSETCHAINS_NOTARY_PAY[ASSETCHAINS_MAX_ERAS+1], ASSETCHAINS_TIMELOCKGTE, ASSETCHAINS_NONCEMASK[],ASSETCHAINS_NK[2];
extern const char *ASSETCHAINS_ALGORITHMS[];
extern int32_t VERUS_MIN_STAKEAGE;
extern uint32_t ASSETCHAINS_VERUSHASH, ASSETCHAINS_VERUSHASHV1_1, ASSETCHAINS_NONCESHIFT[], ASSETCHAINS_HASHESPERROUND[];
@@ -335,6 +340,9 @@ int64_t komodo_pricemult(int32_t ind);
int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblocks);
uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight);
int32_t komodo_currentheight();
int32_t komodo_notarized_bracket(struct notarized_checkpoint *nps[2],int32_t height);
arith_uint256 komodo_adaptivepow_target(int32_t height,arith_uint256 bnTarget,uint32_t nTime);
uint256 Parseuint256(const char *hexstr);
#endif
+6 -3
View File
@@ -652,6 +652,9 @@ const char *banned_txids[] =
//"01d8c839463bda2f2f6400ede4611357913684927a767422a8560ead1b22557c",
//"6e4980a9e1bd669f4df04732dc6f11b7773b6de88d1abcf89a6b9007d72ef9ac",
//"6cc1d0495170bc0e11fd3925297623562e529ea1336b66ea61f8a1159041aed2",
//"250875424cece9bcd98cb226b09da7671625633d6958589e3a462bad89ad87cc", // missed
//"ea8659011de52f4dac42cda12326064b7b5013b8492f88e33159884ca299aa05", // missed
//"ce567928b5490a17244167af161b1d8dd6ff753fef222fe6855d95b2278a35b3", // missed
};
int32_t komodo_checkvout(int32_t vout,int32_t k,int32_t indallvouts)
@@ -668,7 +671,7 @@ int32_t komodo_bannedset(int32_t *indallvoutsp,uint256 *array,int32_t max)
int32_t i;
if ( sizeof(banned_txids)/sizeof(*banned_txids) > max )
{
fprintf(stderr,"komodo_bannedset: buffer too small %ld vs %d\n",sizeof(banned_txids)/sizeof(*banned_txids),max);
fprintf(stderr,"komodo_bannedset: buffer too small %d vs %d\n",(int32_t)(sizeof(banned_txids)/sizeof(*banned_txids)),max);
StartShutdown();
}
for (i=0; i<sizeof(banned_txids)/sizeof(*banned_txids); i++)
@@ -1288,7 +1291,7 @@ long komodo_stateind_validate(struct komodo_state *sp,char *indfname,uint8_t *fi
if ( (inds= OS_fileptr(&fsize,indfname)) != 0 )
{
lastfpos = 0;
fprintf(stderr,"inds.%p validate %s fsize.%ld datalen.%ld n.%ld lastfpos.%ld\n",inds,indfname,fsize,datalen,fsize / sizeof(uint32_t),lastfpos);
fprintf(stderr,"inds.%p validate %s fsize.%ld datalen.%ld n.%d lastfpos.%ld\n",inds,indfname,fsize,datalen,(int32_t)(fsize / sizeof(uint32_t)),lastfpos);
if ( (fsize % sizeof(uint32_t)) == 0 )
{
n = (int32_t)(fsize / sizeof(uint32_t));
@@ -1379,7 +1382,7 @@ int32_t komodo_faststateinit(struct komodo_state *sp,char *fname,char *symbol,ch
if ( (indfp= fopen(indfname,"rb+")) != 0 )
{
lastfpos = fpos = validated;
fprintf(stderr,"datalen.%ld validated %ld -> indcounter %u, prevpos100 %u offset.%ld\n",datalen,validated,indcounter,prevpos100,indcounter * sizeof(uint32_t));
fprintf(stderr,"datalen.%ld validated %ld -> indcounter %u, prevpos100 %u offset.%d\n",datalen,validated,indcounter,prevpos100,(int32_t)(indcounter * sizeof(uint32_t)));
if ( fpos < datalen )
{
fseek(indfp,indcounter * sizeof(uint32_t),SEEK_SET);
+4 -2
View File
@@ -46,10 +46,12 @@ struct komodo_state KOMODO_STATES[34];
int COINBASE_MATURITY = _COINBASE_MATURITY;//100;
unsigned int WITNESS_CACHE_SIZE = _COINBASE_MATURITY+10;
uint256 KOMODO_EARLYTXID;
int32_t KOMODO_MININGTHREADS = -1,IS_KOMODO_NOTARY,IS_STAKED_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND,STAKED_ERA,KOMODO_CONNECTING = -1,KOMODO_DEALERNODE,KOMODO_EXTRASATOSHI,ASSETCHAINS_FOUNDERS;
int32_t KOMODO_MININGTHREADS = -1,IS_KOMODO_NOTARY,IS_STAKED_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND,STAKED_ERA,KOMODO_CONNECTING = -1,KOMODO_DEALERNODE,KOMODO_EXTRASATOSHI,ASSETCHAINS_FOUNDERS,ASSETCHAINS_CBMATURITY,KOMODO_NSPV;
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,NOTARY_ADDRESS,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;
int8_t ASSETCHAINS_ADAPTIVEPOW;
bool VERUS_MINTBLOCKS;
std::vector<uint8_t> Mineropret;
std::vector<std::string> vWhiteListAddress;
@@ -74,7 +76,7 @@ uint64_t ASSETCHAINS_TIMELOCKGTE = _ASSETCHAINS_TIMELOCKOFF;
uint64_t ASSETCHAINS_TIMEUNLOCKFROM = 0, ASSETCHAINS_TIMEUNLOCKTO = 0,ASSETCHAINS_CBOPRET=0;
uint64_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],ASSETCHAINS_NOTARY_PAY[ASSETCHAINS_MAX_ERAS];
uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_DECAY[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_NOTARY_PAY[ASSETCHAINS_MAX_ERAS+1],ASSETCHAINS_PEGSCCPARAMS[3];
uint8_t ASSETCHAINS_CCDISABLES[256];
std::vector<std::string> ASSETCHAINS_PRICES,ASSETCHAINS_STOCKS;
+588
View File
@@ -0,0 +1,588 @@
/******************************************************************************
* 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. *
* *
******************************************************************************/
// todo:
// spentinfo via CC
// headers "sync" make sure it connects to prior blocks to notarization. use getinfo hdrht to get missing hdrs
// make sure to sanity check all vector lengths on receipt
// make sure no files are updated (this is to allow nSPV=1 and later nSPV=0 without affecting database)
// bug: under load, fullnode was returning all 0 nServices
#ifndef KOMODO_NSPV_H
#define KOMODO_NSPV_H
int32_t iguana_rwbuf(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *buf)
{
if ( rwflag != 0 )
memcpy(serialized,buf,len);
else memcpy(buf,serialized,len);
return(len);
}
int32_t NSPV_rwequihdr(int32_t rwflag,uint8_t *serialized,struct NSPV_equihdr *ptr)
{
int32_t len = 0;
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->nVersion),&ptr->nVersion);
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->hashPrevBlock),(uint8_t *)&ptr->hashPrevBlock);
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->hashMerkleRoot),(uint8_t *)&ptr->hashMerkleRoot);
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->hashFinalSaplingRoot),(uint8_t *)&ptr->hashFinalSaplingRoot);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->nTime),&ptr->nTime);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->nBits),&ptr->nBits);
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->nNonce),(uint8_t *)&ptr->nNonce);
len += iguana_rwbuf(rwflag,&serialized[len],sizeof(ptr->nSolution),ptr->nSolution);
return(len);
}
int32_t iguana_rwequihdrvec(int32_t rwflag,uint8_t *serialized,uint16_t *vecsizep,struct NSPV_equihdr **ptrp)
{
int32_t i,vsize,len = 0;
len += iguana_rwnum(rwflag,&serialized[len],sizeof(*vecsizep),vecsizep);
if ( (vsize= *vecsizep) != 0 )
{
//fprintf(stderr,"vsize.%d ptrp.%p alloc %ld\n",vsize,*ptrp,sizeof(struct NSPV_equihdr)*vsize);
if ( *ptrp == 0 )
*ptrp = (struct NSPV_equihdr *)calloc(sizeof(struct NSPV_equihdr),vsize); // relies on uint16_t being "small" to prevent mem exhaustion
for (i=0; i<vsize; i++)
len += NSPV_rwequihdr(rwflag,&serialized[len],&(*ptrp)[i]);
}
return(len);
}
int32_t iguana_rwuint8vec(int32_t rwflag,uint8_t *serialized,int32_t *biglenp,uint8_t **ptrp)
{
int32_t vsize,len = 0;
len += iguana_rwnum(rwflag,&serialized[len],sizeof(*biglenp),biglenp);
if ( (vsize= *biglenp) > 0 && vsize < MAX_TX_SIZE_AFTER_SAPLING )
{
if ( *ptrp == 0 )
*ptrp = (uint8_t *)calloc(1,vsize);
len += iguana_rwbuf(rwflag,&serialized[len],vsize,*ptrp);
}
return(len);
}
int32_t NSPV_rwutxoresp(int32_t rwflag,uint8_t *serialized,struct NSPV_utxoresp *ptr)
{
int32_t len = 0;
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->txid),(uint8_t *)&ptr->txid);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->satoshis),&ptr->satoshis);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->extradata),&ptr->extradata);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->vout),&ptr->vout);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->height),&ptr->height);
return(len);
}
int32_t NSPV_rwutxosresp(int32_t rwflag,uint8_t *serialized,struct NSPV_utxosresp *ptr) // check mempool
{
int32_t i,len = 0;
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->numutxos),&ptr->numutxos);
if ( ptr->numutxos != 0 )
{
if ( ptr->utxos == 0 )
ptr->utxos = (struct NSPV_utxoresp *)calloc(sizeof(*ptr->utxos),ptr->numutxos); // relies on uint16_t being "small" to prevent mem exhaustion
for (i=0; i<ptr->numutxos; i++)
len += NSPV_rwutxoresp(rwflag,&serialized[len],&ptr->utxos[i]);
}
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->total),&ptr->total);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->interest),&ptr->interest);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->nodeheight),&ptr->nodeheight);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->filter),&ptr->filter);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->CCflag),&ptr->CCflag);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->skipcount),&ptr->skipcount);
if ( rwflag != 0 )
{
memcpy(&serialized[len],ptr->coinaddr,sizeof(ptr->coinaddr));
len += sizeof(ptr->coinaddr);
}
else
{
memcpy(ptr->coinaddr,&serialized[len],sizeof(ptr->coinaddr));
len += sizeof(ptr->coinaddr);
}
return(len);
}
void NSPV_utxosresp_purge(struct NSPV_utxosresp *ptr)
{
if ( ptr != 0 )
{
if ( ptr->utxos != 0 )
free(ptr->utxos);
memset(ptr,0,sizeof(*ptr));
}
}
void NSPV_utxosresp_copy(struct NSPV_utxosresp *dest,struct NSPV_utxosresp *ptr)
{
*dest = *ptr;
if ( ptr->utxos != 0 )
{
dest->utxos = (struct NSPV_utxoresp *)malloc(ptr->numutxos * sizeof(*ptr->utxos));
memcpy(dest->utxos,ptr->utxos,ptr->numutxos * sizeof(*ptr->utxos));
}
}
int32_t NSPV_rwtxidresp(int32_t rwflag,uint8_t *serialized,struct NSPV_txidresp *ptr)
{
int32_t len = 0;
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->txid),(uint8_t *)&ptr->txid);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->satoshis),&ptr->satoshis);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->vout),&ptr->vout);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->height),&ptr->height);
return(len);
}
int32_t NSPV_rwtxidsresp(int32_t rwflag,uint8_t *serialized,struct NSPV_txidsresp *ptr)
{
int32_t i,len = 0;
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->numtxids),&ptr->numtxids);
if ( ptr->numtxids != 0 )
{
if ( ptr->txids == 0 )
ptr->txids = (struct NSPV_txidresp *)calloc(sizeof(*ptr->txids),ptr->numtxids);
for (i=0; i<ptr->numtxids; i++)
len += NSPV_rwtxidresp(rwflag,&serialized[len],&ptr->txids[i]);
}
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->nodeheight),&ptr->nodeheight);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->filter),&ptr->filter);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->CCflag),&ptr->CCflag);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->skipcount),&ptr->skipcount);
if ( rwflag != 0 )
{
memcpy(&serialized[len],ptr->coinaddr,sizeof(ptr->coinaddr));
len += sizeof(ptr->coinaddr);
}
else
{
memcpy(ptr->coinaddr,&serialized[len],sizeof(ptr->coinaddr));
len += sizeof(ptr->coinaddr);
}
//fprintf(stderr,"rwlen.%d\n",len);
return(len);
}
void NSPV_txidsresp_purge(struct NSPV_txidsresp *ptr)
{
if ( ptr != 0 )
{
if ( ptr->txids != 0 )
free(ptr->txids);
memset(ptr,0,sizeof(*ptr));
}
}
void NSPV_txidsresp_copy(struct NSPV_txidsresp *dest,struct NSPV_txidsresp *ptr)
{
*dest = *ptr;
if ( ptr->txids != 0 )
{
dest->txids = (struct NSPV_txidresp *)malloc(ptr->numtxids * sizeof(*ptr->txids));
memcpy(dest->txids,ptr->txids,ptr->numtxids * sizeof(*ptr->txids));
}
}
int32_t NSPV_rwmempoolresp(int32_t rwflag,uint8_t *serialized,struct NSPV_mempoolresp *ptr)
{
int32_t i,len = 0;
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->numtxids),&ptr->numtxids);
if ( ptr->numtxids != 0 )
{
if ( ptr->txids == 0 )
ptr->txids = (uint256 *)calloc(sizeof(*ptr->txids),ptr->numtxids);
for (i=0; i<ptr->numtxids; i++)
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->txids[i]),(uint8_t *)&ptr->txids[i]);
}
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->txid),(uint8_t *)&ptr->txid);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->nodeheight),&ptr->nodeheight);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->vout),&ptr->vout);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->vindex),&ptr->vindex);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->CCflag),&ptr->CCflag);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->funcid),&ptr->funcid);
if ( rwflag != 0 )
{
memcpy(&serialized[len],ptr->coinaddr,sizeof(ptr->coinaddr));
len += sizeof(ptr->coinaddr);
}
else
{
memcpy(ptr->coinaddr,&serialized[len],sizeof(ptr->coinaddr));
len += sizeof(ptr->coinaddr);
}
//fprintf(stderr,"NSPV_rwmempoolresp rwlen.%d\n",len);
return(len);
}
void NSPV_mempoolresp_purge(struct NSPV_mempoolresp *ptr)
{
if ( ptr != 0 )
{
if ( ptr->txids != 0 )
free(ptr->txids);
memset(ptr,0,sizeof(*ptr));
}
}
void NSPV_mempoolresp_copy(struct NSPV_mempoolresp *dest,struct NSPV_mempoolresp *ptr)
{
*dest = *ptr;
if ( ptr->txids != 0 )
{
dest->txids = (uint256 *)malloc(ptr->numtxids * sizeof(*ptr->txids));
memcpy(dest->txids,ptr->txids,ptr->numtxids * sizeof(*ptr->txids));
}
}
int32_t NSPV_rwntz(int32_t rwflag,uint8_t *serialized,struct NSPV_ntz *ptr)
{
int32_t len = 0;
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->blockhash),(uint8_t *)&ptr->blockhash);
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->txid),(uint8_t *)&ptr->txid);
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->othertxid),(uint8_t *)&ptr->othertxid);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->height),&ptr->height);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->txidheight),&ptr->txidheight);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->timestamp),&ptr->timestamp);
return(len);
}
int32_t NSPV_rwntzsresp(int32_t rwflag,uint8_t *serialized,struct NSPV_ntzsresp *ptr)
{
int32_t len = 0;
len += NSPV_rwntz(rwflag,&serialized[len],&ptr->prevntz);
len += NSPV_rwntz(rwflag,&serialized[len],&ptr->nextntz);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->reqheight),&ptr->reqheight);
return(len);
}
void NSPV_ntzsresp_copy(struct NSPV_ntzsresp *dest,struct NSPV_ntzsresp *ptr)
{
*dest = *ptr;
}
void NSPV_ntzsresp_purge(struct NSPV_ntzsresp *ptr)
{
if ( ptr != 0 )
memset(ptr,0,sizeof(*ptr));
}
int32_t NSPV_rwinforesp(int32_t rwflag,uint8_t *serialized,struct NSPV_inforesp *ptr)
{
int32_t len = 0;
len += NSPV_rwntz(rwflag,&serialized[len],&ptr->notarization);
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->blockhash),(uint8_t *)&ptr->blockhash);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->height),&ptr->height);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->hdrheight),&ptr->hdrheight);
len += NSPV_rwequihdr(rwflag,&serialized[len],&ptr->H);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->version),&ptr->version);
//fprintf(stderr,"getinfo rwlen.%d\n",len);
return(len);
}
void NSPV_inforesp_purge(struct NSPV_inforesp *ptr)
{
if ( ptr != 0 )
memset(ptr,0,sizeof(*ptr));
}
int32_t NSPV_rwtxproof(int32_t rwflag,uint8_t *serialized,struct NSPV_txproof *ptr)
{
int32_t len = 0;
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->txid),(uint8_t *)&ptr->txid);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->unspentvalue),&ptr->unspentvalue);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->height),&ptr->height);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->vout),&ptr->vout);
len += iguana_rwuint8vec(rwflag,&serialized[len],&ptr->txlen,&ptr->tx);
len += iguana_rwuint8vec(rwflag,&serialized[len],&ptr->txprooflen,&ptr->txproof);
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->hashblock),(uint8_t *)&ptr->hashblock);
return(len);
}
void NSPV_txproof_copy(struct NSPV_txproof *dest,struct NSPV_txproof *ptr)
{
*dest = *ptr;
if ( ptr->tx != 0 && ptr->txlen < MAX_TX_SIZE_AFTER_SAPLING )
{
dest->tx = (uint8_t *)malloc(ptr->txlen);
memcpy(dest->tx,ptr->tx,ptr->txlen);
}
if ( ptr->txproof != 0 )
{
dest->txproof = (uint8_t *)malloc(ptr->txprooflen);
memcpy(dest->txproof,ptr->txproof,ptr->txprooflen);
}
}
void NSPV_txproof_purge(struct NSPV_txproof *ptr)
{
if ( ptr != 0 )
{
if ( ptr->tx != 0 )
free(ptr->tx);
if ( ptr->txproof != 0 )
free(ptr->txproof);
memset(ptr,0,sizeof(*ptr));
}
}
int32_t NSPV_rwntzproofshared(int32_t rwflag,uint8_t *serialized,struct NSPV_ntzproofshared *ptr)
{
int32_t len = 0;
len += iguana_rwequihdrvec(rwflag,&serialized[len],&ptr->numhdrs,&ptr->hdrs);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->prevht),&ptr->prevht);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->nextht),&ptr->nextht);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->pad32),&ptr->pad32);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->pad16),&ptr->pad16);
//fprintf(stderr,"rwcommon prev.%d next.%d\n",ptr->prevht,ptr->nextht);
return(len);
}
int32_t NSPV_rwntzsproofresp(int32_t rwflag,uint8_t *serialized,struct NSPV_ntzsproofresp *ptr)
{
int32_t len = 0;
len += NSPV_rwntzproofshared(rwflag,&serialized[len],&ptr->common);
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->prevtxid),(uint8_t *)&ptr->prevtxid);
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->nexttxid),(uint8_t *)&ptr->nexttxid);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->prevtxidht),&ptr->prevtxidht);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->nexttxidht),&ptr->nexttxidht);
len += iguana_rwuint8vec(rwflag,&serialized[len],&ptr->prevtxlen,&ptr->prevntz);
len += iguana_rwuint8vec(rwflag,&serialized[len],&ptr->nexttxlen,&ptr->nextntz);
//fprintf(stderr,"retlen.%d\n",len);
return(len);
}
void NSPV_ntzsproofresp_copy(struct NSPV_ntzsproofresp *dest,struct NSPV_ntzsproofresp *ptr)
{
*dest = *ptr;
if ( ptr->common.hdrs != 0 )
{
dest->common.hdrs = (struct NSPV_equihdr *)malloc(ptr->common.numhdrs * sizeof(*ptr->common.hdrs));
memcpy(dest->common.hdrs,ptr->common.hdrs,ptr->common.numhdrs * sizeof(*ptr->common.hdrs));
}
if ( ptr->prevntz != 0 )
{
dest->prevntz = (uint8_t *)malloc(ptr->prevtxlen);
memcpy(dest->prevntz,ptr->prevntz,ptr->prevtxlen);
}
if ( ptr->nextntz != 0 )
{
dest->nextntz = (uint8_t *)malloc(ptr->nexttxlen);
memcpy(dest->nextntz,ptr->nextntz,ptr->nexttxlen);
}
}
void NSPV_ntzsproofresp_purge(struct NSPV_ntzsproofresp *ptr)
{
if ( ptr != 0 )
{
if ( ptr->common.hdrs != 0 )
free(ptr->common.hdrs);
if ( ptr->prevntz != 0 )
free(ptr->prevntz);
if ( ptr->nextntz != 0 )
free(ptr->nextntz);
memset(ptr,0,sizeof(*ptr));
}
}
int32_t NSPV_rwspentinfo(int32_t rwflag,uint8_t *serialized,struct NSPV_spentinfo *ptr) // check mempool
{
int32_t len = 0;
len += NSPV_rwtxproof(rwflag,&serialized[len],&ptr->spent);
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->txid),(uint8_t *)&ptr->txid);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->vout),&ptr->vout);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->spentvini),&ptr->spentvini);
return(len);
}
void NSPV_spentinfo_purge(struct NSPV_spentinfo *ptr)
{
if ( ptr != 0 )
{
NSPV_txproof_purge(&ptr->spent);
memset(ptr,0,sizeof(*ptr));
}
}
int32_t NSPV_rwbroadcastresp(int32_t rwflag,uint8_t *serialized,struct NSPV_broadcastresp *ptr)
{
int32_t len = 0;
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(ptr->txid),(uint8_t *)&ptr->txid);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->retcode),&ptr->retcode);
return(len);
}
void NSPV_broadcast_purge(struct NSPV_broadcastresp *ptr)
{
if ( ptr != 0 )
memset(ptr,0,sizeof(*ptr));
}
// useful utility functions
uint256 NSPV_doublesha256(uint8_t *data,int32_t datalen)
{
bits256 _hash; uint256 hash; int32_t i;
_hash = bits256_doublesha256(0,data,datalen);
for (i=0; i<32; i++)
((uint8_t *)&hash)[i] = _hash.bytes[31 - i];
return(hash);
}
uint256 NSPV_hdrhash(struct NSPV_equihdr *hdr)
{
CBlockHeader block;
block.nVersion = hdr->nVersion;
block.hashPrevBlock = hdr->hashPrevBlock;
block.hashMerkleRoot = hdr->hashMerkleRoot;
block.hashFinalSaplingRoot = hdr->hashFinalSaplingRoot;
block.nTime = hdr->nTime;
block.nBits = hdr->nBits;
block.nNonce = hdr->nNonce;
block.nSolution.resize(sizeof(hdr->nSolution));
memcpy(&block.nSolution[0],hdr->nSolution,sizeof(hdr->nSolution));
return(block.GetHash());
}
int32_t NSPV_txextract(CTransaction &tx,uint8_t *data,int32_t datalen)
{
std::vector<uint8_t> rawdata;
if ( datalen < MAX_TX_SIZE_AFTER_SAPLING )
{
rawdata.resize(datalen);
memcpy(&rawdata[0],data,datalen);
if ( DecodeHexTx(tx,HexStr(rawdata)) != 0 )
return(0);
}
return(-1);
}
bool NSPV_SignTx(CMutableTransaction &mtx,int32_t vini,int64_t utxovalue,const CScript scriptPubKey,uint32_t nTime);
int32_t NSPV_fastnotariescount(CTransaction tx,uint8_t elected[64][33],uint32_t nTime)
{
CPubKey pubkeys[64]; uint8_t sig[512]; CScript scriptPubKeys[64]; CMutableTransaction mtx(tx); int32_t vini,j,siglen,retval; uint64_t mask = 0; char *str; std::vector<std::vector<unsigned char>> vData;
for (j=0; j<64; j++)
{
pubkeys[j] = buf2pk(elected[j]);
scriptPubKeys[j] = (CScript() << ParseHex(HexStr(pubkeys[j])) << OP_CHECKSIG);
//fprintf(stderr,"%d %s\n",j,HexStr(pubkeys[j]).c_str());
}
fprintf(stderr,"txid %s\n",tx.GetHash().GetHex().c_str());
//for (vini=0; vini<tx.vin.size(); vini++)
// mtx.vin[vini].scriptSig.resize(0);
for (vini=0; vini<tx.vin.size(); vini++)
{
CScript::const_iterator pc = tx.vin[vini].scriptSig.begin();
if ( tx.vin[vini].scriptSig.GetPushedData(pc,vData) != 0 )
{
vData[0].pop_back();
for (j=0; j<64; j++)
{
if ( ((1LL << j) & mask) != 0 )
continue;
char coinaddr[64]; Getscriptaddress(coinaddr,scriptPubKeys[j]);
NSPV_SignTx(mtx,vini,10000,scriptPubKeys[j],nTime); // sets SIG_TXHASH
//fprintf(stderr,"%s ",SIG_TXHASH.GetHex().c_str());
if ( (retval= pubkeys[j].Verify(SIG_TXHASH,vData[0])) != 0 )
{
//fprintf(stderr,"(vini.%d %s.%d) ",vini,coinaddr,retval);
mask |= (1LL << j);
break;
}
}
//fprintf(stderr," vini.%d verified %llx\n",vini,(long long)mask);
}
}
return(bitweight(mask));
}
/*
NSPV_notariescount is the slowest process during full validation as it requires looking up 13 transactions.
one way that would be 10000x faster would be to bruteforce validate the signatures in each vin, against all 64 pubkeys! for a valid tx, that is on average 13*32 secp256k1/sapling verify operations, which is much faster than even a single network request.
Unfortunately, due to the complexity of calculating the hash to sign for a tx, this bruteforcing would require determining what type of signature method and having sapling vs legacy methods of calculating the txhash.
It could be that the fullnode side could calculate this and send it back to the superlite side as any hash that would validate 13 different ways has to be the valid txhash.
However, since the vouts being spent by the notaries are highly constrained p2pk vouts, the txhash can be deduced if a specific notary pubkey is indeed the signer
*/
int32_t NSPV_notariescount(CTransaction tx,uint8_t elected[64][33])
{
uint8_t *script; CTransaction vintx; int64_t rewardsum = 0; int32_t i,j,utxovout,scriptlen,numsigs = 0,txheight,currentheight; uint256 hashBlock;
for (i=0; i<tx.vin.size(); i++)
{
utxovout = tx.vin[i].prevout.n;
if ( NSPV_gettransaction(1,utxovout,tx.vin[i].prevout.hash,0,vintx,hashBlock,txheight,currentheight,-1,0,rewardsum) != 0 )
{
fprintf(stderr,"error getting %s/v%d\n",tx.vin[i].prevout.hash.GetHex().c_str(),utxovout);
return(numsigs);
}
if ( utxovout < vintx.vout.size() )
{
script = (uint8_t *)&vintx.vout[utxovout].scriptPubKey[0];
if ( (scriptlen= vintx.vout[utxovout].scriptPubKey.size()) == 35 )
{
for (j=0; j<64; j++)
if ( memcmp(&script[1],elected[j],33) == 0 )
{
numsigs++;
break;
}
} else fprintf(stderr,"invalid scriptlen.%d\n",scriptlen);
} else fprintf(stderr,"invalid utxovout.%d vs %d\n",utxovout,(int32_t)vintx.vout.size());
}
return(numsigs);
}
uint256 NSPV_opretextract(int32_t *heightp,uint256 *blockhashp,char *symbol,std::vector<uint8_t> opret,uint256 txid)
{
uint256 desttxid; int32_t i;
iguana_rwnum(0,&opret[32],sizeof(*heightp),heightp);
for (i=0; i<32; i++)
((uint8_t *)blockhashp)[i] = opret[i];
for (i=0; i<32; i++)
((uint8_t *)&desttxid)[i] = opret[4 + 32 + i];
if ( 0 && *heightp != 2690 )
fprintf(stderr," ntzht.%d %s <- txid.%s size.%d\n",*heightp,(*blockhashp).GetHex().c_str(),(txid).GetHex().c_str(),(int32_t)opret.size());
return(desttxid);
}
int32_t NSPV_notarizationextract(int32_t verifyntz,int32_t *ntzheightp,uint256 *blockhashp,uint256 *desttxidp,CTransaction tx)
{
int32_t numsigs=0; uint8_t elected[64][33]; char *symbol; std::vector<uint8_t> opret; uint32_t nTime;
if ( tx.vout.size() >= 2 )
{
symbol = (ASSETCHAINS_SYMBOL[0] == 0) ? (char *)"KMD" : ASSETCHAINS_SYMBOL;
GetOpReturnData(tx.vout[1].scriptPubKey,opret);
if ( opret.size() >= 32*2+4 )
{
//sleep(1); // needed to avoid no pnodes error
*desttxidp = NSPV_opretextract(ntzheightp,blockhashp,symbol,opret,tx.GetHash());
nTime = NSPV_blocktime(*ntzheightp);
komodo_notaries(elected,*ntzheightp,nTime);
if ( verifyntz != 0 && (numsigs= NSPV_fastnotariescount(tx,elected,nTime)) < 12 )
{
fprintf(stderr,"numsigs.%d error\n",numsigs);
return(-3);
}
return(0);
}
else
{
fprintf(stderr,"opretsize.%d error\n",(int32_t)opret.size());
return(-2);
}
} else return(-1);
}
#endif // KOMODO_NSPV_H
+181
View File
@@ -0,0 +1,181 @@
/******************************************************************************
* 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. *
* *
******************************************************************************/
#ifndef KOMODO_NSPV_DEFSH
#define KOMODO_NSPV_DEFSH
#define NSPV_PROTOCOL_VERSION 0x00000002
#define NSPV_POLLITERS 200
#define NSPV_POLLMICROS 50000
#define NSPV_MAXVINS 64
#define NSPV_AUTOLOGOUT 777
#define NSPV_BRANCHID 0x76b809bb
// nSPV defines and struct definitions with serialization and purge functions
#define NSPV_INFO 0x00
#define NSPV_INFORESP 0x01
#define NSPV_UTXOS 0x02
#define NSPV_UTXOSRESP 0x03
#define NSPV_NTZS 0x04
#define NSPV_NTZSRESP 0x05
#define NSPV_NTZSPROOF 0x06
#define NSPV_NTZSPROOFRESP 0x07
#define NSPV_TXPROOF 0x08
#define NSPV_TXPROOFRESP 0x09
#define NSPV_SPENTINFO 0x0a
#define NSPV_SPENTINFORESP 0x0b
#define NSPV_BROADCAST 0x0c
#define NSPV_BROADCASTRESP 0x0d
#define NSPV_TXIDS 0x0e
#define NSPV_TXIDSRESP 0x0f
#define NSPV_MEMPOOL 0x10
#define NSPV_MEMPOOLRESP 0x11
#define NSPV_MEMPOOL_ALL 0
#define NSPV_MEMPOOL_ADDRESS 1
#define NSPV_MEMPOOL_ISSPENT 2
#define NSPV_MEMPOOL_INMEMPOOL 3
#define NSPV_MEMPOOL_CCEVALCODE 4
int32_t NSPV_gettransaction(int32_t skipvalidation,int32_t vout,uint256 txid,int32_t height,CTransaction &tx,uint256 &hashblock,int32_t &txheight,int32_t &currentheight,int64_t extradata,uint32_t tiptime,int64_t &rewardsum);
UniValue NSPV_spend(char *srcaddr,char *destaddr,int64_t satoshis);
extern uint256 SIG_TXHASH;
uint32_t NSPV_blocktime(int32_t hdrheight);
struct NSPV_equihdr
{
int32_t nVersion;
uint256 hashPrevBlock;
uint256 hashMerkleRoot;
uint256 hashFinalSaplingRoot;
uint32_t nTime;
uint32_t nBits;
uint256 nNonce;
uint8_t nSolution[1344];
};
struct NSPV_utxoresp
{
uint256 txid;
int64_t satoshis,extradata;
int32_t vout,height;
};
struct NSPV_utxosresp
{
struct NSPV_utxoresp *utxos;
char coinaddr[64];
int64_t total,interest;
int32_t nodeheight,skipcount,filter;
uint16_t numutxos,CCflag;
};
struct NSPV_txidresp
{
uint256 txid;
int64_t satoshis;
int32_t vout,height;
};
struct NSPV_txidsresp
{
struct NSPV_txidresp *txids;
char coinaddr[64];
int32_t nodeheight,skipcount,filter;
uint16_t numtxids,CCflag;
};
struct NSPV_mempoolresp
{
uint256 *txids;
char coinaddr[64];
uint256 txid;
int32_t nodeheight,vout,vindex;
uint16_t numtxids; uint8_t CCflag,funcid;
};
struct NSPV_ntz
{
uint256 blockhash,txid,othertxid;
int32_t height,txidheight;
uint32_t timestamp;
};
struct NSPV_ntzsresp
{
struct NSPV_ntz prevntz,nextntz;
int32_t reqheight;
};
struct NSPV_inforesp
{
struct NSPV_ntz notarization;
uint256 blockhash;
int32_t height,hdrheight;
struct NSPV_equihdr H;
uint32_t version;
};
struct NSPV_txproof
{
uint256 txid;
int64_t unspentvalue;
int32_t height,vout,txlen,txprooflen;
uint8_t *tx,*txproof;
uint256 hashblock;
};
struct NSPV_ntzproofshared
{
struct NSPV_equihdr *hdrs;
int32_t prevht,nextht,pad32;
uint16_t numhdrs,pad16;
};
struct NSPV_ntzsproofresp
{
struct NSPV_ntzproofshared common;
uint256 prevtxid,nexttxid;
int32_t prevtxidht,nexttxidht,prevtxlen,nexttxlen;
uint8_t *prevntz,*nextntz;
};
struct NSPV_MMRproof
{
struct NSPV_ntzproofshared common;
// tbd
};
struct NSPV_spentinfo
{
struct NSPV_txproof spent;
uint256 txid;
int32_t vout,spentvini;
};
struct NSPV_broadcastresp
{
uint256 txid;
int32_t retcode;
};
struct NSPV_CCmtxinfo
{
struct NSPV_utxosresp U;
struct NSPV_utxoresp used[NSPV_MAXVINS];
};
#endif // KOMODO_NSPV_DEFSH
+805
View File
@@ -0,0 +1,805 @@
/******************************************************************************
* 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. *
* *
******************************************************************************/
#ifndef KOMODO_NSPVFULLNODE_H
#define KOMODO_NSPVFULLNODE_H
// NSPV_get... functions need to return the exact serialized length, which is the size of the structure minus size of pointers, plus size of allocated data
#include "notarisationdb.h"
struct NSPV_ntzargs
{
uint256 txid,desttxid,blockhash;
int32_t txidht,ntzheight;
};
int32_t NSPV_notarization_find(struct NSPV_ntzargs *args,int32_t height,int32_t dir)
{
int32_t ntzheight = 0; uint256 hashBlock; CTransaction tx; Notarisation nota; char *symbol; std::vector<uint8_t> opret;
symbol = (ASSETCHAINS_SYMBOL[0] == 0) ? (char *)"KMD" : ASSETCHAINS_SYMBOL;
memset(args,0,sizeof(*args));
if ( dir > 0 )
height += 10;
if ( (args->txidht= ScanNotarisationsDB(height,symbol,1440,nota)) == 0 )
return(-1);
args->txid = nota.first;
if ( !GetTransaction(args->txid,tx,hashBlock,false) || tx.vout.size() < 2 )
return(-2);
GetOpReturnData(tx.vout[1].scriptPubKey,opret);
if ( opret.size() >= 32*2+4 )
args->desttxid = NSPV_opretextract(&args->ntzheight,&args->blockhash,symbol,opret,args->txid);
return(args->ntzheight);
}
int32_t NSPV_notarized_bracket(struct NSPV_ntzargs *prev,struct NSPV_ntzargs *next,int32_t height)
{
uint256 bhash; int32_t txidht,ntzht,nextht,i=0;
memset(prev,0,sizeof(*prev));
memset(next,0,sizeof(*next));
if ( (ntzht= NSPV_notarization_find(prev,height,-1)) < 0 || ntzht > height || ntzht == 0 )
return(-1);
txidht = height+1;
while ( (ntzht= NSPV_notarization_find(next,txidht,1)) < height )
{
nextht = next->txidht + 10*i;
//fprintf(stderr,"found forward ntz, but ntzht.%d vs height.%d, txidht.%d -> nextht.%d\n",next->ntzheight,height,txidht,nextht);
memset(next,0,sizeof(*next));
txidht = nextht;
if ( ntzht <= 0 )
break;
if ( i++ > 10 )
break;
}
return(0);
}
int32_t NSPV_ntzextract(struct NSPV_ntz *ptr,uint256 ntztxid,int32_t txidht,uint256 desttxid,int32_t ntzheight)
{
CBlockIndex *pindex;
ptr->blockhash = *chainActive[ntzheight]->phashBlock;
ptr->height = ntzheight;
ptr->txidheight = txidht;
ptr->othertxid = desttxid;
ptr->txid = ntztxid;
if ( (pindex= komodo_chainactive(ptr->txidheight)) != 0 )
ptr->timestamp = pindex->nTime;
return(0);
}
int32_t NSPV_getntzsresp(struct NSPV_ntzsresp *ptr,int32_t origreqheight)
{
struct NSPV_ntzargs prev,next; int32_t reqheight = origreqheight;
if ( reqheight < chainActive.LastTip()->GetHeight() )
reqheight++;
if ( NSPV_notarized_bracket(&prev,&next,reqheight) == 0 )
{
if ( prev.ntzheight != 0 )
{
ptr->reqheight = origreqheight;
if ( NSPV_ntzextract(&ptr->prevntz,prev.txid,prev.txidht,prev.desttxid,prev.ntzheight) < 0 )
return(-1);
}
if ( next.ntzheight != 0 )
{
if ( NSPV_ntzextract(&ptr->nextntz,next.txid,next.txidht,next.desttxid,next.ntzheight) < 0 )
return(-1);
}
}
return(sizeof(*ptr));
}
int32_t NSPV_setequihdr(struct NSPV_equihdr *hdr,int32_t height)
{
CBlockIndex *pindex;
if ( (pindex= komodo_chainactive(height)) != 0 )
{
hdr->nVersion = pindex->nVersion;
if ( pindex->pprev == 0 )
return(-1);
hdr->hashPrevBlock = pindex->pprev->GetBlockHash();
hdr->hashMerkleRoot = pindex->hashMerkleRoot;
hdr->hashFinalSaplingRoot = pindex->hashFinalSaplingRoot;
hdr->nTime = pindex->nTime;
hdr->nBits = pindex->nBits;
hdr->nNonce = pindex->nNonce;
memcpy(hdr->nSolution,&pindex->nSolution[0],sizeof(hdr->nSolution));
return(sizeof(*hdr));
}
return(-1);
}
int32_t NSPV_getinfo(struct NSPV_inforesp *ptr,int32_t reqheight)
{
int32_t prevMoMheight,len = 0; CBlockIndex *pindex, *pindex2; struct NSPV_ntzsresp pair;
if ( (pindex= chainActive.LastTip()) != 0 )
{
ptr->height = pindex->GetHeight();
ptr->blockhash = pindex->GetBlockHash();
memset(&pair,0,sizeof(pair));
if ( NSPV_getntzsresp(&pair,ptr->height-1) < 0 )
return(-1);
ptr->notarization = pair.prevntz;
if ( (pindex2= komodo_chainactive(ptr->notarization.txidheight)) != 0 )
ptr->notarization.timestamp = pindex->nTime;
//fprintf(stderr, "timestamp.%i\n", ptr->notarization.timestamp );
if ( reqheight == 0 )
reqheight = ptr->height;
ptr->hdrheight = reqheight;
ptr->version = NSPV_PROTOCOL_VERSION;
if ( NSPV_setequihdr(&ptr->H,reqheight) < 0 )
return(-1);
return(sizeof(*ptr));
} else return(-1);
}
int32_t NSPV_getaddressutxos(struct NSPV_utxosresp *ptr,char *coinaddr,bool isCC,int32_t skipcount,uint32_t filter)
{
int64_t total = 0,interest=0; uint32_t locktime; int32_t ind=0,tipheight,maxlen,txheight,n = 0,len = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
SetCCunspents(unspentOutputs,coinaddr,isCC);
maxlen = MAX_BLOCK_SIZE(tipheight) - 512;
maxlen /= sizeof(*ptr->utxos);
strncpy(ptr->coinaddr,coinaddr,sizeof(ptr->coinaddr)-1);
ptr->CCflag = isCC;
ptr->filter = filter;
if ( skipcount < 0 )
skipcount = 0;
if ( (ptr->numutxos= (int32_t)unspentOutputs.size()) >= 0 && ptr->numutxos < maxlen )
{
tipheight = chainActive.LastTip()->GetHeight();
ptr->nodeheight = tipheight;
if ( skipcount >= ptr->numutxos )
skipcount = ptr->numutxos-1;
ptr->skipcount = skipcount;
if ( ptr->numutxos-skipcount > 0 )
{
ptr->utxos = (struct NSPV_utxoresp *)calloc(ptr->numutxos-skipcount,sizeof(*ptr->utxos));
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
// if gettxout is != null to handle mempool
{
if ( n >= skipcount )
{
ptr->utxos[ind].txid = it->first.txhash;
ptr->utxos[ind].vout = (int32_t)it->first.index;
ptr->utxos[ind].satoshis = it->second.satoshis;
ptr->utxos[ind].height = it->second.blockHeight;
if ( ASSETCHAINS_SYMBOL[0] == 0 && it->second.satoshis >= 10*COIN )
{
ptr->utxos[n].extradata = komodo_accrued_interest(&txheight,&locktime,ptr->utxos[ind].txid,ptr->utxos[ind].vout,ptr->utxos[ind].height,ptr->utxos[ind].satoshis,tipheight);
interest += ptr->utxos[ind].extradata;
}
ind++;
total += it->second.satoshis;
}
n++;
}
}
}
ptr->numutxos = ind;
if ( len < maxlen )
{
len = (int32_t)(sizeof(*ptr) + sizeof(*ptr->utxos)*ptr->numutxos - sizeof(ptr->utxos));
//fprintf(stderr,"getaddressutxos for %s -> n.%d:%d total %.8f interest %.8f len.%d\n",coinaddr,n,ptr->numutxos,dstr(total),dstr(interest),len);
ptr->total = total;
ptr->interest = interest;
return(len);
}
}
if ( ptr->utxos != 0 )
free(ptr->utxos);
memset(ptr,0,sizeof(*ptr));
return(0);
}
int32_t NSPV_getaddresstxids(struct NSPV_txidsresp *ptr,char *coinaddr,bool isCC,int32_t skipcount,uint32_t filter)
{
int32_t maxlen,txheight,ind=0,n = 0,len = 0;
std::vector<std::pair<CAddressIndexKey, CAmount> > txids;
SetCCtxids(txids,coinaddr,isCC);
ptr->nodeheight = chainActive.LastTip()->GetHeight();
maxlen = MAX_BLOCK_SIZE(ptr->nodeheight) - 512;
maxlen /= sizeof(*ptr->txids);
strncpy(ptr->coinaddr,coinaddr,sizeof(ptr->coinaddr)-1);
ptr->CCflag = isCC;
ptr->filter = filter;
if ( skipcount < 0 )
skipcount = 0;
if ( (ptr->numtxids= (int32_t)txids.size()) >= 0 && ptr->numtxids < maxlen )
{
if ( skipcount >= ptr->numtxids )
skipcount = ptr->numtxids-1;
ptr->skipcount = skipcount;
if ( ptr->numtxids-skipcount > 0 )
{
ptr->txids = (struct NSPV_txidresp *)calloc(ptr->numtxids-skipcount,sizeof(*ptr->txids));
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=txids.begin(); it!=txids.end(); it++)
{
if ( n >= skipcount )
{
ptr->txids[ind].txid = it->first.txhash;
ptr->txids[ind].vout = (int32_t)it->first.index;
ptr->txids[ind].satoshis = (int64_t)it->second;
ptr->txids[ind].height = (int64_t)it->first.blockHeight;
ind++;
}
n++;
}
}
ptr->numtxids = ind;
len = (int32_t)(sizeof(*ptr) + sizeof(*ptr->txids)*ptr->numtxids - sizeof(ptr->txids));
return(len);
}
if ( ptr->txids != 0 )
free(ptr->txids);
memset(ptr,0,sizeof(*ptr));
return(0);
}
int32_t NSPV_mempoolfuncs(int32_t *vindexp,std::vector<uint256> &txids,char *coinaddr,bool isCC,uint8_t funcid,uint256 txid,int32_t vout)
{
int32_t num = 0,vini = 0,vouti = 0; uint8_t evalcode=0,func=0; std::vector<uint8_t> vopret; char destaddr[64];
*vindexp = -1;
if ( mempool.size() == 0 )
return(0);
if ( funcid == NSPV_MEMPOOL_CCEVALCODE )
{
isCC = true;
evalcode = vout & 0xff;
func = (vout >> 8) & 0xff;
}
LOCK(mempool.cs);
BOOST_FOREACH(const CTxMemPoolEntry &e,mempool.mapTx)
{
const CTransaction &tx = e.GetTx();
const uint256 &hash = tx.GetHash();
if ( funcid == NSPV_MEMPOOL_ALL )
{
txids.push_back(hash);
num++;
continue;
}
else if ( funcid == NSPV_MEMPOOL_INMEMPOOL )
{
if ( hash == txid )
{
txids.push_back(hash);
return(++num);
}
continue;
}
else if ( funcid == NSPV_MEMPOOL_CCEVALCODE )
{
if ( tx.vout.size() > 1 )
{
CScript scriptPubKey = tx.vout[tx.vout.size()-1].scriptPubKey;
if ( GetOpReturnData(scriptPubKey,vopret) != 0 )
{
if ( vopret[0] == evalcode && vopret[1] == func )
{
txids.push_back(hash);
num++;
}
}
}
continue;
}
if ( funcid == NSPV_MEMPOOL_ISSPENT )
{
BOOST_FOREACH(const CTxIn &txin,tx.vin)
{
//fprintf(stderr,"%s/v%d ",uint256_str(str,txin.prevout.hash),txin.prevout.n);
if ( txin.prevout.n == vout && txin.prevout.hash == txid )
{
txids.push_back(hash);
*vindexp = vini;
return(++num);
}
vini++;
}
}
else if ( funcid == NSPV_MEMPOOL_ADDRESS )
{
BOOST_FOREACH(const CTxOut &txout,tx.vout)
{
if ( txout.scriptPubKey.IsPayToCryptoCondition() == isCC )
{
Getscriptaddress(destaddr,txout.scriptPubKey);
if ( strcmp(destaddr,coinaddr) == 0 )
{
txids.push_back(hash);
*vindexp = vouti;
num++;
}
}
vouti++;
}
}
//fprintf(stderr,"are vins for %s\n",uint256_str(str,hash));
}
return(num);
}
int32_t NSPV_mempooltxids(struct NSPV_mempoolresp *ptr,char *coinaddr,uint8_t isCC,uint8_t funcid,uint256 txid,int32_t vout)
{
std::vector<uint256> txids; uint256 tmp,tmpdest; int32_t i,len = 0;
ptr->nodeheight = chainActive.LastTip()->GetHeight();
strncpy(ptr->coinaddr,coinaddr,sizeof(ptr->coinaddr)-1);
ptr->CCflag = isCC;
ptr->txid = txid;
ptr->vout = vout;
ptr->funcid = funcid;
if ( NSPV_mempoolfuncs(&ptr->vindex,txids,coinaddr,isCC,funcid,txid,vout) >= 0 )
{
if ( (ptr->numtxids= (int32_t)txids.size()) >= 0 )
{
if ( ptr->numtxids > 0 )
{
ptr->txids = (uint256 *)calloc(ptr->numtxids,sizeof(*ptr->txids));
for (i=0; i<ptr->numtxids; i++)
{
tmp = txids[i];
iguana_rwbignum(0,(uint8_t *)&tmp,sizeof(*ptr->txids),(uint8_t *)&ptr->txids[i]);
}
}
len = (int32_t)(sizeof(*ptr) + sizeof(*ptr->txids)*ptr->numtxids - sizeof(ptr->txids));
return(len);
}
}
if ( ptr->txids != 0 )
free(ptr->txids);
memset(ptr,0,sizeof(*ptr));
return(0);
}
uint8_t *NSPV_getrawtx(CTransaction &tx,uint256 &hashBlock,int32_t *txlenp,uint256 txid)
{
uint8_t *rawtx = 0;
*txlenp = 0;
{
if (!GetTransaction(txid, tx, hashBlock, false))
{
//fprintf(stderr,"error getting transaction %s\n",txid.GetHex().c_str());
return(0);
}
string strHex = EncodeHexTx(tx);
*txlenp = (int32_t)strHex.size() >> 1;
if ( *txlenp > 0 )
{
rawtx = (uint8_t *)calloc(1,*txlenp);
decode_hex(rawtx,*txlenp,(char *)strHex.c_str());
}
}
return(rawtx);
}
int32_t NSPV_sendrawtransaction(struct NSPV_broadcastresp *ptr,uint8_t *data,int32_t n)
{
CTransaction tx;
ptr->retcode = 0;
if ( NSPV_txextract(tx,data,n) == 0 )
{
//LOCK(cs_main);
ptr->txid = tx.GetHash();
//fprintf(stderr,"try to addmempool transaction %s\n",ptr->txid.GetHex().c_str());
if ( myAddtomempool(tx) != 0 )
{
ptr->retcode = 1;
//int32_t i;
//for (i=0; i<n; i++)
// fprintf(stderr,"%02x",data[i]);
fprintf(stderr," relay transaction %s retcode.%d\n",ptr->txid.GetHex().c_str(),ptr->retcode);
RelayTransaction(tx);
} else ptr->retcode = -3;
} else ptr->retcode = -1;
return(sizeof(*ptr));
}
int32_t NSPV_gettxproof(struct NSPV_txproof *ptr,int32_t vout,uint256 txid,int32_t height)
{
int32_t flag = 0,len = 0; CTransaction _tx; uint256 hashBlock; CBlock block; CBlockIndex *pindex;
if ( (ptr->tx= NSPV_getrawtx(_tx,hashBlock,&ptr->txlen,txid)) == 0 )
return(-1);
ptr->txid = txid;
ptr->vout = vout;
ptr->hashblock = hashBlock;
if ( height == 0 )
ptr->height = komodo_blockheight(hashBlock);
else
{
ptr->height = height;
if ((pindex= komodo_chainactive(height)) != 0 && komodo_blockload(block,pindex) == 0 )
{
BOOST_FOREACH(const CTransaction&tx, block.vtx)
{
if ( tx.GetHash() == txid )
{
flag = 1;
break;
}
}
if ( flag != 0 )
{
set<uint256> setTxids;
CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION);
setTxids.insert(txid);
CMerkleBlock mb(block, setTxids);
ssMB << mb;
std::vector<uint8_t> proof(ssMB.begin(), ssMB.end());
ptr->txprooflen = (int32_t)proof.size();
//fprintf(stderr,"%s txproof.(%s)\n",txid.GetHex().c_str(),HexStr(proof).c_str());
if ( ptr->txprooflen > 0 )
{
ptr->txproof = (uint8_t *)calloc(1,ptr->txprooflen);
memcpy(ptr->txproof,&proof[0],ptr->txprooflen);
}
//fprintf(stderr,"gettxproof slen.%d\n",(int32_t)(sizeof(*ptr) - sizeof(ptr->tx) - sizeof(ptr->txproof) + ptr->txlen + ptr->txprooflen));
}
}
}
ptr->unspentvalue = CCgettxout(txid,vout,1,1);
return(sizeof(*ptr) - sizeof(ptr->tx) - sizeof(ptr->txproof) + ptr->txlen + ptr->txprooflen);
}
int32_t NSPV_getntzsproofresp(struct NSPV_ntzsproofresp *ptr,uint256 prevntztxid,uint256 nextntztxid)
{
int32_t i; uint256 hashBlock,bhash0,bhash1,desttxid0,desttxid1; CTransaction tx;
ptr->prevtxid = prevntztxid;
ptr->prevntz = NSPV_getrawtx(tx,hashBlock,&ptr->prevtxlen,ptr->prevtxid);
ptr->prevtxidht = komodo_blockheight(hashBlock);
if ( NSPV_notarizationextract(0,&ptr->common.prevht,&bhash0,&desttxid0,tx) < 0 )
return(-2);
else if ( komodo_blockheight(bhash0) != ptr->common.prevht )
return(-3);
ptr->nexttxid = nextntztxid;
ptr->nextntz = NSPV_getrawtx(tx,hashBlock,&ptr->nexttxlen,ptr->nexttxid);
ptr->nexttxidht = komodo_blockheight(hashBlock);
if ( NSPV_notarizationextract(0,&ptr->common.nextht,&bhash1,&desttxid1,tx) < 0 )
return(-5);
else if ( komodo_blockheight(bhash1) != ptr->common.nextht )
return(-6);
else if ( ptr->common.prevht > ptr->common.nextht || (ptr->common.nextht - ptr->common.prevht) > 1440 )
{
fprintf(stderr,"illegal prevht.%d nextht.%d\n",ptr->common.prevht,ptr->common.nextht);
return(-7);
}
//fprintf(stderr,"%s -> prevht.%d, %s -> nexht.%d\n",ptr->prevtxid.GetHex().c_str(),ptr->common.prevht,ptr->nexttxid.GetHex().c_str(),ptr->common.nextht);
ptr->common.numhdrs = (ptr->common.nextht - ptr->common.prevht + 1);
ptr->common.hdrs = (struct NSPV_equihdr *)calloc(ptr->common.numhdrs,sizeof(*ptr->common.hdrs));
//fprintf(stderr,"prev.%d next.%d allocate numhdrs.%d\n",prevht,nextht,ptr->common.numhdrs);
for (i=0; i<ptr->common.numhdrs; i++)
{
//hashBlock = NSPV_hdrhash(&ptr->common.hdrs[i]);
//fprintf(stderr,"hdr[%d] %s\n",prevht+i,hashBlock.GetHex().c_str());
if ( NSPV_setequihdr(&ptr->common.hdrs[i],ptr->common.prevht+i) < 0 )
{
fprintf(stderr,"error setting hdr.%d\n",ptr->common.prevht+i);
free(ptr->common.hdrs);
ptr->common.hdrs = 0;
return(-1);
}
}
//fprintf(stderr,"sizeof ptr %ld, common.%ld lens.%d %d\n",sizeof(*ptr),sizeof(ptr->common),ptr->prevtxlen,ptr->nexttxlen);
return(sizeof(*ptr) + sizeof(*ptr->common.hdrs)*ptr->common.numhdrs - sizeof(ptr->common.hdrs) - sizeof(ptr->prevntz) - sizeof(ptr->nextntz) + ptr->prevtxlen + ptr->nexttxlen);
}
int32_t NSPV_getspentinfo(struct NSPV_spentinfo *ptr,uint256 txid,int32_t vout)
{
int32_t len = 0;
ptr->txid = txid;
ptr->vout = vout;
ptr->spentvini = -1;
len = (int32_t)(sizeof(*ptr) - sizeof(ptr->spent.tx) - sizeof(ptr->spent.txproof));
if ( CCgetspenttxid(ptr->spent.txid,ptr->spentvini,ptr->spent.height,txid,vout) == 0 )
{
if ( NSPV_gettxproof(&ptr->spent,0,ptr->spent.txid,ptr->spent.height) > 0 )
len += ptr->spent.txlen + ptr->spent.txprooflen;
else
{
NSPV_txproof_purge(&ptr->spent);
return(-1);
}
}
return(len);
}
void komodo_nSPVreq(CNode *pfrom,std::vector<uint8_t> request) // received a request
{
int32_t len,slen,ind,reqheight,n; std::vector<uint8_t> response; uint32_t timestamp = (uint32_t)time(NULL);
if ( (len= request.size()) > 0 )
{
if ( (ind= request[0]>>1) >= sizeof(pfrom->prevtimes)/sizeof(*pfrom->prevtimes) )
ind = (int32_t)(sizeof(pfrom->prevtimes)/sizeof(*pfrom->prevtimes)) - 1;
if ( pfrom->prevtimes[ind] > timestamp )
pfrom->prevtimes[ind] = 0;
if ( request[0] == NSPV_INFO ) // info
{
//fprintf(stderr,"check info %u vs %u, ind.%d\n",timestamp,pfrom->prevtimes[ind],ind);
if ( timestamp > pfrom->prevtimes[ind] )
{
struct NSPV_inforesp I;
if ( len == 1+sizeof(reqheight) )
iguana_rwnum(0,&request[1],sizeof(reqheight),&reqheight);
else reqheight = 0;
//fprintf(stderr,"request height.%d\n",reqheight);
memset(&I,0,sizeof(I));
if ( (slen= NSPV_getinfo(&I,reqheight)) > 0 )
{
response.resize(1 + slen);
response[0] = NSPV_INFORESP;
//fprintf(stderr,"slen.%d version.%d\n",slen,I.version);
if ( NSPV_rwinforesp(1,&response[1],&I) == slen )
{
//fprintf(stderr,"send info resp to id %d\n",(int32_t)pfrom->id);
pfrom->PushMessage("nSPV",response);
pfrom->prevtimes[ind] = timestamp;
}
NSPV_inforesp_purge(&I);
}
}
}
else if ( request[0] == NSPV_UTXOS )
{
//fprintf(stderr,"utxos: %u > %u, ind.%d, len.%d\n",timestamp,pfrom->prevtimes[ind],ind,len);
if ( timestamp > pfrom->prevtimes[ind] )
{
struct NSPV_utxosresp U;
if ( len < 64+5 && (request[1] == len-3 || request[1] == len-7 || request[1] == len-11) )
{
int32_t skipcount = 0; char coinaddr[64]; uint8_t filter; uint8_t isCC = 0;
memcpy(coinaddr,&request[2],request[1]);
coinaddr[request[1]] = 0;
if ( request[1] == len-3 )
isCC = (request[len-1] != 0);
else if ( request[1] == len-7 )
{
isCC = (request[len-5] != 0);
iguana_rwnum(0,&request[len-4],sizeof(skipcount),&skipcount);
}
else
{
isCC = (request[len-9] != 0);
iguana_rwnum(0,&request[len-4],sizeof(skipcount),&skipcount);
iguana_rwnum(0,&request[len-4],sizeof(filter),&filter);
}
if ( isCC != 0 )
fprintf(stderr,"utxos %s isCC.%d skipcount.%d filter.%x\n",coinaddr,isCC,skipcount,filter);
memset(&U,0,sizeof(U));
if ( (slen= NSPV_getaddressutxos(&U,coinaddr,isCC,skipcount,filter)) > 0 )
{
response.resize(1 + slen);
response[0] = NSPV_UTXOSRESP;
if ( NSPV_rwutxosresp(1,&response[1],&U) == slen )
{
pfrom->PushMessage("nSPV",response);
pfrom->prevtimes[ind] = timestamp;
}
NSPV_utxosresp_purge(&U);
}
}
}
}
else if ( request[0] == NSPV_TXIDS )
{
if ( timestamp > pfrom->prevtimes[ind] )
{
struct NSPV_txidsresp T;
if ( len < 64+5 && (request[1] == len-3 || request[1] == len-7 || request[1] == len-11) )
{
int32_t skipcount = 0; char coinaddr[64]; uint32_t filter; uint8_t isCC = 0;
memcpy(coinaddr,&request[2],request[1]);
coinaddr[request[1]] = 0;
if ( request[1] == len-3 )
isCC = (request[len-1] != 0);
else if ( request[1] == len-7 )
{
isCC = (request[len-5] != 0);
iguana_rwnum(0,&request[len-4],sizeof(skipcount),&skipcount);
}
else
{
isCC = (request[len-9] != 0);
iguana_rwnum(0,&request[len-4],sizeof(skipcount),&skipcount);
iguana_rwnum(0,&request[len-4],sizeof(filter),&filter);
}
//if ( isCC != 0 )
fprintf(stderr,"txids %s isCC.%d skipcount.%d filter.%d\n",coinaddr,isCC,skipcount,filter);
memset(&T,0,sizeof(T));
if ( (slen= NSPV_getaddresstxids(&T,coinaddr,isCC,skipcount,filter)) > 0 )
{
//fprintf(stderr,"slen.%d\n",slen);
response.resize(1 + slen);
response[0] = NSPV_TXIDSRESP;
if ( NSPV_rwtxidsresp(1,&response[1],&T) == slen )
{
pfrom->PushMessage("nSPV",response);
pfrom->prevtimes[ind] = timestamp;
}
NSPV_txidsresp_purge(&T);
}
} else fprintf(stderr,"len.%d req1.%d\n",len,request[1]);
}
}
else if ( request[0] == NSPV_MEMPOOL )
{
if ( timestamp > pfrom->prevtimes[ind] )
{
struct NSPV_mempoolresp M; char coinaddr[64];
if ( len < sizeof(M)+64 )
{
int32_t vout; uint256 txid; uint8_t funcid,isCC = 0;
n = 1;
n += iguana_rwnum(0,&request[n],sizeof(isCC),&isCC);
n += iguana_rwnum(0,&request[n],sizeof(funcid),&funcid);
n += iguana_rwnum(0,&request[n],sizeof(vout),&vout);
n += iguana_rwbignum(0,&request[n],sizeof(txid),(uint8_t *)&txid);
slen = request[n++];
if ( slen < 63 )
{
memcpy(coinaddr,&request[n],slen), n += slen;
coinaddr[slen] = 0;
if ( isCC != 0 )
fprintf(stderr,"(%s) isCC.%d funcid.%d %s/v%d len.%d slen.%d\n",coinaddr,isCC,funcid,txid.GetHex().c_str(),vout,len,slen);
memset(&M,0,sizeof(M));
if ( (slen= NSPV_mempooltxids(&M,coinaddr,isCC,funcid,txid,vout)) > 0 )
{
//fprintf(stderr,"NSPV_mempooltxids slen.%d\n",slen);
response.resize(1 + slen);
response[0] = NSPV_MEMPOOLRESP;
if ( NSPV_rwmempoolresp(1,&response[1],&M) == slen )
{
pfrom->PushMessage("nSPV",response);
pfrom->prevtimes[ind] = timestamp;
}
NSPV_mempoolresp_purge(&M);
}
}
} else fprintf(stderr,"len.%d req1.%d\n",len,request[1]);
}
}
else if ( request[0] == NSPV_NTZS )
{
if ( timestamp > pfrom->prevtimes[ind] )
{
struct NSPV_ntzsresp N; int32_t height;
if ( len == 1+sizeof(height) )
{
iguana_rwnum(0,&request[1],sizeof(height),&height);
memset(&N,0,sizeof(N));
if ( (slen= NSPV_getntzsresp(&N,height)) > 0 )
{
response.resize(1 + slen);
response[0] = NSPV_NTZSRESP;
if ( NSPV_rwntzsresp(1,&response[1],&N) == slen )
{
pfrom->PushMessage("nSPV",response);
pfrom->prevtimes[ind] = timestamp;
}
NSPV_ntzsresp_purge(&N);
}
}
}
}
else if ( request[0] == NSPV_NTZSPROOF )
{
if ( timestamp > pfrom->prevtimes[ind] )
{
struct NSPV_ntzsproofresp P; uint256 prevntz,nextntz;
if ( len == 1+sizeof(prevntz)+sizeof(nextntz) )
{
iguana_rwbignum(0,&request[1],sizeof(prevntz),(uint8_t *)&prevntz);
iguana_rwbignum(0,&request[1+sizeof(prevntz)],sizeof(nextntz),(uint8_t *)&nextntz);
memset(&P,0,sizeof(P));
if ( (slen= NSPV_getntzsproofresp(&P,prevntz,nextntz)) > 0 )
{
// fprintf(stderr,"slen.%d msg prev.%s next.%s\n",slen,prevntz.GetHex().c_str(),nextntz.GetHex().c_str());
response.resize(1 + slen);
response[0] = NSPV_NTZSPROOFRESP;
if ( NSPV_rwntzsproofresp(1,&response[1],&P) == slen )
{
pfrom->PushMessage("nSPV",response);
pfrom->prevtimes[ind] = timestamp;
}
NSPV_ntzsproofresp_purge(&P);
} else fprintf(stderr,"err.%d\n",slen);
}
}
}
else if ( request[0] == NSPV_TXPROOF )
{
if ( timestamp > pfrom->prevtimes[ind] )
{
struct NSPV_txproof P; uint256 txid; int32_t height,vout;
if ( len == 1+sizeof(txid)+sizeof(height)+sizeof(vout) )
{
iguana_rwnum(0,&request[1],sizeof(height),&height);
iguana_rwnum(0,&request[1+sizeof(height)],sizeof(vout),&vout);
iguana_rwbignum(0,&request[1+sizeof(height)+sizeof(vout)],sizeof(txid),(uint8_t *)&txid);
//fprintf(stderr,"got txid %s/v%d ht.%d\n",txid.GetHex().c_str(),vout,height);
memset(&P,0,sizeof(P));
if ( (slen= NSPV_gettxproof(&P,vout,txid,height)) > 0 )
{
//fprintf(stderr,"slen.%d\n",slen);
response.resize(1 + slen);
response[0] = NSPV_TXPROOFRESP;
if ( NSPV_rwtxproof(1,&response[1],&P) == slen )
{
//fprintf(stderr,"send response\n");
pfrom->PushMessage("nSPV",response);
pfrom->prevtimes[ind] = timestamp;
}
NSPV_txproof_purge(&P);
} else fprintf(stderr,"gettxproof error.%d\n",slen);
} else fprintf(stderr,"txproof reqlen.%d\n",len);
}
}
else if ( request[0] == NSPV_SPENTINFO )
{
if ( timestamp > pfrom->prevtimes[ind] )
{
struct NSPV_spentinfo S; int32_t vout; uint256 txid;
if ( len == 1+sizeof(txid)+sizeof(vout) )
{
iguana_rwnum(0,&request[1],sizeof(vout),&vout);
iguana_rwbignum(0,&request[1+sizeof(vout)],sizeof(txid),(uint8_t *)&txid);
memset(&S,0,sizeof(S));
if ( (slen= NSPV_getspentinfo(&S,txid,vout)) > 0 )
{
response.resize(1 + slen);
response[0] = NSPV_SPENTINFORESP;
if ( NSPV_rwspentinfo(1,&response[1],&S) == slen )
{
pfrom->PushMessage("nSPV",response);
pfrom->prevtimes[ind] = timestamp;
}
NSPV_spentinfo_purge(&S);
}
}
}
}
else if ( request[0] == NSPV_BROADCAST )
{
if ( timestamp > pfrom->prevtimes[ind] )
{
struct NSPV_broadcastresp B; uint32_t n,offset; uint256 txid;
if ( len > 1+sizeof(txid)+sizeof(n) )
{
iguana_rwbignum(0,&request[1],sizeof(txid),(uint8_t *)&txid);
iguana_rwnum(0,&request[1+sizeof(txid)],sizeof(n),&n);
memset(&B,0,sizeof(B));
offset = 1 + sizeof(txid) + sizeof(n);
if ( n < MAX_TX_SIZE_AFTER_SAPLING && request.size() == offset+n && (slen= NSPV_sendrawtransaction(&B,&request[offset],n)) > 0 )
{
response.resize(1 + slen);
response[0] = NSPV_BROADCASTRESP;
if ( NSPV_rwbroadcastresp(1,&response[1],&B) == slen )
{
pfrom->PushMessage("nSPV",response);
pfrom->prevtimes[ind] = timestamp;
}
NSPV_broadcast_purge(&B);
}
}
}
}
}
}
#endif // KOMODO_NSPVFULLNODE_H
+889
View File
@@ -0,0 +1,889 @@
/******************************************************************************
* 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. *
* *
******************************************************************************/
#ifndef KOMODO_NSPVSUPERLITE_H
#define KOMODO_NSPVSUPERLITE_H
// nSPV client. VERY simplistic "single threaded" networking model. for production GUI best to multithread, etc.
// no caching, no optimizations, no reducing the number of ntzsproofs needed by detecting overlaps, etc.
// advantage is that it is simpler to implement and understand to create a design for a more performant version
CAmount AmountFromValue(const UniValue& value);
int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr);
uint32_t NSPV_lastinfo,NSPV_logintime,NSPV_tiptime;
CKey NSPV_key;
char NSPV_wifstr[64],NSPV_pubkeystr[67],NSPV_lastpeer[128];
std::string NSPV_address;
struct NSPV_inforesp NSPV_inforesult;
struct NSPV_utxosresp NSPV_utxosresult;
struct NSPV_txidsresp NSPV_txidsresult;
struct NSPV_mempoolresp NSPV_mempoolresult;
struct NSPV_spentinfo NSPV_spentresult;
struct NSPV_ntzsresp NSPV_ntzsresult;
struct NSPV_ntzsproofresp NSPV_ntzsproofresult;
struct NSPV_txproof NSPV_txproofresult;
struct NSPV_broadcastresp NSPV_broadcastresult;
struct NSPV_ntzsresp NSPV_ntzsresp_cache[NSPV_MAXVINS];
struct NSPV_ntzsproofresp NSPV_ntzsproofresp_cache[NSPV_MAXVINS * 2];
struct NSPV_txproof NSPV_txproof_cache[NSPV_MAXVINS * 4];
struct NSPV_ntzsresp *NSPV_ntzsresp_find(int32_t reqheight)
{
int32_t i;
for (i=0; i<sizeof(NSPV_ntzsresp_cache)/sizeof(*NSPV_ntzsresp_cache); i++)
if ( NSPV_ntzsresp_cache[i].reqheight == reqheight )
return(&NSPV_ntzsresp_cache[i]);
return(0);
}
struct NSPV_ntzsresp *NSPV_ntzsresp_add(struct NSPV_ntzsresp *ptr)
{
int32_t i;
for (i=0; i<sizeof(NSPV_ntzsresp_cache)/sizeof(*NSPV_ntzsresp_cache); i++)
if ( NSPV_ntzsresp_cache[i].reqheight == 0 )
break;
if ( i == sizeof(NSPV_ntzsresp_cache)/sizeof(*NSPV_ntzsresp_cache) )
i = (rand() % (sizeof(NSPV_ntzsresp_cache)/sizeof(*NSPV_ntzsresp_cache)));
NSPV_ntzsresp_purge(&NSPV_ntzsresp_cache[i]);
NSPV_ntzsresp_copy(&NSPV_ntzsresp_cache[i],ptr);
fprintf(stderr,"ADD CACHE ntzsresp req.%d\n",ptr->reqheight);
return(&NSPV_ntzsresp_cache[i]);
}
struct NSPV_txproof *NSPV_txproof_find(uint256 txid)
{
int32_t i; struct NSPV_txproof *backup = 0;
for (i=0; i<sizeof(NSPV_txproof_cache)/sizeof(*NSPV_txproof_cache); i++)
if ( NSPV_txproof_cache[i].txid == txid )
{
if ( NSPV_txproof_cache[i].txprooflen != 0 )
return(&NSPV_txproof_cache[i]);
else backup = &NSPV_txproof_cache[i];
}
return(backup);
}
struct NSPV_txproof *NSPV_txproof_add(struct NSPV_txproof *ptr)
{
int32_t i;
for (i=0; i<sizeof(NSPV_txproof_cache)/sizeof(*NSPV_txproof_cache); i++)
if ( NSPV_txproof_cache[i].txid == ptr->txid )
{
if ( NSPV_txproof_cache[i].txprooflen == 0 && ptr->txprooflen != 0 )
{
NSPV_txproof_purge(&NSPV_txproof_cache[i]);
NSPV_txproof_copy(&NSPV_txproof_cache[i],ptr);
return(&NSPV_txproof_cache[i]);
}
else if ( NSPV_txproof_cache[i].txprooflen != 0 || ptr->txprooflen == 0 )
return(&NSPV_txproof_cache[i]);
}
for (i=0; i<sizeof(NSPV_txproof_cache)/sizeof(*NSPV_txproof_cache); i++)
if ( NSPV_txproof_cache[i].txlen == 0 )
break;
if ( i == sizeof(NSPV_txproof_cache)/sizeof(*NSPV_txproof_cache) )
i = (rand() % (sizeof(NSPV_txproof_cache)/sizeof(*NSPV_txproof_cache)));
NSPV_txproof_purge(&NSPV_txproof_cache[i]);
NSPV_txproof_copy(&NSPV_txproof_cache[i],ptr);
fprintf(stderr,"ADD CACHE txproof %s\n",ptr->txid.GetHex().c_str());
return(&NSPV_txproof_cache[i]);
}
struct NSPV_ntzsproofresp *NSPV_ntzsproof_find(uint256 prevtxid,uint256 nexttxid)
{
int32_t i;
for (i=0; i<sizeof(NSPV_ntzsproofresp_cache)/sizeof(*NSPV_ntzsproofresp_cache); i++)
if ( NSPV_ntzsproofresp_cache[i].prevtxid == prevtxid && NSPV_ntzsproofresp_cache[i].nexttxid == nexttxid )
return(&NSPV_ntzsproofresp_cache[i]);
return(0);
}
struct NSPV_ntzsproofresp *NSPV_ntzsproof_add(struct NSPV_ntzsproofresp *ptr)
{
int32_t i;
for (i=0; i<sizeof(NSPV_ntzsproofresp_cache)/sizeof(*NSPV_ntzsproofresp_cache); i++)
if ( NSPV_ntzsproofresp_cache[i].common.hdrs == 0 )
break;
if ( i == sizeof(NSPV_ntzsproofresp_cache)/sizeof(*NSPV_ntzsproofresp_cache) )
i = (rand() % (sizeof(NSPV_ntzsproofresp_cache)/sizeof(*NSPV_ntzsproofresp_cache)));
NSPV_ntzsproofresp_purge(&NSPV_ntzsproofresp_cache[i]);
NSPV_ntzsproofresp_copy(&NSPV_ntzsproofresp_cache[i],ptr);
fprintf(stderr,"ADD CACHE ntzsproof %s %s\n",ptr->prevtxid.GetHex().c_str(),ptr->nexttxid.GetHex().c_str());
return(&NSPV_ntzsproofresp_cache[i]);
}
// komodo_nSPVresp is called from async message processing
void komodo_nSPVresp(CNode *pfrom,std::vector<uint8_t> response) // received a response
{
struct NSPV_inforesp I; int32_t len; uint32_t timestamp = (uint32_t)time(NULL);
strncpy(NSPV_lastpeer,pfrom->addr.ToString().c_str(),sizeof(NSPV_lastpeer)-1);
if ( (len= response.size()) > 0 )
{
switch ( response[0] )
{
case NSPV_INFORESP:
fprintf(stderr,"got version.%d info response %u size.%d height.%d\n",NSPV_inforesult.version,timestamp,(int32_t)response.size(),NSPV_inforesult.height); // update current height and ntrz status
I = NSPV_inforesult;
NSPV_inforesp_purge(&NSPV_inforesult);
NSPV_rwinforesp(0,&response[1],&NSPV_inforesult);
if ( NSPV_inforesult.height < I.height )
{
fprintf(stderr,"got old info response %u size.%d height.%d\n",timestamp,(int32_t)response.size(),NSPV_inforesult.height); // update current height and ntrz status
NSPV_inforesp_purge(&NSPV_inforesult);
NSPV_inforesult = I;
}
else if ( NSPV_inforesult.height > I.height )
{
NSPV_lastinfo = timestamp - ASSETCHAINS_BLOCKTIME/4;
// need to validate new header to make sure it is valid mainchain
if ( NSPV_inforesult.height == NSPV_inforesult.hdrheight )
NSPV_tiptime = NSPV_inforesult.H.nTime;
}
break;
case NSPV_UTXOSRESP:
NSPV_utxosresp_purge(&NSPV_utxosresult);
NSPV_rwutxosresp(0,&response[1],&NSPV_utxosresult);
fprintf(stderr,"got utxos response %u size.%d\n",timestamp,(int32_t)response.size());
break;
case NSPV_TXIDSRESP:
NSPV_txidsresp_purge(&NSPV_txidsresult);
NSPV_rwtxidsresp(0,&response[1],&NSPV_txidsresult);
fprintf(stderr,"got txids response %u size.%d %s CC.%d num.%d\n",timestamp,(int32_t)response.size(),NSPV_txidsresult.coinaddr,NSPV_txidsresult.CCflag,NSPV_txidsresult.numtxids);
break;
case NSPV_MEMPOOLRESP:
NSPV_mempoolresp_purge(&NSPV_mempoolresult);
NSPV_rwmempoolresp(0,&response[1],&NSPV_mempoolresult);
fprintf(stderr,"got mempool response %u size.%d %s CC.%d num.%d funcid.%d %s/v%d\n",timestamp,(int32_t)response.size(),NSPV_mempoolresult.coinaddr,NSPV_mempoolresult.CCflag,NSPV_mempoolresult.numtxids,NSPV_mempoolresult.funcid,NSPV_mempoolresult.txid.GetHex().c_str(),NSPV_mempoolresult.vout);
break;
case NSPV_NTZSRESP:
NSPV_ntzsresp_purge(&NSPV_ntzsresult);
NSPV_rwntzsresp(0,&response[1],&NSPV_ntzsresult);
if ( NSPV_ntzsresp_find(NSPV_ntzsresult.reqheight) == 0 )
NSPV_ntzsresp_add(&NSPV_ntzsresult);
fprintf(stderr,"got ntzs response %u size.%d %s prev.%d, %s next.%d\n",timestamp,(int32_t)response.size(),NSPV_ntzsresult.prevntz.txid.GetHex().c_str(),NSPV_ntzsresult.prevntz.height,NSPV_ntzsresult.nextntz.txid.GetHex().c_str(),NSPV_ntzsresult.nextntz.height);
break;
case NSPV_NTZSPROOFRESP:
NSPV_ntzsproofresp_purge(&NSPV_ntzsproofresult);
NSPV_rwntzsproofresp(0,&response[1],&NSPV_ntzsproofresult);
if ( NSPV_ntzsproof_find(NSPV_ntzsproofresult.prevtxid,NSPV_ntzsproofresult.nexttxid) == 0 )
NSPV_ntzsproof_add(&NSPV_ntzsproofresult);
fprintf(stderr,"got ntzproof response %u size.%d prev.%d next.%d\n",timestamp,(int32_t)response.size(),NSPV_ntzsproofresult.common.prevht,NSPV_ntzsproofresult.common.nextht);
break;
case NSPV_TXPROOFRESP:
NSPV_txproof_purge(&NSPV_txproofresult);
NSPV_rwtxproof(0,&response[1],&NSPV_txproofresult);
if ( NSPV_txproof_find(NSPV_txproofresult.txid) == 0 )
NSPV_txproof_add(&NSPV_txproofresult);
fprintf(stderr,"got txproof response %u size.%d %s ht.%d\n",timestamp,(int32_t)response.size(),NSPV_txproofresult.txid.GetHex().c_str(),NSPV_txproofresult.height);
break;
case NSPV_SPENTINFORESP:
NSPV_spentinfo_purge(&NSPV_spentresult);
NSPV_rwspentinfo(0,&response[1],&NSPV_spentresult);
fprintf(stderr,"got spentinfo response %u size.%d\n",timestamp,(int32_t)response.size());
break;
case NSPV_BROADCASTRESP:
NSPV_broadcast_purge(&NSPV_broadcastresult);
NSPV_rwbroadcastresp(0,&response[1],&NSPV_broadcastresult);
fprintf(stderr,"got broadcast response %u size.%d %s retcode.%d\n",timestamp,(int32_t)response.size(),NSPV_broadcastresult.txid.GetHex().c_str(),NSPV_broadcastresult.retcode);
break;
default: fprintf(stderr,"unexpected response %02x size.%d at %u\n",response[0],(int32_t)response.size(),timestamp);
break;
}
}
}
// superlite message issuing
CNode *NSPV_req(CNode *pnode,uint8_t *msg,int32_t len,uint64_t mask,int32_t ind)
{
int32_t n,flag = 0; CNode *pnodes[64]; uint32_t timestamp = (uint32_t)time(NULL);
if ( KOMODO_NSPV <= 0 )
return(0);
if ( pnode == 0 )
{
memset(pnodes,0,sizeof(pnodes));
//LOCK(cs_vNodes);
n = 0;
BOOST_FOREACH(CNode *ptr,vNodes)
{
if ( ptr->prevtimes[ind] > timestamp )
ptr->prevtimes[ind] = 0;
if ( ptr->hSocket == INVALID_SOCKET )
continue;
if ( (ptr->nServices & mask) == mask && timestamp > ptr->prevtimes[ind] )
{
flag = 1;
pnodes[n++] = ptr;
if ( n == sizeof(pnodes)/sizeof(*pnodes) )
break;
} // else fprintf(stderr,"nServices %llx vs mask %llx, t%u vs %u, ind.%d\n",(long long)ptr->nServices,(long long)mask,timestamp,ptr->prevtimes[ind],ind);
}
if ( n > 0 )
pnode = pnodes[rand() % n];
} else flag = 1;
if ( pnode != 0 )
{
std::vector<uint8_t> request;
request.resize(len);
memcpy(&request[0],msg,len);
if ( (0) && KOMODO_NSPV > 0 )
fprintf(stderr,"pushmessage [%d] len.%d\n",msg[0],len);
pnode->PushMessage("getnSPV",request);
pnode->prevtimes[ind] = timestamp;
return(pnode);
} else fprintf(stderr,"no pnodes\n");
return(0);
}
UniValue NSPV_logout()
{
UniValue result(UniValue::VOBJ);
result.push_back(Pair("result","success"));
if ( NSPV_logintime != 0 )
fprintf(stderr,"scrub wif and privkey from NSPV memory\n");
else result.push_back(Pair("status","wasnt logged in"));
memset(NSPV_ntzsproofresp_cache,0,sizeof(NSPV_ntzsproofresp_cache));
memset(NSPV_txproof_cache,0,sizeof(NSPV_txproof_cache));
memset(NSPV_ntzsresp_cache,0,sizeof(NSPV_ntzsresp_cache));
memset(NSPV_wifstr,0,sizeof(NSPV_wifstr));
memset(&NSPV_key,0,sizeof(NSPV_key));
NSPV_logintime = 0;
return(result);
}
// komodo_nSPV from main polling loop (really this belongs in its own file, but it is so small, it ended up here)
void komodo_nSPV(CNode *pto) // polling loop from SendMessages
{
uint8_t msg[256]; int32_t i,len=0; uint32_t timestamp = (uint32_t)time(NULL);
if ( NSPV_logintime != 0 && timestamp > NSPV_logintime+NSPV_AUTOLOGOUT )
NSPV_logout();
if ( (pto->nServices & NODE_NSPV) == 0 )
return;
if ( pto->prevtimes[NSPV_INFO>>1] > timestamp )
pto->prevtimes[NSPV_INFO>>1] = 0;
if ( KOMODO_NSPV > 0 )
{
if ( timestamp > NSPV_lastinfo + ASSETCHAINS_BLOCKTIME/2 && timestamp > pto->prevtimes[NSPV_INFO>>1] + 2*ASSETCHAINS_BLOCKTIME/3 )
{
int32_t reqht;
reqht = 0;
len = 0;
msg[len++] = NSPV_INFO;
len += iguana_rwnum(1,&msg[len],sizeof(reqht),&reqht);
//fprintf(stderr,"issue getinfo\n");
NSPV_req(pto,msg,len,NODE_NSPV,NSPV_INFO>>1);
}
}
}
UniValue NSPV_txproof_json(struct NSPV_txproof *ptr)
{
UniValue result(UniValue::VOBJ);
result.push_back(Pair("txid",ptr->txid.GetHex()));
result.push_back(Pair("height",(int64_t)ptr->height));
result.push_back(Pair("txlen",(int64_t)ptr->txlen));
result.push_back(Pair("txprooflen",(int64_t)ptr->txprooflen));
result.push_back(Pair("lastpeer",NSPV_lastpeer));
return(result);
}
UniValue NSPV_spentinfo_json(struct NSPV_spentinfo *ptr)
{
UniValue result(UniValue::VOBJ);
result.push_back(Pair("result","success"));
result.push_back(Pair("txid",ptr->txid.GetHex()));
result.push_back(Pair("vout",(int64_t)ptr->vout));
result.push_back(Pair("spentheight",(int64_t)ptr->spent.height));
result.push_back(Pair("spenttxid",ptr->spent.txid.GetHex()));
result.push_back(Pair("spentvini",(int64_t)ptr->spentvini));
result.push_back(Pair("spenttxlen",(int64_t)ptr->spent.txlen));
result.push_back(Pair("spenttxprooflen",(int64_t)ptr->spent.txprooflen));
result.push_back(Pair("lastpeer",NSPV_lastpeer));
return(result);
}
UniValue NSPV_ntz_json(struct NSPV_ntz *ptr)
{
UniValue result(UniValue::VOBJ);
result.push_back(Pair("notarized_height",(int64_t)ptr->height));
result.push_back(Pair("notarized_blockhash",ptr->blockhash.GetHex()));
result.push_back(Pair("notarization_txid",ptr->txid.GetHex()));
result.push_back(Pair("notarization_txidheight",(int64_t)ptr->txidheight));
result.push_back(Pair("notarization_desttxid",ptr->othertxid.GetHex()));
return(result);
}
UniValue NSPV_header_json(struct NSPV_equihdr *hdr,int32_t height)
{
UniValue item(UniValue::VOBJ);
item.push_back(Pair("height",(int64_t)height));
item.push_back(Pair("blockhash",NSPV_hdrhash(hdr).GetHex()));
item.push_back(Pair("hashPrevBlock",hdr->hashPrevBlock.GetHex()));
item.push_back(Pair("hashMerkleRoot",hdr->hashMerkleRoot.GetHex()));
item.push_back(Pair("nTime",(int64_t)hdr->nTime));
item.push_back(Pair("nBits",(int64_t)hdr->nBits));
return(item);
}
UniValue NSPV_headers_json(struct NSPV_equihdr *hdrs,int32_t numhdrs,int32_t height)
{
UniValue array(UniValue::VARR); int32_t i;
for (i=0; i<numhdrs; i++)
array.push_back(NSPV_header_json(&hdrs[i],height+i));
return(array);
}
UniValue NSPV_getinfo_json(struct NSPV_inforesp *ptr)
{
UniValue result(UniValue::VOBJ); int32_t expiration; uint32_t timestamp = (uint32_t)time(NULL);
result.push_back(Pair("result","success"));
result.push_back(Pair("nSPV",KOMODO_NSPV!=0?"superlite":"fullnode"));
if ( NSPV_address.size() != 0 )
{
result.push_back(Pair("address",NSPV_address));
result.push_back(Pair("pubkey",NSPV_pubkeystr));
}
if ( NSPV_logintime != 0 )
{
expiration = (NSPV_logintime + NSPV_AUTOLOGOUT - timestamp);
result.push_back(Pair("wifexpires",expiration));
}
result.push_back(Pair("height",(int64_t)ptr->height));
result.push_back(Pair("chaintip",ptr->blockhash.GetHex()));
result.push_back(Pair("notarization",NSPV_ntz_json(&ptr->notarization)));
result.push_back(Pair("header",NSPV_header_json(&ptr->H,ptr->hdrheight)));
result.push_back(Pair("protocolversion",(int64_t)ptr->version));
result.push_back(Pair("lastpeer",NSPV_lastpeer));
return(result);
}
UniValue NSPV_utxoresp_json(struct NSPV_utxoresp *utxos,int32_t numutxos)
{
UniValue array(UniValue::VARR); int32_t i;
for (i=0; i<numutxos; i++)
{
UniValue item(UniValue::VOBJ);
item.push_back(Pair("height",(int64_t)utxos[i].height));
item.push_back(Pair("txid",utxos[i].txid.GetHex()));
item.push_back(Pair("vout",(int64_t)utxos[i].vout));
item.push_back(Pair("value",(double)utxos[i].satoshis/COIN));
if ( ASSETCHAINS_SYMBOL[0] == 0 )
item.push_back(Pair("interest",(double)utxos[i].extradata/COIN));
array.push_back(item);
}
return(array);
}
UniValue NSPV_utxosresp_json(struct NSPV_utxosresp *ptr)
{
UniValue result(UniValue::VOBJ);
result.push_back(Pair("result","success"));
result.push_back(Pair("utxos",NSPV_utxoresp_json(ptr->utxos,ptr->numutxos)));
result.push_back(Pair("address",ptr->coinaddr));
result.push_back(Pair("isCC",ptr->CCflag));
result.push_back(Pair("height",(int64_t)ptr->nodeheight));
result.push_back(Pair("numutxos",(int64_t)ptr->numutxos));
result.push_back(Pair("balance",(double)ptr->total/COIN));
if ( ASSETCHAINS_SYMBOL[0] == 0 )
result.push_back(Pair("interest",(double)ptr->interest/COIN));
result.push_back(Pair("filter",(int64_t)ptr->filter));
result.push_back(Pair("lastpeer",NSPV_lastpeer));
return(result);
}
UniValue NSPV_txidresp_json(struct NSPV_txidresp *utxos,int32_t numutxos)
{
UniValue array(UniValue::VARR); int32_t i;
for (i=0; i<numutxos; i++)
{
UniValue item(UniValue::VOBJ);
item.push_back(Pair("height",(int64_t)utxos[i].height));
item.push_back(Pair("txid",utxos[i].txid.GetHex()));
item.push_back(Pair("value",(double)utxos[i].satoshis/COIN));
if ( utxos[i].satoshis > 0 )
item.push_back(Pair("vout",(int64_t)utxos[i].vout));
else item.push_back(Pair("vin",(int64_t)utxos[i].vout));
array.push_back(item);
}
return(array);
}
UniValue NSPV_txidsresp_json(struct NSPV_txidsresp *ptr)
{
UniValue result(UniValue::VOBJ);
result.push_back(Pair("result","success"));
result.push_back(Pair("txids",NSPV_txidresp_json(ptr->txids,ptr->numtxids)));
result.push_back(Pair("address",ptr->coinaddr));
result.push_back(Pair("isCC",ptr->CCflag));
result.push_back(Pair("height",(int64_t)ptr->nodeheight));
result.push_back(Pair("numtxids",(int64_t)ptr->numtxids));
result.push_back(Pair("filter",(int64_t)ptr->filter));
result.push_back(Pair("lastpeer",NSPV_lastpeer));
return(result);
}
UniValue NSPV_mempoolresp_json(struct NSPV_mempoolresp *ptr)
{
UniValue result(UniValue::VOBJ),array(UniValue::VARR); int32_t i;
result.push_back(Pair("result","success"));
for (i=0; i<ptr->numtxids; i++)
array.push_back(ptr->txids[i].GetHex().c_str());
result.push_back(Pair("txids",array));
result.push_back(Pair("address",ptr->coinaddr));
result.push_back(Pair("isCC",ptr->CCflag));
result.push_back(Pair("height",(int64_t)ptr->nodeheight));
result.push_back(Pair("numtxids",(int64_t)ptr->numtxids));
result.push_back(Pair("txid",ptr->txid.GetHex().c_str()));
result.push_back(Pair("vout",(int64_t)ptr->vout));
result.push_back(Pair("funcid",(int64_t)ptr->funcid));
result.push_back(Pair("lastpeer",NSPV_lastpeer));
return(result);
}
UniValue NSPV_ntzsresp_json(struct NSPV_ntzsresp *ptr)
{
UniValue result(UniValue::VOBJ);
result.push_back(Pair("result","success"));
result.push_back(Pair("prev",NSPV_ntz_json(&ptr->prevntz)));
result.push_back(Pair("next",NSPV_ntz_json(&ptr->nextntz)));
result.push_back(Pair("lastpeer",NSPV_lastpeer));
return(result);
}
UniValue NSPV_ntzsproof_json(struct NSPV_ntzsproofresp *ptr)
{
UniValue result(UniValue::VOBJ);
result.push_back(Pair("result","success"));
result.push_back(Pair("prevht",(int64_t)ptr->common.prevht));
result.push_back(Pair("nextht",(int64_t)ptr->common.nextht));
result.push_back(Pair("prevtxid",ptr->prevtxid.GetHex()));
result.push_back(Pair("prevtxidht",(int64_t)ptr->prevtxidht));
result.push_back(Pair("prevtxlen",(int64_t)ptr->prevtxlen));
result.push_back(Pair("nexttxid",ptr->nexttxid.GetHex()));
result.push_back(Pair("nexttxidht",(int64_t)ptr->nexttxidht));
result.push_back(Pair("nexttxlen",(int64_t)ptr->nexttxlen));
result.push_back(Pair("numhdrs",(int64_t)ptr->common.numhdrs));
result.push_back(Pair("headers",NSPV_headers_json(ptr->common.hdrs,ptr->common.numhdrs,ptr->common.prevht)));
result.push_back(Pair("lastpeer",NSPV_lastpeer));
//fprintf(stderr,"ntzs_proof %s %d, %s %d\n",ptr->prevtxid.GetHex().c_str(),ptr->common.prevht,ptr->nexttxid.GetHex().c_str(),ptr->common.nextht);
return(result);
}
UniValue NSPV_broadcast_json(struct NSPV_broadcastresp *ptr,uint256 txid)
{
UniValue result(UniValue::VOBJ);
result.push_back(Pair("result","success"));
result.push_back(Pair("expected",txid.GetHex()));
result.push_back(Pair("broadcast",ptr->txid.GetHex()));
result.push_back(Pair("retcode",(int64_t)ptr->retcode));
switch ( ptr->retcode )
{
case 1: result.push_back(Pair("type","broadcast and mempool")); break;
case 0: result.push_back(Pair("type","broadcast")); break;
case -1: result.push_back(Pair("type","decode error")); break;
case -2: result.push_back(Pair("type","timeout")); break;
case -3: result.push_back(Pair("type","error adding to mempool")); break;
default: result.push_back(Pair("type","unknown")); break;
}
result.push_back(Pair("lastpeer",NSPV_lastpeer));
return(result);
}
UniValue NSPV_login(char *wifstr)
{
UniValue result(UniValue::VOBJ); char coinaddr[64]; uint8_t data[128]; int32_t len,valid = 0;
NSPV_logout();
len = bitcoin_base58decode(data,wifstr);
if ( strlen(wifstr) < 64 && (len == 38 && data[len-5] == 1) || (len == 37 && data[len-5] != 1) )
valid = 1;
if ( valid == 0 || data[0] != 188 )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","invalid wif"));
result.push_back(Pair("len",(int64_t)len));
result.push_back(Pair("prefix",(int64_t)data[0]));
return(result);
}
memset(NSPV_wifstr,0,sizeof(NSPV_wifstr));
NSPV_logintime = (uint32_t)time(NULL);
if ( strcmp(NSPV_wifstr,wifstr) != 0 )
{
strncpy(NSPV_wifstr,wifstr,sizeof(NSPV_wifstr)-1);
NSPV_key = DecodeSecret(wifstr);
}
result.push_back(Pair("result","success"));
result.push_back(Pair("status","wif will expire in 777 seconds"));
CPubKey pubkey = NSPV_key.GetPubKey();
CKeyID vchAddress = pubkey.GetID();
NSPV_address = EncodeDestination(vchAddress);
result.push_back(Pair("address",NSPV_address));
result.push_back(Pair("pubkey",HexStr(pubkey)));
strcpy(NSPV_pubkeystr,HexStr(pubkey).c_str());
if ( KOMODO_NSPV > 0 )
decode_hex(NOTARY_PUBKEY33,33,NSPV_pubkeystr);
result.push_back(Pair("wifprefix",(int64_t)data[0]));
result.push_back(Pair("compressed",(int64_t)(data[len-5] == 1)));
memset(data,0,sizeof(data));
return(result);
}
UniValue NSPV_getinfo_req(int32_t reqht)
{
uint8_t msg[512]; int32_t i,iter,len = 0; struct NSPV_inforesp I;
NSPV_inforesp_purge(&NSPV_inforesult);
msg[len++] = NSPV_INFO;
len += iguana_rwnum(1,&msg[len],sizeof(reqht),&reqht);
for (iter=0; iter<3; iter++)
if ( NSPV_req(0,msg,len,NODE_NSPV,msg[0]>>1) != 0 )
{
for (i=0; i<NSPV_POLLITERS; i++)
{
usleep(NSPV_POLLMICROS);
if ( NSPV_inforesult.height != 0 )
return(NSPV_getinfo_json(&NSPV_inforesult));
}
} else sleep(1);
memset(&I,0,sizeof(I));
return(NSPV_getinfo_json(&NSPV_inforesult));
}
uint32_t NSPV_blocktime(int32_t hdrheight)
{
uint32_t timestamp; struct NSPV_inforesp old = NSPV_inforesult;
if ( hdrheight > 0 )
{
NSPV_getinfo_req(hdrheight);
if ( NSPV_inforesult.hdrheight == hdrheight )
{
timestamp = NSPV_inforesult.H.nTime;
NSPV_inforesult = old;
fprintf(stderr,"NSPV_blocktime ht.%d -> t%u\n",hdrheight,timestamp);
return(timestamp);
}
}
NSPV_inforesult = old;
return(0);
}
UniValue NSPV_addressutxos(char *coinaddr,int32_t CCflag,int32_t skipcount,int32_t filter)
{
UniValue result(UniValue::VOBJ); uint8_t msg[512]; int32_t i,iter,slen,len = 0;
//fprintf(stderr,"utxos %s NSPV addr %s\n",coinaddr,NSPV_address.c_str());
//if ( NSPV_utxosresult.nodeheight >= NSPV_inforesult.height && strcmp(coinaddr,NSPV_utxosresult.coinaddr) == 0 && CCflag == NSPV_utxosresult.CCflag && skipcount == NSPV_utxosresult.skipcount && filter == NSPV_utxosresult.filter )
// return(NSPV_utxosresp_json(&NSPV_utxosresult));
if ( skipcount < 0 )
skipcount = 0;
NSPV_utxosresp_purge(&NSPV_utxosresult);
if ( bitcoin_base58decode(msg,coinaddr) != 25 )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","invalid address"));
return(result);
}
slen = (int32_t)strlen(coinaddr);
msg[len++] = NSPV_UTXOS;
msg[len++] = slen;
memcpy(&msg[len],coinaddr,slen), len += slen;
msg[len++] = (CCflag != 0);
len += iguana_rwnum(1,&msg[len],sizeof(skipcount),&skipcount);
len += iguana_rwnum(1,&msg[len],sizeof(filter),&filter);
for (iter=0; iter<3; iter++)
if ( NSPV_req(0,msg,len,NODE_ADDRINDEX,msg[0]>>1) != 0 )
{
for (i=0; i<NSPV_POLLITERS; i++)
{
usleep(NSPV_POLLMICROS);
if ( (NSPV_inforesult.height == 0 || NSPV_utxosresult.nodeheight >= NSPV_inforesult.height) && strcmp(coinaddr,NSPV_utxosresult.coinaddr) == 0 && CCflag == NSPV_utxosresult.CCflag )
return(NSPV_utxosresp_json(&NSPV_utxosresult));
}
} else sleep(1);
result.push_back(Pair("result","error"));
result.push_back(Pair("error","no utxos result"));
result.push_back(Pair("lastpeer",NSPV_lastpeer));
return(result);
}
UniValue NSPV_addresstxids(char *coinaddr,int32_t CCflag,int32_t skipcount,int32_t filter)
{
UniValue result(UniValue::VOBJ); uint8_t msg[512]; int32_t i,iter,slen,len = 0;
if ( NSPV_txidsresult.nodeheight >= NSPV_inforesult.height && strcmp(coinaddr,NSPV_txidsresult.coinaddr) == 0 && CCflag == NSPV_txidsresult.CCflag && skipcount == NSPV_txidsresult.skipcount )
return(NSPV_txidsresp_json(&NSPV_txidsresult));
if ( skipcount < 0 )
skipcount = 0;
NSPV_txidsresp_purge(&NSPV_txidsresult);
if ( bitcoin_base58decode(msg,coinaddr) != 25 )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","invalid address"));
return(result);
}
slen = (int32_t)strlen(coinaddr);
msg[len++] = NSPV_TXIDS;
msg[len++] = slen;
memcpy(&msg[len],coinaddr,slen), len += slen;
msg[len++] = (CCflag != 0);
len += iguana_rwnum(1,&msg[len],sizeof(skipcount),&skipcount);
len += iguana_rwnum(1,&msg[len],sizeof(filter),&filter);
//fprintf(stderr,"skipcount.%d\n",skipcount);
for (iter=0; iter<3; iter++)
if ( NSPV_req(0,msg,len,NODE_ADDRINDEX,msg[0]>>1) != 0 )
{
for (i=0; i<NSPV_POLLITERS; i++)
{
usleep(NSPV_POLLMICROS);
if ( (NSPV_inforesult.height == 0 || NSPV_txidsresult.nodeheight >= NSPV_inforesult.height) && strcmp(coinaddr,NSPV_txidsresult.coinaddr) == 0 && CCflag == NSPV_txidsresult.CCflag )
return(NSPV_txidsresp_json(&NSPV_txidsresult));
}
} else sleep(1);
result.push_back(Pair("result","error"));
result.push_back(Pair("error","no txid result"));
result.push_back(Pair("lastpeer",NSPV_lastpeer));
return(result);
}
UniValue NSPV_mempooltxids(char *coinaddr,int32_t CCflag,uint8_t funcid,uint256 txid,int32_t vout)
{
UniValue result(UniValue::VOBJ); uint8_t msg[512]; char zeroes[64]; int32_t i,iter,slen,len = 0;
NSPV_mempoolresp_purge(&NSPV_mempoolresult);
memset(zeroes,0,sizeof(zeroes));
if ( coinaddr == 0 )
coinaddr = zeroes;
if ( coinaddr[0] != 0 && bitcoin_base58decode(msg,coinaddr) != 25 )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","invalid address"));
return(result);
}
msg[len++] = NSPV_MEMPOOL;
msg[len++] = (CCflag != 0);
len += iguana_rwnum(1,&msg[len],sizeof(funcid),&funcid);
len += iguana_rwnum(1,&msg[len],sizeof(vout),&vout);
len += iguana_rwbignum(1,&msg[len],sizeof(txid),(uint8_t *)&txid);
slen = (int32_t)strlen(coinaddr);
msg[len++] = slen;
memcpy(&msg[len],coinaddr,slen), len += slen;
fprintf(stderr,"(%s) func.%d CC.%d %s/v%d len.%d\n",coinaddr,funcid,CCflag,txid.GetHex().c_str(),vout,len);
for (iter=0; iter<3; iter++)
if ( NSPV_req(0,msg,len,NODE_NSPV,msg[0]>>1) != 0 )
{
for (i=0; i<NSPV_POLLITERS; i++)
{
usleep(NSPV_POLLMICROS);
if ( NSPV_mempoolresult.nodeheight >= NSPV_inforesult.height && strcmp(coinaddr,NSPV_mempoolresult.coinaddr) == 0 && CCflag == NSPV_mempoolresult.CCflag && txid == NSPV_mempoolresult.txid && vout == NSPV_mempoolresult.vout && funcid == NSPV_mempoolresult.funcid )
return(NSPV_mempoolresp_json(&NSPV_mempoolresult));
}
} else sleep(1);
result.push_back(Pair("result","error"));
result.push_back(Pair("error","no txid result"));
result.push_back(Pair("lastpeer",NSPV_lastpeer));
return(result);
}
int32_t NSPV_coinaddr_inmempool(char const *logcategory,char *coinaddr,uint8_t CCflag)
{
NSPV_mempooltxids(coinaddr,CCflag,NSPV_MEMPOOL_ADDRESS,zeroid,-1);
if ( NSPV_mempoolresult.txids != 0 && NSPV_mempoolresult.numtxids >= 1 && strcmp(NSPV_mempoolresult.coinaddr,coinaddr) == 0 && NSPV_mempoolresult.CCflag == CCflag )
{
LogPrint(logcategory,"found (%s) vout in mempool\n",coinaddr);
return(true);
} else return(false);
}
bool NSPV_spentinmempool(uint256 &spenttxid,int32_t &spentvini,uint256 txid,int32_t vout)
{
NSPV_mempooltxids((char *)"",0,NSPV_MEMPOOL_ISSPENT,txid,vout);
if ( NSPV_mempoolresult.txids != 0 && NSPV_mempoolresult.numtxids == 1 && NSPV_mempoolresult.txid == txid )
{
spenttxid = NSPV_mempoolresult.txids[0];
spentvini = NSPV_mempoolresult.vindex;
return(true);
} else return(false);
}
bool NSPV_inmempool(uint256 txid)
{
NSPV_mempooltxids((char *)"",0,NSPV_MEMPOOL_INMEMPOOL,txid,0);
if ( NSPV_mempoolresult.txids != 0 && NSPV_mempoolresult.numtxids == 1 && NSPV_mempoolresult.txids[0] == txid )
return(true);
else return(false);
}
bool NSPV_evalcode_inmempool(uint8_t evalcode,uint8_t funcid)
{
int32_t vout;
vout = ((uint32_t)funcid << 8) | evalcode;
NSPV_mempooltxids((char *)"",1,NSPV_MEMPOOL_CCEVALCODE,zeroid,vout);
if ( NSPV_mempoolresult.txids != 0 && NSPV_mempoolresult.numtxids >= 1 && NSPV_mempoolresult.vout == vout )
return(true);
else return(false);
}
UniValue NSPV_notarizations(int32_t reqheight)
{
uint8_t msg[512]; int32_t i,iter,len = 0; struct NSPV_ntzsresp N,*ptr;
if ( (ptr= NSPV_ntzsresp_find(reqheight)) != 0 )
{
fprintf(stderr,"FROM CACHE NSPV_notarizations.%d\n",reqheight);
NSPV_ntzsresp_purge(&NSPV_ntzsresult);
NSPV_ntzsresp_copy(&NSPV_ntzsresult,ptr);
return(NSPV_ntzsresp_json(ptr));
}
msg[len++] = NSPV_NTZS;
len += iguana_rwnum(1,&msg[len],sizeof(reqheight),&reqheight);
for (iter=0; iter<3; iter++)
if ( NSPV_req(0,msg,len,NODE_NSPV,msg[0]>>1) != 0 )
{
for (i=0; i<NSPV_POLLITERS; i++)
{
usleep(NSPV_POLLMICROS);
if ( NSPV_ntzsresult.reqheight == reqheight )
return(NSPV_ntzsresp_json(&NSPV_ntzsresult));
}
} else sleep(1);
memset(&N,0,sizeof(N));
return(NSPV_ntzsresp_json(&N));
}
UniValue NSPV_txidhdrsproof(uint256 prevtxid,uint256 nexttxid)
{
uint8_t msg[512]; int32_t i,iter,len = 0; struct NSPV_ntzsproofresp P,*ptr;
if ( (ptr= NSPV_ntzsproof_find(prevtxid,nexttxid)) != 0 )
{
fprintf(stderr,"FROM CACHE NSPV_txidhdrsproof %s %s\n",ptr->prevtxid.GetHex().c_str(),ptr->nexttxid.GetHex().c_str());
NSPV_ntzsproofresp_purge(&NSPV_ntzsproofresult);
NSPV_ntzsproofresp_copy(&NSPV_ntzsproofresult,ptr);
return(NSPV_ntzsproof_json(ptr));
}
NSPV_ntzsproofresp_purge(&NSPV_ntzsproofresult);
msg[len++] = NSPV_NTZSPROOF;
len += iguana_rwbignum(1,&msg[len],sizeof(prevtxid),(uint8_t *)&prevtxid);
len += iguana_rwbignum(1,&msg[len],sizeof(nexttxid),(uint8_t *)&nexttxid);
for (iter=0; iter<3; iter++)
if ( NSPV_req(0,msg,len,NODE_NSPV,msg[0]>>1) != 0 )
{
for (i=0; i<NSPV_POLLITERS; i++)
{
usleep(NSPV_POLLMICROS);
if ( NSPV_ntzsproofresult.prevtxid == prevtxid && NSPV_ntzsproofresult.nexttxid == nexttxid )
return(NSPV_ntzsproof_json(&NSPV_ntzsproofresult));
}
} else sleep(1);
memset(&P,0,sizeof(P));
return(NSPV_ntzsproof_json(&P));
}
UniValue NSPV_hdrsproof(int32_t prevht,int32_t nextht)
{
uint256 prevtxid,nexttxid;
NSPV_notarizations(prevht);
prevtxid = NSPV_ntzsresult.prevntz.txid;
NSPV_notarizations(nextht);
nexttxid = NSPV_ntzsresult.nextntz.txid;
return(NSPV_txidhdrsproof(prevtxid,nexttxid));
}
UniValue NSPV_txproof(int32_t vout,uint256 txid,int32_t height)
{
uint8_t msg[512]; int32_t i,iter,len = 0; struct NSPV_txproof P,*ptr;
if ( (ptr= NSPV_txproof_find(txid)) != 0 )
{
fprintf(stderr,"FROM CACHE NSPV_txproof %s\n",txid.GetHex().c_str());
NSPV_txproof_purge(&NSPV_txproofresult);
NSPV_txproof_copy(&NSPV_txproofresult,ptr);
return(NSPV_txproof_json(ptr));
}
NSPV_txproof_purge(&NSPV_txproofresult);
msg[len++] = NSPV_TXPROOF;
len += iguana_rwnum(1,&msg[len],sizeof(height),&height);
len += iguana_rwnum(1,&msg[len],sizeof(vout),&vout);
len += iguana_rwbignum(1,&msg[len],sizeof(txid),(uint8_t *)&txid);
fprintf(stderr,"req txproof %s/v%d at height.%d\n",txid.GetHex().c_str(),vout,height);
for (iter=0; iter<3; iter++)
if ( NSPV_req(0,msg,len,NODE_NSPV,msg[0]>>1) != 0 )
{
for (i=0; i<NSPV_POLLITERS; i++)
{
usleep(NSPV_POLLMICROS);
if ( NSPV_txproofresult.txid == txid )
return(NSPV_txproof_json(&NSPV_txproofresult));
}
} else sleep(1);
fprintf(stderr,"txproof timeout\n");
memset(&P,0,sizeof(P));
return(NSPV_txproof_json(&P));
}
UniValue NSPV_spentinfo(uint256 txid,int32_t vout)
{
uint8_t msg[512]; int32_t i,iter,len = 0; struct NSPV_spentinfo I;
NSPV_spentinfo_purge(&NSPV_spentresult);
msg[len++] = NSPV_SPENTINFO;
len += iguana_rwnum(1,&msg[len],sizeof(vout),&vout);
len += iguana_rwbignum(1,&msg[len],sizeof(txid),(uint8_t *)&txid);
for (iter=0; iter<3; iter++)
if ( NSPV_req(0,msg,len,NODE_SPENTINDEX,msg[0]>>1) != 0 )
{
for (i=0; i<NSPV_POLLITERS; i++)
{
usleep(NSPV_POLLMICROS);
if ( NSPV_spentresult.txid == txid && NSPV_spentresult.vout == vout )
return(NSPV_spentinfo_json(&NSPV_spentresult));
}
} else sleep(1);
memset(&I,0,sizeof(I));
return(NSPV_spentinfo_json(&I));
}
UniValue NSPV_broadcast(char *hex)
{
uint8_t *msg,*data; uint256 txid; int32_t i,n,iter,len = 0; struct NSPV_broadcastresp B;
NSPV_broadcast_purge(&NSPV_broadcastresult);
n = (int32_t)strlen(hex) >> 1;
data = (uint8_t *)malloc(n);
decode_hex(data,n,hex);
txid = NSPV_doublesha256(data,n);
msg = (uint8_t *)malloc(1 + sizeof(txid) + sizeof(n) + n);
msg[len++] = NSPV_BROADCAST;
len += iguana_rwbignum(1,&msg[len],sizeof(txid),(uint8_t *)&txid);
len += iguana_rwnum(1,&msg[len],sizeof(n),&n);
memcpy(&msg[len],data,n), len += n;
free(data);
//fprintf(stderr,"send txid.%s\n",txid.GetHex().c_str());
for (iter=0; iter<3; iter++)
if ( NSPV_req(0,msg,len,NODE_NSPV,msg[0]>>1) != 0 )
{
for (i=0; i<NSPV_POLLITERS; i++)
{
usleep(NSPV_POLLMICROS);
if ( NSPV_broadcastresult.txid == txid )
{
free(msg);
return(NSPV_broadcast_json(&NSPV_broadcastresult,txid));
}
}
} else sleep(1);
free(msg);
memset(&B,0,sizeof(B));
B.retcode = -2;
return(NSPV_broadcast_json(&B,txid));
}
#endif // KOMODO_NSPVSUPERLITE_H
+529
View File
@@ -0,0 +1,529 @@
/******************************************************************************
* 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. *
* *
******************************************************************************/
#ifndef KOMODO_NSPVWALLET_H
#define KOMODO_NSPVWALLET_H
// nSPV wallet uses superlite functions (and some komodod built in functions) to implement nSPV_spend
extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
int32_t NSPV_validatehdrs(struct NSPV_ntzsproofresp *ptr)
{
int32_t i,height,txidht; CTransaction tx; uint256 blockhash,txid,desttxid;
if ( (ptr->common.nextht-ptr->common.prevht+1) != ptr->common.numhdrs )
{
fprintf(stderr,"next.%d prev.%d -> %d vs %d\n",ptr->common.nextht,ptr->common.prevht,ptr->common.nextht-ptr->common.prevht+1,ptr->common.numhdrs);
return(-2);
}
else if ( NSPV_txextract(tx,ptr->nextntz,ptr->nexttxlen) < 0 )
return(-3);
else if ( tx.GetHash() != ptr->nexttxid )
return(-4);
else if ( NSPV_notarizationextract(1,&height,&blockhash,&desttxid,tx) < 0 )
return(-5);
else if ( height != ptr->common.nextht )
return(-6);
else if ( NSPV_hdrhash(&ptr->common.hdrs[ptr->common.numhdrs-1]) != blockhash )
return(-7);
for (i=ptr->common.numhdrs-1; i>0; i--)
{
blockhash = NSPV_hdrhash(&ptr->common.hdrs[i-1]);
if ( blockhash != ptr->common.hdrs[i].hashPrevBlock )
return(-i-13);
}
sleep(1); // need this to get past the once per second rate limiter per message
if ( NSPV_txextract(tx,ptr->prevntz,ptr->prevtxlen) < 0 )
return(-8);
else if ( tx.GetHash() != ptr->prevtxid )
return(-9);
else if ( NSPV_notarizationextract(1,&height,&blockhash,&desttxid,tx) < 0 )
return(-10);
else if ( height != ptr->common.prevht )
return(-11);
else if ( NSPV_hdrhash(&ptr->common.hdrs[0]) != blockhash )
return(-12);
return(0);
}
int32_t NSPV_gettransaction(int32_t skipvalidation,int32_t vout,uint256 txid,int32_t height,CTransaction &tx,uint256 &hashblock,int32_t &txheight,int32_t &currentheight,int64_t extradata,uint32_t tiptime,int64_t &rewardsum)
{
struct NSPV_txproof *ptr; int32_t i,offset,retval; int64_t rewards = 0; uint32_t nLockTime; std::vector<uint8_t> proof;
retval = skipvalidation != 0 ? 0 : -1;
//fprintf(stderr,"NSPV_gettx %s/v%d ht.%d\n",txid.GetHex().c_str(),vout,height);
if ( (ptr= NSPV_txproof_find(txid)) == 0 )
{
NSPV_txproof(vout,txid,height);
ptr = &NSPV_txproofresult;
}
hashblock=ptr->hashblock;
txheight=ptr->height;
currentheight=NSPV_inforesult.height;
if ( ptr->txid != txid )
{
fprintf(stderr,"txproof error %s != %s\n",ptr->txid.GetHex().c_str(),txid.GetHex().c_str());
return(-1);
}
else if ( NSPV_txextract(tx,ptr->tx,ptr->txlen) < 0 || ptr->txlen <= 0 )
retval = -2000;
else if ( tx.GetHash() != txid )
retval = -2001;
else if ( skipvalidation == 0 && ptr->unspentvalue <= 0 )
retval = -2002;
else if ( ASSETCHAINS_SYMBOL[0] == 0 && tiptime != 0 )
{
rewards = komodo_interestnew(height,tx.vout[vout].nValue,tx.nLockTime,tiptime);
if ( rewards != extradata )
fprintf(stderr,"extradata %.8f vs rewards %.8f\n",dstr(extradata),dstr(rewards));
rewardsum += rewards;
}
//char coinaddr[64];
//Getscriptaddress(coinaddr,tx.vout[0].scriptPubKey); causes crash??
//fprintf(stderr,"%s txid.%s vs hash.%s\n",coinaddr,txid.GetHex().c_str(),tx.GetHash().GetHex().c_str());
if ( skipvalidation == 0 )
{
if ( ptr->txprooflen > 0 )
{
proof.resize(ptr->txprooflen);
memcpy(&proof[0],ptr->txproof,ptr->txprooflen);
}
NSPV_notarizations(height); // gets the prev and next notarizations
if ( NSPV_inforesult.notarization.height >= height && (NSPV_ntzsresult.prevntz.height == 0 || NSPV_ntzsresult.prevntz.height >= NSPV_ntzsresult.nextntz.height) )
{
fprintf(stderr,"issue manual bracket\n");
NSPV_notarizations(height-1);
NSPV_notarizations(height+1);
NSPV_notarizations(height); // gets the prev and next notarizations
}
if ( NSPV_ntzsresult.prevntz.height != 0 && NSPV_ntzsresult.prevntz.height <= NSPV_ntzsresult.nextntz.height )
{
fprintf(stderr,">>>>> gettx ht.%d prev.%d next.%d\n",height,NSPV_ntzsresult.prevntz.height, NSPV_ntzsresult.nextntz.height);
offset = (height - NSPV_ntzsresult.prevntz.height);
if ( offset >= 0 && height <= NSPV_ntzsresult.nextntz.height )
{
//fprintf(stderr,"call NSPV_txidhdrsproof %s %s\n",NSPV_ntzsresult.prevntz.txid.GetHex().c_str(),NSPV_ntzsresult.nextntz.txid.GetHex().c_str());
NSPV_txidhdrsproof(NSPV_ntzsresult.prevntz.txid,NSPV_ntzsresult.nextntz.txid);
usleep(10000);
if ( (retval= NSPV_validatehdrs(&NSPV_ntzsproofresult)) == 0 )
{
std::vector<uint256> txids; uint256 proofroot;
proofroot = BitcoinGetProofMerkleRoot(proof,txids);
if ( proofroot != NSPV_ntzsproofresult.common.hdrs[offset].hashMerkleRoot || txids[0] != txid )
{
fprintf(stderr,"txid.%s vs txids[0] %s\n",txid.GetHex().c_str(),txids[0].GetHex().c_str());
fprintf(stderr,"prooflen.%d proofroot.%s vs %s\n",(int32_t)proof.size(),proofroot.GetHex().c_str(),NSPV_ntzsproofresult.common.hdrs[offset].hashMerkleRoot.GetHex().c_str());
retval = -2003;
} else retval = 0;
}
} else retval = -2005;
} else retval = -2004;
}
return(retval);
}
int32_t NSPV_vinselect(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *belowp,struct NSPV_utxoresp utxos[],int32_t numunspents,int64_t value)
{
int32_t i,abovei,belowi; int64_t above,below,gap,atx_value;
abovei = belowi = -1;
for (above=below=i=0; i<numunspents; i++)
{
if ( (atx_value= utxos[i].satoshis) <= 0 )
continue;
if ( atx_value == value )
{
*aboveip = *belowip = i;
*abovep = *belowp = 0;
return(i);
}
else if ( atx_value > value )
{
gap = (atx_value - value);
if ( above == 0 || gap < above )
{
above = gap;
abovei = i;
}
}
else
{
gap = (value - atx_value);
if ( below == 0 || gap < below )
{
below = gap;
belowi = i;
}
}
//printf("value %.8f gap %.8f abovei.%d %.8f belowi.%d %.8f\n",dstr(value),dstr(gap),abovei,dstr(above),belowi,dstr(below));
}
*aboveip = abovei;
*abovep = above;
*belowip = belowi;
*belowp = below;
//printf("above.%d below.%d\n",abovei,belowi);
if ( abovei >= 0 && belowi >= 0 )
{
if ( above < (below >> 1) )
return(abovei);
else return(belowi);
}
else if ( abovei >= 0 )
return(abovei);
else return(belowi);
}
int64_t NSPV_addinputs(struct NSPV_utxoresp *used,CMutableTransaction &mtx,int64_t total,int32_t maxinputs,struct NSPV_utxoresp *ptr,int32_t num)
{
int32_t abovei,belowi,ind,vout,i,n = 0; int64_t threshold,above,below; int64_t remains,totalinputs = 0; CTransaction tx; struct NSPV_utxoresp utxos[NSPV_MAXVINS],*up;
memset(utxos,0,sizeof(utxos));
if ( maxinputs > NSPV_MAXVINS )
maxinputs = NSPV_MAXVINS;
if ( maxinputs > 0 )
threshold = total/maxinputs;
else threshold = total;
for (i=0; i<num; i++)
{
if ( num < NSPV_MAXVINS || ptr[i].satoshis > threshold )
utxos[n++] = ptr[i];
}
remains = total;
//fprintf(stderr,"threshold %.8f n.%d for total %.8f\n",(double)threshold/COIN,n,(double)total/COIN);
for (i=0; i<maxinputs && n>0; i++)
{
below = above = 0;
abovei = belowi = -1;
if ( NSPV_vinselect(&abovei,&above,&belowi,&below,utxos,n,remains) < 0 )
{
fprintf(stderr,"error finding unspent i.%d of %d, %.8f vs %.8f\n",i,n,(double)remains/COIN,(double)total/COIN);
return(0);
}
if ( belowi < 0 || abovei >= 0 )
ind = abovei;
else ind = belowi;
if ( ind < 0 )
{
fprintf(stderr,"error finding unspent i.%d of %d, %.8f vs %.8f, abovei.%d belowi.%d ind.%d\n",i,n,(double)remains/COIN,(double)total/COIN,abovei,belowi,ind);
return(0);
}
//fprintf(stderr,"i.%d ind.%d abovei.%d belowi.%d n.%d\n",i,ind,abovei,belowi,n);
up = &utxos[ind];
mtx.vin.push_back(CTxIn(up->txid,up->vout,CScript()));
used[i] = *up;
totalinputs += up->satoshis;
remains -= up->satoshis;
utxos[ind] = utxos[--n];
memset(&utxos[n],0,sizeof(utxos[n]));
//fprintf(stderr,"totalinputs %.8f vs total %.8f i.%d vs max.%d\n",(double)totalinputs/COIN,(double)total/COIN,i,maxinputs);
if ( totalinputs >= total || (i+1) >= maxinputs )
break;
}
//fprintf(stderr,"totalinputs %.8f vs total %.8f\n",(double)totalinputs/COIN,(double)total/COIN);
if ( totalinputs >= total )
return(totalinputs);
return(0);
}
bool NSPV_SignTx(CMutableTransaction &mtx,int32_t vini,int64_t utxovalue,const CScript scriptPubKey,uint32_t nTime)
{
CTransaction txNewConst(mtx); SignatureData sigdata; CBasicKeyStore keystore; int64_t branchid = NSPV_BRANCHID;
if ( NSPV_logintime == 0 || time(NULL) > NSPV_logintime+NSPV_AUTOLOGOUT )
{
fprintf(stderr,"need to be logged in to get myprivkey\n");
return false;
}
keystore.AddKey(NSPV_key);
if ( nTime != 0 && nTime < KOMODO_SAPLING_ACTIVATION )
{
fprintf(stderr,"use legacy sig validation\n");
branchid = 0;
}
if ( ProduceSignature(TransactionSignatureCreator(&keystore,&txNewConst,vini,utxovalue,SIGHASH_ALL),scriptPubKey,sigdata,branchid) != 0 )
{
UpdateTransaction(mtx,vini,sigdata);
fprintf(stderr,"SIG_TXHASH %s vini.%d %.8f\n",SIG_TXHASH.GetHex().c_str(),vini,(double)utxovalue/COIN);
return(true);
} //else fprintf(stderr,"sigerr SIG_TXHASH %s vini.%d %.8f\n",SIG_TXHASH.GetHex().c_str(),vini,(double)utxovalue/COIN);
return(false);
}
std::string NSPV_signtx(int64_t &rewardsum,int64_t &interestsum,UniValue &retcodes,CMutableTransaction &mtx,uint64_t txfee,CScript opret,struct NSPV_utxoresp used[])
{
CTransaction vintx; std::string hex; uint256 hashBlock; int64_t interest=0,change,totaloutputs=0,totalinputs=0; int32_t i,utxovout,n,validation,txheight,currentheight;
n = mtx.vout.size();
for (i=0; i<n; i++)
totaloutputs += mtx.vout[i].nValue;
n = mtx.vin.size();
for (i=0; i<n; i++)
{
totalinputs += used[i].satoshis;
interest += used[i].extradata;
}
interestsum = interest;
if ( (totalinputs+interest) >= totaloutputs+2*txfee )
{
change = (totalinputs+interest) - (totaloutputs+txfee);
mtx.vout.push_back(CTxOut(change,CScript() << ParseHex(NSPV_pubkeystr) << OP_CHECKSIG));
}
if ( opret.size() > 0 )
mtx.vout.push_back(CTxOut(0,opret));
for (i=0; i<n; i++)
{
utxovout = mtx.vin[i].prevout.n;
if ( i > 0 )
sleep(1);
validation = NSPV_gettransaction(0,utxovout,mtx.vin[i].prevout.hash,used[i].height,vintx,hashBlock,txheight,currentheight,used[i].extradata,NSPV_tiptime,rewardsum);
retcodes.push_back(validation);
if ( validation != -1 ) // most others are degraded security
{
if ( vintx.vout[utxovout].nValue != used[i].satoshis )
{
fprintf(stderr,"vintx mismatch %.8f != %.8f\n",(double)vintx.vout[utxovout].nValue/COIN,(double)used[i].satoshis/COIN);
return("");
}
else if ( utxovout != used[i].vout )
{
fprintf(stderr,"vintx vout mismatch %d != %d\n",utxovout,used[i].vout);
return("");
}
else if ( NSPV_SignTx(mtx,i,vintx.vout[utxovout].nValue,vintx.vout[utxovout].scriptPubKey,0) == 0 )
{
fprintf(stderr,"signing error for vini.%d\n",i);
return("");
}
} else fprintf(stderr,"couldnt find txid.%s/v%d or it was spent\n",mtx.vin[i].prevout.hash.GetHex().c_str(),utxovout); // of course much better handling is needed
}
fprintf(stderr,"sign %d inputs %.8f + interest %.8f -> %d outputs %.8f change %.8f\n",(int32_t)mtx.vin.size(),(double)totalinputs/COIN,(double)interest/COIN,(int32_t)mtx.vout.size(),(double)totaloutputs/COIN,(double)change/COIN);
return(EncodeHexTx(mtx));
}
UniValue NSPV_spend(char *srcaddr,char *destaddr,int64_t satoshis) // what its all about!
{
UniValue result(UniValue::VOBJ),retcodes(UniValue::VARR); std::vector<uint8_t> data; CScript scriptPubKey; uint8_t *ptr,rmd160[128]; int32_t len; int64_t txfee = 10000;
if ( NSPV_logintime == 0 || time(NULL) > NSPV_logintime+NSPV_AUTOLOGOUT )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","wif expired"));
return(result);
}
if ( strcmp(srcaddr,NSPV_address.c_str()) != 0 )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","invalid address"));
result.push_back(Pair("mismatched",srcaddr));
return(result);
}
else if ( bitcoin_base58decode(rmd160,destaddr) != 25 )
{
if ( (len= is_hexstr(destaddr,0)) > 0 )
{
len >>= 1;
data.resize(len);
decode_hex(&data[0],len,destaddr);
if ( data[len-1] == OP_CHECKCRYPTOCONDITION )
{
data.resize(--len);
scriptPubKey = CScript() << data << OP_CHECKCRYPTOCONDITION;
}
else
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","only CC hex allowed for now"));
return(result); }
}
else
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","invalid destaddr/CCvout hex"));
return(result);
}
}
else
{
data.resize(20);
memcpy(&data[0],&rmd160[1],20);
scriptPubKey = (CScript() << OP_DUP << OP_HASH160 << ParseHex(HexStr(data)) << OP_EQUALVERIFY << OP_CHECKSIG);
}
if ( NSPV_inforesult.height == 0 )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","couldnt getinfo"));
return(result);
}
if ( NSPV_utxosresult.CCflag != 0 || strcmp(NSPV_utxosresult.coinaddr,srcaddr) != 0 || NSPV_utxosresult.nodeheight < NSPV_inforesult.height )
NSPV_addressutxos(srcaddr,0,0,0);
if ( NSPV_utxosresult.CCflag != 0 || strcmp(NSPV_utxosresult.coinaddr,srcaddr) != 0 || NSPV_utxosresult.nodeheight < NSPV_inforesult.height )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("address",NSPV_utxosresult.coinaddr));
result.push_back(Pair("srcaddr",srcaddr));
result.push_back(Pair("nodeheight",(int64_t)NSPV_utxosresult.nodeheight));
result.push_back(Pair("infoheight",(int64_t)NSPV_inforesult.height));
result.push_back(Pair("error","couldnt get addressutxos"));
return(result);
}
if ( NSPV_utxosresult.total < satoshis+txfee )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","not enough funds"));
result.push_back(Pair("balance",(double)NSPV_utxosresult.total/COIN));
result.push_back(Pair("amount",(double)satoshis/COIN));
return(result);
}
printf("%s numutxos.%d balance %.8f\n",NSPV_utxosresult.coinaddr,NSPV_utxosresult.numutxos,(double)NSPV_utxosresult.total/COIN);
CScript opret; std::string hex; struct NSPV_utxoresp used[NSPV_MAXVINS]; CMutableTransaction mtx; CTransaction tx; int64_t rewardsum=0,interestsum=0;
mtx.fOverwintered = true;
mtx.nExpiryHeight = 0;
mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID;
mtx.nVersion = SAPLING_TX_VERSION;
if ( ASSETCHAINS_SYMBOL[0] == 0 )
mtx.nLockTime = (uint32_t)time(NULL) - 777;
memset(used,0,sizeof(used));
if ( NSPV_addinputs(used,mtx,satoshis+txfee,64,NSPV_utxosresult.utxos,NSPV_utxosresult.numutxos) > 0 )
{
mtx.vout.push_back(CTxOut(satoshis,scriptPubKey));
if ( NSPV_logintime == 0 || time(NULL) > NSPV_logintime+NSPV_AUTOLOGOUT )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","wif expired"));
return(result);
}
hex = NSPV_signtx(rewardsum,interestsum,retcodes,mtx,txfee,opret,used);
if ( ASSETCHAINS_SYMBOL[0] == 0 )
{
char numstr[64];
sprintf(numstr,"%.8f",(double)interestsum/COIN);
result.push_back(Pair("rewards",numstr));
sprintf(numstr,"%.8f",(double)rewardsum/COIN);
result.push_back(Pair("validated",numstr));
}
if ( hex.size() > 0 )
{
if ( DecodeHexTx(tx,hex) != 0 )
{
TxToJSON(tx,uint256(),result);
result.push_back(Pair("result","success"));
result.push_back(Pair("hex",hex));
result.push_back(Pair("retcodes",retcodes));
}
else
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","couldnt decode"));
result.push_back(Pair("hex",hex));
}
}
else
{
result.push_back(Pair("result","error"));
result.push_back(Pair("retcodes",retcodes));
result.push_back(Pair("error","signing error"));
}
return(result);
}
else
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","couldnt create tx"));
return(result);
}
}
int64_t NSPV_AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int32_t maxinputs,struct NSPV_CCmtxinfo *ptr)
{
char coinaddr[64]; int32_t CCflag = 0;
if ( ptr != 0 )
{
mtx.fOverwintered = true;
mtx.nExpiryHeight = 0;
mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID;
mtx.nVersion = SAPLING_TX_VERSION;
Getscriptaddress(coinaddr,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG);
if ( strcmp(ptr->U.coinaddr,coinaddr) != 0 )
{
NSPV_addressutxos(coinaddr,CCflag,0,0);
NSPV_utxosresp_purge(&ptr->U);
NSPV_utxosresp_copy(&ptr->U,&NSPV_utxosresult);
}
fprintf(stderr,"%s numutxos.%d\n",ptr->U.coinaddr,ptr->U.numutxos);
memset(ptr->used,0,sizeof(ptr->used));
return(NSPV_addinputs(ptr->used,mtx,total,maxinputs,ptr->U.utxos,ptr->U.numutxos));
} else return(0);
}
void NSPV_utxos2CCunspents(struct NSPV_utxosresp *ptr,std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &outputs)
{
CAddressUnspentKey key; CAddressUnspentValue value; int32_t i,type; uint160 hashBytes; std::string addrstr(ptr->coinaddr);
if ( ptr->utxos != NULL && ptr->numutxos > 0 )
{
CBitcoinAddress address(addrstr);
if ( address.GetIndexKey(hashBytes, type, ptr->CCflag) == 0 )
{
fprintf(stderr,"couldnt get indexkey\n");
return;
}
for (i = 0; i < ptr->numutxos; i ++)
{
key.type = type;
key.hashBytes = hashBytes;
key.txhash = ptr->utxos[i].txid;
key.index = ptr->utxos[i].vout;
value.satoshis = ptr->utxos[i].satoshis;
value.blockHeight = ptr->utxos[i].height;
outputs.push_back(std::make_pair(key, value));
}
}
}
void NSPV_txids2CCtxids(struct NSPV_txidsresp *ptr,std::vector<std::pair<CAddressIndexKey, CAmount> > &txids)
{
CAddressIndexKey key; int64_t value; int32_t i,type; uint160 hashBytes; std::string addrstr(ptr->coinaddr);
if ( ptr->txids != NULL && ptr->numtxids > 0 )
{
CBitcoinAddress address(addrstr);
if ( address.GetIndexKey(hashBytes, type, ptr->CCflag) == 0 )
{
fprintf(stderr,"couldnt get indexkey\n");
return;
}
for (i = 0; i < ptr->numtxids; i ++)
{
key.type = type;
key.hashBytes = hashBytes;
key.txhash = ptr->txids[i].txid;
key.index = ptr->txids[i].vout;
key.blockHeight = ptr->txids[i].height;
value = ptr->txids[i].satoshis;
txids.push_back(std::make_pair(key, value));
}
}
}
void NSPV_CCunspents(std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &outputs,char *coinaddr,bool ccflag)
{
int32_t filter = 0;
NSPV_addressutxos(coinaddr,ccflag,0,filter);
NSPV_utxos2CCunspents(&NSPV_utxosresult,outputs);
}
void NSPV_CCtxids(std::vector<std::pair<CAddressIndexKey, CAmount> > &txids,char *coinaddr,bool ccflag)
{
int32_t filter = 0;
NSPV_addresstxids(coinaddr,ccflag,0,filter);
NSPV_txids2CCtxids(&NSPV_txidsresult,txids);
}
#endif // KOMODO_NSPVWALLET_H
+2 -2
View File
@@ -73,7 +73,7 @@ int32_t getkmdseason(int32_t height)
return(i+1);
}
return(0);
};
}
int32_t getacseason(uint32_t timestamp)
{
@@ -85,7 +85,7 @@ int32_t getacseason(uint32_t timestamp)
return(i+1);
}
return(0);
};
}
int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp)
{
+76 -27
View File
@@ -1692,11 +1692,15 @@ int8_t equihash_params_possible(uint64_t n, uint64_t k)
void komodo_args(char *argv0)
{
std::string name,addn,hexstr,symbol; char *dirname,fname[512],arg0str[64],magicstr[9]; uint8_t magic[4],extrabuf[32756],disablebits[32],*extraptr=0; FILE *fp; uint64_t val; uint16_t port; int32_t i,nonz=0,baseid,len,n,extralen = 0; uint64_t ccenables[256], ccEnablesHeight[512] = {0};
std::string name,addn,hexstr,symbol; char *dirname,fname[512],arg0str[64],magicstr[9]; uint8_t magic[4],extrabuf[32756],disablebits[32],*extraptr=0;
FILE *fp; uint64_t val; uint16_t port; int32_t i,nonz=0,baseid,len,n,extralen = 0; uint64_t ccenables[256], ccEnablesHeight[512] = {0}; CTransaction earlytx; uint256 hashBlock;
IS_KOMODO_NOTARY = GetBoolArg("-notary", false);
IS_STAKED_NOTARY = GetArg("-stakednotary", -1);
KOMODO_NSPV = GetArg("-nSPV",0);
memset(ccenables,0,sizeof(ccenables));
memset(disablebits,0,sizeof(disablebits));
memset(ccEnablesHeight,0,sizeof(ccEnablesHeight));
if ( GetBoolArg("-gen", false) != 0 )
{
KOMODO_MININGTHREADS = GetArg("-genproclimit",-1);
@@ -1758,10 +1762,10 @@ void komodo_args(char *argv0)
ASSETCHAINS_PUBLIC = GetArg("-ac_public",0);
ASSETCHAINS_PRIVATE = GetArg("-ac_private",0);
KOMODO_SNAPSHOT_INTERVAL = GetArg("-ac_snapshot",0);
Split(GetArg("-ac_nk",""), ASSETCHAINS_NK, 0);
Split(GetArg("-ac_nk",""), sizeof(ASSETCHAINS_NK)/sizeof(*ASSETCHAINS_NK), ASSETCHAINS_NK, 0);
// -ac_ccactivateht=evalcode,height,evalcode,height,evalcode,height....
Split(GetArg("-ac_ccactivateht",""), ccEnablesHeight, 0);
Split(GetArg("-ac_ccactivateht",""), sizeof(ccEnablesHeight)/sizeof(*ccEnablesHeight), ccEnablesHeight, 0);
// fill map with all eval codes and activation height of 0.
for ( int i = 0; i < 256; i++ )
mapHeightEvalActivate[i] = 0;
@@ -1769,6 +1773,8 @@ void komodo_args(char *argv0)
{
int32_t ecode = ccEnablesHeight[i];
int32_t ht = ccEnablesHeight[i+1];
if ( i > 1 && ccEnablesHeight[i-2] == ecode )
break;
if ( ecode > 255 || ecode < 0 )
fprintf(stderr, "ac_ccactivateht: invalid evalcode.%i must be between 0 and 256.\n", ecode);
else if ( ht > 0 )
@@ -1784,7 +1790,7 @@ void komodo_args(char *argv0)
{
printf("KOMODO_REWIND %d\n",KOMODO_REWIND);
}
KOMODO_EARLYTXID = Parseuint256(GetArg("-earlytxid","0").c_str());
KOMODO_EARLYTXID = Parseuint256(GetArg("-earlytxid","0").c_str());
ASSETCHAINS_EARLYTXIDCONTRACT = GetArg("-ac_earlytxidcontract",0);
if ( name.c_str()[0] != 0 )
{
@@ -1833,11 +1839,11 @@ void komodo_args(char *argv0)
ASSETCHAINS_TIMEUNLOCKFROM = ASSETCHAINS_TIMEUNLOCKTO = 0;
}
Split(GetArg("-ac_end",""), ASSETCHAINS_ENDSUBSIDY, 0);
Split(GetArg("-ac_reward",""), ASSETCHAINS_REWARD, 0);
Split(GetArg("-ac_halving",""), ASSETCHAINS_HALVING, 0);
Split(GetArg("-ac_decay",""), ASSETCHAINS_DECAY, 0);
Split(GetArg("-ac_notarypay",""), ASSETCHAINS_NOTARY_PAY, 0);
Split(GetArg("-ac_end",""), sizeof(ASSETCHAINS_ENDSUBSIDY)/sizeof(*ASSETCHAINS_ENDSUBSIDY), ASSETCHAINS_ENDSUBSIDY, 0);
Split(GetArg("-ac_reward",""), sizeof(ASSETCHAINS_REWARD)/sizeof(*ASSETCHAINS_REWARD), ASSETCHAINS_REWARD, 0);
Split(GetArg("-ac_halving",""), sizeof(ASSETCHAINS_HALVING)/sizeof(*ASSETCHAINS_HALVING), ASSETCHAINS_HALVING, 0);
Split(GetArg("-ac_decay",""), sizeof(ASSETCHAINS_DECAY)/sizeof(*ASSETCHAINS_DECAY), ASSETCHAINS_DECAY, 0);
Split(GetArg("-ac_notarypay",""), sizeof(ASSETCHAINS_NOTARY_PAY)/sizeof(*ASSETCHAINS_NOTARY_PAY), ASSETCHAINS_NOTARY_PAY, 0);
for ( int i = 0; i < ASSETCHAINS_MAX_ERAS; i++ )
{
@@ -1872,6 +1878,8 @@ void komodo_args(char *argv0)
ASSETCHAINS_CODAPORT = GetArg("-ac_coda",0);
ASSETCHAINS_MARMARA = GetArg("-ac_marmara",0);
ASSETCHAINS_CBOPRET = GetArg("-ac_cbopret",0);
ASSETCHAINS_CBMATURITY = GetArg("-ac_cbmaturity",0);
ASSETCHAINS_ADAPTIVEPOW = GetArg("-ac_adaptivepow",0);
//fprintf(stderr,"ASSETCHAINS_CBOPRET.%llx\n",(long long)ASSETCHAINS_CBOPRET);
if ( ASSETCHAINS_CBOPRET != 0 )
{
@@ -1904,13 +1912,15 @@ void komodo_args(char *argv0)
}
if ( ASSETCHAINS_CC != 0 )
{
uint8_t prevCCi = 0;
ASSETCHAINS_CCLIB = GetArg("-ac_cclib","");
Split(GetArg("-ac_ccenable",""), ccenables, 0);
Split(GetArg("-ac_ccenable",""), sizeof(ccenables)/sizeof(*ccenables), ccenables, 0);
for (i=nonz=0; i<0x100; i++)
{
if ( ccenables[i] != 0 )
if ( ccenables[i] != prevCCi && ccenables[i] != 0 )
{
nonz++;
prevCCi = ccenables[i];
fprintf(stderr,"%d ",(uint8_t)(ccenables[i] & 0xff));
}
}
@@ -1922,11 +1932,12 @@ void komodo_args(char *argv0)
ASSETCHAINS_CCDISABLES[i] = 1;
SETBIT(disablebits,i);
}
for (i=0; i<256; i++)
for (i=0; i<nonz; i++)
{
CLEARBIT(disablebits,(ccenables[i] & 0xff));
ASSETCHAINS_CCDISABLES[ccenables[i] & 0xff] = 0;
}
CLEARBIT(disablebits,0);
}
/*if ( ASSETCHAINS_CCLIB.size() > 0 )
{
@@ -1937,7 +1948,7 @@ void komodo_args(char *argv0)
}
}*/
}
if ( ASSETCHAINS_BEAMPORT != 0 && ASSETCHAINS_CODAPORT != 0 )
if ( ASSETCHAINS_BEAMPORT != 0 )
{
fprintf(stderr,"can only have one of -ac_beam or -ac_coda\n");
StartShutdown();
@@ -1951,18 +1962,33 @@ void komodo_args(char *argv0)
StartShutdown();
}
}
else if ( ASSETCHAINS_SELFIMPORT == "BEAM" && ASSETCHAINS_BEAMPORT == 0 )
else if ( ASSETCHAINS_SELFIMPORT == "BEAM" )
{
fprintf(stderr,"missing -ac_beam for BEAM rpcport\n");
StartShutdown();
if (ASSETCHAINS_BEAMPORT == 0)
{
fprintf(stderr,"missing -ac_beam for BEAM rpcport\n");
StartShutdown();
}
}
else if ( ASSETCHAINS_SELFIMPORT == "CODA" && ASSETCHAINS_CODAPORT == 0 )
else if ( ASSETCHAINS_SELFIMPORT == "CODA" )
{
fprintf(stderr,"missing -ac_coda for CODA rpcport\n");
StartShutdown();
if (ASSETCHAINS_CODAPORT == 0)
{
fprintf(stderr,"missing -ac_coda for CODA rpcport\n");
StartShutdown();
}
}
else if ( ASSETCHAINS_SELFIMPORT == "PEGSCC")
{
Split(GetArg("-ac_pegsccparams",""), sizeof(ASSETCHAINS_PEGSCCPARAMS)/sizeof(*ASSETCHAINS_PEGSCCPARAMS), ASSETCHAINS_PEGSCCPARAMS, 0);
if (ASSETCHAINS_ENDSUBSIDY[0]!=1 || ASSETCHAINS_COMMISSION!=0)
{
fprintf(stderr,"when using import for pegsCC these must be set: -ac_end=1 -ac_perc=0\n");
StartShutdown();
}
}
// else it can be gateway coin
else if (!ASSETCHAINS_SELFIMPORT.empty() && (ASSETCHAINS_ENDSUBSIDY[0]!=1 || ASSETCHAINS_SUPPLY>10 || ASSETCHAINS_COMMISSION!=0))
else if (!ASSETCHAINS_SELFIMPORT.empty() && (ASSETCHAINS_ENDSUBSIDY[0]!=1 || ASSETCHAINS_SUPPLY>0 || ASSETCHAINS_COMMISSION!=0))
{
fprintf(stderr,"when using gateway import these must be set: -ac_end=1 -ac_supply=0 -ac_perc=0\n");
StartShutdown();
@@ -2040,7 +2066,7 @@ void komodo_args(char *argv0)
fprintf(stderr,"-ac_script and -ac_marmara are mutually exclusive\n");
StartShutdown();
}
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 || ASSETCHAINS_FOUNDERS_REWARD != 0 || ASSETCHAINS_NOTARY_PAY[0] != 0 || ASSETCHAINS_BLOCKTIME != 60 || ASSETCHAINS_CBOPRET != 0 || Mineropret.size() != 0 || (ASSETCHAINS_NK[0] != 0 && ASSETCHAINS_NK[1] != 0) || KOMODO_SNAPSHOT_INTERVAL != 0 || ASSETCHAINS_EARLYTXIDCONTRACT != 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 || ASSETCHAINS_FOUNDERS_REWARD != 0 || ASSETCHAINS_NOTARY_PAY[0] != 0 || ASSETCHAINS_BLOCKTIME != 60 || ASSETCHAINS_CBOPRET != 0 || Mineropret.size() != 0 || (ASSETCHAINS_NK[0] != 0 && ASSETCHAINS_NK[1] != 0) || KOMODO_SNAPSHOT_INTERVAL != 0 || ASSETCHAINS_EARLYTXIDCONTRACT != 0 || ASSETCHAINS_CBMATURITY != 0 || ASSETCHAINS_ADAPTIVEPOW != 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());
extraptr = extrabuf;
@@ -2100,7 +2126,7 @@ void komodo_args(char *argv0)
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_FOUNDERS),(void *)&ASSETCHAINS_FOUNDERS);
if ( ASSETCHAINS_FOUNDERS_REWARD != 0 )
{
fprintf(stderr, "set founders reward.%li\n",ASSETCHAINS_FOUNDERS_REWARD);
fprintf(stderr, "set founders reward.%lld\n",(long long)ASSETCHAINS_FOUNDERS_REWARD);
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_FOUNDERS_REWARD),(void *)&ASSETCHAINS_FOUNDERS_REWARD);
}
}
@@ -2125,6 +2151,7 @@ void komodo_args(char *argv0)
extraptr[extralen++] = 'c';
if ( ASSETCHAINS_MARMARA != 0 )
extraptr[extralen++] = ASSETCHAINS_MARMARA;
fprintf(stderr,"extralen.%d before disable bits\n",extralen);
if ( nonz > 0 )
{
memcpy(&extraptr[extralen],disablebits,sizeof(disablebits));
@@ -2184,6 +2211,12 @@ void komodo_args(char *argv0)
{
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_EARLYTXIDCONTRACT),(void *)&ASSETCHAINS_EARLYTXIDCONTRACT);
}
if ( ASSETCHAINS_CBMATURITY != 0 )
{
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_CBMATURITY),(void *)&ASSETCHAINS_CBMATURITY);
}
if ( ASSETCHAINS_ADAPTIVEPOW != 0 )
extraptr[extralen++] = ASSETCHAINS_ADAPTIVEPOW;
}
addn = GetArg("-seednode","");
@@ -2235,8 +2268,16 @@ void komodo_args(char *argv0)
if ( (port= komodo_userpass(ASSETCHAINS_USERPASS,ASSETCHAINS_SYMBOL)) != 0 )
ASSETCHAINS_RPCPORT = port;
else komodo_configfile(ASSETCHAINS_SYMBOL,ASSETCHAINS_P2PPORT + 1);
if (ASSETCHAINS_LASTERA == 0 || is_STAKED(ASSETCHAINS_SYMBOL) != 0)
if (ASSETCHAINS_CBMATURITY != 0)
COINBASE_MATURITY = ASSETCHAINS_CBMATURITY;
else if (ASSETCHAINS_LASTERA == 0 || is_STAKED(ASSETCHAINS_SYMBOL) != 0)
COINBASE_MATURITY = 1;
if (COINBASE_MATURITY < 1)
{
fprintf(stderr,"ac_cbmaturity must be >0, shutting down\n");
StartShutdown();
}
//fprintf(stderr,"ASSETCHAINS_RPCPORT (%s) %u\n",ASSETCHAINS_SYMBOL,ASSETCHAINS_RPCPORT);
}
if ( ASSETCHAINS_RPCPORT == 0 )
@@ -2259,10 +2300,18 @@ void komodo_args(char *argv0)
//printf("created (%s)\n",fname);
} else printf("error creating (%s)\n",fname);
#endif
if ( KOMODO_CCACTIVATE != 0 && ASSETCHAINS_CC < 2 )
if ( ASSETCHAINS_CC < 2 )
{
ASSETCHAINS_CC = 2;
fprintf(stderr,"smart utxo CC contracts will activate at height.%d\n",KOMODO_CCACTIVATE);
if ( KOMODO_CCACTIVATE != 0 )
{
ASSETCHAINS_CC = 2;
fprintf(stderr,"smart utxo CC contracts will activate at height.%d\n",KOMODO_CCACTIVATE);
}
else if ( ccEnablesHeight[0] != 0 )
{
ASSETCHAINS_CC = 2;
fprintf(stderr,"smart utxo CC contract %d will activate at height.%d\n",(int32_t)ccEnablesHeight[0],(int32_t)ccEnablesHeight[1]);
}
}
}
else
@@ -2311,7 +2360,7 @@ void komodo_args(char *argv0)
if ( strcmp("PIRATE",ASSETCHAINS_SYMBOL) == 0 && ASSETCHAINS_HALVING[0] == 77777 )
{
ASSETCHAINS_HALVING[0] *= 5;
fprintf(stderr,"PIRATE halving changed to %d %.1f days ASSETCHAINS_LASTERA.%lu\n",(int32_t)ASSETCHAINS_HALVING[0],(double)ASSETCHAINS_HALVING[0]/1440,ASSETCHAINS_LASTERA);
fprintf(stderr,"PIRATE halving changed to %d %.1f days ASSETCHAINS_LASTERA.%llu\n",(int32_t)ASSETCHAINS_HALVING[0],(double)ASSETCHAINS_HALVING[0]/1440,(long long)ASSETCHAINS_LASTERA);
}
else if ( strcmp("VRSC",ASSETCHAINS_SYMBOL) == 0 )
dpowconfs = 0;
+334 -194
View File
@@ -147,7 +147,7 @@ namespace {
struct CBlockIndexWorkComparator
{
bool operator()(const CBlockIndex *pa, const CBlockIndex *pb) const {
bool operator()(CBlockIndex *pa, const CBlockIndex *pb) const {
// First sort by most total work, ...
if (ASSETCHAINS_LWMAPOS) {
@@ -352,7 +352,10 @@ namespace {
int GetHeight()
{
return chainActive.LastTip()->GetHeight();
CBlockIndex *pindex;
if ( (pindex= chainActive.LastTip()) != 0 )
return pindex->GetHeight();
else return(0);
}
void UpdatePreferredDownload(CNode* node, CNodeState* state)
@@ -735,6 +738,7 @@ bool komodo_dailysnapshot(int32_t height)
for (unsigned int j = tx.vin.size(); j-- > 0;)
{
uint256 blockhash; CTransaction txin;
if (tx.IsPegsImport() && j==0) continue;
if ( !tx.IsCoinImport() && !tx.IsCoinBase() && myGetTransaction(tx.vin[j].prevout.hash,txin,blockhash) )
{
int vout = tx.vin[j].prevout.n;
@@ -758,7 +762,7 @@ bool komodo_dailysnapshot(int32_t height)
// include only top 3999 address.
if ( vAddressSnapshot.size() > 3999 ) vAddressSnapshot.resize(3999);
lastSnapShotHeight = undo_height;
fprintf(stderr, "vAddressSnapshot.size.%li\n", vAddressSnapshot.size());
fprintf(stderr, "vAddressSnapshot.size.%d\n", (int32_t)vAddressSnapshot.size());
return true;
}
@@ -1012,6 +1016,7 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs,
for (unsigned int i = 0; i < tx.vin.size(); i++)
{
if (tx.IsPegsImport() && i==0) continue;
const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]);
vector<vector<unsigned char> > vSolutions;
@@ -1089,6 +1094,7 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in
unsigned int nSigOps = 0;
for (unsigned int i = 0; i < tx.vin.size(); i++)
{
if (tx.IsPegsImport() && i==0) continue;
const CTxOut &prevout = inputs.GetOutputFor(tx.vin[i]);
if (prevout.scriptPubKey.IsPayToScriptHash())
nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
@@ -1100,7 +1106,7 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in
* Ensure that a coinbase transaction is structured according to the consensus rules of the
* chain
*/
bool ContextualCheckCoinbaseTransaction(const CBlock *block,CBlockIndex * const previndex,const CTransaction& tx, const int nHeight,int32_t validateprices)
bool ContextualCheckCoinbaseTransaction(int32_t slowflag,const CBlock *block,CBlockIndex * const previndex,const CTransaction& tx, const int nHeight,int32_t validateprices)
{
// if time locks are on, ensure that this coin base is time locked exactly as it should be
if (((uint64_t)(tx.GetValueOut()) >= ASSETCHAINS_TIMELOCKGTE) ||
@@ -1141,7 +1147,7 @@ bool ContextualCheckCoinbaseTransaction(const CBlock *block,CBlockIndex * const
{
}
else if ( ASSETCHAINS_CBOPRET != 0 && validateprices != 0 && nHeight > 0 && tx.vout.size() > 0 )
else if ( slowflag != 0 && ASSETCHAINS_CBOPRET != 0 && validateprices != 0 && nHeight > 0 && tx.vout.size() > 0 )
{
if ( komodo_opretvalidate(block,previndex,nHeight,tx.vout[tx.vout.size()-1].scriptPubKey) < 0 )
return(false);
@@ -1158,7 +1164,7 @@ bool ContextualCheckCoinbaseTransaction(const CBlock *block,CBlockIndex * const
* and ContextualCheckBlock (which calls this function).
* 3. The isInitBlockDownload argument is only to assist with testing.
*/
bool ContextualCheckTransaction(const CBlock *block, CBlockIndex * const previndex,
bool ContextualCheckTransaction(int32_t slowflag,const CBlock *block, CBlockIndex * const previndex,
const CTransaction& tx,
CValidationState &state,
const int nHeight,
@@ -1294,7 +1300,7 @@ bool ContextualCheckTransaction(const CBlock *block, CBlockIndex * const prevind
if (tx.IsCoinBase())
{
if (!ContextualCheckCoinbaseTransaction(block,previndex,tx, nHeight,validateprices))
if (!ContextualCheckCoinbaseTransaction(slowflag,block,previndex,tx, nHeight,validateprices))
return state.DoS(100, error("CheckTransaction(): invalid script data for coinbase time lock"),
REJECT_INVALID, "bad-txns-invalid-script-data-for-coinbase-time-lock");
}
@@ -1774,7 +1780,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
//fprintf(stderr,"already in mempool\n");
return state.Invalid(false, REJECT_DUPLICATE, "already in mempool");
}
//fprintf(stderr,"addmempool 0\n");
// Node operator can choose to reject tx by number of transparent inputs
static_assert(std::numeric_limits<size_t>::max() >= std::numeric_limits<int64_t>::max(), "size_t too small");
size_t limit = (size_t) GetArg("-mempooltxinputlimit", 0);
@@ -1788,6 +1794,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
return false;
}
}
//fprintf(stderr,"addmempool 1\n");
auto verifier = libzcash::ProofVerifier::Strict();
if ( ASSETCHAINS_SYMBOL[0] == 0 && komodo_validate_interest(tx,chainActive.LastTip()->GetHeight()+1,chainActive.LastTip()->GetMedianTimePast() + 777,0) < 0 )
@@ -1801,11 +1808,12 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
}
// DoS level set to 10 to be more forgiving.
// Check transaction contextually against the set of consensus rules which apply in the next block to be mined.
if (!fSkipExpiry && !ContextualCheckTransaction(0,0,tx, state, nextBlockHeight, (dosLevel == -1) ? 10 : dosLevel,0))
if (!fSkipExpiry && !ContextualCheckTransaction(0,0,0,tx, state, nextBlockHeight, (dosLevel == -1) ? 10 : dosLevel,0))
{
return error("AcceptToMemoryPool: ContextualCheckTransaction failed");
}
// Coinbase is only valid in a block, not as a loose transaction
//fprintf(stderr,"addmempool 2\n");
// Coinbase is only valid in a block, not as a loose transaction
if (tx.IsCoinBase())
{
fprintf(stderr,"AcceptToMemoryPool coinbase as individual tx\n");
@@ -1827,6 +1835,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
//fprintf(stderr,"AcceptToMemoryPool reject non-final\n");
return state.DoS(0, false, REJECT_NONSTANDARD, "non-final");
}
//fprintf(stderr,"addmempool 3\n");
// Check for conflicts with in-memory transactions
if (!fSkipExpiry)
@@ -1855,6 +1864,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
}
}
}
//fprintf(stderr,"addmempool 4\n");
{
CCoinsView dummy;
@@ -1873,7 +1883,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
return state.Invalid(false, REJECT_DUPLICATE, "already have coins");
}
if (tx.IsCoinImport())
if (tx.IsCoinImport() || tx.IsPegsImport())
{
// Inverse of normal case; if input exists, it's been spent
if (ExistsImportTombstone(tx, view))
@@ -1945,7 +1955,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// Keep track of transactions that spend a coinbase, which we re-scan
// during reorgs to ensure COINBASE_MATURITY is still met.
bool fSpendsCoinbase = false;
if (!fSkipExpiry && !tx.IsCoinImport()) {
if (!fSkipExpiry && !tx.IsCoinImport() && !tx.IsPegsImport()) {
BOOST_FOREACH(const CTxIn &txin, tx.vin) {
const CCoins *coins = view.AccessCoins(txin.prevout.hash);
if (coins->IsCoinBase()) {
@@ -1954,6 +1964,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
}
}
}
//fprintf(stderr,"addmempool 5\n");
// Grab the branch ID we expect this transaction to commit to. We don't
// yet know if it does, but if the entry gets added to the mempool, then
@@ -1985,7 +1996,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// Continuously rate-limit free (really, very-low-fee) transactions
// This mitigates 'penny-flooding' -- sending thousands of free transactions just to
// be annoying or make others' transactions take longer to confirm.
if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize) && !tx.IsCoinImport())
if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize) && !tx.IsCoinImport() && !tx.IsPegsImport())
{
static CCriticalSection csFreeLimiter;
static double dFreeCount;
@@ -2008,7 +2019,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
dFreeCount += nSize;
}
if (!tx.IsCoinImport() && fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19)
if (!tx.IsCoinImport() && !tx.IsPegsImport() && fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19)
{
string errmsg = strprintf("absurdly high fees %s, %d > %d",
hash.ToString(),
@@ -2016,6 +2027,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
LogPrint("mempool", errmsg.c_str());
return state.Error("AcceptToMemoryPool: " + errmsg);
}
//fprintf(stderr,"addmempool 6\n");
// Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
@@ -2041,6 +2053,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
flag = 1;
KOMODO_CONNECTING = (1<<30) + (int32_t)chainActive.LastTip()->GetHeight() + 1;
}
//fprintf(stderr,"addmempool 7\n");
if (!fSkipExpiry && !ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
{
if ( flag != 0 )
@@ -2214,6 +2227,18 @@ bool myAddtomempool(CTransaction &tx, CValidationState *pstate, bool fSkipExpiry
bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock)
{
memset(&hashBlock,0,sizeof(hashBlock));
if ( KOMODO_NSPV > 0 )
{
int64_t rewardsum = 0; int32_t i,retval,txheight,currentheight,height=0,vout = 0;
for (i=0; i<NSPV_U.U.numutxos; i++)
if ( NSPV_U.U.utxos[i].txid == hash )
{
height = NSPV_U.U.utxos[i].height;
break;
}
retval = NSPV_gettransaction(1,vout,hash,height,txOut,hashBlock,txheight,currentheight,0,0,rewardsum);
return(retval != -1);
}
// need a GetTransaction without lock so the validation code for assets can run without deadlock
{
//fprintf(stderr,"check mempool %s\n",hash.GetHex().c_str());
@@ -2253,6 +2278,24 @@ bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlo
return false;
}
bool NSPV_myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, int32_t &txheight, int32_t &currentheight)
{
memset(&hashBlock,0,sizeof(hashBlock));
if ( KOMODO_NSPV > 0 )
{
int64_t rewardsum = 0; int32_t i,retval,height=0,vout = 0;
for (i=0; i<NSPV_U.U.numutxos; i++)
if ( NSPV_U.U.utxos[i].txid == hash )
{
height = NSPV_U.U.utxos[i].height;
break;
}
retval = NSPV_gettransaction(1,vout,hash,height,txOut,hashBlock,txheight,currentheight,0,0,rewardsum);
return(retval != -1);
}
return false;
}
/** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */
bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
{
@@ -2407,7 +2450,7 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW)
//uint64_t komodo_moneysupply(int32_t height);
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
extern uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS];
extern uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS+1], ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS+1], ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS+1];
extern uint32_t ASSETCHAINS_MAGIC;
extern uint64_t ASSETCHAINS_LINEAR,ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY;
extern uint8_t ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE;
@@ -2689,6 +2732,7 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txund
{
txundo.vprevout.reserve(tx.vin.size());
BOOST_FOREACH(const CTxIn &txin, tx.vin) {
if (tx.IsPegsImport() && txin.prevout.n==10e8) continue;
CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash);
unsigned nPos = txin.prevout.n;
@@ -2712,7 +2756,7 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txund
inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); // add outputs
// Unorthodox state
if (tx.IsCoinImport()) {
if (tx.IsCoinImport() || tx.IsPegsImport()) {
// add a tombstone for the burnTx
AddImportTombstone(tx, inputs, nHeight);
}
@@ -2756,6 +2800,11 @@ namespace Consensus {
CAmount nFees = 0;
for (unsigned int i = 0; i < tx.vin.size(); i++)
{
if (tx.IsPegsImport() && i==0)
{
nValueIn=GetCoinImportValue(tx);
continue;
}
const COutPoint &prevout = tx.vin[i].prevout;
const CCoins *coins = inputs.AccessCoins(prevout.hash);
assert(coins);
@@ -2867,6 +2916,7 @@ bool ContextualCheckInputs(
// still computed and checked, and any change will be caught at the next checkpoint.
if (fScriptChecks) {
for (unsigned int i = 0; i < tx.vin.size(); i++) {
if (tx.IsPegsImport() && i==0) continue;
const COutPoint &prevout = tx.vin[i].prevout;
const CCoins* coins = inputs.AccessCoins(prevout.hash);
assert(coins);
@@ -2902,7 +2952,7 @@ bool ContextualCheckInputs(
}
}
if (tx.IsCoinImport())
if (tx.IsCoinImport() || tx.IsPegsImport())
{
LOCK(cs_main);
ServerTransactionSignatureChecker checker(&tx, 0, 0, false, txdata);
@@ -3188,10 +3238,12 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
// restore inputs
if (!tx.IsMint()) {
const CTxUndo &txundo = blockUndo.vtxundo[i-1];
CTxUndo &txundo = blockUndo.vtxundo[i-1];
if (tx.IsPegsImport()) txundo.vprevout.insert(txundo.vprevout.begin(),CTxInUndo());
if (txundo.vprevout.size() != tx.vin.size())
return error("DisconnectBlock(): transaction and undo data inconsistent");
for (unsigned int j = tx.vin.size(); j-- > 0;) {
if (tx.IsPegsImport() && j==0) continue;
const COutPoint &out = tx.vin[j].prevout;
const CTxInUndo &undo = txundo.vprevout[j];
if (!ApplyTxInUndo(undo, view, out))
@@ -3225,7 +3277,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
}
}
}
else if (tx.IsCoinImport())
else if (tx.IsCoinImport() || tx.IsPegsImport())
{
RemoveImportTombstone(tx, view);
}
@@ -3375,6 +3427,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
{
CDiskBlockPos blockPos;
const CChainParams& chainparams = Params();
if ( KOMODO_NSPV > 0 )
return(true);
if ( KOMODO_STOPAT != 0 && pindex->GetHeight() > KOMODO_STOPAT )
return(false);
//fprintf(stderr,"connectblock ht.%d\n",(int32_t)pindex->GetHeight());
@@ -3399,7 +3453,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
}
if ( fCheckPOW != 0 && (pindex->nStatus & BLOCK_VALID_CONTEXT) != BLOCK_VALID_CONTEXT ) // Activate Jan 15th, 2019
{
if ( !ContextualCheckBlock(block, state, pindex->pprev) )
if ( !ContextualCheckBlock(1,block, state, pindex->pprev) )
{
fprintf(stderr,"ContextualCheckBlock failed ht.%d\n",(int32_t)pindex->GetHeight());
if ( pindex->nTime > 1547510400 )
@@ -3573,6 +3627,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
{
for (size_t j = 0; j < tx.vin.size(); j++)
{
if (tx.IsPegsImport() && j==0) continue;
const CTxIn input = tx.vin[j];
const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
@@ -3956,7 +4011,8 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
void FlushStateToDisk() {
CValidationState state;
FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
if ( KOMODO_NSPV <= 0 )
FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
}
void PruneAndFlush() {
@@ -4106,7 +4162,7 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) {
if ((i == (block.vtx.size() - 1)) && (ASSETCHAINS_STAKED != 0 && (komodo_isPoS((CBlock *)&block,pindexDelete->GetHeight(),true) != 0)))
{
#ifdef ENABLE_WALLET
if ( !GetBoolArg("-disablewallet", false) )
if ( !GetBoolArg("-disablewallet", false) && KOMODO_NSPV <= 0 )
pwalletMain->EraseFromWallet(tx.GetHash());
#endif
}
@@ -4211,8 +4267,11 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
// Get the current commitment tree
SproutMerkleTree oldSproutTree;
SaplingMerkleTree oldSaplingTree;
assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), oldSproutTree));
assert(pcoinsTip->GetSaplingAnchorAt(pcoinsTip->GetBestAnchor(SAPLING), oldSaplingTree));
if ( KOMODO_NSPV <= 0 )
{
assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), oldSproutTree));
assert(pcoinsTip->GetSaplingAnchorAt(pcoinsTip->GetBestAnchor(SAPLING), oldSaplingTree));
}
// Apply the block atomically to the chain state.
int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
int64_t nTime3;
@@ -4237,13 +4296,17 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
mapBlockSource.erase(pindexNew->GetBlockHash());
nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
LogPrint("bench", " - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
assert(view.Flush());
if ( KOMODO_NSPV <= 0 )
assert(view.Flush());
}
int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
LogPrint("bench", " - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001);
// Write the chain state to disk, if necessary.
if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
return false;
if ( KOMODO_NSPV <= 0 )
{
if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
return false;
}
int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);
// Remove conflicting transactions from the mempool.
@@ -4255,14 +4318,17 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
// Update chainActive & related variables.
UpdateTip(pindexNew);
// Tell wallet about transactions that went from mempool
// to conflicted:
BOOST_FOREACH(const CTransaction &tx, txConflicted) {
SyncWithWallets(tx, NULL);
}
// ... and about transactions that got confirmed:
BOOST_FOREACH(const CTransaction &tx, pblock->vtx) {
SyncWithWallets(tx, pblock);
if ( KOMODO_NSPV <= 0 )
{
// Tell wallet about transactions that went from mempool
// to conflicted:
BOOST_FOREACH(const CTransaction &tx, txConflicted) {
SyncWithWallets(tx, NULL);
}
// ... and about transactions that got confirmed:
BOOST_FOREACH(const CTransaction &tx, pblock->vtx) {
SyncWithWallets(tx, pblock);
}
}
// Update cached incremental witnesses
GetMainSignals().ChainTip(pindexNew, pblock, oldSproutTree, oldSaplingTree, true);
@@ -4280,19 +4346,22 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
komodo_broadcast(pblock,8);
else if ( ASSETCHAINS_SYMBOL[0] != 0 )
komodo_broadcast(pblock,4);*/
if ( ASSETCHAINS_CBOPRET != 0 )
komodo_pricesupdate(pindexNew->GetHeight(),pblock);
if ( ASSETCHAINS_SAPLING <= 0 && pindexNew->nTime > KOMODO_SAPLING_ACTIVATION - 24*3600 )
komodo_activate_sapling(pindexNew);
if ( ASSETCHAINS_CC != 0 && KOMODO_SNAPSHOT_INTERVAL != 0 && (pindexNew->GetHeight() % KOMODO_SNAPSHOT_INTERVAL) == 0 && pindexNew->GetHeight() >= KOMODO_SNAPSHOT_INTERVAL )
if ( KOMODO_NSPV <= 0 )
{
uint64_t start = time(NULL);
if ( !komodo_dailysnapshot(pindexNew->GetHeight()) )
if ( ASSETCHAINS_CBOPRET != 0 )
komodo_pricesupdate(pindexNew->GetHeight(),pblock);
if ( ASSETCHAINS_SAPLING <= 0 && pindexNew->nTime > KOMODO_SAPLING_ACTIVATION - 24*3600 )
komodo_activate_sapling(pindexNew);
if ( ASSETCHAINS_CC != 0 && KOMODO_SNAPSHOT_INTERVAL != 0 && (pindexNew->GetHeight() % KOMODO_SNAPSHOT_INTERVAL) == 0 && pindexNew->GetHeight() >= KOMODO_SNAPSHOT_INTERVAL )
{
fprintf(stderr, "daily snapshot failed, please reindex your chain\n");
StartShutdown();
uint64_t start = time(NULL);
if ( !komodo_dailysnapshot(pindexNew->GetHeight()) )
{
fprintf(stderr, "daily snapshot failed, please reindex your chain\n");
StartShutdown();
}
fprintf(stderr, "snapshot completed in: %d seconds\n", (int32_t)(time(NULL)-start));
}
fprintf(stderr, "snapshot completed in: %lu seconds\n", time(NULL)-start);
}
return true;
}
@@ -5022,7 +5091,15 @@ bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,
}
}
*futureblockp = 0;
if (blockhdr.GetBlockTime() > GetAdjustedTime() + 60)
if ( ASSETCHAINS_ADAPTIVEPOW > 0 )
{
if (blockhdr.GetBlockTime() > GetAdjustedTime() + 4)
{
//LogPrintf("CheckBlockHeader block from future %d error",blockhdr.GetBlockTime() - GetAdjustedTime());
return false;
}
}
else if (blockhdr.GetBlockTime() > GetAdjustedTime() + 60)
{
/*CBlockIndex *tipindex;
//fprintf(stderr,"ht.%d future block %u vs time.%u + 60\n",height,(uint32_t)blockhdr.GetBlockTime(),(uint32_t)GetAdjustedTime());
@@ -5267,10 +5344,23 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
}
// Check timestamp against prev
if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
if ( ASSETCHAINS_ADAPTIVEPOW <= 0 || nHeight < 30 )
{
return state.Invalid(error("%s: block's timestamp is too early", __func__),
REJECT_INVALID, "time-too-old");
if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast() )
{
fprintf(stderr,"ht.%d too early %u vs %u\n",(int32_t)nHeight,(uint32_t)block.GetBlockTime(),(uint32_t)pindexPrev->GetMedianTimePast());
return state.Invalid(error("%s: block's timestamp is too early", __func__),
REJECT_INVALID, "time-too-old");
}
}
else
{
if ( block.GetBlockTime() <= pindexPrev->nTime )
{
fprintf(stderr,"ht.%d too early2 %u vs %u\n",(int32_t)nHeight,(uint32_t)block.GetBlockTime(),(uint32_t)pindexPrev->nTime);
return state.Invalid(error("%s: block's timestamp is too early2", __func__),
REJECT_INVALID, "time-too-old");
}
}
// Check that timestamp is not too far in the future
@@ -5326,7 +5416,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
return true;
}
bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex * const pindexPrev)
bool ContextualCheckBlock(int32_t slowflag,const CBlock& block, CValidationState& state, CBlockIndex * const pindexPrev)
{
const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->GetHeight() + 1;
const Consensus::Params& consensusParams = Params().GetConsensus();
@@ -5337,7 +5427,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
const CTransaction& tx = block.vtx[i];
// Check transaction contextually against consensus rules at block height
if (!ContextualCheckTransaction(&block,pindexPrev,tx, state, nHeight, 100)) {
if (!ContextualCheckTransaction(slowflag,&block,pindexPrev,tx, state, nHeight, 100)) {
return false; // Failure reason has been set in validation state object
}
@@ -5506,7 +5596,7 @@ bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, C
// See method docstring for why this is always disabled
auto verifier = libzcash::ProofVerifier::Disabled();
bool fContextualCheckBlock = ContextualCheckBlock(block, state, pindex->pprev);
bool fContextualCheckBlock = ContextualCheckBlock(0,block, state, pindex->pprev);
if ( (!CheckBlock(futureblockp,pindex->GetHeight(),pindex,block, state, verifier,0)) || !fContextualCheckBlock )
{
static int32_t saplinght = -1;
@@ -5774,7 +5864,7 @@ bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex
//fprintf(stderr,"TestBlockValidity failure B checkPOW.%d\n",fCheckPOW);
return false;
}
if (!ContextualCheckBlock(block, state, pindexPrev))
if (!ContextualCheckBlock(0,block, state, pindexPrev))
{
//fprintf(stderr,"TestBlockValidity failure C checkPOW.%d\n",fCheckPOW);
return false;
@@ -6488,22 +6578,24 @@ bool InitBlockIndex() {
{
return true;
}
// Use the provided setting for -txindex in the new database
fTxIndex = GetBoolArg("-txindex", true);
pblocktree->WriteFlag("txindex", fTxIndex);
// Use the provided setting for -addressindex in the new database
fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX);
pblocktree->WriteFlag("addressindex", fAddressIndex);
// Use the provided setting for -timestampindex in the new database
fTimestampIndex = GetBoolArg("-timestampindex", DEFAULT_TIMESTAMPINDEX);
pblocktree->WriteFlag("timestampindex", fTimestampIndex);
fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX);
pblocktree->WriteFlag("spentindex", fSpentIndex);
fprintf(stderr,"fAddressIndex.%d/%d fSpentIndex.%d/%d\n",fAddressIndex,DEFAULT_ADDRESSINDEX,fSpentIndex,DEFAULT_SPENTINDEX);
LogPrintf("Initializing databases...\n");
if ( pblocktree != 0 )
{
// Use the provided setting for -txindex in the new database
fTxIndex = GetBoolArg("-txindex", true);
pblocktree->WriteFlag("txindex", fTxIndex);
// Use the provided setting for -addressindex in the new database
fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX);
pblocktree->WriteFlag("addressindex", fAddressIndex);
// Use the provided setting for -timestampindex in the new database
fTimestampIndex = GetBoolArg("-timestampindex", DEFAULT_TIMESTAMPINDEX);
pblocktree->WriteFlag("timestampindex", fTimestampIndex);
fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX);
pblocktree->WriteFlag("spentindex", fSpentIndex);
fprintf(stderr,"fAddressIndex.%d/%d fSpentIndex.%d/%d\n",fAddressIndex,DEFAULT_ADDRESSINDEX,fSpentIndex,DEFAULT_SPENTINDEX);
LogPrintf("Initializing databases...\n");
}
// Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
if (!fReindex) {
try {
@@ -6524,7 +6616,9 @@ bool InitBlockIndex() {
if (!ActivateBestChain(true, state, &block))
return error("LoadBlockIndex(): genesis block cannot be activated");
// Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data
return FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
if ( KOMODO_NSPV <= 0 )
return FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
else return(true);
} catch (const std::runtime_error& e) {
return error("LoadBlockIndex(): failed to initialize block database: %s", e.what());
}
@@ -7072,11 +7166,19 @@ void static ProcessGetData(CNode* pfrom)
}
}
#include "komodo_nSPV_defs.h"
#include "komodo_nSPV.h" // shared defines, structs, serdes, purge functions
#include "komodo_nSPV_fullnode.h" // nSPV fullnode handling of the getnSPV request messages
#include "komodo_nSPV_superlite.h" // nSPV superlite client, issuing requests and handling nSPV responses
#include "komodo_nSPV_wallet.h" // nSPV_send and support functions, really all the rest is to support this
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
{
const CChainParams& chainparams = Params();
LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
//fprintf(stderr, "recv: %s peer=%d\n", SanitizeString(strCommand).c_str(), (int32_t)pfrom->GetId());
//if ( KOMODO_NSPV > 0 )
//if ( strCommand != "version" && strCommand != "verack" )
// fprintf(stderr, "recv: %s (%u bytes) peer=%d\n", SanitizeString(strCommand).c_str(), (int32_t)vRecv.size(), (int32_t)pfrom->GetId());
if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
{
LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
@@ -7235,7 +7337,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
}
else if ( strCommand == "events" )
{
int32_t i;
if ( ASSETCHAINS_CCLIB != "gamescc" )
{
Misbehaving(pfrom->GetId(), 1);
@@ -7250,6 +7351,15 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
{
pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
if ( KOMODO_NSPV > 0 )
{
if ( (pfrom->nServices & NODE_NSPV) == 0 )
{
// fprintf(stderr,"invalid nServices.%llx nSPV peer.%d\n",(long long)pfrom->nServices,pfrom->id);
pfrom->fDisconnect = true;
return false;
}
}
// Mark this node as currently connected, so we update its timestamp later.
if (pfrom->fNetworkNode) {
LOCK(cs_main);
@@ -7264,7 +7374,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
else if (pfrom->nVersion < chainparams.GetConsensus().vUpgrades[
CurrentEpoch(GetHeight(), chainparams.GetConsensus())].nProtocolVersion)
{
LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
LogPrintf("peer=%d using obsolete version %i vs %d; disconnecting\n", pfrom->id, pfrom->nVersion,(int32_t)chainparams.GetConsensus().vUpgrades[
CurrentEpoch(GetHeight(), chainparams.GetConsensus())].nProtocolVersion);
pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
strprintf("Version must be %d or greater",
chainparams.GetConsensus().vUpgrades[
@@ -7339,8 +7450,127 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
if (pfrom->fOneShot)
pfrom->fDisconnect = true;
}
else if (strCommand == "ping")
{
if (pfrom->nVersion > BIP0031_VERSION)
{
uint64_t nonce = 0;
vRecv >> nonce;
// Echo the message back with the nonce. This allows for two useful features:
//
// 1) A remote node can quickly check if the connection is operational
// 2) Remote nodes can measure the latency of the network thread. If this node
// is overloaded it won't respond to pings quickly and the remote node can
// avoid sending us more work, like chain download requests.
//
// The nonce stops the remote getting confused between different pings: without
// it, if the remote node sends a ping once per second and this node takes 5
// seconds to respond to each, the 5th ping the remote sends would appear to
// return very quickly.
pfrom->PushMessage("pong", nonce);
}
}
else if (strCommand == "pong")
{
int64_t pingUsecEnd = nTimeReceived;
uint64_t nonce = 0;
size_t nAvail = vRecv.in_avail();
bool bPingFinished = false;
std::string sProblem;
if (nAvail >= sizeof(nonce)) {
vRecv >> nonce;
// Only process pong message if there is an outstanding ping (old ping without nonce should never pong)
if (pfrom->nPingNonceSent != 0) {
if (nonce == pfrom->nPingNonceSent) {
// Matching pong received, this ping is no longer outstanding
bPingFinished = true;
int64_t pingUsecTime = pingUsecEnd - pfrom->nPingUsecStart;
if (pingUsecTime > 0) {
// Successful ping time measurement, replace previous
pfrom->nPingUsecTime = pingUsecTime;
pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime, pingUsecTime);
} else {
// This should never happen
sProblem = "Timing mishap";
}
} else {
// Nonce mismatches are normal when pings are overlapping
sProblem = "Nonce mismatch";
if (nonce == 0) {
// This is most likely a bug in another implementation somewhere; cancel this ping
bPingFinished = true;
sProblem = "Nonce zero";
}
}
} else {
sProblem = "Unsolicited pong without ping";
}
} else {
// This is most likely a bug in another implementation somewhere; cancel this ping
bPingFinished = true;
sProblem = "Short payload";
}
if (!(sProblem.empty())) {
LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n",
pfrom->id,
pfrom->cleanSubVer,
sProblem,
pfrom->nPingNonceSent,
nonce,
nAvail);
}
if (bPingFinished) {
pfrom->nPingNonceSent = 0;
}
}
// This asymmetric behavior for inbound and outbound connections was introduced
// to prevent a fingerprinting attack: an attacker can send specific fake addresses
// to users' AddrMan and later request them by sending getaddr messages.
// Making nodes which are behind NAT and can only make outgoing connections ignore
// the getaddr message mitigates the attack.
else if ((strCommand == "getaddr") && (pfrom->fInbound))
{
// Only send one GetAddr response per connection to reduce resource waste
// and discourage addr stamping of INV announcements.
if (pfrom->fSentAddr) {
LogPrint("net", "Ignoring repeated \"getaddr\". peer=%d\n", pfrom->id);
return true;
}
pfrom->fSentAddr = true;
pfrom->vAddrToSend.clear();
vector<CAddress> vAddr = addrman.GetAddr();
BOOST_FOREACH(const CAddress &addr, vAddr)
pfrom->PushAddress(addr);
}
else if (strCommand == "getnSPV")
{
if ( KOMODO_NSPV == 0 && KOMODO_INSYNC != 0 )
{
std::vector<uint8_t> payload;
vRecv >> payload;
komodo_nSPVreq(pfrom,payload);
}
return(true);
}
else if (strCommand == "nSPV")
{
if ( KOMODO_NSPV > 0 )
{
std::vector<uint8_t> payload;
vRecv >> payload;
komodo_nSPVresp(pfrom,payload);
}
return(true);
}
else if ( KOMODO_NSPV > 0 )
return(true);
else if (strCommand == "inv")
{
vector<CInv> vInv;
@@ -7752,28 +7982,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
}
// This asymmetric behavior for inbound and outbound connections was introduced
// to prevent a fingerprinting attack: an attacker can send specific fake addresses
// to users' AddrMan and later request them by sending getaddr messages.
// Making nodes which are behind NAT and can only make outgoing connections ignore
// the getaddr message mitigates the attack.
else if ((strCommand == "getaddr") && (pfrom->fInbound))
{
// Only send one GetAddr response per connection to reduce resource waste
// and discourage addr stamping of INV announcements.
if (pfrom->fSentAddr) {
LogPrint("net", "Ignoring repeated \"getaddr\". peer=%d\n", pfrom->id);
return true;
}
pfrom->fSentAddr = true;
pfrom->vAddrToSend.clear();
vector<CAddress> vAddr = addrman.GetAddr();
BOOST_FOREACH(const CAddress &addr, vAddr)
pfrom->PushAddress(addr);
}
else if (strCommand == "mempool")
{
LOCK2(cs_main, pfrom->cs_filter);
@@ -7798,88 +8006,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
if (vInv.size() > 0)
pfrom->PushMessage("inv", vInv);
}
else if (strCommand == "ping")
{
if (pfrom->nVersion > BIP0031_VERSION)
{
uint64_t nonce = 0;
vRecv >> nonce;
// Echo the message back with the nonce. This allows for two useful features:
//
// 1) A remote node can quickly check if the connection is operational
// 2) Remote nodes can measure the latency of the network thread. If this node
// is overloaded it won't respond to pings quickly and the remote node can
// avoid sending us more work, like chain download requests.
//
// The nonce stops the remote getting confused between different pings: without
// it, if the remote node sends a ping once per second and this node takes 5
// seconds to respond to each, the 5th ping the remote sends would appear to
// return very quickly.
pfrom->PushMessage("pong", nonce);
}
}
else if (strCommand == "pong")
{
int64_t pingUsecEnd = nTimeReceived;
uint64_t nonce = 0;
size_t nAvail = vRecv.in_avail();
bool bPingFinished = false;
std::string sProblem;
if (nAvail >= sizeof(nonce)) {
vRecv >> nonce;
// Only process pong message if there is an outstanding ping (old ping without nonce should never pong)
if (pfrom->nPingNonceSent != 0) {
if (nonce == pfrom->nPingNonceSent) {
// Matching pong received, this ping is no longer outstanding
bPingFinished = true;
int64_t pingUsecTime = pingUsecEnd - pfrom->nPingUsecStart;
if (pingUsecTime > 0) {
// Successful ping time measurement, replace previous
pfrom->nPingUsecTime = pingUsecTime;
pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime, pingUsecTime);
} else {
// This should never happen
sProblem = "Timing mishap";
}
} else {
// Nonce mismatches are normal when pings are overlapping
sProblem = "Nonce mismatch";
if (nonce == 0) {
// This is most likely a bug in another implementation somewhere; cancel this ping
bPingFinished = true;
sProblem = "Nonce zero";
}
}
} else {
sProblem = "Unsolicited pong without ping";
}
} else {
// This is most likely a bug in another implementation somewhere; cancel this ping
bPingFinished = true;
sProblem = "Short payload";
}
if (!(sProblem.empty())) {
LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n",
pfrom->id,
pfrom->cleanSubVer,
sProblem,
pfrom->nPingNonceSent,
nonce,
nAvail);
}
if (bPingFinished) {
pfrom->nPingNonceSent = 0;
}
}
else if (fAlerts && strCommand == "alert")
{
CAlert alert;
@@ -8233,7 +8359,11 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
}
state.fShouldBan = false;
}
if ( KOMODO_NSPV > 0 )
{
komodo_nSPV(pto);
return(true);
}
BOOST_FOREACH(const CBlockReject& reject, state.rejects)
pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock);
state.rejects.clear();
@@ -8242,7 +8372,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
if (pindexBestHeader == NULL)
pindexBestHeader = chainActive.Tip();
bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->fOneShot); // Download if this is a nice peer, or we have no nice peers and this one might do.
if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) {
if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex && pindexBestHeader!=0) {
// Only actively request headers from a single peer, unless we're close to today.
if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) {
state.fSyncStarted = true;
@@ -8440,21 +8570,31 @@ extern "C" const char* getDataDir()
CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight)
{
CMutableTransaction mtx;
bool isOverwintered = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_OVERWINTER);
if (isOverwintered) {
if ( KOMODO_NSPV > 0 )
{
mtx.fOverwintered = true;
mtx.nExpiryHeight = nHeight + expiryDelta;
if (NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_SAPLING)) {
mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID;
mtx.nVersion = SAPLING_TX_VERSION;
} else {
mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID;
mtx.nVersion = OVERWINTER_TX_VERSION;
mtx.nExpiryHeight = std::min(
mtx.nExpiryHeight,
static_cast<uint32_t>(consensusParams.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight - 1));
mtx.nExpiryHeight = 0;
mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID;
mtx.nVersion = SAPLING_TX_VERSION;
}
else
{
bool isOverwintered = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_OVERWINTER);
if (isOverwintered)
{
mtx.fOverwintered = true;
mtx.nExpiryHeight = nHeight + expiryDelta;
if (NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_SAPLING))
{
mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID;
mtx.nVersion = SAPLING_TX_VERSION;
}
else
{
mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID;
mtx.nVersion = OVERWINTER_TX_VERSION;
mtx.nExpiryHeight = std::min(mtx.nExpiryHeight,static_cast<uint32_t>(consensusParams.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight - 1));
}
}
}
return mtx;
+2 -2
View File
@@ -706,7 +706,7 @@ bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, cons
std::vector<CScriptCheck> *pvChecks = NULL);
/** Check a transaction contextually against a set of consensus rules */
bool ContextualCheckTransaction(const CBlock *block, CBlockIndex * const pindexPrev,const CTransaction& tx, CValidationState &state, int nHeight, int dosLevel,
bool ContextualCheckTransaction(int32_t slowflag,const CBlock *block, CBlockIndex * const pindexPrev,const CTransaction& tx, CValidationState &state, int nHeight, int dosLevel,
bool (*isInitBlockDownload)() = IsInitialBlockDownload,int32_t validateprices=1);
/** Apply the effects of this transaction on the UTXO set represented by view */
@@ -829,7 +829,7 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
/** Context-dependent validity checks */
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex *pindexPrev);
bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex *pindexPrev);
bool ContextualCheckBlock(int32_t slowflag,const CBlock& block, CValidationState& state, CBlockIndex *pindexPrev);
/** Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) */
bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex *pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true);
+45 -12
View File
@@ -123,10 +123,13 @@ public:
void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
{
pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
if ( ASSETCHAINS_ADAPTIVEPOW <= 0 )
pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
else pblock->nTime = std::max((int64_t)(pindexPrev->nTime+1), GetAdjustedTime());
// Updating time can change work required on testnet:
if (consensusParams.nPowAllowMinDifficultyBlocksAfterHeight != boost::none) {
if (ASSETCHAINS_ADAPTIVEPOW > 0 || consensusParams.nPowAllowMinDifficultyBlocksAfterHeight != boost::none)
{
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams);
}
}
@@ -323,6 +326,13 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
BOOST_FOREACH(const CTxIn& txin, tx.vin)
{
if (tx.IsPegsImport() && txin.prevout.n==10e8)
{
CAmount nValueIn = GetCoinImportValue(tx); // burn amount
nTotalIn += nValueIn;
dPriority += (double)nValueIn * 1000; // flat multiplier... max = 1e16.
continue;
}
// Read prev transaction
if (!view.HaveCoins(txin.prevout.hash))
{
@@ -560,7 +570,9 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
nLastBlockTx = nBlockTx;
nLastBlockSize = nBlockSize;
blocktime = 1 + std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
if ( ASSETCHAINS_ADAPTIVEPOW <= 0 )
blocktime = 1 + std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
else blocktime = 1 + std::max((int64_t)(pindexPrev->nTime+1), GetAdjustedTime());
//pblock->nTime = blocktime + 1;
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
@@ -589,8 +601,6 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
else
{
blocktime = GetAdjustedTime();
//if ( blocktime > pindexPrev->GetMedianTimePast()+60 )
// blocktime = pindexPrev->GetMedianTimePast() + 60;
siglen = komodo_staked(txStaked, pblock->nBits, &blocktime, &txtime, &utxotxid, &utxovout, &utxovalue, utxosig);
// if you skip this check it will create a block too far into the future and not pass ProcessBlock or AcceptBlock.
// This has been moved from the mining loop to save CPU, and to also make ac_staked work with the verus miner.
@@ -635,7 +645,10 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
txNew.vout[0].nValue = GetBlockSubsidy(nHeight,consensusParams) + nFees;
//fprintf(stderr,"mine ht.%d with %.8f\n",nHeight,(double)txNew.vout[0].nValue/COIN);
txNew.nExpiryHeight = 0;
txNew.nLockTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
if ( ASSETCHAINS_ADAPTIVEPOW <= 0 )
txNew.nLockTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
else txNew.nLockTime = std::max((int64_t)(pindexPrev->nTime+1), GetAdjustedTime());
if ( ASSETCHAINS_SYMBOL[0] == 0 && IS_KOMODO_NOTARY != 0 && My_notaryid >= 0 )
txNew.vout[0].nValue += 5000;
@@ -658,7 +671,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
if ( ASSETCHAINS_SCRIPTPUB.size() > 1 )
{
static bool didinit = false;
if ( !didinit && nHeight > 100 && KOMODO_EARLYTXID != zeroid && komodo_appendACscriptpub() )
if ( !didinit && nHeight > KOMODO_EARLYTXID_HEIGHT && KOMODO_EARLYTXID != zeroid && komodo_appendACscriptpub() )
{
fprintf(stderr, "appended ccopreturn to ASSETCHAINS_SCRIPTPUB.%s\n", ASSETCHAINS_SCRIPTPUB.c_str());
didinit = true;
@@ -1440,7 +1453,9 @@ void static BitcoinMiner_noeq()
HASHTarget.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow);
LogPrintf("Block %d : PoS %d%% vs target %d%%\n", Mining_height, percPoS, (int32_t)ASSETCHAINS_STAKED);
}
//else if ( ASSETCHAINS_ADAPTIVEPOW > 0 && ASSETCHAINS_STAKED == 0 )
// HASHTarget_POW = komodo_adaptivepow_target(Mining_height,HASHTarget,pblock->nTime);
while (true)
{
arith_uint256 arNonce = UintToArith256(pblock->nNonce);
@@ -1473,7 +1488,9 @@ void static BitcoinMiner_noeq()
}
else if ( ASSETCHAINS_STAKED == 100 && Mining_height > 100 )
hashTarget = HASHTarget;
//else if ( ASSETCHAINS_ADAPTIVEPOW > 0 && ASSETCHAINS_STAKED == 0 )
// hashTarget = HASHTarget_POW;
// for speed check NONCEMASK at a time
for (i = 0; i < count; i++)
{
@@ -1751,7 +1768,7 @@ void static BitcoinMiner()
if ( (Mining_height >= 235300 && Mining_height < 236000) || (Mining_height % KOMODO_ELECTION_GAP) > 64 || (Mining_height % KOMODO_ELECTION_GAP) == 0 || Mining_height > 1000000 )
{
int32_t dispflag = 0;
if ( notaryid <= 3 || notaryid == 32 || (notaryid >= 43 && notaryid <= 45) &&notaryid == 51 || notaryid == 52 || notaryid == 56 || notaryid == 57 )
if ( notaryid <= 3 || notaryid == 32 || (notaryid >= 43 && notaryid <= 45) || notaryid == 51 || notaryid == 52 || notaryid == 56 || notaryid == 57 )
dispflag = 1;
komodo_eligiblenotary(pubkeys,mids,blocktimes,&nonzpkeys,pindexPrev->GetHeight());
if ( nonzpkeys > 0 )
@@ -1774,8 +1791,12 @@ void static BitcoinMiner()
if ( dispflag != 0 )
{
if ( mids[j] >= 0 )
fprintf(stderr,"%d ",mids[j]);
else fprintf(stderr,"GPU ");
{
if ( mids[j] == notaryid )
fprintf(stderr,"--<%d>-- ",mids[j]);
else
fprintf(stderr,"%d ",mids[j]);
} else fprintf(stderr,"GPU ");
}
if ( mids[j] == -1 )
gpucount++;
@@ -1805,6 +1826,8 @@ void static BitcoinMiner()
if ( ASSETCHAINS_STAKED < 100 )
LogPrintf("Block %d : PoS %d%% vs target %d%% \n",Mining_height,percPoS,(int32_t)ASSETCHAINS_STAKED);
}
//else if ( ASSETCHAINS_ADAPTIVEPOW > 0 )
// HASHTarget_POW = komodo_adaptivepow_target(Mining_height,HASHTarget,pblock->nTime);
gotinvalid = 0;
while (true)
{
@@ -1832,6 +1855,8 @@ void static BitcoinMiner()
arith_uint256 hashTarget;
if ( KOMODO_MININGTHREADS > 0 && ASSETCHAINS_STAKED > 0 && ASSETCHAINS_STAKED < 100 && Mining_height > 10 )
hashTarget = HASHTarget_POW;
//else if ( ASSETCHAINS_ADAPTIVEPOW > 0 )
// hashTarget = HASHTarget_POW;
else hashTarget = HASHTarget;
std::function<bool(std::vector<unsigned char>)> validBlock =
#ifdef ENABLE_WALLET
@@ -2021,6 +2046,14 @@ void static BitcoinMiner()
// Update nNonce and nTime
pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1);
pblock->nBits = savebits;
if ( ASSETCHAINS_ADAPTIVEPOW > 0 )
{
UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
HASHTarget.SetCompact(pblock->nBits);
hashTarget = HASHTarget;
savebits = pblock->nBits;
//hashTarget = HASHTarget_POW = komodo_adaptivepow_target(Mining_height,HASHTarget,pblock->nTime);
}
/*if ( NOTARY_PUBKEY33[0] == 0 )
{
int32_t percPoS;
+6 -10
View File
@@ -83,7 +83,7 @@ extern char ASSETCHAINS_SYMBOL[65];
bool fDiscover = true;
bool fListen = true;
uint64_t nLocalServices = NODE_NETWORK;
uint64_t nLocalServices = NODE_NETWORK | NODE_NSPV;
CCriticalSection cs_mapLocalHost;
map<CNetAddr, LocalServiceInfo> mapLocalHost;
static bool vfLimited[NET_MAX] = {};
@@ -444,6 +444,8 @@ void CNode::CloseSocketDisconnect()
vRecvMsg.clear();
}
extern int32_t KOMODO_NSPV;
void CNode::PushVersion()
{
int nBestHeight = g_signals.GetHeight().get_value_or(0);
@@ -458,6 +460,7 @@ void CNode::PushVersion()
LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id);
PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
nLocalHostNonce, strSubVersion, nBestHeight, true);
//fprintf(stderr,"KOMODO_NSPV.%d PUSH services.%llx\n",KOMODO_NSPV,(long long)nLocalServices);
}
@@ -681,12 +684,6 @@ int CNetMessage::readData(const char *pch, unsigned int nBytes)
// requires LOCK(cs_vSend)
void SocketSendData(CNode *pnode)
{
@@ -1846,7 +1843,7 @@ bool StopNode()
for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
semOutbound->post();
if (fAddressesInitialized)
if (KOMODO_NSPV <= 0 && fAddressesInitialized)
{
DumpAddresses();
fAddressesInitialized = false;
@@ -1926,8 +1923,7 @@ void RelayTransaction(const CTransaction& tx, const CDataStream& ss)
{
if (pnode->pfilter->IsRelevantAndUpdate(tx))
pnode->PushInventory(inv);
} else
pnode->PushInventory(inv);
} else pnode->PushInventory(inv);
}
}
+3
View File
@@ -276,6 +276,7 @@ public:
int64_t nLastRecv;
int64_t nTimeConnected;
int64_t nTimeOffset;
uint32_t prevtimes[16];
CAddress addr;
std::string addrName;
CService addrLocal;
@@ -462,6 +463,7 @@ public:
void PushMessage(const char* pszCommand)
{
//fprintf(stderr,"push.(%s)\n",pszCommand);
try
{
BeginMessage(pszCommand);
@@ -477,6 +479,7 @@ public:
template<typename T1>
void PushMessage(const char* pszCommand, const T1& a1)
{
//fprintf(stderr,"push.(%s)\n",pszCommand);
try
{
BeginMessage(pszCommand);
+27
View File
@@ -135,3 +135,30 @@ int ScanNotarisationsDB(int height, std::string symbol, int scanLimitBlocks, Not
}
return 0;
}
int ScanNotarisationsDB2(int height, std::string symbol, int scanLimitBlocks, Notarisation& out)
{
int32_t i,maxheight,ht;
maxheight = chainActive.Height();
if ( height < 0 || height > maxheight )
return false;
for (i=0; i<scanLimitBlocks; i++)
{
ht = height+i;
if ( ht > maxheight )
break;
NotarisationsInBlock notarisations;
uint256 blockHash = *chainActive[ht]->phashBlock;
if ( !GetBlockNotarisations(blockHash,notarisations) )
continue;
BOOST_FOREACH(Notarisation& nota,notarisations)
{
if ( strcmp(nota.second.symbol,symbol.data()) == 0 )
{
out = nota;
return(ht);
}
}
}
return 0;
}
+1
View File
@@ -24,6 +24,7 @@ bool GetBackNotarisation(uint256 notarisationHash, Notarisation &n);
void WriteBackNotarisations(const NotarisationsInBlock notarisations, CDBBatch &batch);
void EraseBackNotarisations(const NotarisationsInBlock notarisations, CDBBatch &batch);
int ScanNotarisationsDB(int height, std::string symbol, int scanLimitBlocks, Notarisation& out);
int ScanNotarisationsDB2(int height, std::string symbol, int scanLimitBlocks, Notarisation& out);
bool IsTXSCL(const char* symbol);
#endif /* NOTARISATIONDB_H */
+128 -12
View File
@@ -42,6 +42,33 @@ uint32_t komodo_chainactive_timestamp();
unsigned int lwmaGetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params);
unsigned int lwmaCalculateNextWorkRequired(const CBlockIndex* pindexLast, const Consensus::Params& params);
arith_uint256 zawy_targetMA(arith_uint256 easy,arith_uint256 bnSum,int32_t num,int32_t numerator,int32_t divisor)
{
bnSum /= arith_uint256(ASSETCHAINS_BLOCKTIME * num * num * divisor);
bnSum *= arith_uint256(numerator);
if ( bnSum > easy )
bnSum = easy;
return(bnSum);
}
arith_uint256 zawy_exponential(arith_uint256 bnTarget,int32_t mult)
{
int32_t i,n,modval; int64_t A = 1, B = 3600 * 100;
if ( (n= (mult/ASSETCHAINS_BLOCKTIME)) > 0 )
{
for (i=1; i<=n; i++)
A *= 3;
}
if ( (modval= (mult % ASSETCHAINS_BLOCKTIME)) != 0 )
{
B += (3600 * 110 * modval) / ASSETCHAINS_BLOCKTIME;
B += (3600 * 60 * modval * modval) / (ASSETCHAINS_BLOCKTIME * ASSETCHAINS_BLOCKTIME);
}
bnTarget /= arith_uint256(100 * 3600);
bnTarget *= arith_uint256(A * B);
return(bnTarget);
}
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
{
if (ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH && ASSETCHAINS_STAKED == 0)
@@ -73,21 +100,106 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
// Find the first block in the averaging interval
const CBlockIndex* pindexFirst = pindexLast;
arith_uint256 bnTot {0};
for (int i = 0; pindexFirst && i < params.nPowAveragingWindow; i++) {
arith_uint256 bnTmp;
arith_uint256 bnTmp,bnTarget,bnPrev {0},bnSum4 {0},bnSum7 {0},bnSum12 {0},bnTot {0};
uint32_t nbits,blocktime,block4diff=0,block7diff=0,block12diff=0; int32_t diff,mult = 0;
if ( ASSETCHAINS_ADAPTIVEPOW > 0 && pindexFirst != 0 && pblock != 0 )
{
mult = pblock->nTime - pindexFirst->nTime - 7 * ASSETCHAINS_BLOCKTIME;
bnPrev.SetCompact(pindexFirst->nBits);
//fprintf(stderr,"ht.%d mult.%d = (%u - %u - 7x)\n",pindexLast->GetHeight(),(int32_t)mult,pblock->nTime, pindexFirst->nTime);
}
for (int i = 0; pindexFirst && i < params.nPowAveragingWindow; i++)
{
bnTmp.SetCompact(pindexFirst->nBits);
bnTot += bnTmp;
if ( ASSETCHAINS_ADAPTIVEPOW > 0 && pblock != 0 )
{
blocktime = pindexFirst->nTime;
diff = (pblock->nTime - blocktime);
//fprintf(stderr,"%d ",diff);
if ( i < 12 )
{
if ( i == 3 )
{
block4diff = diff;
bnSum4 = bnTot;
}
else if ( i == 6 )
{
block7diff = diff;
bnSum7 = bnTot;
}
else if ( i == 11 )
{
block12diff = diff;
bnSum12 = bnTot;
}
diff -= (8+i)*ASSETCHAINS_BLOCKTIME;
if ( diff > mult )
{
//fprintf(stderr,"i.%d diff.%d (%u - %u - %dx)\n",i,(int32_t)diff,pblock->nTime,pindexFirst->nTime,(8+i));
mult = diff;
}
}
}
pindexFirst = pindexFirst->pprev;
}
//fprintf(stderr,"diffs %d\n",(int32_t) pindexLast->GetHeight());
// Check we have enough blocks
if (pindexFirst == NULL)
return nProofOfWorkLimit;
arith_uint256 bnAvg {bnTot / params.nPowAveragingWindow};
return CalculateNextWorkRequired(bnAvg, pindexLast->GetMedianTimePast(), pindexFirst->GetMedianTimePast(), params);
bool fNegative,fOverflow; int32_t flag = 0; arith_uint256 easy,origtarget,bnAvg {bnTot / params.nPowAveragingWindow};
nbits = CalculateNextWorkRequired(bnAvg, pindexLast->GetMedianTimePast(), pindexFirst->GetMedianTimePast(), params);
if ( ASSETCHAINS_ADAPTIVEPOW > 0 && block12diff != 0 && block7diff != 0 && block4diff != 0 )
{
origtarget = bnTarget = arith_uint256().SetCompact(nbits);
easy.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow);
bnSum4 = zawy_targetMA(easy,bnSum4,4,block4diff * 5,1);
bnSum7 = zawy_targetMA(easy,bnSum7,7,block7diff * 3,1);
bnSum12 = zawy_targetMA(easy,bnSum12,12,block12diff * 2,1);
if ( bnSum4 < bnSum7 )
bnTmp = bnSum4;
else bnTmp = bnSum7;
if ( bnSum12 < bnTmp )
bnTmp = bnSum12;
if ( bnTmp < bnTarget )
{
fprintf(stderr,"ht.%d block12diff %d vs %d, make harder\n",(int32_t)pindexLast->GetHeight()+1,block12diff,ASSETCHAINS_BLOCKTIME*11);
bnTarget = (bnTmp + bnPrev) / arith_uint256(2);
flag = 1;
}
else if ( flag == 0 && mult > 1 ) // e^mult case, jl777: test of mult > 1 failed when it was int64_t???
{
flag = 1;
bnTarget = zawy_exponential(bnTarget,mult);
if ( bnTarget < origtarget || bnTarget > easy )
{
bnTarget = easy;
fprintf(stderr,"cmp.%d mult.%d ht.%d -> easy target\n",mult>1,(int32_t)mult,(int32_t)pindexLast->GetHeight());
return(KOMODO_MINDIFF_NBITS);
} else fprintf(stderr,"cmp.%d mult.%d for ht.%d\n",mult>1,(int32_t)mult,(int32_t)pindexLast->GetHeight());
}
if ( flag == 0 )
{
bnSum4 = zawy_targetMA(easy,bnSum4,4,block4diff * 3,10);
bnSum7 = zawy_targetMA(easy,bnSum7,7,block7diff * 5,10);
bnSum12 = zawy_targetMA(easy,bnSum12,12,block12diff * 6,10);
if ( bnSum4 > bnSum7 )
bnTmp = bnSum4;
else bnTmp = bnSum7;
if ( bnSum12 > bnTmp )
bnTmp = bnSum12;
if ( bnTmp > bnTarget )
{
fprintf(stderr,"ht.%d block12diff %d > %d, make easier\n",(int32_t)pindexLast->GetHeight()+1,block12diff,ASSETCHAINS_BLOCKTIME*13);
bnTarget = (bnTmp + bnPrev) / arith_uint256(2);
flag = 1;
}
}
nbits = bnTarget.GetCompact();
}
return(nbits);
}
unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg,
@@ -101,11 +213,13 @@ unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg,
nActualTimespan = params.AveragingWindowTimespan() + (nActualTimespan - params.AveragingWindowTimespan())/4;
LogPrint("pow", " nActualTimespan = %d before bounds\n", nActualTimespan);
if (nActualTimespan < params.MinActualTimespan())
nActualTimespan = params.MinActualTimespan();
if (nActualTimespan > params.MaxActualTimespan())
nActualTimespan = params.MaxActualTimespan();
if ( ASSETCHAINS_ADAPTIVEPOW <= 0 )
{
if (nActualTimespan < params.MinActualTimespan())
nActualTimespan = params.MinActualTimespan();
if (nActualTimespan > params.MaxActualTimespan())
nActualTimespan = params.MaxActualTimespan();
}
// Retarget
arith_uint256 bnLimit;
if (ASSETCHAINS_ALGO == ASSETCHAINS_EQUIHASH)
@@ -453,6 +567,8 @@ bool CheckProofOfWork(const CBlockHeader &blkHeader, uint8_t *pubkey33, int32_t
arith_uint256 bnMaxPoSdiff;
bnTarget.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow);
}
//else if ( ASSETCHAINS_ADAPTIVEPOW > 0 && ASSETCHAINS_STAKED == 0 )
// bnTarget = komodo_adaptivepow_target(height,bnTarget,blkHeader.nTime);
// Check proof of work matches claimed amount
if ( UintToArith256(hash = blkHeader.GetHash()) > bnTarget && !blkHeader.IsVerusPOSBlock() )
{
+6
View File
@@ -46,6 +46,7 @@
#include "zcash/Proof.hpp"
extern uint32_t ASSETCHAINS_MAGIC;
extern std::string ASSETCHAINS_SELFIMPORT;
// Overwinter transaction version
static const int32_t OVERWINTER_TX_VERSION = 3;
@@ -711,6 +712,11 @@ public:
return (vin.size() == 1 && vin[0].prevout.n == 10e8);
}
bool IsPegsImport() const
{
return (ASSETCHAINS_SELFIMPORT=="PEGSCC" && vin[0].prevout.n == 10e8);
}
friend bool operator==(const CTransaction& a, const CTransaction& b)
{
return a.hash == b.hash;
+1 -1
View File
@@ -102,7 +102,7 @@ CAddress::CAddress(CService ipIn, uint64_t nServicesIn) : CService(ipIn)
void CAddress::Init()
{
nServices = NODE_NETWORK;
nServices = NODE_NETWORK | NODE_NSPV;
nTime = 100000000;
}
+4
View File
@@ -91,6 +91,10 @@ enum {
// but no longer do as of protocol version 170004 (= NO_BLOOM_VERSION)
NODE_BLOOM = (1 << 2),
NODE_NSPV = (1 << 30),
NODE_ADDRINDEX = (1 << 29),
NODE_SPENTINDEX = (1 << 28),
// Bits 24-31 are reserved for temporary experiments. Just pick a bit that
// isn't getting used, or one not being used much, and notify the
// bitcoin-development mailing list. Remember that service bits are just
+9 -2
View File
@@ -390,11 +390,14 @@ UniValue getdifficulty(const UniValue& params, bool fHelp)
return GetNetworkDifficulty();
}
bool NSPV_spentinmempool(uint256 &spenttxid,int32_t &spentvini,uint256 txid,int32_t vout);
bool NSPV_inmempool(uint256 txid);
bool myIsutxo_spentinmempool(uint256 &spenttxid,int32_t &spentvini,uint256 txid,int32_t vout)
{
//char *uint256_str(char *str,uint256); char str[65];
//LOCK(mempool.cs);
int32_t vini = 0;
if ( KOMODO_NSPV > 0 )
return(NSPV_spentinmempool(spenttxid,spentvini,txid,vout));
BOOST_FOREACH(const CTxMemPoolEntry &e,mempool.mapTx)
{
const CTransaction &tx = e.GetTx();
@@ -417,6 +420,10 @@ bool myIsutxo_spentinmempool(uint256 &spenttxid,int32_t &spentvini,uint256 txid,
bool mytxid_inmempool(uint256 txid)
{
if ( KOMODO_NSPV > 0 )
{
}
BOOST_FOREACH(const CTxMemPoolEntry &e,mempool.mapTx)
{
const CTransaction &tx = e.GetTx();
+1
View File
@@ -109,6 +109,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "lockunspent", 1 },
{ "importprivkey", 2 },
{ "importprivkey", 3 },
{ "importprivkey", 4 },
{ "importaddress", 2 },
{ "verifychain", 0 },
{ "verifychain", 1 },
+21 -24
View File
@@ -430,7 +430,7 @@ void CheckBurnTxSource(uint256 burntxid, UniValue &info) {
CTransaction burnTx;
uint256 blockHash;
if (!GetTransaction(burntxid, burnTx, blockHash, true))
if (!myGetTransaction(burntxid, burnTx, blockHash))
throw std::runtime_error("Cannot find burn transaction");
if (blockHash.IsNull())
@@ -754,6 +754,10 @@ UniValue selfimport(const UniValue& params, bool fHelp)
// return(0);
return -1;
}
else if (source == "PEGSCC")
{
return -1;
}
else if (source == "PUBKEY")
{
ImportProof proofNull;
@@ -833,6 +837,10 @@ UniValue importdual(const UniValue& params, bool fHelp)
// confirm via ASSETCHAINS_CODAPORT that burnTx/hash is a valid CODA burn
// return(0);
}
else if (source == "PEGSCC")
{
return -1;
}
RETURN_IF_ERROR(CCerror);
if ( hex.size() > 0 )
{
@@ -854,6 +862,7 @@ UniValue importgatewayinfo(const UniValue& params, bool fHelp)
return(ImportGatewayInfo(txid));
}
UniValue importgatewaybind(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ);
@@ -866,7 +875,7 @@ UniValue importgatewaybind(const UniValue& params, bool fHelp)
if ( fHelp || params.size() != 8)
throw runtime_error("use \'importgatewaybind coin orcletxid M N pubkeys pubtype p2shtype wiftype [taddr]\' to bind an import gateway\n");
if ( ensure_CCrequirements(EVAL_IMPORTGATEWAY) < 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(CC_REQUIREMENTS_MSG);
CCerror = "";
coin = params[0].get_str();
oracletxid = Parseuint256(params[1].get_str().c_str());
@@ -919,7 +928,7 @@ UniValue importgatewaydeposit(const UniValue& params, bool fHelp)
if ( fHelp || params.size() != 9)
throw runtime_error("use \'importgatewaydeposit bindtxid height coin burntxid nvout rawburntx rawproof destpub amount\' to import deposited coins\n");
if ( ensure_CCrequirements(EVAL_IMPORTGATEWAY) < 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(CC_REQUIREMENTS_MSG);
CCerror = "";
bindtxid = Parseuint256(params[0].get_str().c_str());
height = atoi(params[1].get_str().c_str());
@@ -962,7 +971,7 @@ UniValue importgatewaywithdraw(const UniValue& params, bool fHelp)
if ( fHelp || params.size() != 4)
throw runtime_error("use \'importgatewaywithdraw bindtxid coin withdrawpub amount\' to burn imported coins and withdraw them on external chain\n");
if ( ensure_CCrequirements(EVAL_IMPORTGATEWAY) < 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(CC_REQUIREMENTS_MSG);
CCerror = "";
bindtxid = Parseuint256(params[0].get_str().c_str());
coin = params[1].get_str();
@@ -997,7 +1006,7 @@ UniValue importgatewaypartialsign(const UniValue& params, bool fHelp)
if ( fHelp || params.size() != 3 )
throw runtime_error("importgatewayspartialsign txidaddr refcoin hex\n");
if ( ensure_CCrequirements(EVAL_IMPORTGATEWAY) < 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(CC_REQUIREMENTS_MSG);
txid = Parseuint256((char *)params[0].get_str().c_str());
coin = params[1].get_str();
parthex = params[2].get_str();
@@ -1020,7 +1029,7 @@ UniValue importgatewaycompletesigning(const UniValue& params, bool fHelp)
if ( fHelp || params.size() != 3 )
throw runtime_error("importgatewaycompletesigning withdrawtxid coin hex\n");
if ( ensure_CCrequirements(EVAL_IMPORTGATEWAY) < 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(CC_REQUIREMENTS_MSG);
withdrawtxid = Parseuint256((char *)params[0].get_str().c_str());
coin = params[1].get_str();
txhex = params[2].get_str();
@@ -1040,7 +1049,7 @@ UniValue importgatewaymarkdone(const UniValue& params, bool fHelp)
if ( fHelp || params.size() != 2 )
throw runtime_error("importgatewaymarkdone completesigningtx coin\n");
if ( ensure_CCrequirements(EVAL_IMPORTGATEWAY) < 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(CC_REQUIREMENTS_MSG);
completetxid = Parseuint256((char *)params[0].get_str().c_str());
coin = params[1].get_str();
hex = ImportGatewayMarkDone(0,completetxid,coin);
@@ -1053,25 +1062,13 @@ UniValue importgatewaymarkdone(const UniValue& params, bool fHelp)
return(result);
}
UniValue importgatewaypendingdeposits(const UniValue& params, bool fHelp)
{
uint256 bindtxid; std::string coin;
if ( fHelp || params.size() != 2 )
throw runtime_error("importgatewaypendingdeposits bindtxid coin\n");
if ( ensure_CCrequirements(EVAL_IMPORTGATEWAY) < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
bindtxid = Parseuint256((char *)params[0].get_str().c_str());
coin = params[1].get_str();
return(ImportGatewayPendingDeposits(bindtxid,coin));
}
UniValue importgatewaypendingwithdraws(const UniValue& params, bool fHelp)
{
uint256 bindtxid; std::string coin;
if ( fHelp || params.size() != 2 )
throw runtime_error("importgatewaypendingwithdraws bindtxid coin\n");
if ( ensure_CCrequirements(EVAL_IMPORTGATEWAY) < 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(CC_REQUIREMENTS_MSG);
bindtxid = Parseuint256((char *)params[0].get_str().c_str());
coin = params[1].get_str();
return(ImportGatewayPendingWithdraws(bindtxid,coin));
@@ -1083,7 +1080,7 @@ UniValue importgatewayprocessed(const UniValue& params, bool fHelp)
if ( fHelp || params.size() != 2 )
throw runtime_error("importgatewayprocessed bindtxid coin\n");
if ( ensure_CCrequirements(EVAL_IMPORTGATEWAY) < 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(CC_REQUIREMENTS_MSG);
bindtxid = Parseuint256((char *)params[0].get_str().c_str());
coin = params[1].get_str();
return(ImportGatewayProcessedWithdraws(bindtxid,coin));
@@ -1096,7 +1093,7 @@ UniValue importgatewayexternaladdress(const UniValue& params, bool fHelp)
if ( fHelp || params.size() != 2)
throw runtime_error("importgatewayexternaladdress bindtxid pubkey\n");
if ( ensure_CCrequirements(EVAL_IMPORTGATEWAY) < 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(CC_REQUIREMENTS_MSG);
bindtxid = Parseuint256((char *)params[0].get_str().c_str());
pubkey = ParseHex(params[1].get_str().c_str());
return(ImportGatewayExternalAddress(bindtxid,pubkey));
@@ -1109,7 +1106,7 @@ UniValue importgatewaydumpprivkey(const UniValue& params, bool fHelp)
if ( fHelp || params.size() != 2)
throw runtime_error("importgatewaydumpprivkey bindtxid address\n");
if ( ensure_CCrequirements(EVAL_IMPORTGATEWAY) < 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(CC_REQUIREMENTS_MSG);
bindtxid = Parseuint256((char *)params[0].get_str().c_str());
std::string strAddress = params[1].get_str();
CTxDestination dest = DecodeDestination(strAddress);
@@ -1156,7 +1153,7 @@ UniValue getNotarisationsForBlock(const UniValue& params, bool fHelp)
{
UniValue item(UniValue::VOBJ); UniValue notaryarr(UniValue::VARR); std::vector<int8_t> NotarisationNotaries;
uint256 hash; CTransaction tx;
if ( GetTransaction(n.first,tx,hash,false) )
if ( myGetTransaction(n.first,tx,hash) )
{
if ( is_STAKED(n.second.symbol) != 0 )
{
+5 -1
View File
@@ -837,7 +837,11 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
result.push_back(Pair("PoSperc", (int64_t)PoSperc));
result.push_back(Pair("ac_staked", (int64_t)ASSETCHAINS_STAKED));
result.push_back(Pair("origtarget", hashTarget.GetHex()));
} else result.push_back(Pair("target", hashTarget.GetHex()));
}
/*else if ( ASSETCHAINS_ADAPTIVEPOW > 0 )
result.push_back(Pair("target",komodo_adaptivepow_target((int32_t)(pindexPrev->GetHeight()+1),hashTarget,pblock->nTime).GetHex()));
else*/
result.push_back(Pair("target", hashTarget.GetHex()));
result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
result.push_back(Pair("mutable", aMutable));
result.push_back(Pair("noncerange", "00000000ffffffff"));
+47 -44
View File
@@ -222,17 +222,17 @@ UniValue getinfo(const UniValue& params, bool fHelp)
+ HelpExampleCli("getinfo", "")
+ HelpExampleRpc("getinfo", "")
);
//#ifdef ENABLE_WALLET
// LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
//#else
//#ifdef ENABLE_WALLET
// LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
//#else
LOCK(cs_main);
//#endif
//#endif
proxyType proxy;
GetProxy(NET_IPV4, proxy);
notarized_height = komodo_notarized_height(&prevMoMheight,&notarized_hash,&notarized_desttxid);
//fprintf(stderr,"after notarized_height %u\n",(uint32_t)time(NULL));
UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("version", CLIENT_VERSION));
obj.push_back(Pair("protocolversion", PROTOCOL_VERSION));
@@ -243,50 +243,54 @@ UniValue getinfo(const UniValue& params, bool fHelp)
obj.push_back(Pair("prevMoMheight", prevMoMheight));
obj.push_back(Pair("notarizedhash", notarized_hash.ToString()));
obj.push_back(Pair("notarizedtxid", notarized_desttxid.ToString()));
txid_height = notarizedtxid_height(ASSETCHAINS_SYMBOL[0] != 0 ? (char *)"KMD" : (char *)"BTC",(char *)notarized_desttxid.ToString().c_str(),&kmdnotarized_height);
if ( txid_height > 0 )
obj.push_back(Pair("notarizedtxid_height", txid_height));
else obj.push_back(Pair("notarizedtxid_height", "mempool"));
if ( ASSETCHAINS_SYMBOL[0] != 0 )
obj.push_back(Pair("KMDnotarized_height", kmdnotarized_height));
obj.push_back(Pair("notarized_confirms", txid_height < kmdnotarized_height ? (kmdnotarized_height - txid_height + 1) : 0));
//fprintf(stderr,"after notarized_confirms %u\n",(uint32_t)time(NULL));
if ( KOMODO_NSPV <= 0 )
{
txid_height = notarizedtxid_height(ASSETCHAINS_SYMBOL[0] != 0 ? (char *)"KMD" : (char *)"BTC",(char *)notarized_desttxid.ToString().c_str(),&kmdnotarized_height);
if ( txid_height > 0 )
obj.push_back(Pair("notarizedtxid_height", txid_height));
else obj.push_back(Pair("notarizedtxid_height", "mempool"));
if ( ASSETCHAINS_SYMBOL[0] != 0 )
obj.push_back(Pair("KMDnotarized_height", kmdnotarized_height));
obj.push_back(Pair("notarized_confirms", txid_height < kmdnotarized_height ? (kmdnotarized_height - txid_height + 1) : 0));
//fprintf(stderr,"after notarized_confirms %u\n",(uint32_t)time(NULL));
#ifdef ENABLE_WALLET
if (pwalletMain) {
obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
if ( ASSETCHAINS_SYMBOL[0] == 0 )
{
obj.push_back(Pair("interest", ValueFromAmount(KOMODO_INTERESTSUM)));
obj.push_back(Pair("balance", ValueFromAmount(KOMODO_WALLETBALANCE))); //pwalletMain->GetBalance()
if (pwalletMain) {
obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
if ( ASSETCHAINS_SYMBOL[0] == 0 )
{
obj.push_back(Pair("interest", ValueFromAmount(KOMODO_INTERESTSUM)));
obj.push_back(Pair("balance", ValueFromAmount(KOMODO_WALLETBALANCE))); //pwalletMain->GetBalance()
}
else
{
obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); //
}
}
else
{
obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); //
}
}
#endif
//fprintf(stderr,"after wallet %u\n",(uint32_t)time(NULL));
obj.push_back(Pair("blocks", (int)chainActive.Height()));
if ( (longestchain= KOMODO_LONGESTCHAIN) != 0 && chainActive.Height() > longestchain )
longestchain = chainActive.Height();
//fprintf(stderr,"after longestchain %u\n",(uint32_t)time(NULL));
obj.push_back(Pair("longestchain", longestchain));
//fprintf(stderr,"after wallet %u\n",(uint32_t)time(NULL));
obj.push_back(Pair("blocks", (int)chainActive.Height()));
if ( (longestchain= KOMODO_LONGESTCHAIN) != 0 && chainActive.Height() > longestchain )
longestchain = chainActive.Height();
//fprintf(stderr,"after longestchain %u\n",(uint32_t)time(NULL));
obj.push_back(Pair("longestchain", longestchain));
if ( chainActive.LastTip() != 0 )
obj.push_back(Pair("tiptime", (int)chainActive.LastTip()->nTime));
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
#ifdef ENABLE_WALLET
if (pwalletMain) {
obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
}
if (pwalletMain && pwalletMain->IsCrypted())
obj.push_back(Pair("unlocked_until", nWalletUnlockTime));
obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())));
#endif
obj.push_back(Pair("sapling", ASSETCHAINS_SAPLING));
}
obj.push_back(Pair("timeoffset", GetTimeOffset()));
if ( chainActive.LastTip() != 0 )
obj.push_back(Pair("tiptime", (int)chainActive.LastTip()->nTime));
obj.push_back(Pair("connections", (int)vNodes.size()));
obj.push_back(Pair("proxy", (proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string())));
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
#ifdef ENABLE_WALLET
if (pwalletMain) {
obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
}
if (pwalletMain && pwalletMain->IsCrypted())
obj.push_back(Pair("unlocked_until", nWalletUnlockTime));
obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())));
#endif
obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
obj.push_back(Pair("errors", GetWarnings("statusbar")));
if ( NOTARY_PUBKEY33[0] != 0 ) {
@@ -304,7 +308,6 @@ UniValue getinfo(const UniValue& params, bool fHelp)
if ( ASSETCHAINS_CC != 0 )
obj.push_back(Pair("CCid", (int)ASSETCHAINS_CC));
obj.push_back(Pair("name", ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL));
obj.push_back(Pair("sapling", ASSETCHAINS_SAPLING));
obj.push_back(Pair("p2pport", ASSETCHAINS_P2PPORT));
obj.push_back(Pair("rpcport", ASSETCHAINS_RPCPORT));
+98 -44
View File
@@ -206,7 +206,7 @@ void TxToJSONExpanded(const CTransaction& tx, const uint256 hashBlock, UniValue&
UniValue in(UniValue::VOBJ);
if (tx.IsCoinBase())
in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
else if (tx.IsCoinImport()) {
else if (tx.IsCoinImport() && txin.prevout.n==10e8) {
in.push_back(Pair("is_import", "1"));
ImportProof proof; CTransaction burnTx; std::vector<CTxOut> payouts; CTxDestination importaddress;
if (UnmarshalImportTx(tx, proof, burnTx, payouts))
@@ -368,13 +368,13 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
entry.push_back(Pair("vin", vin));
UniValue vout(UniValue::VARR);
BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
CBlockIndex *tipindex,*pindex = it->second;
CBlockIndex *tipindex;//,*pindex = it->second;
uint64_t interest;
for (unsigned int i = 0; i < tx.vout.size(); i++) {
const CTxOut& txout = tx.vout[i];
UniValue out(UniValue::VOBJ);
out.push_back(Pair("value", ValueFromAmount(txout.nValue)));
if ( ASSETCHAINS_SYMBOL[0] == 0 && pindex != 0 && tx.nLockTime >= 500000000 && (tipindex= chainActive.LastTip()) != 0 )
if ( KOMODO_NSPV <= 0 && ASSETCHAINS_SYMBOL[0] == 0 && tx.nLockTime >= 500000000 && (tipindex= chainActive.LastTip()) != 0 )
{
int64_t interest; int32_t txheight; uint32_t locktime;
interest = komodo_accrued_interest(&txheight,&locktime,tx.GetHash(),i,0,txout.nValue,(int32_t)tipindex->GetHeight());
@@ -727,27 +727,31 @@ UniValue verifytxoutproof(const UniValue& params, bool fHelp)
UniValue createrawtransaction(const UniValue& params, bool fHelp)
{
string examplescriptPubKey = "21021ce1eac70455c3e6c52d67c133549b8aed4a588fba594372e8048e65c4f0fcb6ac";
if (fHelp || params.size() < 2 || params.size() > 4)
throw runtime_error(
"createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,...} ( locktime ) ( expiryheight )\n"
"\nCreate a transaction spending the given inputs and sending to the given addresses.\n"
"\nCreate a transaction spending the given inputs and creating new outputs.\n"
"Outputs can be addresses or standart scripts (in hex) or data.\n"
"Returns hex-encoded raw transaction.\n"
"Note that the transaction's inputs are not signed, and\n"
"it is not stored in the wallet or transmitted to the network.\n"
"\nArguments:\n"
"1. \"transactions\" (string, required) A json array of json objects\n"
"1. \"inputs\" (array, required) A json array of json objects\n"
" [\n"
" {\n"
" \"txid\":\"id\", (string, required) The transaction id\n"
" \"vout\":n (numeric, required) The output number\n"
" \"sequence\":n (numeric, optional) The sequence number\n"
" }\n"
" \"vout\":n, (numeric, required) The output number\n"
" \"sequence\":n (numeric, optional) The sequence number\n"
" } \n"
" ,...\n"
" ]\n"
"2. \"addresses\" (string, required) a json object with addresses as keys and amounts as values\n"
"2. \"outputs\" (object, required) a json object with outputs\n"
" {\n"
" \"address\": x.xxx (numeric, required) The key is the Komodo address, the value is the " + CURRENCY_UNIT + " amount\n"
" \"address\": x.xxx, (numeric or string, required) The key is the komodo address or script (in hex), the numeric value (can be string) is the " + CURRENCY_UNIT + " amount\n"
" \"data\": \"hex\" (string, required) The key is \"data\", the value is hex encoded data\n"
" ,...\n"
" }\n"
"3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n"
@@ -757,7 +761,11 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp)
"\nExamples\n"
+ HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"")
+ HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\""+examplescriptPubKey+"\\\":0.01}\"")
+ HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"data\\\":\\\"00010203\\\"}\"")
+ HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"")
+ HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\""+examplescriptPubKey+"\\\":0.01}\"")
+ HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"data\\\":\\\"00010203\\\"}\"")
);
LOCK(cs_main);
@@ -817,22 +825,61 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp)
}
std::set<CTxDestination> destinations;
//std::set<std::string> destinations;
vector<string> addrList = sendTo.getKeys();
for (const std::string& name_ : addrList) {
CTxDestination destination = DecodeDestination(name_);
if (!IsValidDestination(destination)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Komodo address: ") + name_);
if (addrList.size() != sendTo.size()) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid outputs")); // for checking edge case, should never happened ...
}
//for (const std::string& name_ : addrList) {
for (size_t idx = 0; idx < sendTo.size(); idx++) {
const std::string& name_ = addrList[idx];
CScript scriptPubKey;
CTxDestination destination;
if (name_ == "data") {
std::vector<unsigned char> data = ParseHexV(sendTo[name_].getValStr(),"Data");
CTxOut out(0, CScript() << OP_RETURN << data);
rawTx.vout.push_back(out);
} else {
destination = DecodeDestination(name_);
if (IsValidDestination(destination)) {
scriptPubKey = GetScriptForDestination(destination);
} else if (IsHex(name_)) {
std::vector<unsigned char> data(ParseHex(name_));
scriptPubKey = CScript(data.begin(), data.end());
// destination is not valid, but we should convert it to valid anyway, to be able to check duplicates,
// so we need to get destination from existing scriptPubKey via ExtractDestination
if (!(ExtractDestination(scriptPubKey, destination) &&
(scriptPubKey.IsPayToPublicKeyHash() || scriptPubKey.IsPayToPublicKey() || scriptPubKey.IsPayToScriptHash())
)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid script: ") + name_ + std::string(" (only P2PKH, P2PK and P2SH scripts are allowed)"));
}
}
else {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Komodo address or script: ") + name_);
}
if (!(fExperimentalMode && IS_KOMODO_NOTARY)) {
// support of sending duplicates in createrawtransaction requires experimental features enabled and
// notary flag, to prevent common users to get messed up with duplicates
//if (!destinations.insert(EncodeDestination(destination)).second) {
if (!destinations.insert(destination).second) {
throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated destination: ") + name_);
}
}
// CAmount nAmount = AmountFromValue(sendTo[name_]); // operator[](const std::string& key) const;
CAmount nAmount = AmountFromValue(sendTo[idx]); // operator[](size_t index) const;
CTxOut out(nAmount, scriptPubKey);
rawTx.vout.push_back(out);
}
if (!destinations.insert(destination).second) {
throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + name_);
}
CScript scriptPubKey = GetScriptForDestination(destination);
CAmount nAmount = AmountFromValue(sendTo[name_]);
CTxOut out(nAmount, scriptPubKey);
rawTx.vout.push_back(out);
}
return EncodeHexTx(rawTx);
@@ -1282,6 +1329,8 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp)
return result;
}
extern UniValue NSPV_broadcast(char *hex);
UniValue sendrawtransaction(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 2)
@@ -1317,30 +1366,35 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp)
bool fOverrideFees = false;
if (params.size() > 1)
fOverrideFees = params[1].get_bool();
CCoinsViewCache &view = *pcoinsTip;
const CCoins* existingCoins = view.AccessCoins(hashTx);
bool fHaveMempool = mempool.exists(hashTx);
bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000;
if (!fHaveMempool && !fHaveChain) {
// push to local node and sync with wallets
CValidationState state;
bool fMissingInputs;
if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees)) {
if (state.IsInvalid()) {
throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
} else {
if (fMissingInputs) {
throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
if ( KOMODO_NSPV <= 0 )
{
CCoinsViewCache &view = *pcoinsTip;
const CCoins* existingCoins = view.AccessCoins(hashTx);
bool fHaveMempool = mempool.exists(hashTx);
bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000;
if (!fHaveMempool && !fHaveChain) {
// push to local node and sync with wallets
CValidationState state;
bool fMissingInputs;
if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees)) {
if (state.IsInvalid()) {
throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
} else {
if (fMissingInputs) {
throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
}
throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason());
}
throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason());
}
} else if (fHaveChain) {
throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
}
} else if (fHaveChain) {
throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
RelayTransaction(tx);
}
else
{
NSPV_broadcast((char *)params[0].get_str().c_str());
}
RelayTransaction(tx);
return hashTx.GetHex();
}
+26 -1
View File
@@ -370,7 +370,6 @@ static const CRPCCommand vRPCCommands[] =
{ "crosschain", "importgatewaypartialsign", &importgatewaypartialsign, true },
{ "crosschain", "importgatewaycompletesigning", &importgatewaycompletesigning, true },
{ "crosschain", "importgatewaymarkdone", &importgatewaymarkdone, true },
{ "crosschain", "importgatewaypendingdeposits", &importgatewaypendingdeposits, true },
{ "crosschain", "importgatewaypendingwithdraws", &importgatewaypendingwithdraws, true },
{ "crosschain", "importgatewayprocessed", &importgatewayprocessed, true },
@@ -416,6 +415,20 @@ static const CRPCCommand vRPCCommands[] =
{ "FSM", "FSMlist", &FSMlist, true },
{ "FSM", "FSMinfo", &FSMinfo, true },
// fsm
{ "nSPV", "nspv_getinfo", &nspv_getinfo, true },
{ "nSPV", "nspv_login", &nspv_login, true },
{ "nSPV", "nspv_listunspent", &nspv_listunspent, true },
{ "nSPV", "nspv_mempool", &nspv_mempool, true },
{ "nSPV", "nspv_listtransactions",&nspv_listtransactions, true },
{ "nSPV", "nspv_spentinfo", &nspv_spentinfo, true },
{ "nSPV", "nspv_notarizations", &nspv_notarizations, true },
{ "nSPV", "nspv_hdrsproof", &nspv_hdrsproof, true },
{ "nSPV", "nspv_txproof", &nspv_txproof, true },
{ "nSPV", "nspv_spend", &nspv_spend, true },
{ "nSPV", "nspv_broadcast", &nspv_broadcast, true },
{ "nSPV", "nspv_logout", &nspv_logout, true },
// rewards
{ "rewards", "rewardslist", &rewardslist, true },
{ "rewards", "rewardsinfo", &rewardsinfo, true },
@@ -554,6 +567,18 @@ static const CRPCCommand vRPCCommands[] =
//{ "tokens", "tokenfillswap", &tokenfillswap, true },
{ "tokens", "tokenconvert", &tokenconvert, true },
// pegs
{ "pegs", "pegscreate", &pegscreate, true },
{ "pegs", "pegsfund", &pegsfund, true },
{ "pegs", "pegsget", &pegsget, true },
{ "pegs", "pegsredeem", &pegsredeem, true },
{ "pegs", "pegsliquidate", &pegsliquidate, true },
{ "pegs", "pegsexchange", &pegsexchange, true },
{ "pegs", "pegsaccounthistory", &pegsaccounthistory, true },
{ "pegs", "pegsaccountinfo", &pegsaccountinfo, true },
{ "pegs", "pegsworstaccounts", &pegsworstaccounts, true },
{ "pegs", "pegsinfo", &pegsinfo, true },
/* Address index */
{ "addressindex", "getaddressmempool", &getaddressmempool, true },
{ "addressindex", "getaddressutxos", &getaddressutxos, false },
+23 -1
View File
@@ -349,6 +349,16 @@ extern UniValue FSMcreate(const UniValue& params, bool fHelp);
extern UniValue FSMlist(const UniValue& params, bool fHelp);
extern UniValue FSMinfo(const UniValue& params, bool fHelp);
extern UniValue auctionaddress(const UniValue& params, bool fHelp);
extern UniValue pegscreate(const UniValue& params, bool fHelp);
extern UniValue pegsfund(const UniValue& params, bool fHelp);
extern UniValue pegsget(const UniValue& params, bool fHelp);
extern UniValue pegsredeem(const UniValue& params, bool fHelp);
extern UniValue pegsliquidate(const UniValue& params, bool fHelp);
extern UniValue pegsexchange(const UniValue& params, bool fHelp);
extern UniValue pegsaccounthistory(const UniValue& params, bool fHelp);
extern UniValue pegsaccountinfo(const UniValue& params, bool fHelp);
extern UniValue pegsworstaccounts(const UniValue& params, bool fHelp);
extern UniValue pegsinfo(const UniValue& params, bool fHelp);
extern UniValue getnewaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp
//extern UniValue getnewaddress64(const UniValue& params, bool fHelp); // in rpcwallet.cpp
@@ -451,10 +461,22 @@ extern UniValue importgatewaywithdraw(const UniValue& params, bool fHelp);
extern UniValue importgatewaypartialsign(const UniValue& params, bool fHelp);
extern UniValue importgatewaycompletesigning(const UniValue& params, bool fHelp);
extern UniValue importgatewaymarkdone(const UniValue& params, bool fHelp);
extern UniValue importgatewaypendingdeposits(const UniValue& params, bool fHelp);
extern UniValue importgatewaypendingwithdraws(const UniValue& params, bool fHelp);
extern UniValue importgatewayprocessed(const UniValue& params, bool fHelp);
extern UniValue nspv_getinfo(const UniValue& params, bool fHelp);
extern UniValue nspv_login(const UniValue& params, bool fHelp);
extern UniValue nspv_listtransactions(const UniValue& params, bool fHelp);
extern UniValue nspv_mempool(const UniValue& params, bool fHelp);
extern UniValue nspv_listunspent(const UniValue& params, bool fHelp);
extern UniValue nspv_spentinfo(const UniValue& params, bool fHelp);
extern UniValue nspv_notarizations(const UniValue& params, bool fHelp);
extern UniValue nspv_hdrsproof(const UniValue& params, bool fHelp);
extern UniValue nspv_txproof(const UniValue& params, bool fHelp);
extern UniValue nspv_spend(const UniValue& params, bool fHelp);
extern UniValue nspv_broadcast(const UniValue& params, bool fHelp);
extern UniValue nspv_logout(const UniValue& params, bool fHelp);
extern UniValue getblocksubsidy(const UniValue& params, bool fHelp);
extern UniValue z_exportkey(const UniValue& params, bool fHelp); // in rpcdump.cpp
+5 -5
View File
@@ -61,7 +61,7 @@ UniValue test_ac(const UniValue& params, bool fHelp)
if (fHelp || (params.size() != 4))
throw runtime_error("incorrect params\n");
if (ensure_CCrequirements(EVAL_HEIR) < 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(CC_REQUIREMENTS_MSG);
std::vector<unsigned char> pubkey1;
std::vector<unsigned char> pubkey2;
@@ -106,7 +106,7 @@ UniValue test_heirmarker(const UniValue& params, bool fHelp)
if (fHelp || (params.size() != 1))
throw runtime_error("incorrect params\n");
if (ensure_CCrequirements(EVAL_HEIR) < 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(CC_REQUIREMENTS_MSG);
uint256 fundingtxid = Parseuint256((char *)params[0].get_str().c_str());
@@ -137,7 +137,7 @@ UniValue test_burntx(const UniValue& params, bool fHelp)
if (fHelp || (params.size() != 1))
throw runtime_error("incorrect params\n");
if (ensure_CCrequirements(EVAL_TOKENS) < 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(CC_REQUIREMENTS_MSG);
uint256 tokenid = Parseuint256((char *)params[0].get_str().c_str());
@@ -230,7 +230,7 @@ UniValue test_pricesmarker(const UniValue& params, bool fHelp)
if (fHelp || (params.size() != 1))
throw runtime_error("incorrect params\n");
if (ensure_CCrequirements(EVAL_PRICES) < 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(CC_REQUIREMENTS_MSG);
uint256 bettxid = Parseuint256((char *)params[0].get_str().c_str());
@@ -265,4 +265,4 @@ void RegisterTesttransactionsRPCCommands(CRPCTable &tableRPC)
{
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
}
}
+45 -14
View File
@@ -35,31 +35,47 @@ using namespace std;
typedef vector<unsigned char> valtype;
extern uint8_t ASSETCHAINS_TXPOW;
extern char NSPV_wifstr[],NSPV_pubkeystr[];
extern int32_t KOMODO_NSPV;
uint256 SIG_TXHASH;
TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {}
bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, uint32_t consensusBranchId, CKey *pprivKey, void *extraData) const
{
CKey key;
if (pprivKey)
key = *pprivKey;
else if (!keystore || !keystore->GetKey(address, key))
return false;
uint256 hash;
CKey key; uint256 hash;
try {
hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, consensusBranchId);
} catch (logic_error ex) {
{
fprintf(stderr,"logic error\n");
return false;
}
}
SIG_TXHASH = hash;
if ( KOMODO_NSPV > 0 )
key = DecodeSecret(NSPV_wifstr);
else if (pprivKey)
key = *pprivKey;
else if (!keystore || !keystore->GetKey(address, key))
{
fprintf(stderr,"keystore.%p error\n",keystore);
return false;
}
//fprintf(stderr,"privkey (%s) for %s\n",NSPV_wifstr,EncodeDestination(key.GetPubKey().GetID()).c_str());
if (scriptCode.IsPayToCryptoCondition())
{
CC *cc = (CC *)extraData;
// assume either 1of1 or 1of2. if the condition created by the
if (!cc || cc_signTreeSecp256k1Msg32(cc, key.begin(), hash.begin()) == 0)
{
fprintf(stderr,"CC tree error\n");
return false;
}
vchSig = CCSigVec(cc);
if ( KOMODO_NSPV > 0 )
memset((uint8_t *)key.begin(),0,32);
return true;
}
else
@@ -67,7 +83,14 @@ bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig,
if ( ASSETCHAINS_TXPOW == 0 )
{
if (!key.Sign(hash, vchSig))
{
fprintf(stderr,"key.Sign error\n");
return false;
}
else
{
//fprintf(stderr,"signed success %s\n",(char *)HexStr(vchSig).c_str());
}
}
else
{
@@ -77,7 +100,8 @@ bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig,
}
vchSig.push_back((unsigned char)nHashType);
if ( KOMODO_NSPV > 0 )
memset((uint8_t *)key.begin(),0,32);
return true;
}
@@ -85,7 +109,10 @@ static bool Sign1(const CKeyID& address, const BaseSignatureCreator& creator, co
{
vector<unsigned char> vchSig;
if (!creator.CreateSig(vchSig, address, scriptCode, consensusBranchId))
{
fprintf(stderr,"Sign1 creatsig error\n");
return false;
}
ret.push_back(vchSig);
return true;
}
@@ -337,7 +364,6 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
}
CKeyID keyID;
switch (whichTypeRet)
{
case TX_NONSTANDARD:
@@ -349,12 +375,18 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
case TX_PUBKEYHASH:
keyID = CKeyID(uint160(vSolutions[0]));
if (!Sign1(keyID, creator, scriptPubKey, ret, consensusBranchId))
{
fprintf(stderr,"sign1 error\n");
return false;
}
else
{
CPubKey vch;
creator.KeyStore().GetPubKey(keyID, vch);
ret.push_back(ToByteVector(vch));
if ( KOMODO_NSPV <= 0 )
{
CPubKey vch;
creator.KeyStore().GetPubKey(keyID, vch);
ret.push_back(ToByteVector(vch));
} else ret.push_back(ParseHex(NSPV_pubkeystr));
}
return true;
case TX_SCRIPTHASH:
@@ -411,7 +443,6 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu
}
sigdata.scriptSig = PushAll(result);
// Test solution
return solved && VerifyScript(sigdata.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker(), consensusBranchId);
}
+2 -2
View File
@@ -491,7 +491,7 @@ void test_simple_joinsplit_invalidity(uint32_t consensusBranchId, CMutableTransa
jsdesc->nullifiers[1] = GetRandHash();
BOOST_CHECK(CheckTransactionWithoutProofVerification(newTx, state));
BOOST_CHECK(!ContextualCheckTransaction(newTx, state, 0, 100));
BOOST_CHECK(!ContextualCheckTransaction(0,newTx, state, 0, 100));
BOOST_CHECK(state.GetRejectReason() == "bad-txns-invalid-joinsplit-signature");
// Empty output script.
@@ -505,7 +505,7 @@ void test_simple_joinsplit_invalidity(uint32_t consensusBranchId, CMutableTransa
) == 0);
BOOST_CHECK(CheckTransactionWithoutProofVerification(newTx, state));
BOOST_CHECK(ContextualCheckTransaction(newTx, state, 0, 100));
BOOST_CHECK(ContextualCheckTransaction(0,newTx, state, 0, 100));
}
{
// Ensure that values within the joinsplit are well-formed.
+9 -2
View File
@@ -31,6 +31,8 @@ using namespace std;
static CCriticalSection cs_nTimeOffset;
static int64_t nTimeOffset = 0;
#define KOMODO_ASSETCHAIN_MAXLEN 65
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
/**
* "Never go to sea with two chronometers; take one or three."
@@ -94,7 +96,7 @@ void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample)
int64_t nMedian = vTimeOffsets.median();
std::vector<int64_t> vSorted = vTimeOffsets.sorted();
// Only let other nodes change our time by so much
if (abs64(nMedian) < 70 * 60)
if (abs64(nMedian) < 30) // thanks to zawy for pointing this out!! zcash issues 4021 //70 * 60)
{
nTimeOffset = nMedian;
}
@@ -114,7 +116,12 @@ void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample)
if (!fMatch)
{
fDone = true;
string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Zcash will not work properly.");
string strMessage;
if( strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ) {
strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Hush will not work properly.");
} else {
strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Komodo will not work properly.");
}
strMiscWarning = strMessage;
LogPrintf("*** %s\n", strMessage);
uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING);
+19 -1
View File
@@ -21,6 +21,24 @@ if operating_system != 'Win64' and operating_system != 'Windows':
import readline
class CustomProxy(Proxy):
def __init__(self,
service_url=None,
service_port=None,
conf_file=None,
timeout=3000):
config = dict()
if conf_file:
config = slickrpc.ConfigObj(conf_file)
if service_url:
config.update(self.url_to_conf(service_url))
if service_port:
config.update(rpcport=service_port)
elif not config.get('rpcport'):
config['rpcport'] = 7771
self.conn = self.prepare_connection(config, timeout=timeout)
def colorize(string, color):
colors = {
@@ -97,7 +115,7 @@ def def_credentials(chain):
print("check "+coin_config_file)
exit(1)
return(Proxy("http://%s:%s@127.0.0.1:%d"%(rpcuser, rpcpassword, int(rpcport))))
return(CustomProxy("http://%s:%s@127.0.0.1:%d"%(rpcuser, rpcpassword, int(rpcport))))
def getinfo_tui(rpc_connection):
+5
View File
@@ -121,7 +121,10 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry,
const CTransaction& tx = mapTx.find(hash)->GetTx();
if (!tx.IsCoinImport()) {
for (unsigned int i = 0; i < tx.vin.size(); i++)
{
if (tx.IsPegsImport() && i==0) continue;
mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i);
}
}
BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
@@ -147,6 +150,7 @@ void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewC
uint256 txhash = tx.GetHash();
for (unsigned int j = 0; j < tx.vin.size(); j++) {
if (tx.IsPegsImport() && j==0) continue;
const CTxIn input = tx.vin[j];
const CTxOut &prevout = view.GetOutputFor(input);
@@ -252,6 +256,7 @@ void CTxMemPool::addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCac
uint256 txhash = tx.GetHash();
for (unsigned int j = 0; j < tx.vin.size(); j++) {
if (tx.IsPegsImport() && j==0) continue;
const CTxIn input = tx.vin[j];
const CTxOut &prevout = view.GetOutputFor(input);
+2 -2
View File
@@ -414,7 +414,7 @@ void SplitStr(const std::string& strVal, std::vector<std::string> &outVals)
}
}
void Split(const std::string& strVal, uint64_t *outVals, const uint64_t nDefault)
void Split(const std::string& strVal, int32_t outsize, uint64_t *outVals, const uint64_t nDefault)
{
stringstream ss(strVal);
vector<uint64_t> vec;
@@ -442,7 +442,7 @@ void Split(const std::string& strVal, uint64_t *outVals, const uint64_t nDefault
else
nLast = nDefault;
for ( i = numVals; i < ASSETCHAINS_MAX_ERAS; i++ )
for ( i = numVals; i < outsize; i++ )
{
outVals[i] = nLast;
}
+1 -1
View File
@@ -185,7 +185,7 @@ inline bool IsSwitchChar(char c)
* else if the string has fewer than _MAX_ERAS entries, then the last
* entry fills remaining entries
*/
void Split(const std::string& strVal, uint64_t *outVals, uint64_t nDefault);
void Split(const std::string& strVal, int32_t outsize, uint64_t *outVals, uint64_t nDefault);
/**
* Return string argument or default value
+206 -3
View File
@@ -153,15 +153,16 @@ UniValue importprivkey(const UniValue& params, bool fHelp)
if (!EnsureWalletIsAvailable(fHelp))
return NullUniValue;
if (fHelp || params.size() < 1 || params.size() > 4)
if (fHelp || params.size() < 1 || params.size() > 5)
throw runtime_error(
"importprivkey \"komodoprivkey\" ( \"label\" rescan height)\n"
"importprivkey \"komodoprivkey\" ( \"label\" rescan height secret_key)\n"
"\nAdds a private key (as returned by dumpprivkey) to your wallet.\n"
"\nArguments:\n"
"1. \"komodoprivkey\" (string, required) The private key (see dumpprivkey)\n"
"2. \"label\" (string, optional, default=\"\") An optional label\n"
"3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n"
"4. height (integer, optional, default=0) start at block height?\n"
"5. secret_key (integer, optional, default=188) used to import WIFs of other coins\n"
"\nNote: This call can take minutes to complete if rescan is true.\n"
"\nExamples:\n"
"\nDump a private key\n"
@@ -174,6 +175,10 @@ UniValue importprivkey(const UniValue& params, bool fHelp)
+ HelpExampleRpc("importprivkey", "\"mykey\", \"testing\", false") +
"\nImport with rescan from a block height\n"
+ HelpExampleCli("importprivkey", "\"mykey\" \"testing\" true 1000") +
"\nImport a BTC WIF with rescan\n"
+ HelpExampleCli("importprivkey", "\"BTCWIF\" \"testing\" true 0 128") +
"\nImport a BTC WIF without rescan\n"
+ HelpExampleCli("importprivkey", "\"BTCWIF\" \"testing\" false 0 128") +
"\nAs a JSON-RPC call\n"
+ HelpExampleRpc("importprivkey", "\"mykey\", \"testing\", true, 1000")
);
@@ -185,6 +190,8 @@ UniValue importprivkey(const UniValue& params, bool fHelp)
string strSecret = params[0].get_str();
string strLabel = "";
int32_t height = 0;
uint8_t secret_key = 0;
CKey key;
if (params.size() > 1)
strLabel = params[1].get_str();
@@ -195,10 +202,18 @@ UniValue importprivkey(const UniValue& params, bool fHelp)
if ( fRescan && params.size() == 4 )
height = params[3].get_int();
if (params.size() > 4)
{
auto secret_key = AmountFromValue(params[4])/100000000;
key = DecodeCustomSecret(strSecret, secret_key);
} else {
key = DecodeSecret(strSecret);
}
if ( height < 0 || height > chainActive.Height() )
throw JSONRPCError(RPC_WALLET_ERROR, "Rescan height is out of range.");
CKey key = DecodeSecret(strSecret);
if (!key.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key encoding");
CPubKey pubkey = key.GetPubKey();
@@ -956,3 +971,191 @@ UniValue z_exportviewingkey(const UniValue& params, bool fHelp)
return EncodeViewingKey(vk);
}
extern int32_t KOMODO_NSPV;
UniValue NSPV_getinfo_req(int32_t reqht);
UniValue NSPV_login(char *wifstr);
UniValue NSPV_logout();
UniValue NSPV_addresstxids(char *coinaddr,int32_t CCflag,int32_t skipcount,int32_t filter);
UniValue NSPV_addressutxos(char *coinaddr,int32_t CCflag,int32_t skipcount,int32_t filter);
UniValue NSPV_mempooltxids(char *coinaddr,int32_t CCflag,uint8_t funcid,uint256 txid,int32_t vout);
UniValue NSPV_broadcast(char *hex);
UniValue NSPV_spend(char *srcaddr,char *destaddr,int64_t satoshis);
UniValue NSPV_spentinfo(uint256 txid,int32_t vout);
UniValue NSPV_notarizations(int32_t height);
UniValue NSPV_hdrsproof(int32_t prevheight,int32_t nextheight);
UniValue NSPV_txproof(int32_t vout,uint256 txid,int32_t height);
uint256 Parseuint256(const char *hexstr);
extern std::string NSPV_address;
UniValue nspv_getinfo(const UniValue& params, bool fHelp)
{
int32_t reqht = 0;
if ( fHelp || params.size() > 1 )
throw runtime_error("nspv_getinfo [hdrheight]\n");
if ( KOMODO_NSPV <= 0 )
throw runtime_error("-nSPV=1 must be set to use nspv\n");
if ( params.size() == 1 )
reqht = atoi((char *)params[0].get_str().c_str());
return(NSPV_getinfo_req(reqht));
}
UniValue nspv_logout(const UniValue& params, bool fHelp)
{
if ( fHelp || params.size() != 0 )
throw runtime_error("nspv_logout\n");
if ( KOMODO_NSPV <= 0 )
throw runtime_error("-nSPV=1 must be set to use nspv\n");
return(NSPV_logout());
}
UniValue nspv_login(const UniValue& params, bool fHelp)
{
if ( fHelp || params.size() != 1 )
throw runtime_error("nspv_login wif\n");
if ( KOMODO_NSPV <= 0 )
throw runtime_error("-nSPV=1 must be set to use nspv\n");
return(NSPV_login((char *)params[0].get_str().c_str()));
}
UniValue nspv_listunspent(const UniValue& params, bool fHelp)
{
int32_t skipcount = 0,CCflag = 0;
if ( fHelp || params.size() > 3 )
throw runtime_error("nspv_listunspent [address [isCC [skipcount]]]\n");
if ( KOMODO_NSPV <= 0 )
throw runtime_error("-nSPV=1 must be set to use nspv\n");
if ( params.size() == 0 )
{
if ( NSPV_address.size() != 0 )
return(NSPV_addressutxos((char *)NSPV_address.c_str(),0,0,0));
else throw runtime_error("nspv_listunspent [address [isCC [skipcount]]]\n");
}
if ( params.size() >= 1 )
{
if ( params.size() >= 2 )
CCflag = atoi((char *)params[1].get_str().c_str());
if ( params.size() == 3 )
skipcount = atoi((char *)params[2].get_str().c_str());
return(NSPV_addressutxos((char *)params[0].get_str().c_str(),CCflag,skipcount,0));
}
else throw runtime_error("nspv_listunspent [address [isCC [skipcount]]]\n");
}
UniValue nspv_mempool(const UniValue& params, bool fHelp)
{
int32_t vout = 0,CCflag = 0; uint256 txid; uint8_t funcid; char *coinaddr;
memset(&txid,0,sizeof(txid));
if ( fHelp || params.size() > 5 )
throw runtime_error("nspv_mempool func(0 all, 1 address recv, 2 txid/vout spent, 3 txid inmempool) address isCC [txid vout]]]\n");
if ( KOMODO_NSPV <= 0 )
throw runtime_error("-nSPV=1 must be set to use nspv\n");
funcid = atoi((char *)params[0].get_str().c_str());
coinaddr = (char *)params[1].get_str().c_str();
CCflag = atoi((char *)params[2].get_str().c_str());
if ( params.size() > 3 )
{
if ( params.size() != 5 )
throw runtime_error("nspv_mempool func(0 all, 1 address recv, 2 txid/vout spent, 3 txid inmempool) address isCC [txid vout]]]\n");
txid = Parseuint256((char *)params[3].get_str().c_str());
vout = atoi((char *)params[4].get_str().c_str());
}
return(NSPV_mempooltxids(coinaddr,CCflag,funcid,txid,vout));
}
UniValue nspv_listtransactions(const UniValue& params, bool fHelp)
{
int32_t skipcount = 0,CCflag = 0;
if ( fHelp || params.size() > 3 )
throw runtime_error("nspv_listtransactions [address [isCC [skipcount]]]\n");
if ( KOMODO_NSPV <= 0 )
throw runtime_error("-nSPV=1 must be set to use nspv\n");
if ( params.size() == 0 )
{
if ( NSPV_address.size() != 0 )
return(NSPV_addresstxids((char *)NSPV_address.c_str(),0,0,0));
else throw runtime_error("nspv_listtransactions [address [isCC [skipcount]]]\n");
}
if ( params.size() >= 1 )
{
if ( params.size() >= 2 )
CCflag = atoi((char *)params[1].get_str().c_str());
if ( params.size() == 3 )
skipcount = atoi((char *)params[2].get_str().c_str());
//fprintf(stderr,"call txids cc.%d skip.%d\n",CCflag,skipcount);
return(NSPV_addresstxids((char *)params[0].get_str().c_str(),CCflag,skipcount,0));
}
else throw runtime_error("nspv_listtransactions [address [isCC [skipcount]]]\n");
}
UniValue nspv_spentinfo(const UniValue& params, bool fHelp)
{
uint256 txid; int32_t vout;
if ( fHelp || params.size() != 2 )
throw runtime_error("nspv_spentinfo txid vout\n");
if ( KOMODO_NSPV <= 0 )
throw runtime_error("-nSPV=1 must be set to use nspv\n");
txid = Parseuint256((char *)params[0].get_str().c_str());
vout = atoi((char *)params[1].get_str().c_str());
return(NSPV_spentinfo(txid,vout));
}
UniValue nspv_notarizations(const UniValue& params, bool fHelp)
{
int32_t height;
if ( fHelp || params.size() != 1 )
throw runtime_error("nspv_notarizations height\n");
if ( KOMODO_NSPV <= 0 )
throw runtime_error("-nSPV=1 must be set to use nspv\n");
height = atoi((char *)params[0].get_str().c_str());
return(NSPV_notarizations(height));
}
UniValue nspv_hdrsproof(const UniValue& params, bool fHelp)
{
int32_t prevheight,nextheight;
if ( fHelp || params.size() != 2 )
throw runtime_error("nspv_hdrsproof prevheight nextheight\n");
if ( KOMODO_NSPV <= 0 )
throw runtime_error("-nSPV=1 must be set to use nspv\n");
prevheight = atoi((char *)params[0].get_str().c_str());
nextheight = atoi((char *)params[1].get_str().c_str());
return(NSPV_hdrsproof(prevheight,nextheight));
}
UniValue nspv_txproof(const UniValue& params, bool fHelp)
{
uint256 txid; int32_t height;
if ( fHelp || params.size() != 2 )
throw runtime_error("nspv_txproof txid height\n");
if ( KOMODO_NSPV <= 0 )
throw runtime_error("-nSPV=1 must be set to use nspv\n");
txid = Parseuint256((char *)params[0].get_str().c_str());
height = atoi((char *)params[1].get_str().c_str());
return(NSPV_txproof(0,txid,height));
}
UniValue nspv_spend(const UniValue& params, bool fHelp)
{
uint64_t satoshis;
if ( fHelp || params.size() != 2 )
throw runtime_error("nspv_spend address amount\n");
if ( KOMODO_NSPV <= 0 )
throw runtime_error("-nSPV=1 must be set to use nspv\n");
if ( NSPV_address.size() == 0 )
throw runtime_error("to nspv_send you need an active nspv_login\n");
satoshis = atof(params[1].get_str().c_str())*COIN + 0.0000000049;
//fprintf(stderr,"satoshis.%lld from %.8f\n",(long long)satoshis,atof(params[1].get_str().c_str()));
if ( satoshis < 1000 )
throw runtime_error("amount too small\n");
return(NSPV_spend((char *)NSPV_address.c_str(),(char *)params[0].get_str().c_str(),satoshis));
}
UniValue nspv_broadcast(const UniValue& params, bool fHelp)
{
if ( fHelp || params.size() != 1 )
throw runtime_error("nspv_broadcast hex\n");
if ( KOMODO_NSPV <= 0 )
throw runtime_error("-nSPV=1 must be set to use nspv\n");
return(NSPV_broadcast((char *)params[0].get_str().c_str()));
}
+377 -125
View File
File diff suppressed because it is too large Load Diff