@@ -36,6 +36,7 @@ BIN_CHECKS=$(top_srcdir)/contrib/devtools/symbol-check.py \
|
|||||||
$(top_srcdir)/contrib/devtools/security-check.py
|
$(top_srcdir)/contrib/devtools/security-check.py
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/bitcoin.ico \
|
WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/bitcoin.ico \
|
||||||
$(top_srcdir)/share/pixmaps/nsis-header.bmp \
|
$(top_srcdir)/share/pixmaps/nsis-header.bmp \
|
||||||
$(top_srcdir)/share/pixmaps/nsis-wizard.bmp
|
$(top_srcdir)/share/pixmaps/nsis-wizard.bmp
|
||||||
|
|||||||
12
doc/beefy-node-reference-komodo.conf
Normal file
12
doc/beefy-node-reference-komodo.conf
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
rpcuser=dontuseweakusernameoryougetrobbed
|
||||||
|
rpcpassword=dontuseweakpasswordoryougetrobbed
|
||||||
|
txindex=1
|
||||||
|
server=1
|
||||||
|
rpcworkqueue=64
|
||||||
|
addnode=5.9.102.210
|
||||||
|
addnode=78.47.196.146
|
||||||
|
addnode=178.63.69.164
|
||||||
|
addnode=88.198.65.74
|
||||||
|
addnode=5.9.122.241
|
||||||
|
addnode=144.76.94.38
|
||||||
|
addnode=89.248.166.91
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
# MigrateCoin protocol
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## ExportCoins tx:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
vin:
|
|
||||||
|
|
||||||
[ any ]
|
|
||||||
|
|
||||||
vout:
|
|
||||||
|
|
||||||
- amount: {burnAmount}
|
|
||||||
|
|
||||||
script: OP_RETURN "send to ledger {id} {voutsHash}"
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
* ExportCoin is a standard tx which burns coins in an OP_RETURN
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## ImportCoins tx:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
vin:
|
|
||||||
|
|
||||||
- txid: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
|
|
||||||
idx: 0
|
|
||||||
|
|
||||||
script: CC_EVAL(EVAL_IMPORTCOINS, {momoProof},{exportCoin}) OP_CHECKCRYPTOCONDITION_UNILATERAL
|
|
||||||
|
|
||||||
vout:
|
|
||||||
|
|
||||||
- [ vouts matching voutsHash in exportCoin ]
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
* ImportCoin transaction has no signature
|
|
||||||
|
|
||||||
* ImportCoin is non malleable
|
|
||||||
|
|
||||||
* ImportCoin satisfies tx.IsCoinBase()
|
|
||||||
|
|
||||||
* ImportCoin uses a new opcode which allows a one sided check (no scriptPubKey)
|
|
||||||
|
|
||||||
* ImportCoin must contain CC opcode EVAL_IMPORTCOINS
|
|
||||||
|
|
||||||
* ImportCoin fees are equal to the difference between burnAmount in exportCoins and the sum of outputs.
|
|
||||||
43
migratecoin.sh
Normal file
43
migratecoin.sh
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
# This script makes the neccesary transactions to migrate
|
||||||
|
# coin between 2 assetchains on the same -ac_cc id
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
source=TXSCL
|
||||||
|
target=TXSCL000
|
||||||
|
address="RFw7byY4xZpZCrtkMk3nFuuG1NTs9rSGgQ"
|
||||||
|
amount=1
|
||||||
|
|
||||||
|
# Alias for running cli on source chain
|
||||||
|
cli_source="komodo-cli -ac_name=$source"
|
||||||
|
|
||||||
|
# Raw tx that we will work with
|
||||||
|
txraw=`$cli_source createrawtransaction "[]" "{\"$address\":$amount}"`
|
||||||
|
|
||||||
|
# Convert to an export tx
|
||||||
|
exportData=`$cli_source migrate_converttoexport $txraw $target $amount`
|
||||||
|
exportRaw=`echo $exportData | jq -r .exportTx`
|
||||||
|
exportPayouts=`echo $exportData | jq -r .payouts`
|
||||||
|
|
||||||
|
# Fund
|
||||||
|
exportFundedData=`$cli_source fundrawtransaction $exportRaw`
|
||||||
|
exportFundedTx=`echo $exportFundedData | jq -r .hex`
|
||||||
|
|
||||||
|
# Sign
|
||||||
|
exportSignedData=`$cli_source signrawtransaction $exportFundedTx`
|
||||||
|
exportSignedTx=`echo $exportSignedData | jq -r .hex`
|
||||||
|
|
||||||
|
# Send
|
||||||
|
echo "Sending export tx"
|
||||||
|
$cli_source sendrawtransaction $exportSignedTx
|
||||||
|
|
||||||
|
read -p "Wait for a notarisation to KMD, and then two more notarisations from the target chain, and then press enter to continue"
|
||||||
|
|
||||||
|
# Create import
|
||||||
|
importTx=`$cli_source migrate_createimporttransaction $exportSignedTx $payouts`
|
||||||
|
importTx=`komodo-cli migrate_completeimporttransaction $importTx`
|
||||||
|
|
||||||
|
# Send import
|
||||||
|
komodo-cli -ac_name=$target sendrawtransaction $importTx
|
||||||
@@ -78,6 +78,12 @@ class CryptoConditionsTest (BitcoinTestFramework):
|
|||||||
for x in ['myCCaddress', 'FaucetCCaddress', 'Faucetmarker', 'myaddress']:
|
for x in ['myCCaddress', 'FaucetCCaddress', 'Faucetmarker', 'myaddress']:
|
||||||
assert_equal(faucet[x][0], 'R')
|
assert_equal(faucet[x][0], 'R')
|
||||||
|
|
||||||
|
result = rpc.faucetaddress(self.pubkey)
|
||||||
|
assert_success(result)
|
||||||
|
# test that additional CCaddress key is returned
|
||||||
|
for x in ['myCCaddress', 'FaucetCCaddress', 'Faucetmarker', 'myaddress', 'CCaddress']:
|
||||||
|
assert_equal(result[x][0], 'R')
|
||||||
|
|
||||||
# no funds in the faucet yet
|
# no funds in the faucet yet
|
||||||
result = rpc.faucetget()
|
result = rpc.faucetget()
|
||||||
assert_error(result)
|
assert_error(result)
|
||||||
@@ -134,12 +140,145 @@ class CryptoConditionsTest (BitcoinTestFramework):
|
|||||||
for x in ['myCCaddress', 'DiceCCaddress', 'Dicemarker', 'myaddress']:
|
for x in ['myCCaddress', 'DiceCCaddress', 'Dicemarker', 'myaddress']:
|
||||||
assert_equal(dice[x][0], 'R')
|
assert_equal(dice[x][0], 'R')
|
||||||
|
|
||||||
|
dice = rpc.diceaddress(self.pubkey)
|
||||||
|
assert_equal(dice['result'], 'success')
|
||||||
|
for x in ['myCCaddress', 'DiceCCaddress', 'Dicemarker', 'myaddress', 'CCaddress']:
|
||||||
|
assert_equal(dice[x][0], 'R')
|
||||||
|
|
||||||
# no dice created yet
|
# no dice created yet
|
||||||
result = rpc.dicelist()
|
result = rpc.dicelist()
|
||||||
assert_equal(result, [])
|
assert_equal(result, [])
|
||||||
|
|
||||||
#result = rpc.dicefund("LUCKY",10000,1,10000,10,5)
|
# creating dice plan with too long name (>8 chars)
|
||||||
#assert_equal(result, [])
|
result = rpc.dicefund("THISISTOOLONG", "10000", "10", "10000", "10", "5")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# creating dice plan with < 100 funding
|
||||||
|
result = rpc.dicefund("LUCKY","10","1","10000","10","5")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# creating dice plan with 0 blocks timeout
|
||||||
|
result = rpc.dicefund("LUCKY","10","1","10000","10","0")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# creating dice plan
|
||||||
|
dicefundtx = rpc.dicefund("LUCKY","1000","1","800","10","5")
|
||||||
|
diceid = self.send_and_mine(dicefundtx['hex'])
|
||||||
|
|
||||||
|
# checking if it in plans list now
|
||||||
|
result = rpc.dicelist()
|
||||||
|
assert_equal(result[0], diceid)
|
||||||
|
|
||||||
|
# set dice name for futher usage
|
||||||
|
dicename = "LUCKY"
|
||||||
|
|
||||||
|
# adding zero funds to plan
|
||||||
|
result = rpc.diceaddfunds(dicename,diceid,"0")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# adding negative funds to plan
|
||||||
|
result = rpc.diceaddfunds(dicename,diceid,"-1")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# adding funds to plan
|
||||||
|
addfundstx = rpc.diceaddfunds(dicename,diceid,"1100")
|
||||||
|
result = self.send_and_mine(addfundstx['hex'])
|
||||||
|
|
||||||
|
# checking if funds added to plan
|
||||||
|
result = rpc.diceinfo(diceid)
|
||||||
|
assert_equal(result["funding"], "2100.00000000")
|
||||||
|
|
||||||
|
# not valid dice info checking
|
||||||
|
result = rpc.diceinfo("invalid")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# placing 0 amount bet
|
||||||
|
result = rpc.dicebet(dicename,diceid,"0","1")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# placing negative amount bet
|
||||||
|
result = rpc.dicebet(dicename,diceid,"-1","1")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# placing bet more than maxbet
|
||||||
|
result = rpc.dicebet(dicename,diceid,"900","1")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# placing bet with amount more than funding
|
||||||
|
result = rpc.dicebet(dicename,diceid,"3000","1")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# placing bet with potential won more than funding
|
||||||
|
result = rpc.dicebet(dicename,diceid,"750","9")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# placing 0 odds bet
|
||||||
|
result = rpc.dicebet(dicename,diceid,"1","0")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# placing negative odds bet
|
||||||
|
result = rpc.dicebet(dicename,diceid,"1","-1")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# placing bet with odds more than allowed
|
||||||
|
result = rpc.dicebet(dicename,diceid,"1","11")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# placing bet with not correct dice name
|
||||||
|
result = rpc.dicebet("nope",diceid,"100","1")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# placing bet with not correct dice id
|
||||||
|
result = rpc.dicebet(dicename,self.pubkey,"100","1")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# valid bet placing
|
||||||
|
placebet = rpc.dicebet(dicename,diceid,"100","1")
|
||||||
|
betid = self.send_and_mine(placebet["hex"])
|
||||||
|
assert result, "bet placed"
|
||||||
|
|
||||||
|
# check bet status
|
||||||
|
result = rpc.dicestatus(dicename,diceid,betid)
|
||||||
|
assert_success(result)
|
||||||
|
|
||||||
|
# have to make some entropy for the next test
|
||||||
|
entropytx = 0
|
||||||
|
fundingsum = 1
|
||||||
|
while entropytx < 10:
|
||||||
|
fundingsuminput = str(fundingsum)
|
||||||
|
fundinghex = rpc.diceaddfunds(dicename,diceid,fundingsuminput)
|
||||||
|
result = self.send_and_mine(fundinghex['hex'])
|
||||||
|
entropytx = entropytx + 1
|
||||||
|
fundingsum = fundingsum + 1
|
||||||
|
|
||||||
|
rpc.generate(2)
|
||||||
|
|
||||||
|
# note initial dice funding state at this point.
|
||||||
|
# TODO: track player balance somehow (hard to do because of mining and fees)
|
||||||
|
diceinfo = rpc.diceinfo(diceid)
|
||||||
|
funding = float(diceinfo['funding'])
|
||||||
|
|
||||||
|
# placing same amount bets with amount 1 and odds 1:2, checking if balance changed correct
|
||||||
|
losscounter = 0
|
||||||
|
wincounter = 0
|
||||||
|
betcounter = 0
|
||||||
|
|
||||||
|
while (betcounter < 10):
|
||||||
|
placebet = rpc.dicebet(dicename,diceid,"1","1")
|
||||||
|
betid = self.send_and_mine(placebet["hex"])
|
||||||
|
finish = rpc.dicefinish(dicename,diceid,betid)
|
||||||
|
self.send_and_mine(finish["hex"])
|
||||||
|
betresult = rpc.dicestatus(dicename,diceid,betid)
|
||||||
|
betcounter = betcounter + 1
|
||||||
|
if betresult["status"] == "loss":
|
||||||
|
losscounter = losscounter + 1
|
||||||
|
elif betresult["status"] == "win":
|
||||||
|
wincounter = wincounter + 1
|
||||||
|
|
||||||
|
# funding balance should increase if player loss, decrease if player won
|
||||||
|
fundbalanceguess = funding + losscounter - wincounter
|
||||||
|
fundinfoactual = rpc.diceinfo(diceid)
|
||||||
|
assert_equal(round(fundbalanceguess),round(float(fundinfoactual['funding'])))
|
||||||
|
|
||||||
def run_token_tests(self):
|
def run_token_tests(self):
|
||||||
rpc = self.nodes[0]
|
rpc = self.nodes[0]
|
||||||
@@ -156,8 +295,18 @@ class CryptoConditionsTest (BitcoinTestFramework):
|
|||||||
result = rpc.tokenlist()
|
result = rpc.tokenlist()
|
||||||
assert_equal(result, [])
|
assert_equal(result, [])
|
||||||
|
|
||||||
result = rpc.tokencreate("DUKE", "1987.420", "duke")
|
# trying to create token with negaive supply
|
||||||
|
result = rpc.tokencreate("NUKE", "-1987420", "no bueno supply")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# creating token with name more than 32 chars
|
||||||
|
result = rpc.tokencreate("NUKE123456789012345678901234567890", "1987420", "name too long")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# creating valid token
|
||||||
|
result = rpc.tokencreate("DUKE", "1987.420", "Duke's custom token")
|
||||||
assert_success(result)
|
assert_success(result)
|
||||||
|
|
||||||
tokenid = self.send_and_mine(result['hex'])
|
tokenid = self.send_and_mine(result['hex'])
|
||||||
|
|
||||||
result = rpc.tokenlist()
|
result = rpc.tokenlist()
|
||||||
@@ -197,7 +346,7 @@ class CryptoConditionsTest (BitcoinTestFramework):
|
|||||||
assert_equal(result['owner'], self.pubkey)
|
assert_equal(result['owner'], self.pubkey)
|
||||||
assert_equal(result['name'], "DUKE")
|
assert_equal(result['name'], "DUKE")
|
||||||
assert_equal(result['supply'], 198742000000)
|
assert_equal(result['supply'], 198742000000)
|
||||||
assert_equal(result['description'], "duke")
|
assert_equal(result['description'], "Duke's custom token")
|
||||||
|
|
||||||
# invalid numtokens ask
|
# invalid numtokens ask
|
||||||
result = rpc.tokenask("-1", tokenid, "1")
|
result = rpc.tokenask("-1", tokenid, "1")
|
||||||
@@ -253,27 +402,26 @@ class CryptoConditionsTest (BitcoinTestFramework):
|
|||||||
result = rpc.tokenorders()
|
result = rpc.tokenorders()
|
||||||
assert_equal(result, [])
|
assert_equal(result, [])
|
||||||
|
|
||||||
# invalid numtokens bid (have to add status to CC code!)
|
# invalid numtokens bid
|
||||||
result = rpc.tokenbid("-1", tokenid, "1")
|
result = rpc.tokenbid("-1", tokenid, "1")
|
||||||
assert_equal(result['error'], 'invalid parameter')
|
assert_error(result)
|
||||||
|
|
||||||
# invalid numtokens bid (have to add status to CC code!)
|
# invalid numtokens bid
|
||||||
result = rpc.tokenbid("0", tokenid, "1")
|
result = rpc.tokenbid("0", tokenid, "1")
|
||||||
assert_equal(result['error'], 'invalid parameter')
|
assert_error(result)
|
||||||
|
|
||||||
# invalid price bid (have to add status to CC code!)
|
# invalid price bid
|
||||||
result = rpc.tokenbid("1", tokenid, "-1")
|
result = rpc.tokenbid("1", tokenid, "-1")
|
||||||
assert_equal(result['error'], 'invalid parameter')
|
assert_error(result)
|
||||||
|
|
||||||
# invalid price bid (have to add status to CC code!)
|
# invalid price bid
|
||||||
result = rpc.tokenbid("1", tokenid, "0")
|
result = rpc.tokenbid("1", tokenid, "0")
|
||||||
assert_equal(result['error'], 'invalid parameter')
|
assert_error(result)
|
||||||
|
|
||||||
# invalid tokenid bid (have to add status to CC code!)
|
# invalid tokenid bid
|
||||||
result = rpc.tokenbid("100", "deadbeef", "1")
|
result = rpc.tokenbid("100", "deadbeef", "1")
|
||||||
assert_equal(result['error'], 'invalid parameter')
|
assert_error(result)
|
||||||
|
|
||||||
# valid bid
|
|
||||||
tokenbid = rpc.tokenbid("100", tokenid, "10")
|
tokenbid = rpc.tokenbid("100", tokenid, "10")
|
||||||
tokenbidhex = tokenbid['hex']
|
tokenbidhex = tokenbid['hex']
|
||||||
tokenbidid = self.send_and_mine(tokenbid['hex'])
|
tokenbidid = self.send_and_mine(tokenbid['hex'])
|
||||||
@@ -310,11 +458,11 @@ class CryptoConditionsTest (BitcoinTestFramework):
|
|||||||
# invalid token transfer amount (have to add status to CC code!)
|
# invalid token transfer amount (have to add status to CC code!)
|
||||||
randompubkey = "021a559101e355c907d9c553671044d619769a6e71d624f68bfec7d0afa6bd6a96"
|
randompubkey = "021a559101e355c907d9c553671044d619769a6e71d624f68bfec7d0afa6bd6a96"
|
||||||
result = rpc.tokentransfer(tokenid,randompubkey,"0")
|
result = rpc.tokentransfer(tokenid,randompubkey,"0")
|
||||||
assert_equal(result['error'], 'invalid parameter')
|
assert_error(result)
|
||||||
|
|
||||||
# invalid token transfer amount (have to add status to CC code!)
|
# invalid token transfer amount (have to add status to CC code!)
|
||||||
result = rpc.tokentransfer(tokenid,randompubkey,"-1")
|
result = rpc.tokentransfer(tokenid,randompubkey,"-1")
|
||||||
assert_equal(result['error'], 'invalid parameter')
|
assert_error(result)
|
||||||
|
|
||||||
# valid token transfer
|
# valid token transfer
|
||||||
sendtokens = rpc.tokentransfer(tokenid,randompubkey,"1")
|
sendtokens = rpc.tokentransfer(tokenid,randompubkey,"1")
|
||||||
@@ -341,14 +489,31 @@ class CryptoConditionsTest (BitcoinTestFramework):
|
|||||||
result = rpc.rewardsinfo("none")
|
result = rpc.rewardsinfo("none")
|
||||||
assert_error(result)
|
assert_error(result)
|
||||||
|
|
||||||
|
# creating rewards plan with name > 8 chars, should return error
|
||||||
|
result = rpc.rewardscreatefunding("STUFFSTUFF", "7777", "25", "0", "10", "10")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# creating rewards plan with 0 funding
|
||||||
|
result = rpc.rewardscreatefunding("STUFF", "0", "25", "0", "10", "10")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# creating rewards plan with 0 maxdays
|
||||||
|
result = rpc.rewardscreatefunding("STUFF", "7777", "25", "0", "10", "0")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# creating rewards plan with > 25% APR
|
||||||
|
result = rpc.rewardscreatefunding("STUFF", "7777", "30", "0", "10", "10")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# creating valid rewards plan
|
||||||
result = rpc.rewardscreatefunding("STUFF", "7777", "25", "0", "10", "10")
|
result = rpc.rewardscreatefunding("STUFF", "7777", "25", "0", "10", "10")
|
||||||
assert result['hex'], 'got raw xtn'
|
assert result['hex'], 'got raw xtn'
|
||||||
txid = rpc.sendrawtransaction(result['hex'])
|
fundingtxid = rpc.sendrawtransaction(result['hex'])
|
||||||
assert txid, 'got txid'
|
assert fundingtxid, 'got txid'
|
||||||
|
|
||||||
# confirm the above xtn
|
# confirm the above xtn
|
||||||
rpc.generate(1)
|
rpc.generate(1)
|
||||||
result = rpc.rewardsinfo(txid)
|
result = rpc.rewardsinfo(fundingtxid)
|
||||||
assert_success(result)
|
assert_success(result)
|
||||||
assert_equal(result['name'], 'STUFF')
|
assert_equal(result['name'], 'STUFF')
|
||||||
assert_equal(result['APR'], "25.00000000")
|
assert_equal(result['APR'], "25.00000000")
|
||||||
@@ -356,39 +521,38 @@ class CryptoConditionsTest (BitcoinTestFramework):
|
|||||||
assert_equal(result['maxseconds'], 864000)
|
assert_equal(result['maxseconds'], 864000)
|
||||||
assert_equal(result['funding'], "7777.00000000")
|
assert_equal(result['funding'], "7777.00000000")
|
||||||
assert_equal(result['mindeposit'], "10.00000000")
|
assert_equal(result['mindeposit'], "10.00000000")
|
||||||
assert_equal(result['fundingtxid'], txid)
|
assert_equal(result['fundingtxid'], fundingtxid)
|
||||||
|
|
||||||
# funding amount must be positive
|
# checking if new plan in rewardslist
|
||||||
result = rpc.rewardsaddfunding("STUFF", txid, "0")
|
result = rpc.rewardslist()
|
||||||
|
assert_equal(result[0], fundingtxid)
|
||||||
|
|
||||||
|
# creating reward plan with already existing name, should return error
|
||||||
|
result = rpc.rewardscreatefunding("STUFF", "7777", "25", "0", "10", "10")
|
||||||
assert_error(result)
|
assert_error(result)
|
||||||
|
|
||||||
result = rpc.rewardsaddfunding("STUFF", txid, "555")
|
# add funding amount must be positive
|
||||||
assert_success(result)
|
result = rpc.rewardsaddfunding("STUFF", fundingtxid, "-1")
|
||||||
fundingtxid = result['hex']
|
|
||||||
assert fundingtxid, "got funding txid"
|
|
||||||
|
|
||||||
result = rpc.rewardslock("STUFF", fundingtxid, "7")
|
|
||||||
assert_error(result)
|
assert_error(result)
|
||||||
|
|
||||||
# the previous xtn has not been broadcasted yet
|
# add funding amount must be positive
|
||||||
result = rpc.rewardsunlock("STUFF", fundingtxid)
|
result = rpc.rewardsaddfunding("STUFF", fundingtxid, "0")
|
||||||
assert_error(result)
|
assert_error(result)
|
||||||
|
|
||||||
# wrong plan name
|
# adding valid funding
|
||||||
result = rpc.rewardsunlock("SHTUFF", fundingtxid)
|
result = rpc.rewardsaddfunding("STUFF", fundingtxid, "555")
|
||||||
assert_error(result)
|
addfundingtxid = self.send_and_mine(result['hex'])
|
||||||
|
assert addfundingtxid, 'got funding txid'
|
||||||
|
|
||||||
txid = rpc.sendrawtransaction(fundingtxid)
|
# checking if funding added to rewardsplan
|
||||||
assert txid, 'got txid from sendrawtransaction'
|
result = rpc.rewardsinfo(fundingtxid)
|
||||||
|
assert_equal(result['funding'], "8332.00000000")
|
||||||
|
|
||||||
# confirm the xtn above
|
# trying to lock funds, locking funds amount must be positive
|
||||||
rpc.generate(1)
|
|
||||||
|
|
||||||
# amount must be positive
|
|
||||||
result = rpc.rewardslock("STUFF", fundingtxid, "-5")
|
result = rpc.rewardslock("STUFF", fundingtxid, "-5")
|
||||||
assert_error(result)
|
assert_error(result)
|
||||||
|
|
||||||
# amount must be positive
|
# trying to lock funds, locking funds amount must be positive
|
||||||
result = rpc.rewardslock("STUFF", fundingtxid, "0")
|
result = rpc.rewardslock("STUFF", fundingtxid, "0")
|
||||||
assert_error(result)
|
assert_error(result)
|
||||||
|
|
||||||
@@ -396,25 +560,26 @@ class CryptoConditionsTest (BitcoinTestFramework):
|
|||||||
result = rpc.rewardslock("STUFF", fundingtxid, "7")
|
result = rpc.rewardslock("STUFF", fundingtxid, "7")
|
||||||
assert_error(result)
|
assert_error(result)
|
||||||
|
|
||||||
# not working
|
# locking funds in rewards plan
|
||||||
#result = rpc.rewardslock("STUFF", fundingtxid, "10")
|
result = rpc.rewardslock("STUFF", fundingtxid, "10")
|
||||||
#assert_success(result)
|
assert_success(result)
|
||||||
#locktxid = result['hex']
|
locktxid = result['hex']
|
||||||
#assert locktxid, "got lock txid"
|
assert locktxid, "got lock txid"
|
||||||
|
|
||||||
# locktxid has not been broadcast yet
|
# locktxid has not been broadcast yet
|
||||||
#result = rpc.rewardsunlock("STUFF", locktxid)
|
result = rpc.rewardsunlock("STUFF", fundingtxid, locktxid)
|
||||||
#assert_error(result)
|
assert_error(result)
|
||||||
|
|
||||||
# broadcast xtn
|
# broadcast xtn
|
||||||
#txid = rpc.sendrawtransaction(locktxid)
|
txid = rpc.sendrawtransaction(locktxid)
|
||||||
#assert txid, 'got txid from sendrawtransaction'
|
assert txid, 'got txid from sendrawtransaction'
|
||||||
|
|
||||||
# confirm the xtn above
|
# confirm the xtn above
|
||||||
#rpc.generate(1)
|
rpc.generate(1)
|
||||||
|
|
||||||
#result = rpc.rewardsunlock("STUFF", locktxid)
|
# will not unlock since reward amount is less than tx fee
|
||||||
#assert_error(result)
|
result = rpc.rewardsunlock("STUFF", fundingtxid, locktxid)
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
|
||||||
def run_test (self):
|
def run_test (self):
|
||||||
@@ -429,6 +594,7 @@ class CryptoConditionsTest (BitcoinTestFramework):
|
|||||||
print("Importing privkey")
|
print("Importing privkey")
|
||||||
rpc.importprivkey(self.privkey)
|
rpc.importprivkey(self.privkey)
|
||||||
|
|
||||||
|
# self.run_faucet_tests()
|
||||||
self.run_rewards_tests()
|
self.run_rewards_tests()
|
||||||
self.run_dice_tests()
|
self.run_dice_tests()
|
||||||
self.run_token_tests()
|
self.run_token_tests()
|
||||||
|
|||||||
@@ -45,7 +45,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ac_name": "COQUI",
|
"ac_name": "COQUI",
|
||||||
"ac_supply": "72000000"
|
"ac_supply": "72000000",
|
||||||
|
"ac_ccactivate": "200000"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ac_name": "WLC",
|
"ac_name": "WLC",
|
||||||
@@ -140,7 +141,9 @@
|
|||||||
"ac_cc": "2",
|
"ac_cc": "2",
|
||||||
"addressindex": "1",
|
"addressindex": "1",
|
||||||
"spentindex": "1",
|
"spentindex": "1",
|
||||||
"addnode": "142.93.136.89",
|
"addnode": [
|
||||||
"addnode": "195.201.22.89"
|
"142.93.136.89",
|
||||||
|
"195.201.22.89"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ echo $pubkey
|
|||||||
./komodod -pubkey=$pubkey -ac_name=MSHARK -ac_supply=1400000 -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=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=MGW -ac_supply=999999 -addnode=78.47.196.146 $1 &
|
||||||
./komodod -pubkey=$pubkey -ac_name=COQUI -ac_supply=72000000 -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=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=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=CEAL -ac_supply=366666666 -addnode=78.47.196.146 $1 &
|
||||||
|
|||||||
@@ -259,14 +259,14 @@ bool ProcessCC(struct CCcontract_info *cp,Eval* eval, std::vector<uint8_t> param
|
|||||||
height = KOMODO_CONNECTING;
|
height = KOMODO_CONNECTING;
|
||||||
if ( KOMODO_CONNECTING < 0 ) // always comes back with > 0 for final confirmation
|
if ( KOMODO_CONNECTING < 0 ) // always comes back with > 0 for final confirmation
|
||||||
return(true);
|
return(true);
|
||||||
if ( ASSETCHAINS_CC == 0 || height < KOMODO_CCACTIVATE )
|
if ( ASSETCHAINS_CC == 0 || (height & ~(1<<30)) < KOMODO_CCACTIVATE )
|
||||||
return eval->Invalid("CC are disabled or not active yet");
|
return eval->Invalid("CC are disabled or not active yet");
|
||||||
if ( (KOMODO_CONNECTING & (1<<30)) != 0 )
|
if ( (KOMODO_CONNECTING & (1<<30)) != 0 )
|
||||||
{
|
{
|
||||||
from_mempool = 1;
|
from_mempool = 1;
|
||||||
height &= ((1<<30) - 1);
|
height &= ((1<<30) - 1);
|
||||||
}
|
}
|
||||||
fprintf(stderr,"KOMODO_CONNECTING.%d mempool.%d\n",height,from_mempool);
|
fprintf(stderr,"KOMODO_CONNECTING.%d mempool.%d vs CCactive.%d\n",height,from_mempool,KOMODO_CCACTIVATE);
|
||||||
// there is a chance CC tx is valid in mempool, but invalid when in block, so we cant filter duplicate requests. if any of the vins are spent, for example
|
// there is a chance CC tx is valid in mempool, but invalid when in block, so we cant filter duplicate requests. if any of the vins are spent, for example
|
||||||
//txid = ctx.GetHash();
|
//txid = ctx.GetHash();
|
||||||
//if ( txid == cp->prevtxid )
|
//if ( txid == cp->prevtxid )
|
||||||
|
|||||||
84
src/cc/disputepayout.cpp
Normal file
84
src/cc/disputepayout.cpp
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
#include <cryptoconditions.h>
|
||||||
|
|
||||||
|
#include "hash.h"
|
||||||
|
#include "chain.h"
|
||||||
|
#include "version.h"
|
||||||
|
#include "script/cc.h"
|
||||||
|
#include "cc/eval.h"
|
||||||
|
#include "cc/betprotocol.h"
|
||||||
|
#include "primitives/transaction.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Crypto-Condition EVAL method that resolves a dispute of a session
|
||||||
|
*
|
||||||
|
* IN: vm - AppVM virtual machine to verify states
|
||||||
|
* IN: params - condition params
|
||||||
|
* IN: disputeTx - transaction attempting to resolve dispute
|
||||||
|
* IN: nIn - index of input of dispute tx
|
||||||
|
*
|
||||||
|
* disputeTx: attempt to resolve a dispute
|
||||||
|
*
|
||||||
|
* in 0: Spends Session TX first output, reveals DisputeHeader
|
||||||
|
* out 0: OP_RETURN hash of payouts
|
||||||
|
*/
|
||||||
|
bool Eval::DisputePayout(AppVM &vm, std::vector<uint8_t> params, const CTransaction &disputeTx, unsigned int nIn)
|
||||||
|
{
|
||||||
|
if (disputeTx.vout.size() == 0) return Invalid("no-vouts");
|
||||||
|
|
||||||
|
// get payouts hash
|
||||||
|
uint256 payoutHash;
|
||||||
|
if (!GetOpReturnHash(disputeTx.vout[0].scriptPubKey, payoutHash))
|
||||||
|
return Invalid("invalid-payout-hash");
|
||||||
|
|
||||||
|
// load params
|
||||||
|
uint16_t waitBlocks;
|
||||||
|
std::vector<uint8_t> vmParams;
|
||||||
|
if (!E_UNMARSHAL(params, ss >> VARINT(waitBlocks); ss >> vmParams))
|
||||||
|
return Invalid("malformed-params");
|
||||||
|
|
||||||
|
// ensure that enough time has passed
|
||||||
|
{
|
||||||
|
CTransaction sessionTx;
|
||||||
|
CBlockIndex sessionBlock;
|
||||||
|
|
||||||
|
// if unconformed its too soon
|
||||||
|
if (!GetTxConfirmed(disputeTx.vin[0].prevout.hash, sessionTx, sessionBlock))
|
||||||
|
return Error("couldnt-get-parent");
|
||||||
|
|
||||||
|
if (GetCurrentHeight() < sessionBlock.nHeight + waitBlocks)
|
||||||
|
return Invalid("dispute-too-soon"); // Not yet
|
||||||
|
}
|
||||||
|
|
||||||
|
// get spends
|
||||||
|
std::vector<CTransaction> spends;
|
||||||
|
if (!GetSpendsConfirmed(disputeTx.vin[0].prevout.hash, spends))
|
||||||
|
return Error("couldnt-get-spends");
|
||||||
|
|
||||||
|
// verify result from VM
|
||||||
|
int maxLength = -1;
|
||||||
|
uint256 bestPayout;
|
||||||
|
for (int i=1; i<spends.size(); i++)
|
||||||
|
{
|
||||||
|
std::vector<unsigned char> vmState;
|
||||||
|
if (spends[i].vout.size() == 0) continue;
|
||||||
|
if (!GetOpReturnData(spends[i].vout[0].scriptPubKey, vmState)) continue;
|
||||||
|
auto out = vm.evaluate(vmParams, vmState);
|
||||||
|
uint256 resultHash = SerializeHash(out.second);
|
||||||
|
if (out.first > maxLength) {
|
||||||
|
maxLength = out.first;
|
||||||
|
bestPayout = resultHash;
|
||||||
|
}
|
||||||
|
// The below means that if for any reason there is a draw, the first dispute wins
|
||||||
|
else if (out.first == maxLength) {
|
||||||
|
if (bestPayout != payoutHash) {
|
||||||
|
fprintf(stderr, "WARNING: VM has multiple solutions of same length\n");
|
||||||
|
bestPayout = resultHash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxLength == -1) return Invalid("no-evidence");
|
||||||
|
|
||||||
|
return bestPayout == payoutHash ? Valid() : Invalid("wrong-payout");
|
||||||
|
}
|
||||||
@@ -59,7 +59,7 @@ bool Eval::ImportCoin(const std::vector<uint8_t> params, const CTransaction &imp
|
|||||||
|
|
||||||
// check burn amount
|
// check burn amount
|
||||||
{
|
{
|
||||||
uint64_t burnAmount = burnTx.vout[0].nValue;
|
uint64_t burnAmount = burnTx.vout.back().nValue;
|
||||||
if (burnAmount == 0)
|
if (burnAmount == 0)
|
||||||
return Invalid("invalid-burn-amount");
|
return Invalid("invalid-burn-amount");
|
||||||
uint64_t totalOut = 0;
|
uint64_t totalOut = 0;
|
||||||
|
|||||||
76
src/cc/importpayout.cpp
Normal file
76
src/cc/importpayout.cpp
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
#include <cryptoconditions.h>
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "chain.h"
|
||||||
|
#include "streams.h"
|
||||||
|
#include "cc/eval.h"
|
||||||
|
#include "cc/betprotocol.h"
|
||||||
|
#include "primitives/transaction.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Crypto-Condition EVAL method that verifies a payout against a transaction
|
||||||
|
* notarised on another chain.
|
||||||
|
*
|
||||||
|
* IN: params - condition params
|
||||||
|
* IN: importTx - Payout transaction on value chain (KMD)
|
||||||
|
* IN: nIn - index of input of stake
|
||||||
|
*
|
||||||
|
* importTx: Spends stakeTx with payouts from asset chain
|
||||||
|
*
|
||||||
|
* in 0: Spends Stake TX and contains ImportPayout CC
|
||||||
|
* out 0: OP_RETURN MomProof, disputeTx
|
||||||
|
* out 1-: arbitrary payouts
|
||||||
|
*
|
||||||
|
* disputeTx: Spends sessionTx.0 (opener on asset chain)
|
||||||
|
*
|
||||||
|
* in 0: spends sessionTx.0
|
||||||
|
* in 1-: anything
|
||||||
|
* out 0: OP_RETURN hash of payouts
|
||||||
|
* out 1-: anything
|
||||||
|
*/
|
||||||
|
bool Eval::ImportPayout(const std::vector<uint8_t> params, const CTransaction &importTx, unsigned int nIn)
|
||||||
|
{
|
||||||
|
if (importTx.vout.size() == 0) return Invalid("no-vouts");
|
||||||
|
|
||||||
|
// load data from vout[0]
|
||||||
|
MoMProof proof;
|
||||||
|
CTransaction disputeTx;
|
||||||
|
{
|
||||||
|
std::vector<unsigned char> vopret;
|
||||||
|
GetOpReturnData(importTx.vout[0].scriptPubKey, vopret);
|
||||||
|
if (!E_UNMARSHAL(vopret, ss >> proof; ss >> disputeTx))
|
||||||
|
return Invalid("invalid-payload");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check disputeTx.0 shows correct payouts
|
||||||
|
{
|
||||||
|
uint256 givenPayoutsHash;
|
||||||
|
GetOpReturnHash(disputeTx.vout[0].scriptPubKey, givenPayoutsHash);
|
||||||
|
std::vector<CTxOut> payouts(importTx.vout.begin() + 1, importTx.vout.end());
|
||||||
|
if (givenPayoutsHash != SerializeHash(payouts))
|
||||||
|
return Invalid("wrong-payouts");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check disputeTx spends sessionTx.0
|
||||||
|
// condition ImportPayout params is session ID from other chain
|
||||||
|
{
|
||||||
|
uint256 sessionHash;
|
||||||
|
if (!E_UNMARSHAL(params, ss >> sessionHash))
|
||||||
|
return Invalid("malformed-params");
|
||||||
|
if (disputeTx.vin[0].prevout != COutPoint(sessionHash, 0))
|
||||||
|
return Invalid("wrong-session");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check disputeTx solves momproof from vout[0]
|
||||||
|
{
|
||||||
|
NotarisationData data;
|
||||||
|
if (!GetNotarisationData(proof.notarisationHash, data))
|
||||||
|
return Invalid("coudnt-load-mom");
|
||||||
|
|
||||||
|
if (data.MoM != proof.Exec(disputeTx.GetHash()))
|
||||||
|
return Invalid("mom-check-fail");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Valid();
|
||||||
|
}
|
||||||
@@ -196,7 +196,7 @@ bool RewardsExactAmounts(struct CCcontract_info *cp,Eval *eval,const CTransactio
|
|||||||
|
|
||||||
bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
|
bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
|
||||||
{
|
{
|
||||||
uint256 txid,fundingtxid,hashBlock; uint64_t sbits,APR,minseconds,maxseconds,mindeposit,amount,reward,txfee=10000; int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; uint8_t funcid; CScript scriptPubKey; CTransaction fundingTx,vinTx;
|
uint256 txid,fundingtxid,hashBlock,vinfundingtxid; uint64_t vinsbits,sbits,APR,minseconds,maxseconds,mindeposit,amount,reward,txfee=10000; int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; uint8_t funcid; CScript scriptPubKey; CTransaction fundingTx,vinTx;
|
||||||
numvins = tx.vin.size();
|
numvins = tx.vin.size();
|
||||||
numvouts = tx.vout.size();
|
numvouts = tx.vout.size();
|
||||||
preventCCvins = preventCCvouts = -1;
|
preventCCvins = preventCCvouts = -1;
|
||||||
@@ -244,8 +244,16 @@ bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
|
|||||||
//vout.0: funding CC change or recover normal payout
|
//vout.0: funding CC change or recover normal payout
|
||||||
//vout.1: normal output to unlock address
|
//vout.1: normal output to unlock address
|
||||||
//vout.n-1: opreturn 'U' sbits fundingtxid
|
//vout.n-1: opreturn 'U' sbits fundingtxid
|
||||||
if ( eval->GetTxUnconfirmed(tx.vin[0].prevout.hash,vinTx,hashBlock) == 0 )
|
//char str[65],str2[65];
|
||||||
|
//fprintf(stderr,"funding.%s vs %s\n",uint256_str(str,fundingtxid),uint256_str(str2,tx.vin[0].prevout.hash));
|
||||||
|
if ( fundingtxid == tx.vin[0].prevout.hash )
|
||||||
|
return eval->Invalid("cant unlock fundingtxid");
|
||||||
|
else if ( eval->GetTxUnconfirmed(tx.vin[0].prevout.hash,vinTx,hashBlock) == 0 )
|
||||||
return eval->Invalid("always should find vin.0, but didnt");
|
return eval->Invalid("always should find vin.0, but didnt");
|
||||||
|
else if ( DecodeRewardsOpRet(tx.vin[0].prevout.hash,vinTx.vout[vinTx.vout.size()-1].scriptPubKey,vinsbits,vinfundingtxid) != 'L' )
|
||||||
|
return eval->Invalid("can only unlock locktxid");
|
||||||
|
else if ( fundingtxid != vinfundingtxid )
|
||||||
|
return eval->Invalid("mismatched vinfundingtxid");
|
||||||
for (i=0; i<numvins; i++)
|
for (i=0; i<numvins; i++)
|
||||||
{
|
{
|
||||||
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) == 0 )
|
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) == 0 )
|
||||||
@@ -609,6 +617,12 @@ std::string RewardsUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint2
|
|||||||
rewardspk = GetUnspendable(cp,0);
|
rewardspk = GetUnspendable(cp,0);
|
||||||
mypk = pubkey2pk(Mypubkey());
|
mypk = pubkey2pk(Mypubkey());
|
||||||
sbits = stringbits(planstr);
|
sbits = stringbits(planstr);
|
||||||
|
if ( locktxid == fundingtxid )
|
||||||
|
{
|
||||||
|
fprintf(stderr,"Rewards plan cant unlock fundingtxid\n");
|
||||||
|
CCerror = "Rewards plan cant unlock fundingtxid";
|
||||||
|
return("");
|
||||||
|
}
|
||||||
if ( RewardsPlanExists(cp,sbits,rewardspk,APR,minseconds,maxseconds,mindeposit) == 0 )
|
if ( RewardsPlanExists(cp,sbits,rewardspk,APR,minseconds,maxseconds,mindeposit) == 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"Rewards plan %s doesnt exist\n",planstr);
|
fprintf(stderr,"Rewards plan %s doesnt exist\n",planstr);
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ uint256 CalculateProofRoot(const char* symbol, uint32_t targetCCid, int kmdHeigh
|
|||||||
|
|
||||||
int seenOwnNotarisations = 0;
|
int seenOwnNotarisations = 0;
|
||||||
|
|
||||||
|
bool txscl = IsTXSCL(symbol);
|
||||||
|
|
||||||
for (int i=0; i<NOTARISATION_SCAN_LIMIT_BLOCKS; i++) {
|
for (int i=0; i<NOTARISATION_SCAN_LIMIT_BLOCKS; i++) {
|
||||||
if (i > kmdHeight) break;
|
if (i > kmdHeight) break;
|
||||||
NotarisationsInBlock notarisations;
|
NotarisationsInBlock notarisations;
|
||||||
@@ -72,8 +74,9 @@ uint256 CalculateProofRoot(const char* symbol, uint32_t targetCCid, int kmdHeigh
|
|||||||
|
|
||||||
if (seenOwnNotarisations == 1) {
|
if (seenOwnNotarisations == 1) {
|
||||||
BOOST_FOREACH(Notarisation& nota, notarisations) {
|
BOOST_FOREACH(Notarisation& nota, notarisations) {
|
||||||
if (nota.second.ccId == targetCCid)
|
if (IsTXSCL(nota.second.symbol) == txscl)
|
||||||
moms.push_back(nota.second.MoM);
|
if (nota.second.ccId == targetCCid)
|
||||||
|
moms.push_back(nota.second.MoM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
src/fiat/vote2018
Executable file
2
src/fiat/vote2018
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
./komodo-cli -ac_name=VOTE2018 $1 $2 $3 $4 $5 $6
|
||||||
@@ -45,7 +45,7 @@ bool UnmarshalBurnTx(const CTransaction &burnTx, std::string &targetSymbol, uint
|
|||||||
{
|
{
|
||||||
std::vector<uint8_t> burnOpret;
|
std::vector<uint8_t> burnOpret;
|
||||||
if (burnTx.vout.size() == 0) return false;
|
if (burnTx.vout.size() == 0) return false;
|
||||||
GetOpReturnData(burnTx.vout[0].scriptPubKey, burnOpret);
|
GetOpReturnData(burnTx.vout.back().scriptPubKey, burnOpret);
|
||||||
return E_UNMARSHAL(burnOpret, ss >> VARINT(*targetCCid);
|
return E_UNMARSHAL(burnOpret, ss >> VARINT(*targetCCid);
|
||||||
ss >> targetSymbol;
|
ss >> targetSymbol;
|
||||||
ss >> payoutsHash);
|
ss >> payoutsHash);
|
||||||
@@ -61,7 +61,7 @@ CAmount GetCoinImportValue(const CTransaction &tx)
|
|||||||
CTransaction burnTx;
|
CTransaction burnTx;
|
||||||
std::vector<CTxOut> payouts;
|
std::vector<CTxOut> payouts;
|
||||||
if (UnmarshalImportTx(tx, proof, burnTx, payouts)) {
|
if (UnmarshalImportTx(tx, proof, burnTx, payouts)) {
|
||||||
return burnTx.vout.size() ? burnTx.vout[0].nValue : 0;
|
return burnTx.vout.size() ? burnTx.vout.back().nValue : 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -311,7 +311,7 @@ int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long
|
|||||||
{
|
{
|
||||||
if ( memread(opret,olen,filedata,&fpos,datalen) != olen )
|
if ( memread(opret,olen,filedata,&fpos,datalen) != olen )
|
||||||
errs++;
|
errs++;
|
||||||
if ( 1 && ASSETCHAINS_SYMBOL[0] != 0 && matched != 0 )
|
if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 && matched != 0 )
|
||||||
{
|
{
|
||||||
int32_t i; for (i=0; i<olen; i++)
|
int32_t i; for (i=0; i<olen; i++)
|
||||||
printf("%02x",opret[i]);
|
printf("%02x",opret[i]);
|
||||||
@@ -600,7 +600,7 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr
|
|||||||
{
|
{
|
||||||
if ( scriptbuf[len] == 'K' )
|
if ( scriptbuf[len] == 'K' )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"i.%d j.%d KV OPRET len.%d %.8f\n",i,j,opretlen,dstr(value));
|
//fprintf(stderr,"i.%d j.%d KV OPRET len.%d %.8f\n",i,j,opretlen,dstr(value));
|
||||||
komodo_stateupdate(height,0,0,0,txhash,0,0,0,0,0,0,value,&scriptbuf[len],opretlen,j,zero,0);
|
komodo_stateupdate(height,0,0,0,txhash,0,0,0,0,0,0,value,&scriptbuf[len],opretlen,j,zero,0);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ int32_t komodo_kvsearch(uint256 *pubkeyp,int32_t current_height,uint32_t *flagsp
|
|||||||
if ( ptr != 0 )
|
if ( ptr != 0 )
|
||||||
{
|
{
|
||||||
duration = komodo_kvduration(ptr->flags);
|
duration = komodo_kvduration(ptr->flags);
|
||||||
fprintf(stderr,"duration.%d flags.%d current.%d ht.%d keylen.%d valuesize.%d\n",duration,ptr->flags,current_height,ptr->height,ptr->keylen,ptr->valuesize);
|
//fprintf(stderr,"duration.%d flags.%d current.%d ht.%d keylen.%d valuesize.%d\n",duration,ptr->flags,current_height,ptr->height,ptr->keylen,ptr->valuesize);
|
||||||
if ( current_height > (ptr->height + duration) )
|
if ( current_height > (ptr->height + duration) )
|
||||||
{
|
{
|
||||||
HASH_DELETE(hh,KOMODO_KV,ptr);
|
HASH_DELETE(hh,KOMODO_KV,ptr);
|
||||||
@@ -117,7 +117,7 @@ void komodo_kvupdate(uint8_t *opretbuf,int32_t opretlen,uint64_t value)
|
|||||||
}
|
}
|
||||||
valueptr = &key[keylen];
|
valueptr = &key[keylen];
|
||||||
fee = komodo_kvfee(flags,opretlen,keylen);
|
fee = komodo_kvfee(flags,opretlen,keylen);
|
||||||
printf("fee %.8f vs %.8f flags.%d keylen.%d valuesize.%d height.%d (%02x %02x %02x) (%02x %02x %02x)\n",(double)fee/COIN,(double)value/COIN,flags,keylen,valuesize,height,key[0],key[1],key[2],valueptr[0],valueptr[1],valueptr[2]);
|
//printf("fee %.8f vs %.8f flags.%d keylen.%d valuesize.%d height.%d (%02x %02x %02x) (%02x %02x %02x)\n",(double)fee/COIN,(double)value/COIN,flags,keylen,valuesize,height,key[0],key[1],key[2],valueptr[0],valueptr[1],valueptr[2]);
|
||||||
if ( value >= fee )
|
if ( value >= fee )
|
||||||
{
|
{
|
||||||
coresize = (int32_t)(sizeof(flags)+sizeof(height)+sizeof(keylen)+sizeof(valuesize)+keylen+valuesize+1);
|
coresize = (int32_t)(sizeof(flags)+sizeof(height)+sizeof(keylen)+sizeof(valuesize)+keylen+valuesize+1);
|
||||||
@@ -142,7 +142,7 @@ void komodo_kvupdate(uint8_t *opretbuf,int32_t opretlen,uint64_t value)
|
|||||||
{
|
{
|
||||||
if ( komodo_kvsigverify(keyvalue,keylen+refvaluesize,refpubkey,sig) < 0 )
|
if ( komodo_kvsigverify(keyvalue,keylen+refvaluesize,refpubkey,sig) < 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"komodo_kvsigverify error [%d]\n",coresize-13);
|
//fprintf(stderr,"komodo_kvsigverify error [%d]\n",coresize-13);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -151,7 +151,7 @@ void komodo_kvupdate(uint8_t *opretbuf,int32_t opretlen,uint64_t value)
|
|||||||
HASH_FIND(hh,KOMODO_KV,key,keylen,ptr);
|
HASH_FIND(hh,KOMODO_KV,key,keylen,ptr);
|
||||||
if ( ptr != 0 )
|
if ( ptr != 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"(%s) already there\n",(char *)key);
|
//fprintf(stderr,"(%s) already there\n",(char *)key);
|
||||||
//if ( (ptr->flags & KOMODO_KVPROTECTED) != 0 )
|
//if ( (ptr->flags & KOMODO_KVPROTECTED) != 0 )
|
||||||
{
|
{
|
||||||
tstr = (char *)"transfer:";
|
tstr = (char *)"transfer:";
|
||||||
|
|||||||
36
src/main.cpp
36
src/main.cpp
@@ -736,7 +736,7 @@ bool IsStandardTx(const CTransaction& tx, string& reason, const int nHeight)
|
|||||||
if (!::IsStandard(txout.scriptPubKey, whichType))
|
if (!::IsStandard(txout.scriptPubKey, whichType))
|
||||||
{
|
{
|
||||||
reason = "scriptpubkey";
|
reason = "scriptpubkey";
|
||||||
fprintf(stderr,">>>>>>>>>>>>>>> vout.%d nDataout.%d\n",v,nDataOut);
|
//fprintf(stderr,">>>>>>>>>>>>>>> vout.%d nDataout.%d\n",v,nDataOut);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1306,7 +1306,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
|||||||
string reason;
|
string reason;
|
||||||
if (Params().RequireStandard() && !IsStandardTx(tx, reason, nextBlockHeight))
|
if (Params().RequireStandard() && !IsStandardTx(tx, reason, nextBlockHeight))
|
||||||
{
|
{
|
||||||
fprintf(stderr,"AcceptToMemoryPool reject nonstandard transaction: %s\n",reason.c_str());
|
//fprintf(stderr,"AcceptToMemoryPool reject nonstandard transaction: %s\n",reason.c_str());
|
||||||
return state.DoS(0,error("AcceptToMemoryPool: nonstandard transaction: %s", reason),REJECT_NONSTANDARD, reason);
|
return state.DoS(0,error("AcceptToMemoryPool: nonstandard transaction: %s", reason),REJECT_NONSTANDARD, reason);
|
||||||
}
|
}
|
||||||
// Only accept nLockTime-using transactions that can be mined in the next
|
// Only accept nLockTime-using transactions that can be mined in the next
|
||||||
@@ -1541,20 +1541,23 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
|||||||
}
|
}
|
||||||
if ( flag != 0 )
|
if ( flag != 0 )
|
||||||
KOMODO_CONNECTING = -1;
|
KOMODO_CONNECTING = -1;
|
||||||
|
|
||||||
// Store transaction in memory
|
// Store transaction in memory
|
||||||
if ( komodo_is_notarytx(tx) == 0 )
|
if ( komodo_is_notarytx(tx) == 0 )
|
||||||
KOMODO_ON_DEMAND++;
|
KOMODO_ON_DEMAND++;
|
||||||
pool.addUnchecked(hash, entry, !IsInitialBlockDownload());
|
pool.addUnchecked(hash, entry, !IsInitialBlockDownload());
|
||||||
|
|
||||||
// Add memory address index
|
if (!tx.IsCoinImport())
|
||||||
if (fAddressIndex) {
|
{
|
||||||
pool.addAddressIndex(entry, view);
|
// Add memory address index
|
||||||
}
|
if (fAddressIndex) {
|
||||||
|
pool.addAddressIndex(entry, view);
|
||||||
|
}
|
||||||
|
|
||||||
// Add memory spent index
|
// Add memory spent index
|
||||||
if (fSpentIndex) {
|
if (fSpentIndex) {
|
||||||
pool.addSpentIndex(entry, view);
|
pool.addSpentIndex(entry, view);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3367,6 +3370,15 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) {
|
|||||||
CBlock block;
|
CBlock block;
|
||||||
if (!ReadBlockFromDisk(block, pindexDelete,1))
|
if (!ReadBlockFromDisk(block, pindexDelete,1))
|
||||||
return AbortNode(state, "Failed to read block");
|
return AbortNode(state, "Failed to read block");
|
||||||
|
{
|
||||||
|
int32_t prevMoMheight; uint256 notarizedhash,txid;
|
||||||
|
komodo_notarized_height(&prevMoMheight,¬arizedhash,&txid);
|
||||||
|
if ( block.GetHash() == notarizedhash )
|
||||||
|
{
|
||||||
|
fprintf(stderr,"DisconnectTip trying to disconnect notarized block at ht.%d\n",(int32_t)pindexDelete->nHeight);
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
// Apply the block atomically to the chain state.
|
// Apply the block atomically to the chain state.
|
||||||
uint256 anchorBeforeDisconnect = pcoinsTip->GetBestAnchor();
|
uint256 anchorBeforeDisconnect = pcoinsTip->GetBestAnchor();
|
||||||
int64_t nStart = GetTimeMicros();
|
int64_t nStart = GetTimeMicros();
|
||||||
@@ -4187,11 +4199,11 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
|
|||||||
}
|
}
|
||||||
if ( rejects == 0 || rejects == lastrejects )
|
if ( rejects == 0 || rejects == lastrejects )
|
||||||
{
|
{
|
||||||
if ( lastrejects != 0 )
|
if ( 0 && lastrejects != 0 )
|
||||||
fprintf(stderr,"lastrejects.%d -> all tx in mempool\n",lastrejects);
|
fprintf(stderr,"lastrejects.%d -> all tx in mempool\n",lastrejects);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprintf(stderr,"addtomempool ht.%d for CC checking: n.%d rejects.%d last.%d\n",height,(int32_t)block.vtx.size(),rejects,lastrejects);
|
//fprintf(stderr,"addtomempool ht.%d for CC checking: n.%d rejects.%d last.%d\n",height,(int32_t)block.vtx.size(),rejects,lastrejects);
|
||||||
lastrejects = rejects;
|
lastrejects = rejects;
|
||||||
rejects = 0;
|
rejects = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "notarisationdb.h"
|
#include "notarisationdb.h"
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
#include "cc/eval.h"
|
#include "cc/eval.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
@@ -25,7 +26,7 @@ NotarisationsInBlock ScanBlockNotarisations(const CBlock &block, int nHeight)
|
|||||||
{
|
{
|
||||||
NotarisationData data;
|
NotarisationData data;
|
||||||
if (ParseNotarisationOpReturn(tx, data))
|
if (ParseNotarisationOpReturn(tx, data))
|
||||||
if (strlen(data.symbol) >= 5 && strncmp(data.symbol, "TXSCL", 5) == 0)
|
if (IsTXSCL(data.symbol))
|
||||||
isTxscl = 1;
|
isTxscl = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,6 +46,11 @@ NotarisationsInBlock ScanBlockNotarisations(const CBlock &block, int nHeight)
|
|||||||
return vNotarisations;
|
return vNotarisations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsTXSCL(const char* symbol)
|
||||||
|
{
|
||||||
|
return strlen(symbol) >= 5 && strncmp(symbol, "TXSCL", 5) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GetBlockNotarisations(uint256 blockHash, NotarisationsInBlock &nibs)
|
bool GetBlockNotarisations(uint256 blockHash, NotarisationsInBlock &nibs)
|
||||||
{
|
{
|
||||||
@@ -82,3 +88,29 @@ void EraseBackNotarisations(const NotarisationsInBlock notarisations, CLevelDBBa
|
|||||||
batch.Erase(n.second.txHash);
|
batch.Erase(n.second.txHash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scan notarisationsdb backwards for blocks containing a notarisation
|
||||||
|
* for given symbol. Return height of matched notarisation or 0.
|
||||||
|
*/
|
||||||
|
int ScanNotarisationsDB(int height, std::string symbol, int scanLimitBlocks, Notarisation& out)
|
||||||
|
{
|
||||||
|
if (height < 0 || height > chainActive.Height())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int i=0; i<scanLimitBlocks; i++) {
|
||||||
|
if (i > height) break;
|
||||||
|
NotarisationsInBlock notarisations;
|
||||||
|
uint256 blockHash = *chainActive[height-i]->phashBlock;
|
||||||
|
if (!GetBlockNotarisations(blockHash, notarisations))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BOOST_FOREACH(Notarisation& nota, notarisations) {
|
||||||
|
if (strcmp(nota.second.symbol, symbol.data()) == 0) {
|
||||||
|
out = nota;
|
||||||
|
return height-i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,5 +23,7 @@ bool GetBlockNotarisations(uint256 blockHash, NotarisationsInBlock &nibs);
|
|||||||
bool GetBackNotarisation(uint256 notarisationHash, Notarisation &n);
|
bool GetBackNotarisation(uint256 notarisationHash, Notarisation &n);
|
||||||
void WriteBackNotarisations(const NotarisationsInBlock notarisations, CLevelDBBatch &batch);
|
void WriteBackNotarisations(const NotarisationsInBlock notarisations, CLevelDBBatch &batch);
|
||||||
void EraseBackNotarisations(const NotarisationsInBlock notarisations, CLevelDBBatch &batch);
|
void EraseBackNotarisations(const NotarisationsInBlock notarisations, CLevelDBBatch &batch);
|
||||||
|
int ScanNotarisationsDB(int height, std::string symbol, int scanLimitBlocks, Notarisation& out);
|
||||||
|
bool IsTXSCL(const char* symbol);
|
||||||
|
|
||||||
#endif /* NOTARISATIONDB_H */
|
#endif /* NOTARISATIONDB_H */
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ using namespace std;
|
|||||||
|
|
||||||
extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
|
extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
|
||||||
void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
|
void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
|
||||||
|
int32_t komodo_longestchain();
|
||||||
|
|
||||||
double GetDifficultyINTERNAL(const CBlockIndex* blockindex, bool networkDifficulty)
|
double GetDifficultyINTERNAL(const CBlockIndex* blockindex, bool networkDifficulty)
|
||||||
{
|
{
|
||||||
@@ -819,7 +820,7 @@ UniValue kvsearch(const UniValue& params, bool fHelp)
|
|||||||
"}\n"
|
"}\n"
|
||||||
"\nExamples:\n"
|
"\nExamples:\n"
|
||||||
+ HelpExampleCli("kvsearch", "examplekey")
|
+ HelpExampleCli("kvsearch", "examplekey")
|
||||||
+ HelpExampleRpc("kvsearch", "examplekey")
|
+ HelpExampleRpc("kvsearch", "\"examplekey\"")
|
||||||
);
|
);
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
if ( (keylen= (int32_t)strlen(params[0].get_str().c_str())) > 0 )
|
if ( (keylen= (int32_t)strlen(params[0].get_str().c_str())) > 0 )
|
||||||
@@ -1297,14 +1298,20 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp)
|
|||||||
);
|
);
|
||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
|
double progress;
|
||||||
|
if ( ASSETCHAINS_SYMBOL[0] == 0 ) {
|
||||||
|
progress = Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.LastTip());
|
||||||
|
} else {
|
||||||
|
int32_t longestchain = komodo_longestchain();
|
||||||
|
progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0;
|
||||||
|
}
|
||||||
UniValue obj(UniValue::VOBJ);
|
UniValue obj(UniValue::VOBJ);
|
||||||
obj.push_back(Pair("chain", Params().NetworkIDString()));
|
obj.push_back(Pair("chain", Params().NetworkIDString()));
|
||||||
obj.push_back(Pair("blocks", (int)chainActive.Height()));
|
obj.push_back(Pair("blocks", (int)chainActive.Height()));
|
||||||
obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
|
obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
|
||||||
obj.push_back(Pair("bestblockhash", chainActive.LastTip()->GetBlockHash().GetHex()));
|
obj.push_back(Pair("bestblockhash", chainActive.LastTip()->GetBlockHash().GetHex()));
|
||||||
obj.push_back(Pair("difficulty", (double)GetNetworkDifficulty()));
|
obj.push_back(Pair("difficulty", (double)GetNetworkDifficulty()));
|
||||||
obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.LastTip())));
|
obj.push_back(Pair("verificationprogress", progress));
|
||||||
obj.push_back(Pair("chainwork", chainActive.LastTip()->nChainWork.GetHex()));
|
obj.push_back(Pair("chainwork", chainActive.LastTip()->nChainWork.GetHex()));
|
||||||
obj.push_back(Pair("pruned", fPruneMode));
|
obj.push_back(Pair("pruned", fPruneMode));
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "chainparams.h"
|
#include "chainparams.h"
|
||||||
#include "checkpoints.h"
|
#include "checkpoints.h"
|
||||||
#include "crosschain.h"
|
#include "crosschain.h"
|
||||||
|
#include "notarisationdb.h"
|
||||||
#include "importcoin.h"
|
#include "importcoin.h"
|
||||||
#include "base58.h"
|
#include "base58.h"
|
||||||
#include "consensus/validation.h"
|
#include "consensus/validation.h"
|
||||||
@@ -251,3 +252,55 @@ UniValue migrate_completeimporttransaction(const UniValue& params, bool fHelp)
|
|||||||
|
|
||||||
return HexStr(E_MARSHAL(ss << importTx));
|
return HexStr(E_MARSHAL(ss << importTx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UniValue getNotarisationsForBlock(const UniValue& params, bool fHelp)
|
||||||
|
{
|
||||||
|
if (fHelp || params.size() != 1)
|
||||||
|
throw runtime_error("getNotarisationsForBlock blockHash\n\n"
|
||||||
|
"Takes a block hash and returns notarisation transactions "
|
||||||
|
"within the block");
|
||||||
|
|
||||||
|
uint256 blockHash = uint256S(params[0].get_str());
|
||||||
|
|
||||||
|
NotarisationsInBlock nibs;
|
||||||
|
GetBlockNotarisations(blockHash, nibs);
|
||||||
|
UniValue out(UniValue::VARR);
|
||||||
|
BOOST_FOREACH(const Notarisation& n, nibs)
|
||||||
|
{
|
||||||
|
UniValue item(UniValue::VARR);
|
||||||
|
item.push_back(n.first.GetHex());
|
||||||
|
item.push_back(HexStr(E_MARSHAL(ss << n.second)));
|
||||||
|
out.push_back(item);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UniValue scanNotarisationsDB(const UniValue& params, bool fHelp)
|
||||||
|
{
|
||||||
|
if (fHelp || params.size() < 2 || params.size() > 3)
|
||||||
|
throw runtime_error("scanNotarisationsDB blockHeight symbol [blocksLimit=1440]\n\n"
|
||||||
|
"Scans notarisationsdb backwards from height for a notarisation"
|
||||||
|
" of given symbol");
|
||||||
|
int height = atoi(params[0].get_str().c_str());
|
||||||
|
std::string symbol = params[1].get_str().c_str();
|
||||||
|
|
||||||
|
int limit = 1440;
|
||||||
|
if (params.size() > 2) {
|
||||||
|
limit = atoi(params[2].get_str().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (height == 0) {
|
||||||
|
height = chainActive.Height();
|
||||||
|
}
|
||||||
|
|
||||||
|
Notarisation nota;
|
||||||
|
int matchedHeight = ScanNotarisationsDB(height, symbol, limit, nota);
|
||||||
|
if (!matchedHeight) return NullUniValue;
|
||||||
|
UniValue out(UniValue::VOBJ);
|
||||||
|
out.pushKV("height", matchedHeight);
|
||||||
|
out.pushKV("hash", nota.first.GetHex());
|
||||||
|
out.pushKV("opreturn", HexStr(E_MARSHAL(ss << nota.second)));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|||||||
@@ -915,7 +915,7 @@ UniValue getblocksubsidy(const UniValue& params, bool fHelp)
|
|||||||
"}\n"
|
"}\n"
|
||||||
"\nExamples:\n"
|
"\nExamples:\n"
|
||||||
+ HelpExampleCli("getblocksubsidy", "1000")
|
+ HelpExampleCli("getblocksubsidy", "1000")
|
||||||
+ HelpExampleRpc("getblockubsidy", "1000")
|
+ HelpExampleRpc("getblocksubsidy", "1000")
|
||||||
);
|
);
|
||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
|||||||
uint32_t komodo_segid32(char *coinaddr);
|
uint32_t komodo_segid32(char *coinaddr);
|
||||||
int64_t komodo_coinsupply(int64_t *zfundsp,int32_t height);
|
int64_t komodo_coinsupply(int64_t *zfundsp,int32_t height);
|
||||||
int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heightp);
|
int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heightp);
|
||||||
#define KOMODO_VERSION "0.2.0"
|
#define KOMODO_VERSION "0.2.1"
|
||||||
extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT;
|
extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT;
|
||||||
extern uint32_t ASSETCHAINS_CC;
|
extern uint32_t ASSETCHAINS_CC;
|
||||||
extern uint32_t ASSETCHAINS_MAGIC;
|
extern uint32_t ASSETCHAINS_MAGIC;
|
||||||
|
|||||||
@@ -303,6 +303,8 @@ static const CRPCCommand vRPCCommands[] =
|
|||||||
{ "blockchain", "paxpending", &paxpending, true },
|
{ "blockchain", "paxpending", &paxpending, true },
|
||||||
{ "blockchain", "paxprices", &paxprices, true },
|
{ "blockchain", "paxprices", &paxprices, true },
|
||||||
{ "blockchain", "notaries", ¬aries, true },
|
{ "blockchain", "notaries", ¬aries, true },
|
||||||
|
//{ "blockchain", "height_MoM", &height_MoM, true },
|
||||||
|
//{ "blockchain", "txMoMproof", &txMoMproof, true },
|
||||||
{ "blockchain", "minerids", &minerids, true },
|
{ "blockchain", "minerids", &minerids, true },
|
||||||
{ "blockchain", "kvsearch", &kvsearch, true },
|
{ "blockchain", "kvsearch", &kvsearch, true },
|
||||||
{ "blockchain", "kvupdate", &kvupdate, true },
|
{ "blockchain", "kvupdate", &kvupdate, true },
|
||||||
@@ -313,6 +315,8 @@ static const CRPCCommand vRPCCommands[] =
|
|||||||
{ "crosschain", "height_MoM", &height_MoM, true },
|
{ "crosschain", "height_MoM", &height_MoM, true },
|
||||||
{ "crosschain", "assetchainproof", &assetchainproof, true },
|
{ "crosschain", "assetchainproof", &assetchainproof, true },
|
||||||
{ "crosschain", "crosschainproof", &crosschainproof, true },
|
{ "crosschain", "crosschainproof", &crosschainproof, true },
|
||||||
|
{ "crosschain", "getNotarisationsForBlock", &getNotarisationsForBlock, true },
|
||||||
|
{ "crosschain", "scanNotarisationsDB", &scanNotarisationsDB, true },
|
||||||
{ "crosschain", "migrate_converttoexport", &migrate_converttoexport, true },
|
{ "crosschain", "migrate_converttoexport", &migrate_converttoexport, true },
|
||||||
{ "crosschain", "migrate_createimporttransaction", &migrate_createimporttransaction, true },
|
{ "crosschain", "migrate_createimporttransaction", &migrate_createimporttransaction, true },
|
||||||
{ "crosschain", "migrate_completeimporttransaction", &migrate_completeimporttransaction, true },
|
{ "crosschain", "migrate_completeimporttransaction", &migrate_completeimporttransaction, true },
|
||||||
|
|||||||
@@ -361,6 +361,8 @@ extern UniValue calc_MoM(const UniValue& params, bool fHelp);
|
|||||||
extern UniValue height_MoM(const UniValue& params, bool fHelp);
|
extern UniValue height_MoM(const UniValue& params, bool fHelp);
|
||||||
extern UniValue assetchainproof(const UniValue& params, bool fHelp);
|
extern UniValue assetchainproof(const UniValue& params, bool fHelp);
|
||||||
extern UniValue crosschainproof(const UniValue& params, bool fHelp);
|
extern UniValue crosschainproof(const UniValue& params, bool fHelp);
|
||||||
|
extern UniValue getNotarisationsForBlock(const UniValue& params, bool fHelp);
|
||||||
|
extern UniValue scanNotarisationsDB(const UniValue& params, bool fHelp);
|
||||||
extern UniValue migrate_converttoexport(const UniValue& params, bool fHelp);
|
extern UniValue migrate_converttoexport(const UniValue& params, bool fHelp);
|
||||||
extern UniValue migrate_createimporttransaction(const UniValue& params, bool fHelp);
|
extern UniValue migrate_createimporttransaction(const UniValue& params, bool fHelp);
|
||||||
extern UniValue migrate_completeimporttransaction(const UniValue& params, bool fHelp);
|
extern UniValue migrate_completeimporttransaction(const UniValue& params, bool fHelp);
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsi
|
|||||||
// small pushdata, <= nMaxDatacarrierBytes
|
// small pushdata, <= nMaxDatacarrierBytes
|
||||||
if (vch1.size() > nMaxDatacarrierBytes)
|
if (vch1.size() > nMaxDatacarrierBytes)
|
||||||
{
|
{
|
||||||
fprintf(stderr,"size.%d > nMaxDatacarrier.%d\n",(int32_t)vch1.size(),(int32_t)nMaxDatacarrierBytes);
|
//fprintf(stderr,"size.%d > nMaxDatacarrier.%d\n",(int32_t)vch1.size(),(int32_t)nMaxDatacarrierBytes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ TEST_F(TestCoinImport, testInvalidBurnOutputs)
|
|||||||
|
|
||||||
TEST_F(TestCoinImport, testInvalidBurnParams)
|
TEST_F(TestCoinImport, testInvalidBurnParams)
|
||||||
{
|
{
|
||||||
burnTx.vout[0].scriptPubKey = CScript() << OP_RETURN << E_MARSHAL(ss << VARINT(testCcid));
|
burnTx.vout.back().scriptPubKey = CScript() << OP_RETURN << E_MARSHAL(ss << VARINT(testCcid));
|
||||||
MoMoM = burnTx.GetHash(); // TODO: an actual branch
|
MoMoM = burnTx.GetHash(); // TODO: an actual branch
|
||||||
CTransaction tx = MakeImportCoinTransaction(proof, CTransaction(burnTx), payouts);
|
CTransaction tx = MakeImportCoinTransaction(proof, CTransaction(burnTx), payouts);
|
||||||
TestRunCCEval(tx);
|
TestRunCCEval(tx);
|
||||||
@@ -198,7 +198,7 @@ TEST_F(TestCoinImport, testWrongChainId)
|
|||||||
|
|
||||||
TEST_F(TestCoinImport, testInvalidBurnAmount)
|
TEST_F(TestCoinImport, testInvalidBurnAmount)
|
||||||
{
|
{
|
||||||
burnTx.vout[0].nValue = 0;
|
burnTx.vout.back().nValue = 0;
|
||||||
MoMoM = burnTx.GetHash(); // TODO: an actual branch
|
MoMoM = burnTx.GetHash(); // TODO: an actual branch
|
||||||
CTransaction tx = MakeImportCoinTransaction(proof, CTransaction(burnTx), payouts);
|
CTransaction tx = MakeImportCoinTransaction(proof, CTransaction(burnTx), payouts);
|
||||||
TestRunCCEval(tx);
|
TestRunCCEval(tx);
|
||||||
|
|||||||
@@ -55,6 +55,9 @@ std::string CCerror;
|
|||||||
// Private method:
|
// Private method:
|
||||||
UniValue z_getoperationstatus_IMPL(const UniValue&, bool);
|
UniValue z_getoperationstatus_IMPL(const UniValue&, bool);
|
||||||
|
|
||||||
|
#define PLAN_NAME_MAX 8
|
||||||
|
#define VALID_PLAN_NAME(x) (strlen(x) <= PLAN_NAME_MAX)
|
||||||
|
|
||||||
std::string HelpRequiringPassphrase()
|
std::string HelpRequiringPassphrase()
|
||||||
{
|
{
|
||||||
return pwalletMain && pwalletMain->IsCrypted()
|
return pwalletMain && pwalletMain->IsCrypted()
|
||||||
@@ -539,7 +542,7 @@ UniValue kvupdate(const UniValue& params, bool fHelp)
|
|||||||
"}\n"
|
"}\n"
|
||||||
"\nExamples:\n"
|
"\nExamples:\n"
|
||||||
+ HelpExampleCli("kvupdate", "examplekey \"examplevalue\" 2 examplepassphrase")
|
+ HelpExampleCli("kvupdate", "examplekey \"examplevalue\" 2 examplepassphrase")
|
||||||
+ HelpExampleRpc("kvupdate", "examplekey \"examplevalue\" 2 examplepassphrase")
|
+ HelpExampleRpc("kvupdate", "\"examplekey\",\"examplevalue\",\"2\",\"examplepassphrase\"")
|
||||||
);
|
);
|
||||||
if (!EnsureWalletIsAvailable(fHelp))
|
if (!EnsureWalletIsAvailable(fHelp))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1249,13 +1252,13 @@ UniValue sendmany(const UniValue& params, bool fHelp)
|
|||||||
" the number of addresses.\n"
|
" the number of addresses.\n"
|
||||||
"\nExamples:\n"
|
"\nExamples:\n"
|
||||||
"\nSend two amounts to two different addresses:\n"
|
"\nSend two amounts to two different addresses:\n"
|
||||||
+ HelpExampleCli("sendmany", "\"\" \"{\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\\\":0.01,\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\\\":0.02}\"") +
|
+ HelpExampleCli("sendmany", "\"\" \"{\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPVMY\\\":0.01,\\\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\\\":0.02}\"") +
|
||||||
"\nSend two amounts to two different addresses setting the confirmation and comment:\n"
|
"\nSend two amounts to two different addresses setting the confirmation and comment:\n"
|
||||||
+ HelpExampleCli("sendmany", "\"\" \"{\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\\\":0.01,\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\\\":0.02}\" 6 \"testing\"") +
|
+ HelpExampleCli("sendmany", "\"\" \"{\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPVMY\\\":0.01,\\\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\\\":0.02}\" 6 \"testing\"") +
|
||||||
"\nSend two amounts to two different addresses, subtract fee from amount:\n"
|
"\nSend two amounts to two different addresses, subtract fee from amount:\n"
|
||||||
+ HelpExampleCli("sendmany", "\"\" \"{\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\\\":0.01,\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\\\":0.02}\" 1 \"\" \"[\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\\\",\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\\\"]\"") +
|
+ HelpExampleCli("sendmany", "\"\" \"{\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPVMY\\\":0.01,\\\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\\\":0.02}\" 1 \"\" \"[\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPVMY\\\",\\\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\\\"]\"") +
|
||||||
"\nAs a json rpc call\n"
|
"\nAs a json rpc call\n"
|
||||||
+ HelpExampleRpc("sendmany", "\"\", \"{\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\\\":0.01,\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\\\":0.02}\", 6, \"testing\"")
|
+ HelpExampleRpc("sendmany", "\"\", {\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPVMY\":0.01,\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\":0.02}, 6, \"testing\"")
|
||||||
);
|
);
|
||||||
if ( ASSETCHAINS_PRIVATE != 0 )
|
if ( ASSETCHAINS_PRIVATE != 0 )
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "cant use transparent addresses in private chain");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "cant use transparent addresses in private chain");
|
||||||
@@ -4982,6 +4985,11 @@ UniValue rewardscreatefunding(const UniValue& params, bool fHelp)
|
|||||||
name = (char *)params[0].get_str().c_str();
|
name = (char *)params[0].get_str().c_str();
|
||||||
funds = atof(params[1].get_str().c_str()) * COIN;
|
funds = atof(params[1].get_str().c_str()) * COIN;
|
||||||
|
|
||||||
|
if (!VALID_PLAN_NAME(name)) {
|
||||||
|
ERR_RESULT(strprintf("Plan name can be at most %d ASCII characters",PLAN_NAME_MAX));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
if ( funds <= 0 ) {
|
if ( funds <= 0 ) {
|
||||||
ERR_RESULT("funds must be positive");
|
ERR_RESULT("funds must be positive");
|
||||||
return result;
|
return result;
|
||||||
@@ -5043,6 +5051,11 @@ UniValue rewardslock(const UniValue& params, bool fHelp)
|
|||||||
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
|
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||||
amount = atof(params[2].get_str().c_str()) * COIN;
|
amount = atof(params[2].get_str().c_str()) * COIN;
|
||||||
hex = RewardsLock(0,name,fundingtxid,amount);
|
hex = RewardsLock(0,name,fundingtxid,amount);
|
||||||
|
|
||||||
|
if (!VALID_PLAN_NAME(name)) {
|
||||||
|
ERR_RESULT(strprintf("Plan name can be at most %d ASCII characters",PLAN_NAME_MAX));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
if ( CCerror != "" ){
|
if ( CCerror != "" ){
|
||||||
ERR_RESULT(CCerror);
|
ERR_RESULT(CCerror);
|
||||||
} else if ( amount > 0 ) {
|
} else if ( amount > 0 ) {
|
||||||
@@ -5068,6 +5081,11 @@ UniValue rewardsaddfunding(const UniValue& params, bool fHelp)
|
|||||||
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
|
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||||
amount = atof(params[2].get_str().c_str()) * COIN;
|
amount = atof(params[2].get_str().c_str()) * COIN;
|
||||||
hex = RewardsAddfunding(0,name,fundingtxid,amount);
|
hex = RewardsAddfunding(0,name,fundingtxid,amount);
|
||||||
|
|
||||||
|
if (!VALID_PLAN_NAME(name)) {
|
||||||
|
ERR_RESULT(strprintf("Plan name can be at most %d ASCII characters",PLAN_NAME_MAX));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
if (CCerror != "") {
|
if (CCerror != "") {
|
||||||
ERR_RESULT(CCerror);
|
ERR_RESULT(CCerror);
|
||||||
} else if (amount > 0) {
|
} else if (amount > 0) {
|
||||||
@@ -5096,6 +5114,11 @@ UniValue rewardsunlock(const UniValue& params, bool fHelp)
|
|||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
name = (char *)params[0].get_str().c_str();
|
name = (char *)params[0].get_str().c_str();
|
||||||
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
|
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||||
|
|
||||||
|
if (!VALID_PLAN_NAME(name)) {
|
||||||
|
ERR_RESULT(strprintf("Plan name can be at most %d ASCII characters",PLAN_NAME_MAX));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
if ( params.size() > 2 )
|
if ( params.size() > 2 )
|
||||||
txid = Parseuint256((char *)params[2].get_str().c_str());
|
txid = Parseuint256((char *)params[2].get_str().c_str());
|
||||||
else memset(&txid,0,sizeof(txid));
|
else memset(&txid,0,sizeof(txid));
|
||||||
@@ -5234,6 +5257,12 @@ UniValue dicefund(const UniValue& params, bool fHelp)
|
|||||||
maxbet = atof(params[3].get_str().c_str()) * COIN;
|
maxbet = atof(params[3].get_str().c_str()) * COIN;
|
||||||
maxodds = atol(params[4].get_str().c_str());
|
maxodds = atol(params[4].get_str().c_str());
|
||||||
timeoutblocks = atol(params[5].get_str().c_str());
|
timeoutblocks = atol(params[5].get_str().c_str());
|
||||||
|
|
||||||
|
if (!VALID_PLAN_NAME(name)) {
|
||||||
|
ERR_RESULT(strprintf("Plan name can be at most %d ASCII characters",PLAN_NAME_MAX));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
hex = DiceCreateFunding(0,name,funds,minbet,maxbet,maxodds,timeoutblocks);
|
hex = DiceCreateFunding(0,name,funds,minbet,maxbet,maxodds,timeoutblocks);
|
||||||
if (CCerror != "") {
|
if (CCerror != "") {
|
||||||
ERR_RESULT(CCerror);
|
ERR_RESULT(CCerror);
|
||||||
@@ -5258,6 +5287,10 @@ UniValue diceaddfunds(const UniValue& params, bool fHelp)
|
|||||||
name = (char *)params[0].get_str().c_str();
|
name = (char *)params[0].get_str().c_str();
|
||||||
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
|
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||||
amount = atof(params[2].get_str().c_str()) * COIN;
|
amount = atof(params[2].get_str().c_str()) * COIN;
|
||||||
|
if (!VALID_PLAN_NAME(name)) {
|
||||||
|
ERR_RESULT(strprintf("Plan name can be at most %d ASCII characters",PLAN_NAME_MAX));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
if ( amount > 0 ) {
|
if ( amount > 0 ) {
|
||||||
hex = DiceAddfunding(0,name,fundingtxid,amount);
|
hex = DiceAddfunding(0,name,fundingtxid,amount);
|
||||||
if (CCerror != "") {
|
if (CCerror != "") {
|
||||||
@@ -5283,6 +5316,11 @@ UniValue dicebet(const UniValue& params, bool fHelp)
|
|||||||
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
|
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||||
amount = atof(params[2].get_str().c_str()) * COIN;
|
amount = atof(params[2].get_str().c_str()) * COIN;
|
||||||
odds = atol(params[3].get_str().c_str());
|
odds = atol(params[3].get_str().c_str());
|
||||||
|
|
||||||
|
if (!VALID_PLAN_NAME(name)) {
|
||||||
|
ERR_RESULT(strprintf("Plan name can be at most %d ASCII characters",PLAN_NAME_MAX));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
if (amount > 0 && odds > 0) {
|
if (amount > 0 && odds > 0) {
|
||||||
hex = DiceBet(0,name,fundingtxid,amount,odds);
|
hex = DiceBet(0,name,fundingtxid,amount,odds);
|
||||||
if ( hex.size() > 0 )
|
if ( hex.size() > 0 )
|
||||||
@@ -5306,6 +5344,10 @@ UniValue dicefinish(const UniValue& params, bool fHelp)
|
|||||||
const CKeyStore& keystore = *pwalletMain;
|
const CKeyStore& keystore = *pwalletMain;
|
||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
name = (char *)params[0].get_str().c_str();
|
name = (char *)params[0].get_str().c_str();
|
||||||
|
if (!VALID_PLAN_NAME(name)) {
|
||||||
|
ERR_RESULT(strprintf("Plan name can be at most %d ASCII characters",PLAN_NAME_MAX));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
|
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||||
bettxid = Parseuint256((char *)params[2].get_str().c_str());
|
bettxid = Parseuint256((char *)params[2].get_str().c_str());
|
||||||
hex = DiceBetFinish(&r,0,name,fundingtxid,bettxid,1);
|
hex = DiceBetFinish(&r,0,name,fundingtxid,bettxid,1);
|
||||||
@@ -5330,6 +5372,10 @@ UniValue dicestatus(const UniValue& params, bool fHelp)
|
|||||||
const CKeyStore& keystore = *pwalletMain;
|
const CKeyStore& keystore = *pwalletMain;
|
||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
name = (char *)params[0].get_str().c_str();
|
name = (char *)params[0].get_str().c_str();
|
||||||
|
if (!VALID_PLAN_NAME(name)) {
|
||||||
|
ERR_RESULT(strprintf("Plan name can be at most %d ASCII characters",PLAN_NAME_MAX));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
|
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||||
memset(&bettxid,0,sizeof(bettxid));
|
memset(&bettxid,0,sizeof(bettxid));
|
||||||
if ( params.size() == 3 )
|
if ( params.size() == 3 )
|
||||||
@@ -5453,9 +5499,14 @@ UniValue tokencreate(const UniValue& params, bool fHelp)
|
|||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
name = params[0].get_str();
|
name = params[0].get_str();
|
||||||
supply = atof(params[1].get_str().c_str()) * COIN;
|
supply = atof(params[1].get_str().c_str()) * COIN;
|
||||||
if ( name.size() == 0 || supply <= 0 )
|
if ( name.size() == 0 || name.size() > 32)
|
||||||
{
|
{
|
||||||
result.push_back(Pair("error", "invalid parameter"));
|
ERR_RESULT("Token name must not be empty and up to 32 characters");
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
if ( supply <= 0 )
|
||||||
|
{
|
||||||
|
ERR_RESULT("Token supply must be positive");
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
if ( params.size() == 3 )
|
if ( params.size() == 3 )
|
||||||
@@ -5463,7 +5514,7 @@ UniValue tokencreate(const UniValue& params, bool fHelp)
|
|||||||
description = params[2].get_str();
|
description = params[2].get_str();
|
||||||
if ( description.size() > 4096 )
|
if ( description.size() > 4096 )
|
||||||
{
|
{
|
||||||
result.push_back(Pair("error", "token description longer than 4096"));
|
ERR_RESULT("Token description must be <= 4096 characters");
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5488,9 +5539,14 @@ UniValue tokentransfer(const UniValue& params, bool fHelp)
|
|||||||
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
||||||
std::vector<unsigned char> pubkey(ParseHex(params[1].get_str().c_str()));
|
std::vector<unsigned char> pubkey(ParseHex(params[1].get_str().c_str()));
|
||||||
amount = atol(params[2].get_str().c_str());
|
amount = atol(params[2].get_str().c_str());
|
||||||
if ( tokenid == zeroid || amount <= 0 )
|
if ( tokenid == zeroid )
|
||||||
{
|
{
|
||||||
result.push_back(Pair("error", "invalid parameter"));
|
ERR_RESULT("invalid tokenid");
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
if ( amount <= 0 )
|
||||||
|
{
|
||||||
|
ERR_RESULT("amount must be positive");
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
hex = AssetTransfer(0,tokenid,pubkey,amount);
|
hex = AssetTransfer(0,tokenid,pubkey,amount);
|
||||||
@@ -5519,9 +5575,19 @@ UniValue tokenbid(const UniValue& params, bool fHelp)
|
|||||||
tokenid = Parseuint256((char *)params[1].get_str().c_str());
|
tokenid = Parseuint256((char *)params[1].get_str().c_str());
|
||||||
price = atof(params[2].get_str().c_str());
|
price = atof(params[2].get_str().c_str());
|
||||||
bidamount = (price * numtokens) * COIN + 0.0000000049999;
|
bidamount = (price * numtokens) * COIN + 0.0000000049999;
|
||||||
if ( tokenid == zeroid || tokenid == zeroid || price <= 0 || bidamount <= 0 )
|
if ( price <= 0 )
|
||||||
{
|
{
|
||||||
result.push_back(Pair("error", "invalid parameter"));
|
ERR_RESULT("price must be positive");
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
if ( tokenid == zeroid )
|
||||||
|
{
|
||||||
|
ERR_RESULT("invalid tokenid");
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
if ( bidamount <= 0 )
|
||||||
|
{
|
||||||
|
ERR_RESULT("bid amount must be positive");
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
hex = CreateBuyOffer(0,bidamount,tokenid,numtokens);
|
hex = CreateBuyOffer(0,bidamount,tokenid,numtokens);
|
||||||
@@ -5530,7 +5596,7 @@ UniValue tokenbid(const UniValue& params, bool fHelp)
|
|||||||
{
|
{
|
||||||
result.push_back(Pair("result", "success"));
|
result.push_back(Pair("result", "success"));
|
||||||
result.push_back(Pair("hex", hex));
|
result.push_back(Pair("hex", hex));
|
||||||
} else result.push_back(Pair("error", "couldnt create bid"));
|
} else ERR_RESULT("couldnt create bid");
|
||||||
} else {
|
} else {
|
||||||
ERR_RESULT("price and numtokens must be positive");
|
ERR_RESULT("price and numtokens must be positive");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,11 @@
|
|||||||
|
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
PARAMS_DIR="$HOME/.zcash-params"
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
|
PARAMS_DIR="$HOME/Library/Application Support/ZcashParams"
|
||||||
|
else
|
||||||
|
PARAMS_DIR="$HOME/.zcash-params"
|
||||||
|
fi
|
||||||
|
|
||||||
SPROUT_PKEY_NAME='sprout-proving.key'
|
SPROUT_PKEY_NAME='sprout-proving.key'
|
||||||
SPROUT_VKEY_NAME='sprout-verifying.key'
|
SPROUT_VKEY_NAME='sprout-verifying.key'
|
||||||
|
|||||||
Reference in New Issue
Block a user