@@ -1,6 +1,6 @@
|
|||||||
package=googletest
|
package=googletest
|
||||||
$(package)_version=1.8.0
|
$(package)_version=1.8.0
|
||||||
$(package)_download_path=https://github.com/google/$(package)/archive/
|
$(package)_download_path=https://github.com/google/$(package)/archive
|
||||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||||
$(package)_download_file=release-$($(package)_version).tar.gz
|
$(package)_download_file=release-$($(package)_version).tar.gz
|
||||||
$(package)_sha256_hash=58a6f4277ca2bc8565222b3bbd58a177609e9c488e8a72649359ba51450db7d8
|
$(package)_sha256_hash=58a6f4277ca2bc8565222b3bbd58a177609e9c488e8a72649359ba51450db7d8
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package=libevent
|
package=libevent
|
||||||
$(package)_version=2.1.8
|
$(package)_version=2.1.8
|
||||||
$(package)_download_path=https://github.com/libevent/libevent/archive/
|
$(package)_download_path=https://github.com/libevent/libevent/archive
|
||||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||||
$(package)_download_file=release-$($(package)_version)-stable.tar.gz
|
$(package)_download_file=release-$($(package)_version)-stable.tar.gz
|
||||||
$(package)_sha256_hash=316ddb401745ac5d222d7c529ef1eada12f58f6376a66c1118eee803cb70f83d
|
$(package)_sha256_hash=316ddb401745ac5d222d7c529ef1eada12f58f6376a66c1118eee803cb70f83d
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package=libgmp
|
package=libgmp
|
||||||
|
|
||||||
ifeq ($(host_os),mingw32)
|
ifeq ($(host_os),mingw32)
|
||||||
$(package)_download_path=https://github.com/joshuayabut/$(package)/archive/
|
$(package)_download_path=https://github.com/joshuayabut/$(package)/archive
|
||||||
$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz
|
$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz
|
||||||
$(package)_download_file=$($(package)_git_commit).tar.gz
|
$(package)_download_file=$($(package)_git_commit).tar.gz
|
||||||
$(package)_sha256_hash=193836c1acc9dc00fe2521205d7bbe1ba13263f6cbef6f02584bf6f8b34b108f
|
$(package)_sha256_hash=193836c1acc9dc00fe2521205d7bbe1ba13263f6cbef6f02584bf6f8b34b108f
|
||||||
@@ -9,7 +9,7 @@ $(package)_git_commit=053c03b1cab347671d936f43ef66b48ab5e380ee
|
|||||||
$(package)_dependencies=
|
$(package)_dependencies=
|
||||||
$(package)_config_opts=--enable-cxx --disable-shared
|
$(package)_config_opts=--enable-cxx --disable-shared
|
||||||
else ifeq ($(build_os),darwin)
|
else ifeq ($(build_os),darwin)
|
||||||
$(package)_download_path=https://github.com/ca333/$(package)/archive/
|
$(package)_download_path=https://github.com/ca333/$(package)/archive
|
||||||
$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz
|
$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz
|
||||||
$(package)_download_file=$($(package)_git_commit).tar.gz
|
$(package)_download_file=$($(package)_git_commit).tar.gz
|
||||||
$(package)_sha256_hash=59b2c2b5d58fdf5943bfde1fa709e9eb53e7e072c9699d28dc1c2cbb3c8cc32c
|
$(package)_sha256_hash=59b2c2b5d58fdf5943bfde1fa709e9eb53e7e072c9699d28dc1c2cbb3c8cc32c
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package=librustzcash
|
package=librustzcash
|
||||||
$(package)_version=0.1
|
$(package)_version=0.1
|
||||||
$(package)_download_path=https://github.com/zcash/$(package)/archive/
|
$(package)_download_path=https://github.com/zcash/$(package)/archive
|
||||||
$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz
|
$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz
|
||||||
$(package)_download_file=$($(package)_git_commit).tar.gz
|
$(package)_download_file=$($(package)_git_commit).tar.gz
|
||||||
$(package)_sha256_hash=a5760a90d4a1045c8944204f29fa2a3cf2f800afee400f88bf89bbfe2cce1279
|
$(package)_sha256_hash=a5760a90d4a1045c8944204f29fa2a3cf2f800afee400f88bf89bbfe2cce1279
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ $(package)_config_opts=
|
|||||||
else
|
else
|
||||||
package=libsodium
|
package=libsodium
|
||||||
$(package)_version=1.0.15
|
$(package)_version=1.0.15
|
||||||
$(package)_download_path=https://download.libsodium.org/libsodium/releases/
|
$(package)_download_path=https://download.libsodium.org/libsodium/releases
|
||||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||||
$(package)_sha256_hash=fb6a9e879a2f674592e4328c5d9f79f082405ee4bb05cb6e679b90afe9e178f4
|
$(package)_sha256_hash=fb6a9e879a2f674592e4328c5d9f79f082405ee4bb05cb6e679b90afe9e178f4
|
||||||
$(package)_dependencies=
|
$(package)_dependencies=
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
ifeq ($(host_os),mingw32)
|
ifeq ($(host_os),mingw32)
|
||||||
$(package)_version=4.2.2-1
|
$(package)_version=4.2.2-1
|
||||||
$(package)_download_path=https://github.com/ca333/libzmq/archive/
|
$(package)_download_path=https://github.com/ca333/libzmq/archive
|
||||||
$(package)_download_file=v$($(package)_version).tar.gz
|
$(package)_download_file=v$($(package)_version).tar.gz
|
||||||
$(package)_file_name=libzmq-$($(package)_version).tar.gz
|
$(package)_file_name=libzmq-$($(package)_version).tar.gz
|
||||||
$(package)_sha256_hash=0e225b85ce11be23bf7eb7d3f25c6686728bf30d5c31f61c12d37bb646c69962
|
$(package)_sha256_hash=0e225b85ce11be23bf7eb7d3f25c6686728bf30d5c31f61c12d37bb646c69962
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export BITCOIND=${REAL_BITCOIND}
|
|||||||
#Run the tests
|
#Run the tests
|
||||||
|
|
||||||
testScripts=(
|
testScripts=(
|
||||||
|
'cryptoconditions.py'
|
||||||
'paymentdisclosure.py'
|
'paymentdisclosure.py'
|
||||||
'prioritisetransaction.py'
|
'prioritisetransaction.py'
|
||||||
'wallet_treestate.py'
|
'wallet_treestate.py'
|
||||||
|
|||||||
@@ -13,6 +13,6 @@ EXEEXT="@EXEEXT@"
|
|||||||
@ENABLE_ZMQ_TRUE@ENABLE_ZMQ=1
|
@ENABLE_ZMQ_TRUE@ENABLE_ZMQ=1
|
||||||
@ENABLE_PROTON_TRUE@ENABLE_PROTON=1
|
@ENABLE_PROTON_TRUE@ENABLE_PROTON=1
|
||||||
|
|
||||||
REAL_BITCOIND="$BUILDDIR/src/zcashd${EXEEXT}"
|
REAL_BITCOIND="$BUILDDIR/src/komodod${EXEEXT}"
|
||||||
REAL_BITCOINCLI="$BUILDDIR/src/zcash-cli${EXEEXT}"
|
REAL_BITCOINCLI="$BUILDDIR/src/komodo-cli${EXEEXT}"
|
||||||
|
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ Possible options:
|
|||||||
|
|
||||||
```
|
```
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
--nocleanup Leave bitcoinds and test.* datadir on exit or error
|
--nocleanup Leave komodods and test.* datadir on exit or error
|
||||||
--noshutdown Don't stop bitcoinds after the test execution
|
--noshutdown Don't stop komodods after the test execution
|
||||||
--srcdir=SRCDIR Source directory containing bitcoind/bitcoin-cli (default:
|
--srcdir=SRCDIR Source directory containing komodod/komodo-cli (default:
|
||||||
../../src)
|
../../src)
|
||||||
--tmpdir=TMPDIR Root directory for datadirs
|
--tmpdir=TMPDIR Root directory for datadirs
|
||||||
--tracerpc Print out all RPC calls as they are made
|
--tracerpc Print out all RPC calls as they are made
|
||||||
@@ -31,7 +31,7 @@ If you set the environment variable `PYTHON_DEBUG=1` you will get some debug out
|
|||||||
A 200-block -regtest blockchain and wallets for four nodes
|
A 200-block -regtest blockchain and wallets for four nodes
|
||||||
is created the first time a regression test is run and
|
is created the first time a regression test is run and
|
||||||
is stored in the cache/ directory. Each node has the miner
|
is stored in the cache/ directory. Each node has the miner
|
||||||
subsidy from 25 mature blocks (25*10=250 ZEC) in its wallet.
|
subsidy from 25 mature blocks (25*10=250 KMD) in its wallet.
|
||||||
|
|
||||||
After the first run, the cache/ blockchain and wallets are
|
After the first run, the cache/ blockchain and wallets are
|
||||||
copied into a temporary directory and used as the initial
|
copied into a temporary directory and used as the initial
|
||||||
@@ -42,5 +42,5 @@ to recover with:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
rm -rf cache
|
rm -rf cache
|
||||||
killall zcashd
|
killall komodod
|
||||||
```
|
```
|
||||||
|
|||||||
337
qa/rpc-tests/cryptoconditions.py
Executable file
337
qa/rpc-tests/cryptoconditions.py
Executable file
@@ -0,0 +1,337 @@
|
|||||||
|
#!/usr/bin/env python2
|
||||||
|
# Copyright (c) 2018 SuperNET developers
|
||||||
|
# Distributed under the MIT software license, see the accompanying
|
||||||
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
from test_framework.test_framework import BitcoinTestFramework
|
||||||
|
from test_framework.authproxy import JSONRPCException
|
||||||
|
from test_framework.util import assert_equal, assert_greater_than, \
|
||||||
|
initialize_chain_clean, start_nodes, start_node, connect_nodes_bi, \
|
||||||
|
stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port
|
||||||
|
|
||||||
|
import time
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
|
def assert_success(result):
|
||||||
|
assert_equal(result['result'], 'success')
|
||||||
|
|
||||||
|
def assert_error(result):
|
||||||
|
assert_equal(result['result'], 'error')
|
||||||
|
|
||||||
|
class CryptoConditionsTest (BitcoinTestFramework):
|
||||||
|
|
||||||
|
def setup_chain(self):
|
||||||
|
print("Initializing CC test directory "+self.options.tmpdir)
|
||||||
|
self.num_nodes = 1
|
||||||
|
initialize_chain_clean(self.options.tmpdir, self.num_nodes)
|
||||||
|
|
||||||
|
def setup_network(self, split = False):
|
||||||
|
print("Setting up network...")
|
||||||
|
self.addr = "RWPg8B91kfK5UtUN7z6s6TeV9cHSGtVY8D"
|
||||||
|
self.pubkey = "02676d00110c2cd14ae24f95969e8598f7ccfaa675498b82654a5b5bd57fc1d8cf"
|
||||||
|
self.privkey = "UqMgxk7ySPNQ4r9nKAFPjkXy6r5t898yhuNCjSZJLg3RAM4WW1m9"
|
||||||
|
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir,
|
||||||
|
extra_args=[[
|
||||||
|
# always give -ac_name as first extra_arg
|
||||||
|
'-ac_name=REGTEST',
|
||||||
|
'-conf='+self.options.tmpdir+'/node0/REGTEST.conf',
|
||||||
|
'-port=64367',
|
||||||
|
'-rpcport=64368',
|
||||||
|
'-regtest',
|
||||||
|
'-addressindex=1',
|
||||||
|
'-spentindex=1',
|
||||||
|
'-ac_supply=5555555',
|
||||||
|
'-ac_reward=10000000',
|
||||||
|
'-pubkey=' + self.pubkey,
|
||||||
|
'-ac_cc=1',
|
||||||
|
'-whitelist=127.0.0.1',
|
||||||
|
'-debug',
|
||||||
|
'-daemon',
|
||||||
|
'-rpcuser=rt',
|
||||||
|
'-rpcpassword=rt'
|
||||||
|
]]
|
||||||
|
)
|
||||||
|
self.is_network_split = split
|
||||||
|
self.rpc = self.nodes[0]
|
||||||
|
self.sync_all()
|
||||||
|
print("Done setting up network")
|
||||||
|
|
||||||
|
def send_and_mine(self, xtn):
|
||||||
|
txid = self.rpc.sendrawtransaction(xtn)
|
||||||
|
assert txid, 'got txid'
|
||||||
|
# we need the tx above to be confirmed in the next block
|
||||||
|
self.rpc.generate(1)
|
||||||
|
return txid
|
||||||
|
|
||||||
|
def run_faucet_tests(self):
|
||||||
|
rpc = self.rpc
|
||||||
|
|
||||||
|
# basic sanity tests
|
||||||
|
result = rpc.getwalletinfo()
|
||||||
|
assert_equal(result['txcount'], 101)
|
||||||
|
assert_greater_than(result['balance'], 0.0)
|
||||||
|
balance = result['balance']
|
||||||
|
|
||||||
|
faucet = rpc.faucetaddress()
|
||||||
|
assert_equal(faucet['result'], 'success')
|
||||||
|
# verify all keys look like valid AC addrs, could be better
|
||||||
|
for x in ['myCCaddress', 'FaucetCCaddress', 'Faucetmarker', 'myaddress']:
|
||||||
|
assert_equal(faucet[x][0], 'R')
|
||||||
|
|
||||||
|
# no funds in the faucet yet
|
||||||
|
result = rpc.faucetget()
|
||||||
|
assert_equal(result['result'], 'error')
|
||||||
|
|
||||||
|
result = rpc.faucetinfo()
|
||||||
|
assert_equal(result['result'], 'success')
|
||||||
|
|
||||||
|
result = rpc.faucetfund("0")
|
||||||
|
assert_equal(result['result'], 'error')
|
||||||
|
|
||||||
|
result = rpc.faucetfund("-1")
|
||||||
|
assert_equal(result['result'], 'error')
|
||||||
|
|
||||||
|
# we need at least 1 + txfee to get
|
||||||
|
result = rpc.faucetfund("2")
|
||||||
|
assert_equal(result['result'], 'success')
|
||||||
|
assert result['hex'], "hex key found"
|
||||||
|
|
||||||
|
# broadcast the xtn
|
||||||
|
result = rpc.sendrawtransaction(result['hex'])
|
||||||
|
txid = result[0]
|
||||||
|
assert txid, "found txid"
|
||||||
|
|
||||||
|
# we need the tx above to be confirmed in the next block
|
||||||
|
rpc.generate(1)
|
||||||
|
|
||||||
|
result = rpc.getwalletinfo()
|
||||||
|
balance2 = result['balance']
|
||||||
|
# make sure our balance is less now
|
||||||
|
assert_greater_than(balance, balance2)
|
||||||
|
|
||||||
|
result = rpc.faucetinfo()
|
||||||
|
assert_equal(result['result'], 'success')
|
||||||
|
assert_greater_than( result['funding'], 0 )
|
||||||
|
|
||||||
|
result = rpc.faucetget()
|
||||||
|
assert_equal(result['result'], 'success')
|
||||||
|
assert result['hex'], "hex key found"
|
||||||
|
|
||||||
|
# broadcast the xtn
|
||||||
|
result = rpc.sendrawtransaction(result['hex'])
|
||||||
|
txid = result[0]
|
||||||
|
assert txid, "found txid"
|
||||||
|
|
||||||
|
# confirm above tx
|
||||||
|
rpc.generate(1)
|
||||||
|
result = rpc.getwalletinfo()
|
||||||
|
|
||||||
|
# we should have slightly more funds from the faucet now
|
||||||
|
assert_greater_than(result['balance'], balance2)
|
||||||
|
|
||||||
|
def run_dice_tests(self):
|
||||||
|
rpc = self.nodes[0]
|
||||||
|
|
||||||
|
dice = rpc.diceaddress()
|
||||||
|
assert_equal(dice['result'], 'success')
|
||||||
|
for x in ['myCCaddress', 'DiceCCaddress', 'Dicemarker', 'myaddress']:
|
||||||
|
assert_equal(dice[x][0], 'R')
|
||||||
|
|
||||||
|
# no dice created yet
|
||||||
|
result = rpc.dicelist()
|
||||||
|
assert_equal(result, [])
|
||||||
|
|
||||||
|
#result = rpc.dicefund("LUCKY",10000,1,10000,10,5)
|
||||||
|
#assert_equal(result, [])
|
||||||
|
|
||||||
|
def run_token_tests(self):
|
||||||
|
rpc = self.nodes[0]
|
||||||
|
result = rpc.tokenaddress()
|
||||||
|
assert_equal(result['result'], 'success')
|
||||||
|
for x in ['AssetsCCaddress', 'myCCaddress', 'Assetsmarker', 'myaddress']:
|
||||||
|
assert_equal(result[x][0], 'R')
|
||||||
|
|
||||||
|
result = rpc.tokenaddress(self.pubkey)
|
||||||
|
assert_equal(result['result'], 'success')
|
||||||
|
for x in ['AssetsCCaddress', 'myCCaddress', 'Assetsmarker', 'myaddress', 'CCaddress']:
|
||||||
|
assert_equal(result[x][0], 'R')
|
||||||
|
# there are no tokens created yet
|
||||||
|
result = rpc.tokenlist()
|
||||||
|
assert_equal(result, [])
|
||||||
|
|
||||||
|
result = rpc.tokencreate("DUKE", "1987.420", "duke")
|
||||||
|
assert_equal(result['result'], 'success')
|
||||||
|
self.send_and_mine(result['hex'])
|
||||||
|
|
||||||
|
result = rpc.tokenlist()
|
||||||
|
tokenid = result[0]
|
||||||
|
assert(tokenid, "got tokenid")
|
||||||
|
|
||||||
|
# there are no token orders yet
|
||||||
|
result = rpc.tokenorders()
|
||||||
|
assert_equal(result, [])
|
||||||
|
|
||||||
|
result = rpc.tokenbalance(self.pubkey)
|
||||||
|
assert_equal(result['balance'], 0)
|
||||||
|
assert_equal(result['result'], 'success')
|
||||||
|
assert_equal(result['CCaddress'], 'RCRsm3VBXz8kKTsYaXKpy7pSEzrtNNQGJC')
|
||||||
|
assert_equal(result['tokenid'], self.pubkey)
|
||||||
|
|
||||||
|
# this is not a valid assetid
|
||||||
|
result = rpc.tokeninfo(self.pubkey)
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# invalid numtokens
|
||||||
|
result = rpc.tokenask("-1", tokenid, "1")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# invalid numtokens
|
||||||
|
result = rpc.tokenask("0", tokenid, "1")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# invalid price
|
||||||
|
result = rpc.tokenask("1", tokenid, "-1")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# invalid price
|
||||||
|
result = rpc.tokenask("1", tokenid, "0")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# invalid tokenid
|
||||||
|
result = rpc.tokenask("100", "deadbeef", "1")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# valid
|
||||||
|
result = rpc.tokenask("100", tokenid, "7.77")
|
||||||
|
assert_success(result)
|
||||||
|
tokenaskhex = result['hex']
|
||||||
|
assert tokenaskhex, "got tokenask hexk"
|
||||||
|
tokenaskid = self.send_and_mine(result['hex'])
|
||||||
|
|
||||||
|
|
||||||
|
# invalid fillunits
|
||||||
|
result = rpc.tokenfillask(tokenid, tokenaskid, "0")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# invalid fillunits
|
||||||
|
result = rpc.tokenfillask(tokenid, tokenaskid, "-777")
|
||||||
|
assert_error(result)
|
||||||
|
|
||||||
|
# should this pass or fail?
|
||||||
|
result = rpc.tokenfillask(tokenid, tokenaskid, "10")
|
||||||
|
#assert_success(result)
|
||||||
|
|
||||||
|
def run_rewards_tests(self):
|
||||||
|
rpc = self.nodes[0]
|
||||||
|
result = rpc.rewardsaddress()
|
||||||
|
for x in ['RewardsCCaddress', 'myCCaddress', 'Rewardsmarker', 'myaddress']:
|
||||||
|
assert_equal(result[x][0], 'R')
|
||||||
|
|
||||||
|
result = rpc.rewardsaddress(self.pubkey)
|
||||||
|
for x in ['RewardsCCaddress', 'myCCaddress', 'Rewardsmarker', 'myaddress', 'CCaddress']:
|
||||||
|
assert_equal(result[x][0], 'R')
|
||||||
|
|
||||||
|
# no rewards yet
|
||||||
|
result = rpc.rewardslist()
|
||||||
|
assert_equal(result, [])
|
||||||
|
|
||||||
|
# looking up non-existent reward should return error
|
||||||
|
result = rpc.rewardsinfo("none")
|
||||||
|
assert_equal(result['result'], 'error')
|
||||||
|
|
||||||
|
result = rpc.rewardscreatefunding("STUFF", "7777", "25", "0", "10", "10")
|
||||||
|
assert result['hex'], 'got raw xtn'
|
||||||
|
txid = rpc.sendrawtransaction(result['hex'])
|
||||||
|
assert txid, 'got txid'
|
||||||
|
|
||||||
|
# confirm the above xtn
|
||||||
|
rpc.generate(1)
|
||||||
|
result = rpc.rewardsinfo(txid)
|
||||||
|
assert_equal(result['result'], 'success')
|
||||||
|
assert_equal(result['name'], 'STUFF')
|
||||||
|
assert_equal(result['APR'], "25.00000000")
|
||||||
|
assert_equal(result['minseconds'], 0)
|
||||||
|
assert_equal(result['maxseconds'], 864000)
|
||||||
|
assert_equal(result['funding'], "7777.00000000")
|
||||||
|
assert_equal(result['mindeposit'], "10.00000000")
|
||||||
|
assert_equal(result['fundingtxid'], txid)
|
||||||
|
|
||||||
|
# funding amount must be positive
|
||||||
|
result = rpc.rewardsaddfunding("STUFF", txid, "0")
|
||||||
|
assert_equal(result['result'], 'error')
|
||||||
|
|
||||||
|
result = rpc.rewardsaddfunding("STUFF", txid, "555")
|
||||||
|
assert_equal(result['result'], 'success')
|
||||||
|
fundingtxid = result['hex']
|
||||||
|
assert fundingtxid, "got funding txid"
|
||||||
|
|
||||||
|
result = rpc.rewardslock("STUFF", fundingtxid, "7")
|
||||||
|
assert_equal(result['result'], 'error')
|
||||||
|
|
||||||
|
# the previous xtn has not been broadcasted yet
|
||||||
|
result = rpc.rewardsunlock("STUFF", fundingtxid)
|
||||||
|
assert_equal(result['result'], 'error')
|
||||||
|
|
||||||
|
# wrong plan name
|
||||||
|
result = rpc.rewardsunlock("SHTUFF", fundingtxid)
|
||||||
|
assert_equal(result['result'], 'error')
|
||||||
|
|
||||||
|
txid = rpc.sendrawtransaction(fundingtxid)
|
||||||
|
assert txid, 'got txid from sendrawtransaction'
|
||||||
|
|
||||||
|
# confirm the xtn above
|
||||||
|
rpc.generate(1)
|
||||||
|
|
||||||
|
# amount must be positive
|
||||||
|
result = rpc.rewardslock("STUFF", fundingtxid, "-5")
|
||||||
|
assert_equal(result['result'], 'error')
|
||||||
|
|
||||||
|
# amount must be positive
|
||||||
|
result = rpc.rewardslock("STUFF", fundingtxid, "0")
|
||||||
|
assert_equal(result['result'], 'error')
|
||||||
|
|
||||||
|
# trying to lock less than the min amount is an error
|
||||||
|
result = rpc.rewardslock("STUFF", fundingtxid, "7")
|
||||||
|
assert_equal(result['result'], 'error')
|
||||||
|
|
||||||
|
# not working
|
||||||
|
#result = rpc.rewardslock("STUFF", fundingtxid, "10")
|
||||||
|
#assert_equal(result['result'], 'success')
|
||||||
|
#locktxid = result['hex']
|
||||||
|
#assert locktxid, "got lock txid"
|
||||||
|
|
||||||
|
# locktxid has not been broadcast yet
|
||||||
|
#result = rpc.rewardsunlock("STUFF", locktxid)
|
||||||
|
#assert_equal(result['result'], 'error')
|
||||||
|
|
||||||
|
# broadcast xtn
|
||||||
|
#txid = rpc.sendrawtransaction(locktxid)
|
||||||
|
#assert txid, 'got txid from sendrawtransaction'
|
||||||
|
|
||||||
|
# confirm the xtn above
|
||||||
|
#rpc.generate(1)
|
||||||
|
|
||||||
|
#result = rpc.rewardsunlock("STUFF", locktxid)
|
||||||
|
#assert_equal(result['result'], 'error')
|
||||||
|
|
||||||
|
|
||||||
|
def run_test (self):
|
||||||
|
print("Mining blocks...")
|
||||||
|
rpc = self.nodes[0]
|
||||||
|
|
||||||
|
# utxos from block 1 become mature in block 101
|
||||||
|
rpc.generate(101)
|
||||||
|
self.sync_all()
|
||||||
|
|
||||||
|
# this corresponds to -pubkey above
|
||||||
|
print("Importing privkey")
|
||||||
|
rpc.importprivkey(self.privkey)
|
||||||
|
|
||||||
|
self.run_faucet_tests()
|
||||||
|
self.run_rewards_tests()
|
||||||
|
self.run_dice_tests()
|
||||||
|
self.run_token_tests()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
CryptoConditionsTest ().main ()
|
||||||
@@ -90,11 +90,11 @@ class BitcoinTestFramework(object):
|
|||||||
|
|
||||||
parser = optparse.OptionParser(usage="%prog [options]")
|
parser = optparse.OptionParser(usage="%prog [options]")
|
||||||
parser.add_option("--nocleanup", dest="nocleanup", default=False, action="store_true",
|
parser.add_option("--nocleanup", dest="nocleanup", default=False, action="store_true",
|
||||||
help="Leave bitcoinds and test.* datadir on exit or error")
|
help="Leave komodods and test.* datadir on exit or error")
|
||||||
parser.add_option("--noshutdown", dest="noshutdown", default=False, action="store_true",
|
parser.add_option("--noshutdown", dest="noshutdown", default=False, action="store_true",
|
||||||
help="Don't stop bitcoinds after the test execution")
|
help="Don't stop komodods after the test execution")
|
||||||
parser.add_option("--srcdir", dest="srcdir", default="../../src",
|
parser.add_option("--srcdir", dest="srcdir", default="../../src",
|
||||||
help="Source directory containing bitcoind/bitcoin-cli (default: %default)")
|
help="Source directory containing komodod/komodo-cli (default: %default)")
|
||||||
parser.add_option("--tmpdir", dest="tmpdir", default=tempfile.mkdtemp(prefix="test"),
|
parser.add_option("--tmpdir", dest="tmpdir", default=tempfile.mkdtemp(prefix="test"),
|
||||||
help="Root directory for datadirs")
|
help="Root directory for datadirs")
|
||||||
parser.add_option("--tracerpc", dest="trace_rpc", default=False, action="store_true",
|
parser.add_option("--tracerpc", dest="trace_rpc", default=False, action="store_true",
|
||||||
@@ -137,7 +137,7 @@ class BitcoinTestFramework(object):
|
|||||||
stop_nodes(self.nodes)
|
stop_nodes(self.nodes)
|
||||||
wait_bitcoinds()
|
wait_bitcoinds()
|
||||||
else:
|
else:
|
||||||
print("Note: bitcoinds were not stopped and may still be running")
|
print("Note: komodods were not stopped and may still be running")
|
||||||
|
|
||||||
if not self.options.nocleanup and not self.options.noshutdown:
|
if not self.options.nocleanup and not self.options.noshutdown:
|
||||||
print("Cleaning up")
|
print("Cleaning up")
|
||||||
@@ -151,7 +151,7 @@ class BitcoinTestFramework(object):
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
# Test framework for doing p2p comparison testing, which sets up some bitcoind
|
# Test framework for doing p2p comparison testing, which sets up some komodod
|
||||||
# binaries:
|
# binaries:
|
||||||
# 1 binary: test binary
|
# 1 binary: test binary
|
||||||
# 2 binaries: 1 test binary, 1 ref binary
|
# 2 binaries: 1 test binary, 1 ref binary
|
||||||
@@ -165,10 +165,10 @@ class ComparisonTestFramework(BitcoinTestFramework):
|
|||||||
|
|
||||||
def add_options(self, parser):
|
def add_options(self, parser):
|
||||||
parser.add_option("--testbinary", dest="testbinary",
|
parser.add_option("--testbinary", dest="testbinary",
|
||||||
default=os.getenv("BITCOIND", "bitcoind"),
|
default=os.getenv("BITCOIND", "komodod"),
|
||||||
help="bitcoind binary to test")
|
help="bitcoind binary to test")
|
||||||
parser.add_option("--refbinary", dest="refbinary",
|
parser.add_option("--refbinary", dest="refbinary",
|
||||||
default=os.getenv("BITCOIND", "bitcoind"),
|
default=os.getenv("BITCOIND", "komodod"),
|
||||||
help="bitcoind binary to use for reference nodes (if any)")
|
help="bitcoind binary to use for reference nodes (if any)")
|
||||||
|
|
||||||
def setup_chain(self):
|
def setup_chain(self):
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
# Copyright (c) 2014 The Bitcoin Core developers
|
# Copyright (c) 2014 The Bitcoin Core developers
|
||||||
|
# Copyright (c) 2018 The SuperNET developers
|
||||||
# Distributed under the MIT software license, see the accompanying
|
# Distributed under the MIT software license, see the accompanying
|
||||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
@@ -75,38 +76,55 @@ def initialize_datadir(dirname, n):
|
|||||||
datadir = os.path.join(dirname, "node"+str(n))
|
datadir = os.path.join(dirname, "node"+str(n))
|
||||||
if not os.path.isdir(datadir):
|
if not os.path.isdir(datadir):
|
||||||
os.makedirs(datadir)
|
os.makedirs(datadir)
|
||||||
with open(os.path.join(datadir, "zcash.conf"), 'w') as f:
|
# kmd AC's don't use this, they use the conf auto-created when the AC is created
|
||||||
|
# plus CLI arguments. This is for komodod tests
|
||||||
|
print("Writing to " + os.path.join(datadir,"komodo.conf"))
|
||||||
|
with open(os.path.join(datadir, "komodo.conf"), 'w') as f:
|
||||||
f.write("regtest=1\n");
|
f.write("regtest=1\n");
|
||||||
|
f.write("txindex=1\n");
|
||||||
|
f.write("server=1\n");
|
||||||
f.write("showmetrics=0\n");
|
f.write("showmetrics=0\n");
|
||||||
f.write("rpcuser=rt\n");
|
f.write("rpcuser=rt\n");
|
||||||
f.write("rpcpassword=rt\n");
|
f.write("rpcpassword=rt\n");
|
||||||
f.write("port="+str(p2p_port(n))+"\n");
|
#f.write("port="+str(p2p_port(n))+"\n");
|
||||||
f.write("rpcport="+str(rpc_port(n))+"\n");
|
#rpcport = str(rpc_port(n))
|
||||||
|
#f.write("rpcport="+rpcport+"\n");
|
||||||
|
#print "RPC port=" + rpcport
|
||||||
f.write("listenonion=0\n");
|
f.write("listenonion=0\n");
|
||||||
|
# TODO: maybe make these optional, defaulted to on for now
|
||||||
|
f.write("addressindex=1\n");
|
||||||
|
f.write("spentindex=1\n");
|
||||||
|
f.write("timestampindex=1\n");
|
||||||
return datadir
|
return datadir
|
||||||
|
|
||||||
def initialize_chain(test_dir):
|
def initialize_chain(test_dir):
|
||||||
"""
|
"""
|
||||||
Create (or copy from cache) a 200-block-long chain and
|
Create (or copy from cache) a 200-block-long chain and
|
||||||
4 wallets.
|
4 wallets.
|
||||||
bitcoind and bitcoin-cli must be in search path.
|
komodod and komodo-cli must be in search path.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
print("initialize_chain")
|
||||||
if not os.path.isdir(os.path.join("cache", "node0")):
|
if not os.path.isdir(os.path.join("cache", "node0")):
|
||||||
devnull = open("/dev/null", "w+")
|
devnull = open("/dev/null", "w+")
|
||||||
# Create cache directories, run bitcoinds:
|
# Create cache directories, run komodods:
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
datadir=initialize_datadir("cache", i)
|
datadir=initialize_datadir("cache", i)
|
||||||
args = [ os.getenv("BITCOIND", "bitcoind"), "-keypool=1", "-datadir="+datadir, "-discover=0" ]
|
args = [ os.getenv("BITCOIND", "komodod"), "-keypool=1", "-datadir="+datadir, "-discover=0" ]
|
||||||
if i > 0:
|
if i > 0:
|
||||||
args.append("-connect=127.0.0.1:"+str(p2p_port(0)))
|
args.append("-connect=127.0.0.1:"+str(p2p_port(0)))
|
||||||
bitcoind_processes[i] = subprocess.Popen(args)
|
bitcoind_processes[i] = subprocess.Popen(args)
|
||||||
|
cmd = os.getenv("BITCOINCLI", "komodo-cli")
|
||||||
|
cmd_args = cmd + " -datadir="+datadir + " -rpcwait getblockcount"
|
||||||
if os.getenv("PYTHON_DEBUG", ""):
|
if os.getenv("PYTHON_DEBUG", ""):
|
||||||
print "initialize_chain: bitcoind started, calling bitcoin-cli -rpcwait getblockcount"
|
print "initialize_chain: komodod started, calling: " + cmd_args
|
||||||
subprocess.check_call([ os.getenv("BITCOINCLI", "bitcoin-cli"), "-datadir="+datadir,
|
strcmd = cmd + " " + "-datadir="+datadir + " -rpcwait getblockcount"
|
||||||
"-rpcwait", "getblockcount"], stdout=devnull)
|
|
||||||
|
print("Running " + strcmd)
|
||||||
|
subprocess.check_call(strcmd, shell=True);
|
||||||
|
#subprocess.check_call([ cmd, "-rpcwait", "getblockcount"], stdout=devnull)
|
||||||
if os.getenv("PYTHON_DEBUG", ""):
|
if os.getenv("PYTHON_DEBUG", ""):
|
||||||
print "initialize_chain: bitcoin-cli -rpcwait getblockcount completed"
|
print "initialize_chain: komodo-cli -rpcwait getblockcount completed"
|
||||||
devnull.close()
|
devnull.close()
|
||||||
rpcs = []
|
rpcs = []
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
@@ -144,7 +162,7 @@ def initialize_chain(test_dir):
|
|||||||
from_dir = os.path.join("cache", "node"+str(i))
|
from_dir = os.path.join("cache", "node"+str(i))
|
||||||
to_dir = os.path.join(test_dir, "node"+str(i))
|
to_dir = os.path.join(test_dir, "node"+str(i))
|
||||||
shutil.copytree(from_dir, to_dir)
|
shutil.copytree(from_dir, to_dir)
|
||||||
initialize_datadir(test_dir, i) # Overwrite port/rpcport in zcash.conf
|
initialize_datadir(test_dir, i) # Overwrite port/rpcport in komodo.conf
|
||||||
|
|
||||||
def initialize_chain_clean(test_dir, num_nodes):
|
def initialize_chain_clean(test_dir, num_nodes):
|
||||||
"""
|
"""
|
||||||
@@ -177,34 +195,50 @@ def _rpchost_to_args(rpchost):
|
|||||||
|
|
||||||
def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary=None):
|
def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary=None):
|
||||||
"""
|
"""
|
||||||
Start a bitcoind and return RPC connection to it
|
Start a komodod and return RPC connection to it
|
||||||
"""
|
"""
|
||||||
datadir = os.path.join(dirname, "node"+str(i))
|
datadir = os.path.join(dirname, "node"+str(i))
|
||||||
if binary is None:
|
if binary is None:
|
||||||
binary = os.getenv("BITCOIND", "bitcoind")
|
binary = os.getenv("BITCOIND", "komodod")
|
||||||
args = [ binary, "-datadir="+datadir, "-keypool=1", "-discover=0", "-rest" ]
|
args = [ binary, "-datadir="+datadir, "-keypool=1", "-discover=0", "-rest" ]
|
||||||
if extra_args is not None: args.extend(extra_args)
|
if extra_args is not None: args.extend(extra_args)
|
||||||
|
#print("args=" + ' '.join(args))
|
||||||
bitcoind_processes[i] = subprocess.Popen(args)
|
bitcoind_processes[i] = subprocess.Popen(args)
|
||||||
devnull = open("/dev/null", "w+")
|
devnull = open("/dev/null", "w+")
|
||||||
|
|
||||||
|
cmd = os.getenv("BITCOINCLI", "komodo-cli")
|
||||||
|
print("cmd=" + cmd)
|
||||||
|
cmd_args = ' '.join(extra_args) + " -rpcwait getblockcount "
|
||||||
if os.getenv("PYTHON_DEBUG", ""):
|
if os.getenv("PYTHON_DEBUG", ""):
|
||||||
print "start_node: bitcoind started, calling bitcoin-cli -rpcwait getblockcount"
|
print "start_node: komodod started, calling : " + cmd + " " + cmd_args
|
||||||
subprocess.check_call([ os.getenv("BITCOINCLI", "bitcoin-cli"), "-datadir="+datadir] +
|
strcmd = cmd + " " + cmd_args
|
||||||
_rpchost_to_args(rpchost) +
|
|
||||||
["-rpcwait", "getblockcount"], stdout=devnull)
|
print("Running " + strcmd)
|
||||||
|
import time
|
||||||
|
time.sleep(2)
|
||||||
|
subprocess.check_call(strcmd, shell=True);
|
||||||
|
#subprocess.check_call([ os.getenv("BITCOINCLI", "komodo-cli"), "-datadir="+datadir] +
|
||||||
|
# _rpchost_to_args(rpchost) +
|
||||||
|
# ["-rpcwait", "-rpcport=6438", "getblockcount"], stdout=devnull)
|
||||||
if os.getenv("PYTHON_DEBUG", ""):
|
if os.getenv("PYTHON_DEBUG", ""):
|
||||||
print "start_node: calling bitcoin-cli -rpcwait getblockcount returned"
|
print "start_node: calling komodo-cli -rpcwait getblockcount returned"
|
||||||
devnull.close()
|
devnull.close()
|
||||||
url = "http://rt:rt@%s:%d" % (rpchost or '127.0.0.1', rpc_port(i))
|
if extra_args[0] == '-ac_name=REGTEST':
|
||||||
|
url = "http://rt:rt@%s:%d" % (rpchost or '127.0.0.1', 64368)
|
||||||
|
else:
|
||||||
|
url = "http://rt:rt@%s:%d" % (rpchost or '127.0.0.1', rpc_port(i))
|
||||||
|
print("connecting to " + url)
|
||||||
if timewait is not None:
|
if timewait is not None:
|
||||||
proxy = AuthServiceProxy(url, timeout=timewait)
|
proxy = AuthServiceProxy(url, timeout=timewait)
|
||||||
else:
|
else:
|
||||||
proxy = AuthServiceProxy(url)
|
proxy = AuthServiceProxy(url)
|
||||||
|
print("created proxy")
|
||||||
proxy.url = url # store URL on proxy for info
|
proxy.url = url # store URL on proxy for info
|
||||||
return proxy
|
return proxy
|
||||||
|
|
||||||
def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, binary=None):
|
def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, binary=None):
|
||||||
"""
|
"""
|
||||||
Start multiple bitcoinds, return RPC connections to them
|
Start multiple komodods, return RPC connections to them
|
||||||
"""
|
"""
|
||||||
if extra_args is None: extra_args = [ None for i in range(num_nodes) ]
|
if extra_args is None: extra_args = [ None for i in range(num_nodes) ]
|
||||||
if binary is None: binary = [ None for i in range(num_nodes) ]
|
if binary is None: binary = [ None for i in range(num_nodes) ]
|
||||||
|
|||||||
@@ -58,16 +58,20 @@ bool ValidateBidRemainder(int64_t remaining_units,int64_t remaining_nValue,int64
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unitprice = (orig_nValue * COIN) / totalunits;
|
//unitprice = (orig_nValue * COIN) / totalunits;
|
||||||
recvunitprice = (received_nValue * COIN) / paidunits;
|
//recvunitprice = (received_nValue * COIN) / paidunits;
|
||||||
|
//if ( remaining_units != 0 )
|
||||||
|
// newunitprice = (remaining_nValue * COIN) / remaining_units;
|
||||||
|
unitprice = (orig_nValue / totalunits);
|
||||||
|
recvunitprice = (received_nValue / paidunits);
|
||||||
if ( remaining_units != 0 )
|
if ( remaining_units != 0 )
|
||||||
newunitprice = (remaining_nValue * COIN) / remaining_units;
|
newunitprice = (remaining_nValue / remaining_units);
|
||||||
if ( recvunitprice < unitprice )
|
if ( recvunitprice < unitprice )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"error recvunitprice %.16f < %.16f unitprice, new unitprice %.16f\n",(double)recvunitprice/(COIN*COIN),(double)unitprice/(COIN*COIN),(double)newunitprice/(COIN*COIN));
|
fprintf(stderr,"error recvunitprice %.16f < %.16f unitprice, new unitprice %.16f\n",(double)recvunitprice/(COIN),(double)unitprice/(COIN),(double)newunitprice/(COIN));
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
fprintf(stderr,"orig %llu total %llu, recv %llu paid %llu,recvunitprice %.16f >= %.16f unitprice, new unitprice %.16f\n",(long long)orig_nValue,(long long)totalunits,(long long)received_nValue,(long long)paidunits,(double)recvunitprice/(COIN*COIN),(double)unitprice/(COIN*COIN),(double)newunitprice/(COIN*COIN));
|
fprintf(stderr,"orig %llu total %llu, recv %llu paid %llu,recvunitprice %.16f >= %.16f unitprice, new unitprice %.16f\n",(long long)orig_nValue,(long long)totalunits,(long long)received_nValue,(long long)paidunits,(double)recvunitprice/(COIN),(double)unitprice/(COIN),(double)newunitprice/(COIN));
|
||||||
}
|
}
|
||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
@@ -89,8 +93,10 @@ bool SetBidFillamounts(int64_t &received_nValue,int64_t &remaining_units,int64_t
|
|||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
remaining_units = (totalunits - paidunits);
|
remaining_units = (totalunits - paidunits);
|
||||||
unitprice = (orig_nValue * COIN) / totalunits;
|
//unitprice = (orig_nValue * COIN) / totalunits;
|
||||||
received_nValue = (paidunits * unitprice) / COIN;
|
//received_nValue = (paidunits * unitprice) / COIN;
|
||||||
|
unitprice = (orig_nValue / totalunits);
|
||||||
|
received_nValue = (paidunits * unitprice);
|
||||||
if ( unitprice > 0 && received_nValue > 0 && received_nValue <= orig_nValue )
|
if ( unitprice > 0 && received_nValue > 0 && received_nValue <= orig_nValue )
|
||||||
{
|
{
|
||||||
remaining_nValue = (orig_nValue - received_nValue);
|
remaining_nValue = (orig_nValue - received_nValue);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include "CCassets.h"
|
#include "CCassets.h"
|
||||||
|
extern std::string CCerror;
|
||||||
|
|
||||||
int64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 assetid,int64_t total,int32_t maxinputs)
|
int64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 assetid,int64_t total,int32_t maxinputs)
|
||||||
{
|
{
|
||||||
@@ -60,20 +61,21 @@ UniValue AssetInfo(uint256 assetid)
|
|||||||
if ( GetTransaction(assetid,vintx,hashBlock,false) == 0 )
|
if ( GetTransaction(assetid,vintx,hashBlock,false) == 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"cant find assetid\n");
|
fprintf(stderr,"cant find assetid\n");
|
||||||
|
result.push_back(Pair("result","error"));
|
||||||
result.push_back(Pair("error","cant find assetid"));
|
result.push_back(Pair("error","cant find assetid"));
|
||||||
return(0);
|
return(result);
|
||||||
}
|
}
|
||||||
if ( vintx.vout.size() > 0 && DecodeAssetCreateOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,origpubkey,name,description) == 0 )
|
if ( vintx.vout.size() > 0 && DecodeAssetCreateOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,origpubkey,name,description) == 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"assetid isnt assetcreation txid\n");
|
fprintf(stderr,"assetid isnt assetcreation txid\n");
|
||||||
|
result.push_back(Pair("result","error"));
|
||||||
result.push_back(Pair("error","assetid isnt assetcreation txid"));
|
result.push_back(Pair("error","assetid isnt assetcreation txid"));
|
||||||
}
|
}
|
||||||
result.push_back(Pair("result","success"));
|
result.push_back(Pair("result","success"));
|
||||||
result.push_back(Pair("tokenid",uint256_str(str,assetid)));
|
result.push_back(Pair("tokenid",uint256_str(str,assetid)));
|
||||||
result.push_back(Pair("owner",pubkey33_str(str,origpubkey.data())));
|
result.push_back(Pair("owner",pubkey33_str(str,origpubkey.data())));
|
||||||
result.push_back(Pair("name",name));
|
result.push_back(Pair("name",name));
|
||||||
sprintf(numstr,"%.8f",(double)vintx.vout[0].nValue/COIN);
|
result.push_back(Pair("supply",vintx.vout[0].nValue));
|
||||||
result.push_back(Pair("supply",numstr));
|
|
||||||
result.push_back(Pair("description",description));
|
result.push_back(Pair("description",description));
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
@@ -182,13 +184,13 @@ std::string CreateAsset(int64_t txfee,int64_t assetsupply,std::string name,std::
|
|||||||
if ( assetsupply < 0 )
|
if ( assetsupply < 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"negative assetsupply %lld\n",(long long)assetsupply);
|
fprintf(stderr,"negative assetsupply %lld\n",(long long)assetsupply);
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
cp = CCinit(&C,EVAL_ASSETS);
|
cp = CCinit(&C,EVAL_ASSETS);
|
||||||
if ( name.size() > 32 || description.size() > 4096 )
|
if ( name.size() > 32 || description.size() > 4096 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"name.%d or description.%d is too big\n",(int32_t)name.size(),(int32_t)description.size());
|
fprintf(stderr,"name.%d or description.%d is too big\n",(int32_t)name.size(),(int32_t)description.size());
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
if ( txfee == 0 )
|
if ( txfee == 0 )
|
||||||
txfee = 10000;
|
txfee = 10000;
|
||||||
@@ -199,7 +201,7 @@ std::string CreateAsset(int64_t txfee,int64_t assetsupply,std::string name,std::
|
|||||||
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(cp->CChexstr) << OP_CHECKSIG));
|
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(cp->CChexstr) << OP_CHECKSIG));
|
||||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetCreateOpRet('c',Mypubkey(),name,description)));
|
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetCreateOpRet('c',Mypubkey(),name,description)));
|
||||||
}
|
}
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector<uint8_t> destpubkey,int64_t total)
|
std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector<uint8_t> destpubkey,int64_t total)
|
||||||
@@ -208,7 +210,7 @@ std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector<uint8_t> des
|
|||||||
if ( total < 0 )
|
if ( total < 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"negative total %lld\n",(long long)total);
|
fprintf(stderr,"negative total %lld\n",(long long)total);
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
cp = CCinit(&C,EVAL_ASSETS);
|
cp = CCinit(&C,EVAL_ASSETS);
|
||||||
if ( txfee == 0 )
|
if ( txfee == 0 )
|
||||||
@@ -234,7 +236,7 @@ std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector<uint8_t> des
|
|||||||
} else fprintf(stderr,"not enough CC asset inputs for %.8f\n",(double)total/COIN);
|
} else fprintf(stderr,"not enough CC asset inputs for %.8f\n",(double)total/COIN);
|
||||||
//} else fprintf(stderr,"numoutputs.%d != numamounts.%d\n",n,(int32_t)amounts.size());
|
//} else fprintf(stderr,"numoutputs.%d != numamounts.%d\n",n,(int32_t)amounts.size());
|
||||||
}
|
}
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CreateBuyOffer(int64_t txfee,int64_t bidamount,uint256 assetid,int64_t pricetotal)
|
std::string CreateBuyOffer(int64_t txfee,int64_t bidamount,uint256 assetid,int64_t pricetotal)
|
||||||
@@ -243,17 +245,17 @@ std::string CreateBuyOffer(int64_t txfee,int64_t bidamount,uint256 assetid,int64
|
|||||||
if ( bidamount < 0 || pricetotal < 0 )
|
if ( bidamount < 0 || pricetotal < 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"negative bidamount %lld, pricetotal %lld\n",(long long)bidamount,(long long)pricetotal);
|
fprintf(stderr,"negative bidamount %lld, pricetotal %lld\n",(long long)bidamount,(long long)pricetotal);
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
if ( GetTransaction(assetid,vintx,hashBlock,false) == 0 )
|
if ( GetTransaction(assetid,vintx,hashBlock,false) == 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"cant find assetid\n");
|
fprintf(stderr,"cant find assetid\n");
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
if ( vintx.vout.size() > 0 && DecodeAssetCreateOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,origpubkey,name,description) == 0 )
|
if ( vintx.vout.size() > 0 && DecodeAssetCreateOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,origpubkey,name,description) == 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"assetid isnt assetcreation txid\n");
|
fprintf(stderr,"assetid isnt assetcreation txid\n");
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
cp = CCinit(&C,EVAL_ASSETS);
|
cp = CCinit(&C,EVAL_ASSETS);
|
||||||
if ( txfee == 0 )
|
if ( txfee == 0 )
|
||||||
@@ -264,7 +266,7 @@ std::string CreateBuyOffer(int64_t txfee,int64_t bidamount,uint256 assetid,int64
|
|||||||
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,bidamount,GetUnspendable(cp,0)));
|
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,bidamount,GetUnspendable(cp,0)));
|
||||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetOpRet('b',assetid,zeroid,pricetotal,Mypubkey())));
|
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetOpRet('b',assetid,zeroid,pricetotal,Mypubkey())));
|
||||||
}
|
}
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t pricetotal)
|
std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t pricetotal)
|
||||||
@@ -273,7 +275,7 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p
|
|||||||
if ( askamount < 0 || pricetotal < 0 )
|
if ( askamount < 0 || pricetotal < 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"negative askamount %lld, askamount %lld\n",(long long)pricetotal,(long long)askamount);
|
fprintf(stderr,"negative askamount %lld, askamount %lld\n",(long long)pricetotal,(long long)askamount);
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
cp = CCinit(&C,EVAL_ASSETS);
|
cp = CCinit(&C,EVAL_ASSETS);
|
||||||
if ( txfee == 0 )
|
if ( txfee == 0 )
|
||||||
@@ -296,18 +298,18 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p
|
|||||||
} else fprintf(stderr,"need some assets to place ask\n");
|
} else fprintf(stderr,"need some assets to place ask\n");
|
||||||
}
|
}
|
||||||
fprintf(stderr,"need some native coins to place ask\n");
|
fprintf(stderr,"need some native coins to place ask\n");
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 assetid2,int64_t pricetotal)
|
std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 assetid2,int64_t pricetotal)
|
||||||
{
|
{
|
||||||
CMutableTransaction mtx; CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C;
|
CMutableTransaction mtx; CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C;
|
||||||
fprintf(stderr,"asset swaps disabled\n");
|
fprintf(stderr,"asset swaps disabled\n");
|
||||||
return(0);
|
return("");
|
||||||
if ( askamount < 0 || pricetotal < 0 )
|
if ( askamount < 0 || pricetotal < 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"negative askamount %lld, askamount %lld\n",(long long)pricetotal,(long long)askamount);
|
fprintf(stderr,"negative askamount %lld, askamount %lld\n",(long long)pricetotal,(long long)askamount);
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
cp = CCinit(&C,EVAL_ASSETS);
|
cp = CCinit(&C,EVAL_ASSETS);
|
||||||
if ( txfee == 0 )
|
if ( txfee == 0 )
|
||||||
@@ -335,7 +337,7 @@ std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 a
|
|||||||
} else fprintf(stderr,"need some assets to place ask\n");
|
} else fprintf(stderr,"need some assets to place ask\n");
|
||||||
}
|
}
|
||||||
fprintf(stderr,"need some native coins to place ask\n");
|
fprintf(stderr,"need some native coins to place ask\n");
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid)
|
std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid)
|
||||||
@@ -356,7 +358,7 @@ std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid)
|
|||||||
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,EncodeAssetOpRet('o',assetid,zeroid,0,Mypubkey())));
|
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,EncodeAssetOpRet('o',assetid,zeroid,0,Mypubkey())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid)
|
std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid)
|
||||||
@@ -377,7 +379,7 @@ std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid)
|
|||||||
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,EncodeAssetOpRet('x',assetid,zeroid,0,Mypubkey())));
|
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,EncodeAssetOpRet('x',assetid,zeroid,0,Mypubkey())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t fillamount)
|
std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t fillamount)
|
||||||
@@ -386,7 +388,7 @@ std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t f
|
|||||||
if ( fillamount < 0 )
|
if ( fillamount < 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"negative fillamount %lld\n",(long long)fillamount);
|
fprintf(stderr,"negative fillamount %lld\n",(long long)fillamount);
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
cp = CCinit(&C,EVAL_ASSETS);
|
cp = CCinit(&C,EVAL_ASSETS);
|
||||||
if ( txfee == 0 )
|
if ( txfee == 0 )
|
||||||
@@ -425,13 +427,15 @@ std::string FillSell(int64_t txfee,uint256 assetid,uint256 assetid2,uint256 askt
|
|||||||
CTransaction vintx,filltx; uint256 hashBlock; CMutableTransaction mtx; CPubKey mypk; std::vector<uint8_t> origpubkey; double dprice; uint64_t mask; int32_t askvout=0; int64_t received_assetoshis,total_nValue,orig_assetoshis,paid_nValue,remaining_nValue,inputs,CCchange=0; struct CCcontract_info *cp,C;
|
CTransaction vintx,filltx; uint256 hashBlock; CMutableTransaction mtx; CPubKey mypk; std::vector<uint8_t> origpubkey; double dprice; uint64_t mask; int32_t askvout=0; int64_t received_assetoshis,total_nValue,orig_assetoshis,paid_nValue,remaining_nValue,inputs,CCchange=0; struct CCcontract_info *cp,C;
|
||||||
if ( fillunits < 0 )
|
if ( fillunits < 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"negative fillunits %lld\n",(long long)fillunits);
|
CCerror = strprintf("negative fillunits %lld\n",(long long)fillunits);
|
||||||
return(0);
|
fprintf(stderr,"%s\n",CCerror.c_str());
|
||||||
|
return("");
|
||||||
}
|
}
|
||||||
if ( assetid2 != zeroid )
|
if ( assetid2 != zeroid )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"asset swaps disabled\n");
|
CCerror = "asset swaps disabled";
|
||||||
return(0);
|
fprintf(stderr,"%s\n",CCerror.c_str());
|
||||||
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
cp = CCinit(&C,EVAL_ASSETS);
|
cp = CCinit(&C,EVAL_ASSETS);
|
||||||
@@ -472,8 +476,11 @@ std::string FillSell(int64_t txfee,uint256 assetid,uint256 assetid2,uint256 askt
|
|||||||
if ( CCchange != 0 )
|
if ( CCchange != 0 )
|
||||||
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk));
|
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk));
|
||||||
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,EncodeAssetOpRet(assetid2!=zeroid?'E':'S',assetid,assetid2,remaining_nValue,origpubkey)));
|
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,EncodeAssetOpRet(assetid2!=zeroid?'E':'S',assetid,assetid2,remaining_nValue,origpubkey)));
|
||||||
} else fprintf(stderr,"filltx not enough utxos\n");
|
} else {
|
||||||
|
CCerror = strprintf("filltx not enough utxos");
|
||||||
|
fprintf(stderr,"%s\n", CCerror.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,8 @@
|
|||||||
|
|
||||||
bool AuctionValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
bool AuctionValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||||
|
|
||||||
std::string AuctionPost(uint64_t txfee,uint256 itemhash,uint64_t minbid,char *title,char *description);
|
std::string AuctionPost(uint64_t txfee,uint256 itemhash,int64_t minbid,char *title,char *description);
|
||||||
std::string AuctionBid(uint64_t txfee,uint256 itemhash,uint64_t amount);
|
std::string AuctionBid(uint64_t txfee,uint256 itemhash,int64_t amount);
|
||||||
std::string AuctionDeliver(uint64_t txfee,uint256 itemhash,uint256 bidtxid);
|
std::string AuctionDeliver(uint64_t txfee,uint256 itemhash,uint256 bidtxid);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,11 +20,12 @@
|
|||||||
#include "CCinclude.h"
|
#include "CCinclude.h"
|
||||||
|
|
||||||
#define EVAL_FAUCET 0xe4
|
#define EVAL_FAUCET 0xe4
|
||||||
|
#define FAUCETSIZE (COIN / 10)
|
||||||
|
|
||||||
bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||||
|
|
||||||
// CCcustom
|
// CCcustom
|
||||||
std::string FaucetFund(uint64_t txfee,uint64_t funds);
|
std::string FaucetFund(uint64_t txfee,int64_t funds);
|
||||||
std::string FaucetGet(uint64_t txfee);
|
std::string FaucetGet(uint64_t txfee);
|
||||||
UniValue FaucetInfo();
|
UniValue FaucetInfo();
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include <univalue.h>
|
#include <univalue.h>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
|
extern int32_t KOMODO_CONNECTING;
|
||||||
|
|
||||||
#define SMALLVAL 0.000000000000001
|
#define SMALLVAL 0.000000000000001
|
||||||
union _bits256 { uint8_t bytes[32]; uint16_t ushorts[16]; uint32_t uints[8]; uint64_t ulongs[4]; uint64_t txid; };
|
union _bits256 { uint8_t bytes[32]; uint16_t ushorts[16]; uint32_t uints[8]; uint64_t ulongs[4]; uint64_t txid; };
|
||||||
@@ -64,6 +65,7 @@ bool myAddtomempool(CTransaction &tx);
|
|||||||
bool myIsutxo_spentinmempool(uint256 txid,int32_t vout);
|
bool myIsutxo_spentinmempool(uint256 txid,int32_t vout);
|
||||||
int32_t myIsutxo_spent(uint256 &spenttxid,uint256 txid,int32_t vout);
|
int32_t myIsutxo_spent(uint256 &spenttxid,uint256 txid,int32_t vout);
|
||||||
bool mySendrawtransaction(std::string res);
|
bool mySendrawtransaction(std::string res);
|
||||||
|
int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex);
|
||||||
|
|
||||||
// CCcustom
|
// CCcustom
|
||||||
CPubKey GetUnspendable(struct CCcontract_info *cp,uint8_t *unspendablepriv);
|
CPubKey GetUnspendable(struct CCcontract_info *cp,uint8_t *unspendablepriv);
|
||||||
@@ -81,7 +83,7 @@ char *pubkey33_str(char *dest,uint8_t *pubkey33);
|
|||||||
uint256 Parseuint256(char *hexstr);
|
uint256 Parseuint256(char *hexstr);
|
||||||
CPubKey pubkey2pk(std::vector<uint8_t> pubkey);
|
CPubKey pubkey2pk(std::vector<uint8_t> pubkey);
|
||||||
bool GetCCaddress(struct CCcontract_info *cp,char *destaddr,CPubKey pk);
|
bool GetCCaddress(struct CCcontract_info *cp,char *destaddr,CPubKey pk);
|
||||||
bool ConstrainVout(CTxOut vout,int32_t CCflag,char *cmpaddr,uint64_t nValue);
|
bool ConstrainVout(CTxOut vout,int32_t CCflag,char *cmpaddr,int64_t nValue);
|
||||||
bool PreventCC(Eval* eval,const CTransaction &tx,int32_t preventCCvins,int32_t numvins,int32_t preventCCvouts,int32_t numvouts);
|
bool PreventCC(Eval* eval,const CTransaction &tx,int32_t preventCCvins,int32_t numvins,int32_t preventCCvouts,int32_t numvouts);
|
||||||
bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey);
|
bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey);
|
||||||
std::vector<uint8_t> Mypubkey();
|
std::vector<uint8_t> Mypubkey();
|
||||||
@@ -92,13 +94,14 @@ int64_t CCduration(int32_t &numblocks,uint256 txid);
|
|||||||
std::string FinalizeCCTx(uint64_t skipmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret);
|
std::string FinalizeCCTx(uint64_t skipmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret);
|
||||||
void SetCCunspents(std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs,char *coinaddr);
|
void SetCCunspents(std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs,char *coinaddr);
|
||||||
void SetCCtxids(std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex,char *coinaddr);
|
void SetCCtxids(std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex,char *coinaddr);
|
||||||
uint64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,uint64_t total,int32_t maxinputs);
|
int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int32_t maxinputs);
|
||||||
uint64_t CCutxovalue(char *coinaddr,uint256 utxotxid,int32_t utxovout);
|
int64_t CCutxovalue(char *coinaddr,uint256 utxotxid,int32_t utxovout);
|
||||||
|
|
||||||
// curve25519 and sha256
|
// curve25519 and sha256
|
||||||
bits256 curve25519_shared(bits256 privkey,bits256 otherpub);
|
bits256 curve25519_shared(bits256 privkey,bits256 otherpub);
|
||||||
bits256 curve25519_basepoint9();
|
bits256 curve25519_basepoint9();
|
||||||
bits256 curve25519(bits256 mysecret,bits256 basepoint);
|
bits256 curve25519(bits256 mysecret,bits256 basepoint);
|
||||||
void vcalc_sha256(char deprecated[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uint8_t *src,int32_t len);
|
void vcalc_sha256(char deprecated[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uint8_t *src,int32_t len);
|
||||||
|
bits256 bits256_doublesha256(char *deprecated,uint8_t *data,int32_t datalen);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
bool LottoValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
bool LottoValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||||
|
|
||||||
std::string LottoTicket(uint64_t txfee,uint64_t numtickets);
|
std::string LottoTicket(uint64_t txfee,int64_t numtickets);
|
||||||
std::string LottoWinner(uint64_t txfee);
|
std::string LottoWinner(uint64_t txfee);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "CCinclude.h"
|
#include "CCinclude.h"
|
||||||
|
|
||||||
#define EVAL_REWARDS 0xe5
|
#define EVAL_REWARDS 0xe5
|
||||||
|
#define REWARDSCC_MAXAPR (COIN * 25)
|
||||||
|
|
||||||
bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||||
UniValue RewardsInfo(uint256 rewardid);
|
UniValue RewardsInfo(uint256 rewardid);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
By using -addressindex=1, it allows tracking of all the CC addresses
|
By using -addressindex=1, it allows tracking of all the CC addresses
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool SignTx(CMutableTransaction &mtx,int32_t vini,uint64_t utxovalue,const CScript scriptPubKey)
|
bool SignTx(CMutableTransaction &mtx,int32_t vini,int64_t utxovalue,const CScript scriptPubKey)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
CTransaction txNewConst(mtx); SignatureData sigdata; const CKeyStore& keystore = *pwalletMain;
|
CTransaction txNewConst(mtx); SignatureData sigdata; const CKeyStore& keystore = *pwalletMain;
|
||||||
@@ -41,7 +41,7 @@ bool SignTx(CMutableTransaction &mtx,int32_t vini,uint64_t utxovalue,const CScri
|
|||||||
std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret)
|
std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret)
|
||||||
{
|
{
|
||||||
auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
|
auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
|
||||||
CTransaction vintx; std::string hex; uint256 hashBlock; uint64_t mask=0,nmask=0,vinimask=0,utxovalues[64],change,normalinputs=0,totaloutputs=0,normaloutputs=0,totalinputs=0; int32_t i,utxovout,n,err = 0; char myaddr[64],destaddr[64],unspendable[64]; uint8_t *privkey,myprivkey[32],unspendablepriv[32],*msg32 = 0; CC *mycond=0,*othercond=0,*cond; CPubKey unspendablepk;
|
CTransaction vintx; std::string hex; uint256 hashBlock; uint64_t mask=0,nmask=0,vinimask=0; int64_t utxovalues[64],change,normalinputs=0,totaloutputs=0,normaloutputs=0,totalinputs=0; int32_t i,utxovout,n,err = 0; char myaddr[64],destaddr[64],unspendable[64]; uint8_t *privkey,myprivkey[32],unspendablepriv[32],*msg32 = 0; CC *mycond=0,*othercond=0,*cond; CPubKey unspendablepk;
|
||||||
n = mtx.vout.size();
|
n = mtx.vout.size();
|
||||||
for (i=0; i<n; i++)
|
for (i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
@@ -188,7 +188,7 @@ void SetCCtxids(std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t CCutxovalue(char *coinaddr,uint256 utxotxid,int32_t utxovout)
|
int64_t CCutxovalue(char *coinaddr,uint256 utxotxid,int32_t utxovout)
|
||||||
{
|
{
|
||||||
uint256 txid; std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
uint256 txid; std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||||
SetCCunspents(unspentOutputs,coinaddr);
|
SetCCunspents(unspentOutputs,coinaddr);
|
||||||
@@ -201,7 +201,7 @@ uint64_t CCutxovalue(char *coinaddr,uint256 utxotxid,int32_t utxovout)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t CC_vinselect(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *belowp,struct CC_utxo utxos[],int32_t numunspents,uint64_t value)
|
int32_t CC_vinselect(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *belowp,struct CC_utxo utxos[],int32_t numunspents,int64_t value)
|
||||||
{
|
{
|
||||||
int32_t i,abovei,belowi; int64_t above,below,gap,atx_value;
|
int32_t i,abovei,belowi; int64_t above,below,gap,atx_value;
|
||||||
abovei = belowi = -1;
|
abovei = belowi = -1;
|
||||||
@@ -249,12 +249,11 @@ int32_t CC_vinselect(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *
|
|||||||
else if ( abovei >= 0 )
|
else if ( abovei >= 0 )
|
||||||
return(abovei);
|
return(abovei);
|
||||||
else return(belowi);
|
else return(belowi);
|
||||||
//return(abovei >= 0 && above < (below>>1) ? abovei : belowi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,uint64_t total,int32_t maxinputs)
|
int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int32_t maxinputs)
|
||||||
{
|
{
|
||||||
int32_t abovei,belowi,ind,vout,i,n = 0,maxutxos=1024; int64_t above,below; uint64_t remains,nValue,totalinputs = 0; uint256 txid,hashBlock; std::vector<COutput> vecOutputs; CTransaction tx; struct CC_utxo *utxos,*up;
|
int32_t abovei,belowi,ind,vout,i,n = 0,maxutxos=1024; int64_t above,below; int64_t remains,nValue,totalinputs = 0; uint256 txid,hashBlock; std::vector<COutput> vecOutputs; CTransaction tx; struct CC_utxo *utxos,*up;
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
const CKeyStore& keystore = *pwalletMain;
|
const CKeyStore& keystore = *pwalletMain;
|
||||||
assert(pwalletMain != NULL);
|
assert(pwalletMain != NULL);
|
||||||
@@ -267,30 +266,38 @@ uint64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,uint64_t total,in
|
|||||||
{
|
{
|
||||||
txid = out.tx->GetHash();
|
txid = out.tx->GetHash();
|
||||||
vout = out.i;
|
vout = out.i;
|
||||||
for (i=0; i<mtx.vin.size(); i++)
|
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && vout < tx.vout.size() && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
||||||
if ( txid == mtx.vin[i].prevout.hash && vout == mtx.vin[i].prevout.n )
|
|
||||||
break;
|
|
||||||
if ( i != mtx.vin.size() )
|
|
||||||
continue;
|
|
||||||
if ( myIsutxo_spentinmempool(txid,vout) == 0 )
|
|
||||||
{
|
{
|
||||||
up = &utxos[n++];
|
if ( mtx.vin.size() > 0 )
|
||||||
up->txid = txid;
|
{
|
||||||
up->nValue = out.tx->vout[out.i].nValue;
|
for (i=0; i<mtx.vin.size(); i++)
|
||||||
up->vout = vout;
|
if ( txid == mtx.vin[i].prevout.hash && vout == mtx.vin[i].prevout.n )
|
||||||
/*mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
break;
|
||||||
nValue = out.tx->vout[out.i].nValue;
|
if ( i != mtx.vin.size() )
|
||||||
totalinputs += nValue;
|
continue;
|
||||||
n++;
|
}
|
||||||
if ( totalinputs >= total || n >= maxinputs )
|
if ( n > 0 )
|
||||||
break;*/
|
{
|
||||||
if ( n >= maxutxos )
|
for (i=0; i<n; i++)
|
||||||
break;
|
if ( txid == utxos[i].txid && vout == utxos[i].vout )
|
||||||
|
break;
|
||||||
|
if ( i != n )
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( myIsutxo_spentinmempool(txid,vout) == 0 )
|
||||||
|
{
|
||||||
|
up = &utxos[n++];
|
||||||
|
up->txid = txid;
|
||||||
|
up->nValue = out.tx->vout[out.i].nValue;
|
||||||
|
up->vout = vout;
|
||||||
|
if ( n >= maxutxos )
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
remains = total;
|
remains = total;
|
||||||
for (i=0; i<maxinputs; i++)
|
for (i=0; i<maxinputs && n>0; i++)
|
||||||
{
|
{
|
||||||
below = above = 0;
|
below = above = 0;
|
||||||
abovei = belowi = -1;
|
abovei = belowi = -1;
|
||||||
@@ -310,11 +317,11 @@ uint64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,uint64_t total,in
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
up = &utxos[ind];
|
up = &utxos[ind];
|
||||||
utxos[ind] = utxos[--n];
|
|
||||||
memset(&utxos[n],0,sizeof(utxos[n]));
|
|
||||||
mtx.vin.push_back(CTxIn(up->txid,up->vout,CScript()));
|
mtx.vin.push_back(CTxIn(up->txid,up->vout,CScript()));
|
||||||
totalinputs += up->nValue;
|
totalinputs += up->nValue;
|
||||||
remains -= up->nValue;
|
remains -= up->nValue;
|
||||||
|
utxos[ind] = utxos[--n];
|
||||||
|
memset(&utxos[n],0,sizeof(utxos[n]));
|
||||||
if ( totalinputs >= total || (i+1) >= maxinputs )
|
if ( totalinputs >= total || (i+1) >= maxinputs )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ bool GetCCaddress(struct CCcontract_info *cp,char *destaddr,CPubKey pk)
|
|||||||
return(destaddr[0] != 0);
|
return(destaddr[0] != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConstrainVout(CTxOut vout,int32_t CCflag,char *cmpaddr,uint64_t nValue)
|
bool ConstrainVout(CTxOut vout,int32_t CCflag,char *cmpaddr,int64_t nValue)
|
||||||
{
|
{
|
||||||
char destaddr[64];
|
char destaddr[64];
|
||||||
if ( vout.scriptPubKey.IsPayToCryptoCondition() != CCflag )
|
if ( vout.scriptPubKey.IsPayToCryptoCondition() != CCflag )
|
||||||
@@ -255,7 +255,16 @@ CPubKey GetUnspendable(struct CCcontract_info *cp,uint8_t *unspendablepriv)
|
|||||||
|
|
||||||
bool ProcessCC(struct CCcontract_info *cp,Eval* eval, std::vector<uint8_t> paramsNull,const CTransaction &ctx, unsigned int nIn)
|
bool ProcessCC(struct CCcontract_info *cp,Eval* eval, std::vector<uint8_t> paramsNull,const CTransaction &ctx, unsigned int nIn)
|
||||||
{
|
{
|
||||||
CTransaction createTx; uint256 assetid,assetid2,hashBlock; uint8_t funcid; int32_t i,n; uint64_t amount; std::vector<uint8_t> origpubkey;
|
CTransaction createTx; uint256 assetid,assetid2,hashBlock; uint8_t funcid; int32_t height,i,n,from_mempool = 0; int64_t amount; std::vector<uint8_t> origpubkey;
|
||||||
|
if ( KOMODO_CONNECTING < 0 ) // always comes back with > 0 for final confirmation
|
||||||
|
return(true);
|
||||||
|
height = KOMODO_CONNECTING;
|
||||||
|
if ( (KOMODO_CONNECTING & (1<<30)) != 0 )
|
||||||
|
{
|
||||||
|
from_mempool = 1;
|
||||||
|
height &= ((1<<30) - 1);
|
||||||
|
}
|
||||||
|
fprintf(stderr,"KOMODO_CONNECTING.%d mempool.%d\n",height,from_mempool);
|
||||||
// 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 )
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
// start of consensus code
|
// start of consensus code
|
||||||
|
|
||||||
uint64_t IsAuctionvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
|
int64_t IsAuctionvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
|
||||||
{
|
{
|
||||||
char destaddr[64];
|
char destaddr[64];
|
||||||
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||||
@@ -35,7 +35,7 @@ uint64_t IsAuctionvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t
|
|||||||
bool AuctionExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
|
bool AuctionExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
|
||||||
{
|
{
|
||||||
static uint256 zerohash;
|
static uint256 zerohash;
|
||||||
CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; uint64_t inputs=0,outputs=0,assetoshis;
|
CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis;
|
||||||
numvins = tx.vin.size();
|
numvins = tx.vin.size();
|
||||||
numvouts = tx.vout.size();
|
numvouts = tx.vout.size();
|
||||||
for (i=0; i<numvins; i++)
|
for (i=0; i<numvins; i++)
|
||||||
@@ -118,9 +118,9 @@ bool AuctionValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
|
|||||||
|
|
||||||
// helper functions for rpc calls in rpcwallet.cpp
|
// helper functions for rpc calls in rpcwallet.cpp
|
||||||
|
|
||||||
uint64_t AddAuctionInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs)
|
int64_t AddAuctionInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
|
||||||
{
|
{
|
||||||
char coinaddr[64]; uint64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t n = 0;
|
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t n = 0;
|
||||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||||
GetCCaddress(cp,coinaddr,pk);
|
GetCCaddress(cp,coinaddr,pk);
|
||||||
SetCCunspents(unspentOutputs,coinaddr);
|
SetCCunspents(unspentOutputs,coinaddr);
|
||||||
@@ -147,9 +147,9 @@ uint64_t AddAuctionInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP
|
|||||||
return(totalinputs);
|
return(totalinputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AuctionBid(uint64_t txfee,uint256 itemhash,uint64_t amount)
|
std::string AuctionBid(uint64_t txfee,uint256 itemhash,int64_t amount)
|
||||||
{
|
{
|
||||||
CMutableTransaction mtx; CPubKey mypk,Auctionpk; CScript opret; uint64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
CMutableTransaction mtx; CPubKey mypk,Auctionpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||||
cp = CCinit(&C,EVAL_AUCTION);
|
cp = CCinit(&C,EVAL_AUCTION);
|
||||||
if ( txfee == 0 )
|
if ( txfee == 0 )
|
||||||
txfee = 10000;
|
txfee = 10000;
|
||||||
@@ -164,12 +164,12 @@ std::string AuctionBid(uint64_t txfee,uint256 itemhash,uint64_t amount)
|
|||||||
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||||
return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,opret));
|
return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,opret));
|
||||||
} else fprintf(stderr,"cant find Auction inputs\n");
|
} else fprintf(stderr,"cant find Auction inputs\n");
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AuctionDeliver(uint64_t txfee,uint256 itemhash,uint256 bidtxid)
|
std::string AuctionDeliver(uint64_t txfee,uint256 itemhash,uint256 bidtxid)
|
||||||
{
|
{
|
||||||
CMutableTransaction mtx; CPubKey mypk,Auctionpk; CScript opret; uint64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
CMutableTransaction mtx; CPubKey mypk,Auctionpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||||
cp = CCinit(&C,EVAL_AUCTION);
|
cp = CCinit(&C,EVAL_AUCTION);
|
||||||
if ( txfee == 0 )
|
if ( txfee == 0 )
|
||||||
txfee = 10000;
|
txfee = 10000;
|
||||||
@@ -184,12 +184,12 @@ std::string AuctionDeliver(uint64_t txfee,uint256 itemhash,uint256 bidtxid)
|
|||||||
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||||
return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,opret));
|
return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,opret));
|
||||||
} else fprintf(stderr,"cant find Auction inputs\n");
|
} else fprintf(stderr,"cant find Auction inputs\n");
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AuctionPost(uint64_t txfee,uint256 itemhash,uint64_t minbid,char *title,char *description)
|
std::string AuctionPost(uint64_t txfee,uint256 itemhash,int64_t minbid,char *title,char *description)
|
||||||
{
|
{
|
||||||
CMutableTransaction mtx; CPubKey mypk,Auctionpk; uint64_t funds = 0; CScript opret; struct CCcontract_info *cp,C;
|
CMutableTransaction mtx; CPubKey mypk,Auctionpk; int64_t funds = 0; CScript opret; struct CCcontract_info *cp,C;
|
||||||
cp = CCinit(&C,EVAL_AUCTION);
|
cp = CCinit(&C,EVAL_AUCTION);
|
||||||
if ( txfee == 0 )
|
if ( txfee == 0 )
|
||||||
txfee = 10000;
|
txfee = 10000;
|
||||||
@@ -200,7 +200,7 @@ std::string AuctionPost(uint64_t txfee,uint256 itemhash,uint64_t minbid,char *ti
|
|||||||
mtx.vout.push_back(MakeCC1vout(EVAL_AUCTION,funds,Auctionpk));
|
mtx.vout.push_back(MakeCC1vout(EVAL_AUCTION,funds,Auctionpk));
|
||||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
|
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
|
||||||
}
|
}
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
186
src/cc/dice.cpp
186
src/cc/dice.cpp
@@ -79,6 +79,12 @@ winner:
|
|||||||
timeout:
|
timeout:
|
||||||
same as winner, just without hentropy or proof
|
same as winner, just without hentropy or proof
|
||||||
|
|
||||||
|
WARNING: there is an attack vector that precludes betting any large amounts, it goes as follows:
|
||||||
|
1. do dicebet to get the house entropy revealed
|
||||||
|
2. calculate bettor entropy that would win against the house entropy
|
||||||
|
3. reorg the chain and make a big bet using the winning entropy calculated in 2.
|
||||||
|
|
||||||
|
In order to mitigate this, the disclosure of the house entropy needs to be delayed beyond a reasonable reorg depth (notarization). It is recommended for production dice game with significant amounts of money to use such a delayed disclosure method.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../compat/endian.h"
|
#include "../compat/endian.h"
|
||||||
@@ -219,9 +225,14 @@ uint256 DiceHashEntropy(uint256 &entropy,uint256 _txidpriv) // max 1 vout per tx
|
|||||||
return(hentropy);
|
return(hentropy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t dice_5nibbles(uint8_t *fivevals)
|
||||||
|
{
|
||||||
|
return(((int32_t)fivevals[0]<<16) + ((int32_t)fivevals[1]<<12) + ((int32_t)fivevals[2]<<8) + ((int32_t)fivevals[3]<<4) + ((int32_t)fivevals[4]));
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t DiceCalc(int64_t bet,int64_t odds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t timeoutblocks,uint256 houseentropy,uint256 bettorentropy)
|
uint64_t DiceCalc(int64_t bet,int64_t odds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t timeoutblocks,uint256 houseentropy,uint256 bettorentropy)
|
||||||
{
|
{
|
||||||
uint8_t buf[64],_house[32],_bettor[32]; uint64_t winnings; arith_uint256 house,bettor; char str[65],str2[65];
|
uint8_t buf[64],_house[32],_bettor[32],_hash[32],hash[32],hash16[64]; uint64_t winnings; arith_uint256 house,bettor; char str[65],str2[65]; int32_t i,modval;
|
||||||
if ( odds < 10000 )
|
if ( odds < 10000 )
|
||||||
return(0);
|
return(0);
|
||||||
else odds -= 10000;
|
else odds -= 10000;
|
||||||
@@ -241,11 +252,43 @@ uint64_t DiceCalc(int64_t bet,int64_t odds,int64_t minbet,int64_t maxbet,int64_t
|
|||||||
endiancpy(&buf[32],(uint8_t *)&houseentropy,32);
|
endiancpy(&buf[32],(uint8_t *)&houseentropy,32);
|
||||||
vcalc_sha256(0,(uint8_t *)&_bettor,buf,64);
|
vcalc_sha256(0,(uint8_t *)&_bettor,buf,64);
|
||||||
endiancpy((uint8_t *)&bettor,_bettor,32);
|
endiancpy((uint8_t *)&bettor,_bettor,32);
|
||||||
|
winnings = 0;
|
||||||
if ( odds > 1 )
|
if ( odds > 1 )
|
||||||
bettor = (bettor / arith_uint256(odds));
|
{
|
||||||
if ( bettor >= house )
|
if ( 0 )
|
||||||
|
{ // old way
|
||||||
|
bettor = (bettor / arith_uint256(odds));
|
||||||
|
if ( bettor >= house )
|
||||||
|
winnings = bet * (odds+1);
|
||||||
|
return(winnings);
|
||||||
|
}
|
||||||
|
if ( odds > 9999 ) // shouldnt happen
|
||||||
|
return(0);
|
||||||
|
endiancpy(buf,(uint8_t *)&house,32);
|
||||||
|
endiancpy(&buf[32],(uint8_t *)&bettor,32);
|
||||||
|
vcalc_sha256(0,(uint8_t *)&_hash,buf,64);
|
||||||
|
endiancpy(hash,_hash,32);
|
||||||
|
for (i=0; i<32; i++)
|
||||||
|
{
|
||||||
|
hash16[i<<1] = ((hash[i] >> 4) & 0x0f);
|
||||||
|
hash16[(i<<1) + 1] = (hash[i] & 0x0f);
|
||||||
|
}
|
||||||
|
modval = 0;
|
||||||
|
for (i=0; i<12; i++)
|
||||||
|
{
|
||||||
|
modval = dice_5nibbles(&hash16[i*5]);
|
||||||
|
if ( modval < 1000000 )
|
||||||
|
{
|
||||||
|
modval %= 10000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(stderr,"modval %d vs %d\n",modval,(int32_t)(10000/(odds+1)));
|
||||||
|
if ( modval < 10000/(odds+1) )
|
||||||
|
winnings = bet * (odds+1);
|
||||||
|
}
|
||||||
|
else if ( bettor >= house )
|
||||||
winnings = bet * (odds+1);
|
winnings = bet * (odds+1);
|
||||||
else winnings = 0;
|
|
||||||
return(winnings);
|
return(winnings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,18 +356,21 @@ uint256 DiceGetEntropy(CTransaction tx,uint8_t reffuncid)
|
|||||||
else return(zeroid);
|
else return(zeroid);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t IsDicevout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
|
uint64_t IsDicevout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v,uint64_t refsbits,uint256 reffundingtxid)
|
||||||
{
|
{
|
||||||
char destaddr[64];
|
char destaddr[64]; uint8_t funcid; int32_t numvouts; uint64_t sbits; uint256 fundingtxid,hash,proof;
|
||||||
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||||
{
|
{
|
||||||
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 )
|
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 && (numvouts= tx.vout.size()) > 0 )
|
||||||
return(tx.vout[v].nValue);
|
{
|
||||||
|
if ( (funcid= DecodeDiceOpRet(tx.GetHash(),tx.vout[numvouts-1].scriptPubKey,sbits,fundingtxid,hash,proof)) != 0 && sbits == refsbits && ((funcid == 'F' && tx.GetHash() == reffundingtxid) || fundingtxid == reffundingtxid) )
|
||||||
|
return(tx.vout[v].nValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t DiceAmounts(uint64_t &inputs,uint64_t &outputs,struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
int64_t DiceAmounts(uint64_t &inputs,uint64_t &outputs,struct CCcontract_info *cp,Eval *eval,const CTransaction &tx,uint64_t refsbits,uint256 reffundingtxid)
|
||||||
{
|
{
|
||||||
CTransaction vinTx; uint256 hashBlock; int32_t i,numvins,numvouts; uint64_t assetoshis;
|
CTransaction vinTx; uint256 hashBlock; int32_t i,numvins,numvouts; uint64_t assetoshis;
|
||||||
numvins = tx.vin.size();
|
numvins = tx.vin.size();
|
||||||
@@ -338,7 +384,7 @@ int64_t DiceAmounts(uint64_t &inputs,uint64_t &outputs,struct CCcontract_info *c
|
|||||||
return eval->Invalid("always should find vin, but didnt");
|
return eval->Invalid("always should find vin, but didnt");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( (assetoshis= IsDicevout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
|
if ( (assetoshis= IsDicevout(cp,vinTx,tx.vin[i].prevout.n,refsbits,reffundingtxid)) != 0 )
|
||||||
inputs += assetoshis;
|
inputs += assetoshis;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -346,7 +392,7 @@ int64_t DiceAmounts(uint64_t &inputs,uint64_t &outputs,struct CCcontract_info *c
|
|||||||
for (i=0; i<numvouts; i++)
|
for (i=0; i<numvouts; i++)
|
||||||
{
|
{
|
||||||
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
|
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
|
||||||
if ( (assetoshis= IsDicevout(cp,tx,i)) != 0 )
|
if ( (assetoshis= IsDicevout(cp,tx,i,refsbits,reffundingtxid)) != 0 )
|
||||||
outputs += assetoshis;
|
outputs += assetoshis;
|
||||||
}
|
}
|
||||||
return(inputs - outputs);
|
return(inputs - outputs);
|
||||||
@@ -415,6 +461,8 @@ bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
|||||||
return eval->Invalid("cant find fundingtxid");
|
return eval->Invalid("cant find fundingtxid");
|
||||||
else if ( fundingTx.vout.size() > 0 && DecodeDiceFundingOpRet(fundingTx.vout[fundingTx.vout.size()-1].scriptPubKey,sbits,minbet,maxbet,maxodds,timeoutblocks) != 'F' )
|
else if ( fundingTx.vout.size() > 0 && DecodeDiceFundingOpRet(fundingTx.vout[fundingTx.vout.size()-1].scriptPubKey,sbits,minbet,maxbet,maxodds,timeoutblocks) != 'F' )
|
||||||
return eval->Invalid("fundingTx not valid");
|
return eval->Invalid("fundingTx not valid");
|
||||||
|
if ( maxodds > 9999 )
|
||||||
|
return eval->Invalid("maxodds too big");
|
||||||
fundingPubKey = fundingTx.vout[1].scriptPubKey;
|
fundingPubKey = fundingTx.vout[1].scriptPubKey;
|
||||||
switch ( funcid )
|
switch ( funcid )
|
||||||
{
|
{
|
||||||
@@ -487,6 +535,7 @@ bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
|||||||
DiceQueue(iswin,sbits,fundingtxid,txid);
|
DiceQueue(iswin,sbits,fundingtxid,txid);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
// make sure all funding txid are from matching sbits and fundingtxid!!
|
||||||
case 'L':
|
case 'L':
|
||||||
case 'W':
|
case 'W':
|
||||||
case 'T':
|
case 'T':
|
||||||
@@ -496,7 +545,7 @@ bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
|||||||
//vin.3+: funding CC vout.0 from 'F', 'E', 'W', 'L' or 'T'
|
//vin.3+: funding CC vout.0 from 'F', 'E', 'W', 'L' or 'T'
|
||||||
//vout.1: tag to owner address for entropy funds
|
//vout.1: tag to owner address for entropy funds
|
||||||
preventCCvouts = 1;
|
preventCCvouts = 1;
|
||||||
DiceAmounts(inputs,outputs,cp,eval,tx);
|
DiceAmounts(inputs,outputs,cp,eval,tx,sbits,fundingtxid);
|
||||||
if ( IsCCInput(tx.vin[1].scriptSig) == 0 || IsCCInput(tx.vin[2].scriptSig) == 0 )
|
if ( IsCCInput(tx.vin[1].scriptSig) == 0 || IsCCInput(tx.vin[2].scriptSig) == 0 )
|
||||||
return eval->Invalid("vin0 or vin1 normal vin for bet");
|
return eval->Invalid("vin0 or vin1 normal vin for bet");
|
||||||
else if ( tx.vin[1].prevout.hash != tx.vin[2].prevout.hash )
|
else if ( tx.vin[1].prevout.hash != tx.vin[2].prevout.hash )
|
||||||
@@ -567,7 +616,7 @@ bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
|||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t AddDiceInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs)
|
uint64_t AddDiceInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs,uint64_t refsbits,uint256 reffundingtxid)
|
||||||
{
|
{
|
||||||
char coinaddr[64],str[65]; uint64_t sbits,nValue,totalinputs = 0; uint256 txid,hash,proof,hashBlock,fundingtxid; CTransaction tx; int32_t j,vout,n = 0; uint8_t funcid;
|
char coinaddr[64],str[65]; uint64_t sbits,nValue,totalinputs = 0; uint256 txid,hash,proof,hashBlock,fundingtxid; CTransaction tx; int32_t j,vout,n = 0; uint8_t funcid;
|
||||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||||
@@ -589,14 +638,20 @@ uint64_t AddDiceInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK
|
|||||||
{
|
{
|
||||||
if ( (funcid= DecodeDiceOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid,hash,proof)) != 0 )
|
if ( (funcid= DecodeDiceOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid,hash,proof)) != 0 )
|
||||||
{
|
{
|
||||||
if ( funcid == 'F' || funcid == 'E' || funcid == 'W' || funcid == 'L' || funcid == 'T' )
|
char str[65],sstr[16];
|
||||||
|
unstringbits(sstr,sbits);
|
||||||
|
fprintf(stderr,"(%c) %.8f %s %s\n",funcid,(double)tx.vout[0].nValue/COIN,sstr,uint256_str(str,txid));
|
||||||
|
if ( sbits == refsbits && (funcid == 'F' && reffundingtxid == txid) || reffundingtxid == fundingtxid )
|
||||||
{
|
{
|
||||||
if ( total != 0 && maxinputs != 0 )
|
if ( funcid == 'F' || funcid == 'E' || funcid == 'W' || funcid == 'L' || funcid == 'T' )
|
||||||
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
{
|
||||||
totalinputs += it->second.satoshis;
|
if ( total != 0 && maxinputs != 0 )
|
||||||
n++;
|
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
||||||
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
|
totalinputs += it->second.satoshis;
|
||||||
break;
|
n++;
|
||||||
|
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else fprintf(stderr,"null funcid\n");
|
} else fprintf(stderr,"null funcid\n");
|
||||||
}
|
}
|
||||||
@@ -604,9 +659,9 @@ uint64_t AddDiceInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK
|
|||||||
return(totalinputs);
|
return(totalinputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t DicePlanFunds(uint64_t &entropyval,uint256 &entropytxid,uint64_t refsbits,struct CCcontract_info *cp,CPubKey dicepk,uint256 reffundingtxid)
|
int64_t DicePlanFunds(uint64_t &entropyval,uint256 &entropytxid,uint64_t refsbits,struct CCcontract_info *cp,CPubKey dicepk,uint256 reffundingtxid)
|
||||||
{
|
{
|
||||||
char coinaddr[64],str[65]; uint64_t sbits,nValue,totalinputs = 0; uint256 hash,txid,proof,hashBlock,fundingtxid; CScript fundingPubKey; CTransaction tx,vinTx; int32_t vout,first=0,n=0; uint8_t funcid;
|
char coinaddr[64],str[65]; uint64_t sbits; int64_t nValue,totalinputs = 0; uint256 hash,txid,proof,hashBlock,fundingtxid; CScript fundingPubKey; CTransaction tx,vinTx; int32_t vout,first=0,n=0; uint8_t funcid;
|
||||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||||
if ( GetTransaction(reffundingtxid,tx,hashBlock,false) != 0 && tx.vout.size() > 1 && ConstrainVout(tx.vout[0],1,cp->unspendableCCaddr,0) != 0 )
|
if ( GetTransaction(reffundingtxid,tx,hashBlock,false) != 0 && tx.vout.size() > 1 && ConstrainVout(tx.vout[0],1,cp->unspendableCCaddr,0) != 0 )
|
||||||
{
|
{
|
||||||
@@ -626,13 +681,11 @@ uint64_t DicePlanFunds(uint64_t &entropyval,uint256 &entropytxid,uint64_t refsbi
|
|||||||
{
|
{
|
||||||
if ( (funcid == 'F' && reffundingtxid == txid) || reffundingtxid == fundingtxid )
|
if ( (funcid == 'F' && reffundingtxid == txid) || reffundingtxid == fundingtxid )
|
||||||
{
|
{
|
||||||
if ( refsbits == sbits && (nValue= IsDicevout(cp,tx,vout)) > 10000 && (funcid == 'F' || funcid == 'E' || funcid == 'W' || funcid == 'L' || funcid == 'T') )
|
if ( refsbits == sbits && (nValue= IsDicevout(cp,tx,vout,refsbits,reffundingtxid)) > 10000 && (funcid == 'F' || funcid == 'E' || funcid == 'W' || funcid == 'L' || funcid == 'T') )
|
||||||
{
|
{
|
||||||
|
fprintf(stderr,"%s.(%c %.8f) ",uint256_str(str,txid),funcid,(double)nValue/COIN);
|
||||||
if ( funcid != 'F' && funcid != 'T' )
|
if ( funcid != 'F' && funcid != 'T' )
|
||||||
{
|
|
||||||
n++;
|
n++;
|
||||||
fprintf(stderr,"%s.(%c %.8f) ",uint256_str(str,txid),funcid,(double)nValue/COIN);
|
|
||||||
}
|
|
||||||
totalinputs += nValue;
|
totalinputs += nValue;
|
||||||
if ( first == 0 && (funcid == 'E' || funcid == 'W' || funcid == 'L') )
|
if ( first == 0 && (funcid == 'E' || funcid == 'W' || funcid == 'L') )
|
||||||
{
|
{
|
||||||
@@ -802,14 +855,14 @@ UniValue DiceList()
|
|||||||
std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t timeoutblocks)
|
std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t timeoutblocks)
|
||||||
{
|
{
|
||||||
CMutableTransaction mtx; uint256 zero; CScript fundingPubKey; CPubKey mypk,dicepk; int64_t a,b,c,d; uint64_t sbits; struct CCcontract_info *cp,C;
|
CMutableTransaction mtx; uint256 zero; CScript fundingPubKey; CPubKey mypk,dicepk; int64_t a,b,c,d; uint64_t sbits; struct CCcontract_info *cp,C;
|
||||||
if ( funds < 0 || minbet < 0 || maxbet < 0 || maxodds < 1 || timeoutblocks < 0 || timeoutblocks > 1440 )
|
if ( funds < 0 || minbet < 0 || maxbet < 0 || maxodds < 1 || maxodds > 9999 || timeoutblocks < 0 || timeoutblocks > 1440 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"negative parameter error\n");
|
fprintf(stderr,"negative parameter error\n");
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
memset(&zero,0,sizeof(zero));
|
memset(&zero,0,sizeof(zero));
|
||||||
if ( (cp= Diceinit(fundingPubKey,zero,&C,planstr,txfee,mypk,dicepk,sbits,a,b,c,d)) == 0 )
|
if ( (cp= Diceinit(fundingPubKey,zero,&C,planstr,txfee,mypk,dicepk,sbits,a,b,c,d)) == 0 )
|
||||||
return(0);
|
return("");
|
||||||
if ( AddNormalinputs(mtx,mypk,funds+3*txfee,60) > 0 )
|
if ( AddNormalinputs(mtx,mypk,funds+3*txfee,60) > 0 )
|
||||||
{
|
{
|
||||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,funds,dicepk));
|
mtx.vout.push_back(MakeCC1vout(cp->evalcode,funds,dicepk));
|
||||||
@@ -818,7 +871,7 @@ std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t
|
|||||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeDiceFundingOpRet('F',sbits,minbet,maxbet,maxodds,timeoutblocks)));
|
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeDiceFundingOpRet('F',sbits,minbet,maxbet,maxodds,timeoutblocks)));
|
||||||
}
|
}
|
||||||
fprintf(stderr,"cant find enough inputs\n");
|
fprintf(stderr,"cant find enough inputs\n");
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount)
|
std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount)
|
||||||
@@ -826,11 +879,11 @@ std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int6
|
|||||||
CMutableTransaction mtx; CScript fundingPubKey,scriptPubKey; uint256 entropy,hentropy; CPubKey mypk,dicepk; uint64_t sbits; struct CCcontract_info *cp,C; int64_t minbet,maxbet,maxodds,timeoutblocks;
|
CMutableTransaction mtx; CScript fundingPubKey,scriptPubKey; uint256 entropy,hentropy; CPubKey mypk,dicepk; uint64_t sbits; struct CCcontract_info *cp,C; int64_t minbet,maxbet,maxodds,timeoutblocks;
|
||||||
if ( amount < 0 )
|
if ( amount < 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"negative parameter error\n");
|
fprintf(stderr,"negative parameter\n");
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
if ( (cp= Diceinit(fundingPubKey,fundingtxid,&C,planstr,txfee,mypk,dicepk,sbits,minbet,maxbet,maxodds,timeoutblocks)) == 0 )
|
if ( (cp= Diceinit(fundingPubKey,fundingtxid,&C,planstr,txfee,mypk,dicepk,sbits,minbet,maxbet,maxodds,timeoutblocks)) == 0 )
|
||||||
return(0);
|
return("");
|
||||||
scriptPubKey = CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG;
|
scriptPubKey = CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG;
|
||||||
if ( 0 )
|
if ( 0 )
|
||||||
{
|
{
|
||||||
@@ -854,30 +907,30 @@ std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int6
|
|||||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeDiceOpRet('E',sbits,fundingtxid,hentropy,zeroid)));
|
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeDiceOpRet('E',sbits,fundingtxid,hentropy,zeroid)));
|
||||||
} else fprintf(stderr,"cant find enough inputs\n");
|
} else fprintf(stderr,"cant find enough inputs\n");
|
||||||
} else fprintf(stderr,"only fund creator can add more funds (entropy)\n");
|
} else fprintf(stderr,"only fund creator can add more funds (entropy)\n");
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet,int32_t odds)
|
std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet,int32_t odds)
|
||||||
{
|
{
|
||||||
CMutableTransaction mtx; CScript fundingPubKey; CPubKey mypk,dicepk; uint64_t sbits,entropyval; int64_t funding,minbet,maxbet,maxodds,timeoutblocks; uint256 entropytxid,entropy,hentropy; struct CCcontract_info *cp,C;
|
CMutableTransaction mtx; CScript fundingPubKey; CPubKey mypk,dicepk; uint64_t sbits,entropyval; int64_t funding,minbet,maxbet,maxodds,timeoutblocks; uint256 entropytxid,entropy,hentropy; struct CCcontract_info *cp,C;
|
||||||
if ( bet < 0 || odds < 1 )
|
if ( bet < 0 || odds < 1 || odds > 9999 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"negative parameter error\n");
|
fprintf(stderr,"negative parameter or odds too big error\n");
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
if ( (cp= Diceinit(fundingPubKey,fundingtxid,&C,planstr,txfee,mypk,dicepk,sbits,minbet,maxbet,maxodds,timeoutblocks)) == 0 )
|
if ( (cp= Diceinit(fundingPubKey,fundingtxid,&C,planstr,txfee,mypk,dicepk,sbits,minbet,maxbet,maxodds,timeoutblocks)) == 0 )
|
||||||
return(0);
|
return("");
|
||||||
if ( bet < minbet || bet > maxbet || odds > maxodds )
|
if ( bet < minbet || bet > maxbet || odds > maxodds )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"Dice plan %s illegal bet %.8f: minbet %.8f maxbet %.8f or odds %d vs max.%d\n",planstr,(double)bet/COIN,(double)minbet/COIN,(double)maxbet/COIN,(int32_t)odds,(int32_t)maxodds);
|
fprintf(stderr,"Dice plan %s illegal bet %.8f: minbet %.8f maxbet %.8f or odds %d vs max.%d\n",planstr,(double)bet/COIN,(double)minbet/COIN,(double)maxbet/COIN,(int32_t)odds,(int32_t)maxodds);
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
if ( (funding= DicePlanFunds(entropyval,entropytxid,sbits,cp,dicepk,fundingtxid)) >= 2*bet*odds+txfee && entropyval != 0 )
|
if ( (funding= DicePlanFunds(entropyval,entropytxid,sbits,cp,dicepk,fundingtxid)) >= 2*bet*odds+txfee && entropyval != 0 )
|
||||||
{
|
{
|
||||||
if ( myIsutxo_spentinmempool(entropytxid,0) != 0 )
|
if ( myIsutxo_spentinmempool(entropytxid,0) != 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"entropy txid is spent\n");
|
fprintf(stderr,"entropy txid is spent\n");
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
mtx.vin.push_back(CTxIn(entropytxid,0,CScript()));
|
mtx.vin.push_back(CTxIn(entropytxid,0,CScript()));
|
||||||
if ( AddNormalinputs(mtx,mypk,bet+2*txfee+odds,60) > 0 )
|
if ( AddNormalinputs(mtx,mypk,bet+2*txfee+odds,60) > 0 )
|
||||||
@@ -892,18 +945,18 @@ std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet
|
|||||||
if ( entropyval == 0 && funding != 0 )
|
if ( entropyval == 0 && funding != 0 )
|
||||||
fprintf(stderr,"cant find dice entropy inputs\n");
|
fprintf(stderr,"cant find dice entropy inputs\n");
|
||||||
else fprintf(stderr,"cant find dice inputs\n");
|
else fprintf(stderr,"cant find dice inputs\n");
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DiceBetFinish(int32_t *resultp,uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettxid,int32_t winlosetimeout)
|
std::string DiceBetFinish(int32_t *resultp,uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettxid,int32_t winlosetimeout)
|
||||||
{
|
{
|
||||||
CMutableTransaction mtx; CScript scriptPubKey,fundingPubKey; CTransaction betTx,entropyTx; uint256 hentropyproof,entropytxid,hashBlock,bettorentropy,entropy,hentropy; CPubKey mypk,dicepk,fundingpk; struct CCcontract_info *cp,C; int64_t inputs,CCchange=0,odds,fundsneeded,minbet,maxbet,maxodds,timeoutblocks; uint8_t funcid=0; int32_t iswin=0; uint64_t entropyval,sbits;
|
CMutableTransaction mtx; CScript scriptPubKey,fundingPubKey; CTransaction betTx,entropyTx; uint256 hentropyproof,entropytxid,hashBlock,bettorentropy,entropy,hentropy; CPubKey mypk,dicepk,fundingpk; struct CCcontract_info *cp,C; int64_t inputs=0,CCchange=0,odds,fundsneeded,minbet,maxbet,maxodds,timeoutblocks; uint8_t funcid=0; int32_t iswin=0; uint64_t entropyval,sbits;
|
||||||
*resultp = 0;
|
*resultp = 0;
|
||||||
//char str[65]; fprintf(stderr,"DiceBetFinish.%s %s\n",planstr,uint256_str(str,bettxid));
|
//char str[65]; fprintf(stderr,"DiceBetFinish.%s %s\n",planstr,uint256_str(str,bettxid));
|
||||||
if ( (cp= Diceinit(fundingPubKey,fundingtxid,&C,planstr,txfee,mypk,dicepk,sbits,minbet,maxbet,maxodds,timeoutblocks)) == 0 )
|
if ( (cp= Diceinit(fundingPubKey,fundingtxid,&C,planstr,txfee,mypk,dicepk,sbits,minbet,maxbet,maxodds,timeoutblocks)) == 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"Diceinit error\n");
|
fprintf(stderr,"Diceinit error\n");
|
||||||
return("0");
|
return("");
|
||||||
}
|
}
|
||||||
fundingpk = DiceFundingPk(fundingPubKey);
|
fundingpk = DiceFundingPk(fundingPubKey);
|
||||||
if ( winlosetimeout != 0 )
|
if ( winlosetimeout != 0 )
|
||||||
@@ -918,7 +971,7 @@ std::string DiceBetFinish(int32_t *resultp,uint64_t txfee,char *planstr,uint256
|
|||||||
if ( AddNormalinputs(mtx,mypk,txfee,1) == 0 )
|
if ( AddNormalinputs(mtx,mypk,txfee,1) == 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"no txfee inputs for win/lose\n");
|
fprintf(stderr,"no txfee inputs for win/lose\n");
|
||||||
return("0");
|
return("");
|
||||||
}
|
}
|
||||||
if ( GetTransaction(bettxid,betTx,hashBlock,false) != 0 && GetTransaction(betTx.vin[0].prevout.hash,entropyTx,hashBlock,false) != 0 )
|
if ( GetTransaction(bettxid,betTx,hashBlock,false) != 0 && GetTransaction(betTx.vin[0].prevout.hash,entropyTx,hashBlock,false) != 0 )
|
||||||
{
|
{
|
||||||
@@ -932,7 +985,7 @@ std::string DiceBetFinish(int32_t *resultp,uint64_t txfee,char *planstr,uint256
|
|||||||
if ( myIsutxo_spentinmempool(bettxid,0) != 0 || myIsutxo_spentinmempool(bettxid,1) != 0 )
|
if ( myIsutxo_spentinmempool(bettxid,0) != 0 || myIsutxo_spentinmempool(bettxid,1) != 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"bettxid already spent\n");
|
fprintf(stderr,"bettxid already spent\n");
|
||||||
return("0");
|
return("");
|
||||||
}
|
}
|
||||||
//fprintf(stderr,"iswin.%d matches\n",iswin);
|
//fprintf(stderr,"iswin.%d matches\n",iswin);
|
||||||
mtx.vin.push_back(CTxIn(bettxid,0,CScript()));
|
mtx.vin.push_back(CTxIn(bettxid,0,CScript()));
|
||||||
@@ -942,7 +995,7 @@ std::string DiceBetFinish(int32_t *resultp,uint64_t txfee,char *planstr,uint256
|
|||||||
funcid = 'T';
|
funcid = 'T';
|
||||||
if ( DiceVerifyTimeout(betTx,timeoutblocks) == 0 ) // hasnt timed out yet
|
if ( DiceVerifyTimeout(betTx,timeoutblocks) == 0 ) // hasnt timed out yet
|
||||||
{
|
{
|
||||||
return("0");
|
return("");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -958,23 +1011,25 @@ std::string DiceBetFinish(int32_t *resultp,uint64_t txfee,char *planstr,uint256
|
|||||||
if ( odds < 1 || odds > maxodds )
|
if ( odds < 1 || odds > maxodds )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"illegal odds.%d vs maxodds.%d\n",(int32_t)odds,(int32_t)maxodds);
|
fprintf(stderr,"illegal odds.%d vs maxodds.%d\n",(int32_t)odds,(int32_t)maxodds);
|
||||||
return("0");
|
return("");
|
||||||
}
|
}
|
||||||
CCchange = betTx.vout[0].nValue;
|
CCchange = betTx.vout[0].nValue + betTx.vout[1].nValue;
|
||||||
fundsneeded = txfee + odds*betTx.vout[1].nValue;
|
fundsneeded = txfee + (odds+1)*betTx.vout[1].nValue;
|
||||||
if ( (inputs= AddDiceInputs(cp,mtx,dicepk,fundsneeded,60)) > 0 )
|
if ( CCchange >= fundsneeded )
|
||||||
|
CCchange -= fundsneeded;
|
||||||
|
else if ( (inputs= AddDiceInputs(cp,mtx,dicepk,fundsneeded,60,sbits,fundingtxid)) > 0 )
|
||||||
{
|
{
|
||||||
if ( inputs > fundsneeded )
|
if ( inputs > fundsneeded )
|
||||||
CCchange += (inputs - fundsneeded);
|
CCchange += (inputs - fundsneeded);
|
||||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,dicepk));
|
|
||||||
mtx.vout.push_back(CTxOut(txfee,fundingPubKey));
|
|
||||||
mtx.vout.push_back(CTxOut((odds+1) * betTx.vout[1].nValue,betTx.vout[2].scriptPubKey));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr,"not enough inputs for %.8f\n",(double)fundsneeded/COIN);
|
fprintf(stderr,"not enough inputs for %.8f\n",(double)fundsneeded/COIN);
|
||||||
return("0");
|
return("");
|
||||||
}
|
}
|
||||||
|
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,dicepk));
|
||||||
|
mtx.vout.push_back(CTxOut(txfee,fundingPubKey));
|
||||||
|
mtx.vout.push_back(CTxOut((odds+1) * betTx.vout[1].nValue,betTx.vout[2].scriptPubKey));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -994,12 +1049,12 @@ std::string DiceBetFinish(int32_t *resultp,uint64_t txfee,char *planstr,uint256
|
|||||||
{
|
{
|
||||||
*resultp = -1;
|
*resultp = -1;
|
||||||
fprintf(stderr,"iswin.%d winlosetimeout.%d\n",iswin,winlosetimeout);
|
fprintf(stderr,"iswin.%d winlosetimeout.%d\n",iswin,winlosetimeout);
|
||||||
return("0");
|
return("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*resultp = -1;
|
*resultp = -1;
|
||||||
fprintf(stderr,"couldnt find bettx or entropytx\n");
|
fprintf(stderr,"couldnt find bettx or entropytx\n");
|
||||||
return("0");
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
double DiceStatus(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettxid)
|
double DiceStatus(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettxid)
|
||||||
@@ -1047,14 +1102,19 @@ double DiceStatus(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettx
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
char str[65];
|
||||||
if ( (vout= myIsutxo_spent(spenttxid,bettxid,1)) >= 0 )
|
if ( (vout= myIsutxo_spent(spenttxid,bettxid,1)) >= 0 )
|
||||||
{
|
{
|
||||||
if ( GetTransaction(spenttxid,spenttx,hashBlock,false) != 0 && spenttx.vout.size() > 2 )
|
//fprintf(stderr,"bettx is spent\n");
|
||||||
|
if ( GetTransaction(bettxid,betTx,hashBlock,false) != 0 && GetTransaction(spenttxid,spenttx,hashBlock,false) != 0 && spenttx.vout.size() > 2 )
|
||||||
{
|
{
|
||||||
if ( spenttx.vout[2].scriptPubKey == fundingPubKey )
|
//fprintf(stderr,"found spenttxid %s\n",uint256_str(str,spenttxid));
|
||||||
|
if ( betTx.vout[1].scriptPubKey.IsPayToCryptoCondition() == 0 || betTx.vout[2].scriptPubKey.IsPayToCryptoCondition() != 0 || spenttx.vout[2].scriptPubKey != betTx.vout[2].scriptPubKey )
|
||||||
return(0.);
|
return(0.);
|
||||||
else return((double)spenttx.vout[2].nValue/COIN);
|
else return((double)spenttx.vout[2].nValue/COIN);
|
||||||
} else return(0.);
|
}
|
||||||
|
fprintf(stderr,"couldnt find bettx or spenttx %s\n",uint256_str(str,spenttxid));
|
||||||
|
return(0.);
|
||||||
}
|
}
|
||||||
else if ( scriptPubKey == fundingPubKey )
|
else if ( scriptPubKey == fundingPubKey )
|
||||||
res = DiceBetFinish(&result,txfee,planstr,fundingtxid,bettxid,1);
|
res = DiceBetFinish(&result,txfee,planstr,fundingtxid,bettxid,1);
|
||||||
@@ -1065,15 +1125,17 @@ double DiceStatus(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettx
|
|||||||
sleep(1);
|
sleep(1);
|
||||||
if ( (vout= myIsutxo_spent(spenttxid,bettxid,1)) >= 0 )
|
if ( (vout= myIsutxo_spent(spenttxid,bettxid,1)) >= 0 )
|
||||||
{
|
{
|
||||||
if ( GetTransaction(spenttxid,spenttx,hashBlock,false) != 0 && spenttx.vout.size() >= 2 )
|
if ( GetTransaction(txid,betTx,hashBlock,false) != 0 && GetTransaction(spenttxid,spenttx,hashBlock,false) != 0 && spenttx.vout.size() >= 2 )
|
||||||
{
|
{
|
||||||
if ( spenttx.vout[2].scriptPubKey == fundingPubKey || ((uint8_t *)spenttx.vout[2].scriptPubKey.data())[0] == 0x6a )
|
if ( betTx.vout[1].scriptPubKey.IsPayToCryptoCondition() == 0 || betTx.vout[2].scriptPubKey.IsPayToCryptoCondition() != 0 || spenttx.vout[2].scriptPubKey != betTx.vout[2].scriptPubKey )
|
||||||
|
//if ( spenttx.vout[2].scriptPubKey == fundingPubKey || ((uint8_t *)spenttx.vout[2].scriptPubKey.data())[0] == 0x6a )
|
||||||
return(0.);
|
return(0.);
|
||||||
else return((double)spenttx.vout[2].nValue/COIN);
|
else return((double)spenttx.vout[2].nValue/COIN);
|
||||||
} else return(0.);
|
} else return(0.);
|
||||||
}
|
}
|
||||||
fprintf(stderr,"didnt find dicefinish tx\n");
|
fprintf(stderr,"didnt find dicefinish tx\n");
|
||||||
} else return(-1.);
|
}
|
||||||
|
return(-1.);
|
||||||
}
|
}
|
||||||
return(0.);
|
return(0.);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ bool RunCCEval(const CC *cond, const CTransaction &tx, unsigned int nIn)
|
|||||||
pthread_mutex_lock(&KOMODO_CC_mutex);
|
pthread_mutex_lock(&KOMODO_CC_mutex);
|
||||||
bool out = eval->Dispatch(cond, tx, nIn);
|
bool out = eval->Dispatch(cond, tx, nIn);
|
||||||
pthread_mutex_unlock(&KOMODO_CC_mutex);
|
pthread_mutex_unlock(&KOMODO_CC_mutex);
|
||||||
//fprintf(stderr,"out %d vs %d isValid\n",(int32_t)out,(int32_t)eval->state.IsValid());
|
//fprintf(stderr,"out %d vs %d isValid\n",(int32_t)out,(int32_t)eval->state.IsValid());
|
||||||
assert(eval->state.IsValid() == out);
|
assert(eval->state.IsValid() == out);
|
||||||
|
|
||||||
if (eval->state.IsValid()) return true;
|
if (eval->state.IsValid()) return true;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
// start of consensus code
|
// start of consensus code
|
||||||
|
|
||||||
uint64_t IsFaucetvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
|
int64_t IsFaucetvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
|
||||||
{
|
{
|
||||||
char destaddr[64];
|
char destaddr[64];
|
||||||
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||||
@@ -42,7 +42,7 @@ uint64_t IsFaucetvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t
|
|||||||
bool FaucetExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
|
bool FaucetExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
|
||||||
{
|
{
|
||||||
static uint256 zerohash;
|
static uint256 zerohash;
|
||||||
CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; uint64_t inputs=0,outputs=0,assetoshis;
|
CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis;
|
||||||
numvins = tx.vin.size();
|
numvins = tx.vin.size();
|
||||||
numvouts = tx.vout.size();
|
numvouts = tx.vout.size();
|
||||||
for (i=0; i<numvins; i++)
|
for (i=0; i<numvins; i++)
|
||||||
@@ -69,17 +69,18 @@ bool FaucetExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction
|
|||||||
if ( (assetoshis= IsFaucetvout(cp,tx,i)) != 0 )
|
if ( (assetoshis= IsFaucetvout(cp,tx,i)) != 0 )
|
||||||
outputs += assetoshis;
|
outputs += assetoshis;
|
||||||
}
|
}
|
||||||
if ( inputs != outputs+COIN+txfee )
|
if ( inputs != outputs+FAUCETSIZE+txfee )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"inputs %llu vs outputs %llu\n",(long long)inputs,(long long)outputs);
|
fprintf(stderr,"inputs %llu vs outputs %llu\n",(long long)inputs,(long long)outputs);
|
||||||
return eval->Invalid("mismatched inputs != outputs + COIN + txfee");
|
return eval->Invalid("mismatched inputs != outputs + FAUCETSIZE + txfee");
|
||||||
}
|
}
|
||||||
else return(true);
|
else return(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
|
bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
|
||||||
{
|
{
|
||||||
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; bool retval;
|
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64];
|
||||||
|
std::vector<std::pair<CAddressIndexKey, CAmount> > txids;
|
||||||
numvins = tx.vin.size();
|
numvins = tx.vin.size();
|
||||||
numvouts = tx.vout.size();
|
numvouts = tx.vout.size();
|
||||||
preventCCvins = preventCCvouts = -1;
|
preventCCvins = preventCCvouts = -1;
|
||||||
@@ -87,7 +88,6 @@ bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
|
|||||||
return eval->Invalid("no vouts");
|
return eval->Invalid("no vouts");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//fprintf(stderr,"check vins\n");
|
|
||||||
for (i=0; i<numvins; i++)
|
for (i=0; i<numvins; i++)
|
||||||
{
|
{
|
||||||
if ( IsCCInput(tx.vin[0].scriptSig) == 0 )
|
if ( IsCCInput(tx.vin[0].scriptSig) == 0 )
|
||||||
@@ -110,8 +110,24 @@ bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
|
|||||||
preventCCvouts++;
|
preventCCvouts++;
|
||||||
i = 1;
|
i = 1;
|
||||||
} else i = 0;
|
} else i = 0;
|
||||||
if ( tx.vout[i].nValue != COIN )
|
txid = tx.GetHash();
|
||||||
|
memcpy(hash,&txid,sizeof(hash));
|
||||||
|
fprintf(stderr,"check faucetget txid %s %02x/%02x\n",uint256_str(str,txid),hash[0],hash[31]);
|
||||||
|
if ( tx.vout[i].nValue != FAUCETSIZE )
|
||||||
return eval->Invalid("invalid faucet output");
|
return eval->Invalid("invalid faucet output");
|
||||||
|
else if ( (hash[0] & 0xff) != 0 || (hash[31] & 0xff) != 0 )
|
||||||
|
return eval->Invalid("invalid faucetget txid");
|
||||||
|
Getscriptaddress(destaddr,tx.vout[i].scriptPubKey);
|
||||||
|
SetCCtxids(txids,destaddr);
|
||||||
|
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=txids.begin(); it!=txids.end(); it++)
|
||||||
|
{
|
||||||
|
//int height = it->first.blockHeight;
|
||||||
|
if ( CCduration(numblocks,it->first.txhash) > 0 && numblocks > 3 )
|
||||||
|
{
|
||||||
|
//fprintf(stderr,"would return error %s numblocks.%d ago\n",uint256_str(str,it->first.txhash),numblocks);
|
||||||
|
return eval->Invalid("faucet is only for brand new addresses");
|
||||||
|
}
|
||||||
|
}
|
||||||
retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
|
retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
|
||||||
if ( retval != 0 )
|
if ( retval != 0 )
|
||||||
fprintf(stderr,"faucetget validated\n");
|
fprintf(stderr,"faucetget validated\n");
|
||||||
@@ -124,9 +140,9 @@ bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
|
|||||||
|
|
||||||
// helper functions for rpc calls in rpcwallet.cpp
|
// helper functions for rpc calls in rpcwallet.cpp
|
||||||
|
|
||||||
uint64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs)
|
int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
|
||||||
{
|
{
|
||||||
char coinaddr[64]; uint64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
|
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
|
||||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||||
GetCCaddress(cp,coinaddr,pk);
|
GetCCaddress(cp,coinaddr,pk);
|
||||||
SetCCunspents(unspentOutputs,coinaddr);
|
SetCCunspents(unspentOutputs,coinaddr);
|
||||||
@@ -154,7 +170,7 @@ uint64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPu
|
|||||||
|
|
||||||
std::string FaucetGet(uint64_t txfee)
|
std::string FaucetGet(uint64_t txfee)
|
||||||
{
|
{
|
||||||
CMutableTransaction mtx; CPubKey mypk,faucetpk; CScript opret; uint64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
CMutableTransaction mtx,tmpmtx; CPubKey mypk,faucetpk; int64_t inputs,CCchange=0,nValue=FAUCETSIZE; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash;
|
||||||
cp = CCinit(&C,EVAL_FAUCET);
|
cp = CCinit(&C,EVAL_FAUCET);
|
||||||
if ( txfee == 0 )
|
if ( txfee == 0 )
|
||||||
txfee = 10000;
|
txfee = 10000;
|
||||||
@@ -167,12 +183,32 @@ std::string FaucetGet(uint64_t txfee)
|
|||||||
if ( CCchange != 0 )
|
if ( CCchange != 0 )
|
||||||
mtx.vout.push_back(MakeCC1vout(EVAL_FAUCET,CCchange,faucetpk));
|
mtx.vout.push_back(MakeCC1vout(EVAL_FAUCET,CCchange,faucetpk));
|
||||||
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||||
return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,opret));
|
fprintf(stderr,"start at %u\n",(uint32_t)time(NULL));
|
||||||
|
j = rand() & 0xfffffff;
|
||||||
|
for (i=0; i<1000000; i++,j++)
|
||||||
|
{
|
||||||
|
tmpmtx = mtx;
|
||||||
|
rawhex = FinalizeCCTx(-1LL,cp,tmpmtx,mypk,txfee,CScript() << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_FAUCET << (uint8_t)'G' << j));
|
||||||
|
if ( (len= (int32_t)rawhex.size()) > 0 && len < 65536 )
|
||||||
|
{
|
||||||
|
len >>= 1;
|
||||||
|
decode_hex(buf,len,(char *)rawhex.c_str());
|
||||||
|
hash = bits256_doublesha256(0,buf,len);
|
||||||
|
if ( (hash.bytes[0] & 0xff) == 0 && (hash.bytes[31] & 0xff) == 0 )
|
||||||
|
{
|
||||||
|
fprintf(stderr,"found valid txid after %d iterations %u\n",i,(uint32_t)time(NULL));
|
||||||
|
return(rawhex);
|
||||||
|
}
|
||||||
|
//fprintf(stderr,"%02x%02x ",hash.bytes[0],hash.bytes[31]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(stderr,"couldnt generate valid txid %u\n",(uint32_t)time(NULL));
|
||||||
|
return("");
|
||||||
} else fprintf(stderr,"cant find faucet inputs\n");
|
} else fprintf(stderr,"cant find faucet inputs\n");
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FaucetFund(uint64_t txfee,uint64_t funds)
|
std::string FaucetFund(uint64_t txfee,int64_t funds)
|
||||||
{
|
{
|
||||||
CMutableTransaction mtx; CPubKey mypk,faucetpk; CScript opret; struct CCcontract_info *cp,C;
|
CMutableTransaction mtx; CPubKey mypk,faucetpk; CScript opret; struct CCcontract_info *cp,C;
|
||||||
cp = CCinit(&C,EVAL_FAUCET);
|
cp = CCinit(&C,EVAL_FAUCET);
|
||||||
@@ -185,13 +221,13 @@ std::string FaucetFund(uint64_t txfee,uint64_t funds)
|
|||||||
mtx.vout.push_back(MakeCC1vout(EVAL_FAUCET,funds,faucetpk));
|
mtx.vout.push_back(MakeCC1vout(EVAL_FAUCET,funds,faucetpk));
|
||||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
|
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
|
||||||
}
|
}
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue FaucetInfo()
|
UniValue FaucetInfo()
|
||||||
{
|
{
|
||||||
UniValue result(UniValue::VOBJ); char numstr[64];
|
UniValue result(UniValue::VOBJ); char numstr[64];
|
||||||
CMutableTransaction mtx; CPubKey faucetpk; struct CCcontract_info *cp,C; uint64_t funding;
|
CMutableTransaction mtx; CPubKey faucetpk; struct CCcontract_info *cp,C; int64_t funding;
|
||||||
result.push_back(Pair("result","success"));
|
result.push_back(Pair("result","success"));
|
||||||
result.push_back(Pair("name","Faucet"));
|
result.push_back(Pair("name","Faucet"));
|
||||||
cp = CCinit(&C,EVAL_FAUCET);
|
cp = CCinit(&C,EVAL_FAUCET);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
// start of consensus code
|
// start of consensus code
|
||||||
|
|
||||||
uint64_t IsFSMvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
|
int64_t IsFSMvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
|
||||||
{
|
{
|
||||||
char destaddr[64];
|
char destaddr[64];
|
||||||
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||||
@@ -35,7 +35,7 @@ uint64_t IsFSMvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
|
|||||||
bool FSMExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
|
bool FSMExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
|
||||||
{
|
{
|
||||||
static uint256 zerohash;
|
static uint256 zerohash;
|
||||||
CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; uint64_t inputs=0,outputs=0,assetoshis;
|
CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis;
|
||||||
numvins = tx.vin.size();
|
numvins = tx.vin.size();
|
||||||
numvouts = tx.vout.size();
|
numvouts = tx.vout.size();
|
||||||
for (i=0; i<numvins; i++)
|
for (i=0; i<numvins; i++)
|
||||||
@@ -118,9 +118,9 @@ bool FSMValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
|
|||||||
|
|
||||||
// helper functions for rpc calls in rpcwallet.cpp
|
// helper functions for rpc calls in rpcwallet.cpp
|
||||||
|
|
||||||
uint64_t AddFSMInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs)
|
int64_t AddFSMInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
|
||||||
{
|
{
|
||||||
char coinaddr[64]; uint64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t n = 0;
|
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t n = 0;
|
||||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||||
GetCCaddress(cp,coinaddr,pk);
|
GetCCaddress(cp,coinaddr,pk);
|
||||||
SetCCunspents(unspentOutputs,coinaddr);
|
SetCCunspents(unspentOutputs,coinaddr);
|
||||||
@@ -149,12 +149,12 @@ uint64_t AddFSMInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKe
|
|||||||
|
|
||||||
std::string FSMList()
|
std::string FSMList()
|
||||||
{
|
{
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FSMCreate(uint64_t txfee,std::string name,std::string states)
|
std::string FSMCreate(uint64_t txfee,std::string name,std::string states)
|
||||||
{
|
{
|
||||||
CMutableTransaction mtx; CPubKey mypk,fsmpk; CScript opret; uint64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
CMutableTransaction mtx; CPubKey mypk,fsmpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||||
cp = CCinit(&C,EVAL_FSM);
|
cp = CCinit(&C,EVAL_FSM);
|
||||||
if ( txfee == 0 )
|
if ( txfee == 0 )
|
||||||
txfee = 10000;
|
txfee = 10000;
|
||||||
@@ -169,16 +169,16 @@ std::string FSMCreate(uint64_t txfee,std::string name,std::string states)
|
|||||||
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||||
return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,opret));
|
return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,opret));
|
||||||
} else fprintf(stderr,"cant find fsm inputs\n");
|
} else fprintf(stderr,"cant find fsm inputs\n");
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FSMInfo(uint256 fsmtxid)
|
std::string FSMInfo(uint256 fsmtxid)
|
||||||
{
|
{
|
||||||
CMutableTransaction mtx; CPubKey mypk,fsmpk; uint64_t funds = 0; CScript opret; struct CCcontract_info *cp,C;
|
CMutableTransaction mtx; CPubKey mypk,fsmpk; int64_t funds = 0; CScript opret; struct CCcontract_info *cp,C;
|
||||||
cp = CCinit(&C,EVAL_FSM);
|
cp = CCinit(&C,EVAL_FSM);
|
||||||
mypk = pubkey2pk(Mypubkey());
|
mypk = pubkey2pk(Mypubkey());
|
||||||
fsmpk = GetUnspendable(cp,0);
|
fsmpk = GetUnspendable(cp,0);
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
// start of consensus code
|
// start of consensus code
|
||||||
|
|
||||||
uint64_t IsLottovout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
|
int64_t IsLottovout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
|
||||||
{
|
{
|
||||||
char destaddr[64];
|
char destaddr[64];
|
||||||
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||||
@@ -35,7 +35,7 @@ uint64_t IsLottovout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v
|
|||||||
bool LottoExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
|
bool LottoExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
|
||||||
{
|
{
|
||||||
static uint256 zerohash;
|
static uint256 zerohash;
|
||||||
CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; uint64_t inputs=0,outputs=0,assetoshis;
|
CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis;
|
||||||
numvins = tx.vin.size();
|
numvins = tx.vin.size();
|
||||||
numvouts = tx.vout.size();
|
numvouts = tx.vout.size();
|
||||||
for (i=0; i<numvins; i++)
|
for (i=0; i<numvins; i++)
|
||||||
@@ -118,9 +118,9 @@ bool LottoValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
|
|||||||
|
|
||||||
// helper functions for rpc calls in rpcwallet.cpp
|
// helper functions for rpc calls in rpcwallet.cpp
|
||||||
|
|
||||||
uint64_t AddLottoInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs)
|
int64_t AddLottoInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
|
||||||
{
|
{
|
||||||
char coinaddr[64]; uint64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t n = 0;
|
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t n = 0;
|
||||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||||
GetCCaddress(cp,coinaddr,pk);
|
GetCCaddress(cp,coinaddr,pk);
|
||||||
SetCCunspents(unspentOutputs,coinaddr);
|
SetCCunspents(unspentOutputs,coinaddr);
|
||||||
@@ -147,9 +147,9 @@ uint64_t AddLottoInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub
|
|||||||
return(totalinputs);
|
return(totalinputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LottoTicket(uint64_t txfee,uint64_t numtickets)
|
std::string LottoTicket(uint64_t txfee,int64_t numtickets)
|
||||||
{
|
{
|
||||||
CMutableTransaction mtx; CPubKey mypk,Lottopk; CScript opret; uint64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
CMutableTransaction mtx; CPubKey mypk,Lottopk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||||
cp = CCinit(&C,EVAL_LOTTO);
|
cp = CCinit(&C,EVAL_LOTTO);
|
||||||
if ( txfee == 0 )
|
if ( txfee == 0 )
|
||||||
txfee = 10000;
|
txfee = 10000;
|
||||||
@@ -164,12 +164,12 @@ std::string LottoTicket(uint64_t txfee,uint64_t numtickets)
|
|||||||
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||||
return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,opret));
|
return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,opret));
|
||||||
} else fprintf(stderr,"cant find Lotto inputs\n");
|
} else fprintf(stderr,"cant find Lotto inputs\n");
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LottoWinner(uint64_t txfee)
|
std::string LottoWinner(uint64_t txfee)
|
||||||
{
|
{
|
||||||
CMutableTransaction mtx; CPubKey mypk,Lottopk; uint64_t winnings = 0; CScript opret; struct CCcontract_info *cp,C;
|
CMutableTransaction mtx; CPubKey mypk,Lottopk; int64_t winnings = 0; CScript opret; struct CCcontract_info *cp,C;
|
||||||
cp = CCinit(&C,EVAL_LOTTO);
|
cp = CCinit(&C,EVAL_LOTTO);
|
||||||
if ( txfee == 0 )
|
if ( txfee == 0 )
|
||||||
txfee = 10000;
|
txfee = 10000;
|
||||||
@@ -180,7 +180,7 @@ std::string LottoWinner(uint64_t txfee)
|
|||||||
mtx.vout.push_back(MakeCC1vout(EVAL_LOTTO,winnings,Lottopk));
|
mtx.vout.push_back(MakeCC1vout(EVAL_LOTTO,winnings,Lottopk));
|
||||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
|
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
|
||||||
}
|
}
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* *
|
* *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include "CCinclude.h"
|
#include "CCrewards.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The rewards CC contract is initially for OOT, which needs this functionality. However, many of the attributes can be parameterized to allow different rewards programs to run. Multiple rewards plans could even run on the same blockchain, though the user would need to choose which one to lock funds into.
|
The rewards CC contract is initially for OOT, which needs this functionality. However, many of the attributes can be parameterized to allow different rewards programs to run. Multiple rewards plans could even run on the same blockchain, though the user would need to choose which one to lock funds into.
|
||||||
@@ -66,10 +66,12 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint64_t RewardsCalc(uint64_t amount,uint256 txid,uint64_t APR,uint64_t minseconds,uint64_t maxseconds,uint64_t mindeposit)
|
extern std::string CCerror;
|
||||||
|
|
||||||
|
int64_t RewardsCalc(int64_t amount,uint256 txid,uint64_t APR,uint64_t minseconds,uint64_t maxseconds,uint64_t mindeposit)
|
||||||
{
|
{
|
||||||
int32_t numblocks; uint64_t duration,reward = 0;
|
int32_t numblocks; uint64_t duration,reward = 0;
|
||||||
fprintf(stderr,"minseconds %llu maxseconds %llu\n",(long long)minseconds,(long long)maxseconds);
|
//fprintf(stderr,"minseconds %llu maxseconds %llu\n",(long long)minseconds,(long long)maxseconds);
|
||||||
if ( (duration= CCduration(numblocks,txid)) < minseconds )
|
if ( (duration= CCduration(numblocks,txid)) < minseconds )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"duration %llu < minseconds %llu\n",(long long)duration,(long long)minseconds);
|
fprintf(stderr,"duration %llu < minseconds %llu\n",(long long)duration,(long long)minseconds);
|
||||||
@@ -77,8 +79,12 @@ uint64_t RewardsCalc(uint64_t amount,uint256 txid,uint64_t APR,uint64_t minsecon
|
|||||||
//duration = (uint32_t)time(NULL) - (1532713903 - 3600 * 24);
|
//duration = (uint32_t)time(NULL) - (1532713903 - 3600 * 24);
|
||||||
} else if ( duration > maxseconds )
|
} else if ( duration > maxseconds )
|
||||||
duration = maxseconds;
|
duration = maxseconds;
|
||||||
reward = (((amount * APR) / COIN) * duration) / (365*24*3600LL * 100);
|
if ( 0 ) // amount * APR * duration / COIN * 100 * 365*24*3600
|
||||||
fprintf(stderr,"amount %.8f %.8f %llu -> duration.%llu reward %.8f\n",(double)amount/COIN,((double)amount * APR)/COIN,(long long)((amount * APR) / (COIN * 365*24*3600)),(long long)duration,(double)reward/COIN);
|
reward = (((amount * APR) / COIN) * duration) / (365*24*3600LL * 100);
|
||||||
|
else reward = (((amount * duration) / (365 * 24 * 3600LL)) * (APR / 1000000)) / 10000;
|
||||||
|
if ( reward > amount )
|
||||||
|
reward = amount;
|
||||||
|
fprintf(stderr,"amount %.8f %.8f %llu -> duration.%llu reward %.8f vals %.8f %.8f\n",(double)amount/COIN,((double)amount * APR)/COIN,(long long)((amount * APR) / (COIN * 365*24*3600)),(long long)duration,(double)reward/COIN,(double)((amount * duration) / (365 * 24 * 3600LL))/COIN,(double)(((amount * duration) / (365 * 24 * 3600LL)) * (APR / 1000000))/COIN);
|
||||||
return(reward);
|
return(reward);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,21 +143,26 @@ uint8_t DecodeRewardsOpRet(uint256 txid,const CScript &scriptPubKey,uint64_t &sb
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t IsRewardsvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
|
int64_t IsRewardsvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v,uint64_t refsbits,uint256 reffundingtxid)
|
||||||
{
|
{
|
||||||
char destaddr[64];
|
char destaddr[64]; uint64_t sbits; uint256 fundingtxid,txid; uint8_t funcid; int32_t numvouts;
|
||||||
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 && (numvouts= (int32_t)tx.vout.size()) > 0 )
|
||||||
{
|
{
|
||||||
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 )
|
txid = tx.GetHash();
|
||||||
return(tx.vout[v].nValue);
|
if ( (funcid= DecodeRewardsOpRet(txid,tx.vout[numvouts-1].scriptPubKey,sbits,fundingtxid)) != 0 && sbits == refsbits && (fundingtxid == reffundingtxid || txid == reffundingtxid) )
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 )
|
||||||
|
return(tx.vout[v].nValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RewardsExactAmounts(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx,uint64_t txfee)
|
bool RewardsExactAmounts(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx,uint64_t txfee,uint64_t refsbits,uint256 reffundingtxid)
|
||||||
{
|
{
|
||||||
static uint256 zerohash;
|
static uint256 zerohash;
|
||||||
CTransaction vinTx; uint256 hashBlock; int32_t i,numvins,numvouts; uint64_t inputs=0,outputs=0,assetoshis;
|
CTransaction vinTx; uint256 hashBlock; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis;
|
||||||
numvins = tx.vin.size();
|
numvins = tx.vin.size();
|
||||||
numvouts = tx.vout.size();
|
numvouts = tx.vout.size();
|
||||||
for (i=0; i<numvins; i++)
|
for (i=0; i<numvins; i++)
|
||||||
@@ -164,7 +175,7 @@ bool RewardsExactAmounts(struct CCcontract_info *cp,Eval *eval,const CTransactio
|
|||||||
{
|
{
|
||||||
if ( hashBlock == zerohash )
|
if ( hashBlock == zerohash )
|
||||||
return eval->Invalid("cant rewards from mempool");
|
return eval->Invalid("cant rewards from mempool");
|
||||||
if ( (assetoshis= IsRewardsvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
|
if ( (assetoshis= IsRewardsvout(cp,vinTx,tx.vin[i].prevout.n,refsbits,reffundingtxid)) != 0 )
|
||||||
inputs += assetoshis;
|
inputs += assetoshis;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,12 +183,12 @@ bool RewardsExactAmounts(struct CCcontract_info *cp,Eval *eval,const CTransactio
|
|||||||
for (i=0; i<numvouts; i++)
|
for (i=0; i<numvouts; i++)
|
||||||
{
|
{
|
||||||
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
|
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
|
||||||
if ( (assetoshis= IsRewardsvout(cp,tx,i)) != 0 )
|
if ( (assetoshis= IsRewardsvout(cp,tx,i,refsbits,reffundingtxid)) != 0 )
|
||||||
outputs += assetoshis;
|
outputs += assetoshis;
|
||||||
}
|
}
|
||||||
if ( inputs != outputs+txfee )
|
if ( inputs != outputs+txfee )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"inputs %llu vs outputs %llu\n",(long long)inputs,(long long)outputs);
|
fprintf(stderr,"inputs %llu vs outputs %llu txfee %llu\n",(long long)inputs,(long long)outputs,(long long)txfee);
|
||||||
return eval->Invalid("mismatched inputs != outputs + txfee");
|
return eval->Invalid("mismatched inputs != outputs + txfee");
|
||||||
}
|
}
|
||||||
else return(true);
|
else return(true);
|
||||||
@@ -200,6 +211,8 @@ bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
|
|||||||
return eval->Invalid("cant find fundingtxid");
|
return eval->Invalid("cant find fundingtxid");
|
||||||
else if ( fundingTx.vout.size() > 0 && DecodeRewardsFundingOpRet(fundingTx.vout[fundingTx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) != 'F' )
|
else if ( fundingTx.vout.size() > 0 && DecodeRewardsFundingOpRet(fundingTx.vout[fundingTx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) != 'F' )
|
||||||
return eval->Invalid("fundingTx not valid");
|
return eval->Invalid("fundingTx not valid");
|
||||||
|
if ( APR > REWARDSCC_MAXAPR )
|
||||||
|
return eval->Invalid("excessive APR");
|
||||||
switch ( funcid )
|
switch ( funcid )
|
||||||
{
|
{
|
||||||
case 'F':
|
case 'F':
|
||||||
@@ -228,22 +241,32 @@ bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
|
|||||||
case 'U':
|
case 'U':
|
||||||
//vin.0: locked funds CC vout.0 from lock
|
//vin.0: locked funds CC vout.0 from lock
|
||||||
//vin.1+: funding CC vout.0 from 'F' and 'A' and 'U'
|
//vin.1+: funding CC vout.0 from 'F' and 'A' and 'U'
|
||||||
//vout.0: funding CC change
|
//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 )
|
||||||
|
return eval->Invalid("always should find vin.0, but didnt");
|
||||||
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 )
|
||||||
return eval->Invalid("unexpected normal vin for unlock");
|
return eval->Invalid("unexpected normal vin for unlock");
|
||||||
}
|
}
|
||||||
if ( RewardsExactAmounts(cp,eval,tx,txfee+tx.vout[1].nValue) == 0 )
|
if ( numvouts == 2 && numvins == 1 )
|
||||||
return false;
|
{
|
||||||
else if ( eval->GetTxUnconfirmed(tx.vin[0].prevout.hash,vinTx,hashBlock) == 0 )
|
if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||||
return eval->Invalid("always should find vin.0, but didnt");
|
return eval->Invalid("unlock recover tx vout.0 is not normal output");
|
||||||
else if ( vinTx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
else if ( tx.vout[0].scriptPubKey != vinTx.vout[1].scriptPubKey )
|
||||||
return eval->Invalid("lock tx vout.0 is normal output");
|
return eval->Invalid("unlock recover tx vout.0 mismatched scriptPubKey");
|
||||||
else if ( tx.vout.size() < 3 )
|
else if ( tx.vout[0].nValue > vinTx.vout[0].nValue )
|
||||||
return eval->Invalid("unlock tx not enough vouts");
|
return eval->Invalid("unlock recover tx vout.0 mismatched amounts");
|
||||||
|
else if ( tx.vout[1].nValue > 0 )
|
||||||
|
return eval->Invalid("unlock recover tx vout.1 nonz amount");
|
||||||
|
else return(true);
|
||||||
|
}
|
||||||
|
if ( vinTx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
||||||
|
return eval->Invalid("unlock tx vout.0 is normal output");
|
||||||
|
else if ( numvouts != 3 )
|
||||||
|
return eval->Invalid("unlock tx wrong number of vouts");
|
||||||
else if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
else if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
||||||
return eval->Invalid("unlock tx vout.0 is normal output");
|
return eval->Invalid("unlock tx vout.0 is normal output");
|
||||||
else if ( tx.vout[1].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
else if ( tx.vout[1].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||||
@@ -252,8 +275,12 @@ bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
|
|||||||
return eval->Invalid("unlock tx vout.1 mismatched scriptPubKey");
|
return eval->Invalid("unlock tx vout.1 mismatched scriptPubKey");
|
||||||
amount = vinTx.vout[0].nValue;
|
amount = vinTx.vout[0].nValue;
|
||||||
reward = RewardsCalc(amount,tx.vin[0].prevout.hash,APR,minseconds,maxseconds,mindeposit);
|
reward = RewardsCalc(amount,tx.vin[0].prevout.hash,APR,minseconds,maxseconds,mindeposit);
|
||||||
if ( tx.vout[1].nValue > amount+reward )
|
if ( RewardsExactAmounts(cp,eval,tx,txfee+tx.vout[1].nValue,sbits,fundingtxid) == 0 )
|
||||||
|
return false;
|
||||||
|
else if ( tx.vout[1].nValue > amount+reward )
|
||||||
return eval->Invalid("unlock tx vout.1 isnt amount+reward");
|
return eval->Invalid("unlock tx vout.1 isnt amount+reward");
|
||||||
|
else if ( tx.vout[2].nValue > 0 )
|
||||||
|
return eval->Invalid("unlock tx vout.2 isnt 0");
|
||||||
preventCCvouts = 1;
|
preventCCvouts = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -263,10 +290,38 @@ bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
|
|||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 'L' vs 'F' and 'A'
|
uint64_t myIs_unlockedtx_inmempool(uint256 &txid,int32_t &vout,uint64_t refsbits,uint256 reffundingtxid,uint64_t needed)
|
||||||
uint64_t AddRewardsInputs(CScript &scriptPubKey,int32_t fundsflag,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs)
|
|
||||||
{
|
{
|
||||||
char coinaddr[64],str[65]; uint64_t sbits,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t j,vout,n = 0; uint8_t funcid;
|
uint8_t funcid; uint64_t sbits,nValue; uint256 fundingtxid; char str[65];
|
||||||
|
memset(&txid,0,sizeof(txid));
|
||||||
|
vout = -1;
|
||||||
|
nValue = 0;
|
||||||
|
BOOST_FOREACH(const CTxMemPoolEntry &e,mempool.mapTx)
|
||||||
|
{
|
||||||
|
const CTransaction &tx = e.GetTx();
|
||||||
|
if ( tx.vout.size() > 0 && tx.vout[0].nValue >= needed )
|
||||||
|
{
|
||||||
|
const uint256 &hash = tx.GetHash();
|
||||||
|
if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(hash,0) == 0 )
|
||||||
|
{
|
||||||
|
if ( (funcid= DecodeRewardsOpRet(hash,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) == 'U' && sbits == refsbits && fundingtxid == reffundingtxid )
|
||||||
|
{
|
||||||
|
txid = hash;
|
||||||
|
vout = 0;
|
||||||
|
nValue = tx.vout[0].nValue;
|
||||||
|
fprintf(stderr,"found 'U' %s %.8f in unspent in mempool\n",uint256_str(str,txid),(double)nValue/COIN);
|
||||||
|
return(nValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(nValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'L' vs 'F' and 'A'
|
||||||
|
int64_t AddRewardsInputs(CScript &scriptPubKey,uint64_t maxseconds,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs,uint64_t refsbits,uint256 reffundingtxid)
|
||||||
|
{
|
||||||
|
char coinaddr[64],str[65]; uint64_t sbits,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t numblocks,j,vout,n = 0; uint8_t funcid;
|
||||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||||
GetCCaddress(cp,coinaddr,pk);
|
GetCCaddress(cp,coinaddr,pk);
|
||||||
SetCCunspents(unspentOutputs,coinaddr);
|
SetCCunspents(unspentOutputs,coinaddr);
|
||||||
@@ -276,7 +331,7 @@ uint64_t AddRewardsInputs(CScript &scriptPubKey,int32_t fundsflag,struct CCcontr
|
|||||||
vout = (int32_t)it->first.index;
|
vout = (int32_t)it->first.index;
|
||||||
if ( it->second.satoshis < 1000000 )
|
if ( it->second.satoshis < 1000000 )
|
||||||
continue;
|
continue;
|
||||||
fprintf(stderr,"(%s) %s/v%d %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN);
|
//fprintf(stderr,"(%s) %s/v%d %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN);
|
||||||
for (j=0; j<mtx.vin.size(); j++)
|
for (j=0; j<mtx.vin.size(); j++)
|
||||||
if ( txid == mtx.vin[j].prevout.hash && vout == mtx.vin[j].prevout.n )
|
if ( txid == mtx.vin[j].prevout.hash && vout == mtx.vin[j].prevout.n )
|
||||||
break;
|
break;
|
||||||
@@ -286,14 +341,19 @@ uint64_t AddRewardsInputs(CScript &scriptPubKey,int32_t fundsflag,struct CCcontr
|
|||||||
{
|
{
|
||||||
if ( (funcid= DecodeRewardsOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) != 0 )
|
if ( (funcid= DecodeRewardsOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) != 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"fundsflag.%d (%c) %.8f %.8f\n",fundsflag,funcid,(double)tx.vout[vout].nValue/COIN,(double)it->second.satoshis/COIN);
|
if ( sbits != refsbits || fundingtxid != reffundingtxid )
|
||||||
if ( fundsflag != 0 && funcid != 'F' && funcid != 'A' && funcid != 'U' )
|
|
||||||
continue;
|
continue;
|
||||||
else if ( fundsflag == 0 && (funcid != 'L' || tx.vout.size() < 4) )
|
if ( maxseconds == 0 && funcid != 'F' && funcid != 'A' && funcid != 'U' )
|
||||||
continue;
|
continue;
|
||||||
|
else if ( maxseconds != 0 && funcid != 'L' )
|
||||||
|
{
|
||||||
|
if ( CCduration(numblocks,txid) < maxseconds )
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
fprintf(stderr,"maxseconds.%d (%c) %.8f %.8f\n",(int32_t)maxseconds,funcid,(double)tx.vout[vout].nValue/COIN,(double)it->second.satoshis/COIN);
|
||||||
if ( total != 0 && maxinputs != 0 )
|
if ( total != 0 && maxinputs != 0 )
|
||||||
{
|
{
|
||||||
if ( fundsflag == 0 )
|
if ( maxseconds != 0 )
|
||||||
scriptPubKey = tx.vout[1].scriptPubKey;
|
scriptPubKey = tx.vout[1].scriptPubKey;
|
||||||
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
||||||
}
|
}
|
||||||
@@ -304,13 +364,25 @@ uint64_t AddRewardsInputs(CScript &scriptPubKey,int32_t fundsflag,struct CCcontr
|
|||||||
} else fprintf(stderr,"null funcid\n");
|
} else fprintf(stderr,"null funcid\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ( maxseconds == 0 && totalinputs < total && (maxinputs == 0 || n < maxinputs-1) )
|
||||||
|
{
|
||||||
|
fprintf(stderr,"search mempool for unlocked and unspent CC rewards output for %.8f\n",(double)(total-totalinputs)/COIN);
|
||||||
|
if ( (nValue= myIs_unlockedtx_inmempool(txid,vout,refsbits,reffundingtxid,total-totalinputs)) > 0 )
|
||||||
|
{
|
||||||
|
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
||||||
|
fprintf(stderr,"added mempool vout for %.8f\n",(double)nValue/COIN);
|
||||||
|
totalinputs += nValue;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
return(totalinputs);
|
return(totalinputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t RewardsPlanFunds(uint64_t refsbits,struct CCcontract_info *cp,CPubKey pk,uint256 reffundingtxid)
|
int64_t RewardsPlanFunds(uint64_t &lockedfunds,uint64_t refsbits,struct CCcontract_info *cp,CPubKey pk,uint256 reffundingtxid)
|
||||||
{
|
{
|
||||||
char coinaddr[64]; uint64_t sbits,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t vout; uint8_t funcid;
|
char coinaddr[64]; uint64_t sbits; int64_t nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t vout; uint8_t funcid;
|
||||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||||
|
lockedfunds = 0;
|
||||||
GetCCaddress(cp,coinaddr,pk);
|
GetCCaddress(cp,coinaddr,pk);
|
||||||
SetCCunspents(unspentOutputs,coinaddr);
|
SetCCunspents(unspentOutputs,coinaddr);
|
||||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||||
@@ -319,12 +391,16 @@ uint64_t RewardsPlanFunds(uint64_t refsbits,struct CCcontract_info *cp,CPubKey p
|
|||||||
vout = (int32_t)it->first.index;
|
vout = (int32_t)it->first.index;
|
||||||
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||||
{
|
{
|
||||||
if ( (funcid= DecodeRewardsOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) != 0 )
|
if ( (funcid= DecodeRewardsOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) == 'F' || funcid == 'A' || funcid == 'U' || funcid == 'L' )
|
||||||
{
|
{
|
||||||
if ( (funcid == 'F' && reffundingtxid == txid) || reffundingtxid == fundingtxid )
|
if ( refsbits == sbits && (funcid == 'F' && reffundingtxid == txid) || reffundingtxid == fundingtxid )
|
||||||
{
|
{
|
||||||
if ( refsbits == sbits && (nValue= IsRewardsvout(cp,tx,vout)) > 0 )
|
if ( (nValue= IsRewardsvout(cp,tx,vout,sbits,fundingtxid)) > 0 )
|
||||||
totalinputs += nValue;
|
{
|
||||||
|
if ( funcid == 'L' )
|
||||||
|
lockedfunds += nValue;
|
||||||
|
else totalinputs += nValue;
|
||||||
|
}
|
||||||
else fprintf(stderr,"refsbits.%llx sbits.%llx nValue %.8f\n",(long long)refsbits,(long long)sbits,(double)nValue/COIN);
|
else fprintf(stderr,"refsbits.%llx sbits.%llx nValue %.8f\n",(long long)refsbits,(long long)sbits,(double)nValue/COIN);
|
||||||
} //else fprintf(stderr,"else case\n");
|
} //else fprintf(stderr,"else case\n");
|
||||||
} else fprintf(stderr,"funcid.%d %c skipped %.8f\n",funcid,funcid,(double)tx.vout[vout].nValue/COIN);
|
} else fprintf(stderr,"funcid.%d %c skipped %.8f\n",funcid,funcid,(double)tx.vout[vout].nValue/COIN);
|
||||||
@@ -358,16 +434,18 @@ bool RewardsPlanExists(struct CCcontract_info *cp,uint64_t refsbits,CPubKey rewa
|
|||||||
|
|
||||||
UniValue RewardsInfo(uint256 rewardsid)
|
UniValue RewardsInfo(uint256 rewardsid)
|
||||||
{
|
{
|
||||||
UniValue result(UniValue::VOBJ); uint256 hashBlock; CTransaction vintx; uint64_t APR,minseconds,maxseconds,mindeposit,sbits,funding; CPubKey rewardspk; struct CCcontract_info *cp,C; char str[67],numstr[65];
|
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 ( GetTransaction(rewardsid,vintx,hashBlock,false) == 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"cant find fundingtxid\n");
|
fprintf(stderr,"cant find fundingtxid\n");
|
||||||
|
result.push_back(Pair("result","error"));
|
||||||
result.push_back(Pair("error","cant find fundingtxid"));
|
result.push_back(Pair("error","cant find fundingtxid"));
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
if ( vintx.vout.size() > 0 && DecodeRewardsFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) == 0 )
|
if ( vintx.vout.size() > 0 && DecodeRewardsFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) == 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"fundingtxid isnt rewards creation txid\n");
|
fprintf(stderr,"fundingtxid isnt rewards creation txid\n");
|
||||||
|
result.push_back(Pair("result","error"));
|
||||||
result.push_back(Pair("error","fundingtxid isnt rewards creation txid"));
|
result.push_back(Pair("error","fundingtxid isnt rewards creation txid"));
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
@@ -384,9 +462,11 @@ UniValue RewardsInfo(uint256 rewardsid)
|
|||||||
result.push_back(Pair("mindeposit",numstr));
|
result.push_back(Pair("mindeposit",numstr));
|
||||||
cp = CCinit(&C,EVAL_REWARDS);
|
cp = CCinit(&C,EVAL_REWARDS);
|
||||||
rewardspk = GetUnspendable(cp,0);
|
rewardspk = GetUnspendable(cp,0);
|
||||||
funding = RewardsPlanFunds(sbits,cp,rewardspk,rewardsid);
|
funding = RewardsPlanFunds(lockedfunds,sbits,cp,rewardspk,rewardsid);
|
||||||
sprintf(numstr,"%.8f",(double)funding/COIN);
|
sprintf(numstr,"%.8f",(double)funding/COIN);
|
||||||
result.push_back(Pair("funding",numstr));
|
result.push_back(Pair("funding",numstr));
|
||||||
|
sprintf(numstr,"%.8f",(double)lockedfunds/COIN);
|
||||||
|
result.push_back(Pair("locked",numstr));
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,10 +492,15 @@ UniValue RewardsList()
|
|||||||
std::string RewardsCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t APR,int64_t minseconds,int64_t maxseconds,int64_t mindeposit)
|
std::string RewardsCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t APR,int64_t minseconds,int64_t maxseconds,int64_t mindeposit)
|
||||||
{
|
{
|
||||||
CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C;
|
CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C;
|
||||||
if ( funds < 0 || mindeposit < 0 || minseconds < 0 || maxseconds < 0 )
|
if ( funds < COIN || mindeposit < 0 || minseconds < 0 || maxseconds < 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"negative parameter error\n");
|
fprintf(stderr,"negative parameter error\n");
|
||||||
return(0);
|
return("");
|
||||||
|
}
|
||||||
|
if ( APR > REWARDSCC_MAXAPR )
|
||||||
|
{
|
||||||
|
fprintf(stderr,"25%% APR is maximum\n");
|
||||||
|
return("");
|
||||||
}
|
}
|
||||||
cp = CCinit(&C,EVAL_REWARDS);
|
cp = CCinit(&C,EVAL_REWARDS);
|
||||||
if ( txfee == 0 )
|
if ( txfee == 0 )
|
||||||
@@ -426,7 +511,7 @@ std::string RewardsCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int6
|
|||||||
if ( RewardsPlanExists(cp,sbits,rewardspk,a,b,c,d) != 0 )
|
if ( RewardsPlanExists(cp,sbits,rewardspk,a,b,c,d) != 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"Rewards plan (%s) already exists\n",planstr);
|
fprintf(stderr,"Rewards plan (%s) already exists\n",planstr);
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
if ( AddNormalinputs(mtx,mypk,funds+2*txfee,64) > 0 )
|
if ( AddNormalinputs(mtx,mypk,funds+2*txfee,64) > 0 )
|
||||||
{
|
{
|
||||||
@@ -435,7 +520,7 @@ std::string RewardsCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int6
|
|||||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeRewardsFundingOpRet('F',sbits,APR,minseconds,maxseconds,mindeposit)));
|
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeRewardsFundingOpRet('F',sbits,APR,minseconds,maxseconds,mindeposit)));
|
||||||
}
|
}
|
||||||
fprintf(stderr,"cant find enough inputs\n");
|
fprintf(stderr,"cant find enough inputs\n");
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string RewardsAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount)
|
std::string RewardsAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount)
|
||||||
@@ -444,7 +529,7 @@ std::string RewardsAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,i
|
|||||||
if ( amount < 0 )
|
if ( amount < 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"negative parameter error\n");
|
fprintf(stderr,"negative parameter error\n");
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
cp = CCinit(&C,EVAL_REWARDS);
|
cp = CCinit(&C,EVAL_REWARDS);
|
||||||
if ( txfee == 0 )
|
if ( txfee == 0 )
|
||||||
@@ -455,7 +540,7 @@ std::string RewardsAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,i
|
|||||||
if ( RewardsPlanExists(cp,sbits,rewardspk,a,b,c,d) == 0 )
|
if ( RewardsPlanExists(cp,sbits,rewardspk,a,b,c,d) == 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"Rewards plan %s doesnt exist\n",planstr);
|
fprintf(stderr,"Rewards plan %s doesnt exist\n",planstr);
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
sbits = stringbits(planstr);
|
sbits = stringbits(planstr);
|
||||||
if ( AddNormalinputs(mtx,mypk,amount+txfee,64) > 0 )
|
if ( AddNormalinputs(mtx,mypk,amount+txfee,64) > 0 )
|
||||||
@@ -464,16 +549,16 @@ std::string RewardsAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,i
|
|||||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeRewardsOpRet('A',sbits,fundingtxid)));
|
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeRewardsOpRet('A',sbits,fundingtxid)));
|
||||||
} else fprintf(stderr,"cant find enough inputs\n");
|
} else fprintf(stderr,"cant find enough inputs\n");
|
||||||
fprintf(stderr,"cant find fundingtxid\n");
|
fprintf(stderr,"cant find fundingtxid\n");
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string RewardsLock(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t deposit)
|
std::string RewardsLock(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t deposit)
|
||||||
{
|
{
|
||||||
CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,funding,APR,minseconds,maxseconds,mindeposit; struct CCcontract_info *cp,C;
|
CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t lockedfunds,sbits,funding,APR,minseconds,maxseconds,mindeposit; struct CCcontract_info *cp,C;
|
||||||
if ( deposit < 0 )
|
if ( deposit < txfee )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"negative parameter error\n");
|
fprintf(stderr,"deposit amount less than txfee\n");
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
cp = CCinit(&C,EVAL_REWARDS);
|
cp = CCinit(&C,EVAL_REWARDS);
|
||||||
if ( txfee == 0 )
|
if ( txfee == 0 )
|
||||||
@@ -484,29 +569,29 @@ std::string RewardsLock(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t
|
|||||||
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);
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
if ( deposit < mindeposit )
|
if ( deposit < mindeposit )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"Rewards plan %s deposit %.8f < mindeposit %.8f\n",planstr,(double)deposit/COIN,(double)mindeposit/COIN);
|
fprintf(stderr,"Rewards plan %s deposit %.8f < mindeposit %.8f\n",planstr,(double)deposit/COIN,(double)mindeposit/COIN);
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
if ( (funding= RewardsPlanFunds(sbits,cp,rewardspk,fundingtxid)) >= deposit ) // arbitrary cmpval
|
if ( (funding= RewardsPlanFunds(lockedfunds,sbits,cp,rewardspk,fundingtxid)) >= deposit ) // arbitrary cmpval
|
||||||
{
|
{
|
||||||
if ( AddNormalinputs(mtx,mypk,deposit+2*txfee,64) > 0 )
|
if ( AddNormalinputs(mtx,mypk,deposit+2*txfee,64) > 0 )
|
||||||
{
|
{
|
||||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,deposit,rewardspk));
|
mtx.vout.push_back(MakeCC1vout(cp->evalcode,deposit,rewardspk));
|
||||||
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeRewardsOpRet('L',sbits,fundingtxid)));
|
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeRewardsOpRet('L',sbits,fundingtxid)));
|
||||||
} else fprintf(stderr,"cant find enough inputs %.8f note enough for %.8f\n",(double)funding/COIN,(double)deposit/COIN);
|
} else fprintf(stderr,"cant find enough inputs %.8f not enough for %.8f, make sure you imported privkey for the -pubkey address\n",(double)funding/COIN,(double)deposit/COIN);
|
||||||
}
|
}
|
||||||
fprintf(stderr,"cant find rewards inputs\n");
|
fprintf(stderr,"cant find rewards inputs funding %.8f locked %.8f vs deposit %.8f\n",(double)funding/COIN,(double)lockedfunds/COIN,(double)deposit/COIN);
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string RewardsUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 locktxid)
|
std::string RewardsUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 locktxid)
|
||||||
{
|
{
|
||||||
CMutableTransaction mtx; CTransaction tx; char coinaddr[64]; CPubKey mypk,rewardspk; CScript opret,scriptPubKey,ignore; uint256 hashBlock; uint64_t funding,sbits,reward=0,amount=0,inputs,CCchange=0,APR,minseconds,maxseconds,mindeposit; struct CCcontract_info *cp,C;
|
CMutableTransaction mtx,firstmtx; CTransaction tx; char coinaddr[64]; CPubKey mypk,rewardspk; CScript scriptPubKey,ignore; uint256 hashBlock; uint64_t sbits,APR,minseconds,maxseconds,mindeposit; int64_t funding,reward=0,amount=0,inputs,CCchange=0; struct CCcontract_info *cp,C;
|
||||||
cp = CCinit(&C,EVAL_REWARDS);
|
cp = CCinit(&C,EVAL_REWARDS);
|
||||||
if ( txfee == 0 )
|
if ( txfee == 0 )
|
||||||
txfee = 10000;
|
txfee = 10000;
|
||||||
@@ -516,18 +601,20 @@ std::string RewardsUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint2
|
|||||||
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);
|
||||||
return(0);
|
CCerror = "Rewards plan does not exist";
|
||||||
|
return("");
|
||||||
}
|
}
|
||||||
fprintf(stderr,"APR %.8f minseconds.%llu maxseconds.%llu mindeposit %.8f\n",(double)APR/COIN,(long long)minseconds,(long long)maxseconds,(double)mindeposit/COIN);
|
fprintf(stderr,"APR %.8f minseconds.%llu maxseconds.%llu mindeposit %.8f\n",(double)APR/COIN,(long long)minseconds,(long long)maxseconds,(double)mindeposit/COIN);
|
||||||
if ( locktxid == zeroid )
|
if ( locktxid == zeroid )
|
||||||
amount = AddRewardsInputs(scriptPubKey,0,cp,mtx,rewardspk,(1LL << 30),1);
|
amount = AddRewardsInputs(scriptPubKey,maxseconds,cp,mtx,rewardspk,(1LL << 30),1,sbits,fundingtxid);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GetCCaddress(cp,coinaddr,rewardspk);
|
GetCCaddress(cp,coinaddr,rewardspk);
|
||||||
if ( (amount= CCutxovalue(coinaddr,locktxid,0)) == 0 )
|
if ( (amount= CCutxovalue(coinaddr,locktxid,0)) == 0 )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"%s locktxid/v0 is spent\n",coinaddr);
|
fprintf(stderr,"%s locktxid/v0 is spent\n",coinaddr);
|
||||||
return(0);
|
CCerror = "locktxid/v0 is spent";
|
||||||
|
return("");
|
||||||
}
|
}
|
||||||
if ( GetTransaction(locktxid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && tx.vout[1].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
if ( GetTransaction(locktxid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && tx.vout[1].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
||||||
{
|
{
|
||||||
@@ -537,23 +624,53 @@ std::string RewardsUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint2
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr,"%s no normal vout.1 in locktxid\n",coinaddr);
|
fprintf(stderr,"%s no normal vout.1 in locktxid\n",coinaddr);
|
||||||
return(0);
|
CCerror = "no normal vout.1 in locktxid";
|
||||||
|
return("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( amount > 0 && (reward= RewardsCalc(amount,mtx.vin[0].prevout.hash,APR,minseconds,maxseconds,mindeposit)) > txfee && scriptPubKey.size() > 0 )
|
if ( amount > txfee )
|
||||||
{
|
{
|
||||||
if ( (inputs= AddRewardsInputs(ignore,1,cp,mtx,rewardspk,reward+txfee,30)) > 0 )
|
reward = RewardsCalc(amount,mtx.vin[0].prevout.hash,APR,minseconds,maxseconds,mindeposit);
|
||||||
|
if ( scriptPubKey.size() > 0 )
|
||||||
{
|
{
|
||||||
if ( inputs >= (reward + 2*txfee) )
|
if ( reward > txfee )
|
||||||
CCchange = (inputs - (reward + txfee));
|
{
|
||||||
fprintf(stderr,"inputs %.8f CCchange %.8f amount %.8f reward %.8f\n",(double)inputs/COIN,(double)CCchange/COIN,(double)amount/COIN,(double)reward/COIN);
|
firstmtx = mtx;
|
||||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,rewardspk));
|
if ( (inputs= AddRewardsInputs(ignore,0,cp,mtx,rewardspk,reward+txfee,30,sbits,fundingtxid)) >= reward+txfee )
|
||||||
mtx.vout.push_back(CTxOut(amount+reward,scriptPubKey));
|
{
|
||||||
return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,EncodeRewardsOpRet('U',sbits,fundingtxid)));
|
if ( inputs >= (reward + 2*txfee) )
|
||||||
|
CCchange = (inputs - (reward + txfee));
|
||||||
|
fprintf(stderr,"inputs %.8f CCchange %.8f amount %.8f reward %.8f\n",(double)inputs/COIN,(double)CCchange/COIN,(double)amount/COIN,(double)reward/COIN);
|
||||||
|
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,rewardspk));
|
||||||
|
mtx.vout.push_back(CTxOut(amount+reward,scriptPubKey));
|
||||||
|
return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,EncodeRewardsOpRet('U',sbits,fundingtxid)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
firstmtx.vout.push_back(CTxOut(amount-txfee,scriptPubKey));
|
||||||
|
//CCerror = "cant find enough rewards inputs";
|
||||||
|
fprintf(stderr,"not enough rewards funds to payout %.8f, recover mode tx\n",(double)(reward+txfee)/COIN);
|
||||||
|
return(FinalizeCCTx(-1LL,cp,firstmtx,mypk,txfee,EncodeRewardsOpRet('U',sbits,fundingtxid)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCerror = strprintf("reward %.8f is <= the transaction fee", reward);
|
||||||
|
fprintf(stderr,"%s\n", CCerror.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fprintf(stderr,"cant find enough rewards inputs\n");
|
else
|
||||||
|
{
|
||||||
|
CCerror = "invalid scriptPubKey";
|
||||||
|
fprintf(stderr,"%s\n", CCerror.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCerror = "amount must be more than txfee";
|
||||||
|
fprintf(stderr,"%s\n", CCerror.c_str());
|
||||||
}
|
}
|
||||||
fprintf(stderr,"amount %.8f -> reward %.8f\n",(double)amount/COIN,(double)reward/COIN);
|
fprintf(stderr,"amount %.8f -> reward %.8f\n",(double)amount/COIN,(double)reward/COIN);
|
||||||
return(0);
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ public:
|
|||||||
|
|
||||||
//! height of the entry in the chain. The genesis block has height 0
|
//! height of the entry in the chain. The genesis block has height 0
|
||||||
int nHeight;
|
int nHeight;
|
||||||
int64_t newcoins,zfunds;
|
int64_t newcoins,zfunds; int8_t segid; // jl777 fields
|
||||||
//! Which # file this block is stored in (blk?????.dat)
|
//! Which # file this block is stored in (blk?????.dat)
|
||||||
int nFile;
|
int nFile;
|
||||||
|
|
||||||
@@ -182,6 +182,7 @@ public:
|
|||||||
{
|
{
|
||||||
phashBlock = NULL;
|
phashBlock = NULL;
|
||||||
newcoins = zfunds = 0;
|
newcoins = zfunds = 0;
|
||||||
|
segid = -2;
|
||||||
pprev = NULL;
|
pprev = NULL;
|
||||||
pskip = NULL;
|
pskip = NULL;
|
||||||
nHeight = 0;
|
nHeight = 0;
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ static void anonToJSON(const CC *cond, cJSON *params) {
|
|||||||
|
|
||||||
static unsigned char *anonFingerprint(const CC *cond) {
|
static unsigned char *anonFingerprint(const CC *cond) {
|
||||||
unsigned char *out = calloc(1, 32);
|
unsigned char *out = calloc(1, 32);
|
||||||
|
fprintf(stderr,"anon fingerprint %p %p\n",out,cond->fingerprint);
|
||||||
memcpy(out, cond->fingerprint, 32);
|
memcpy(out, cond->fingerprint, 32);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,11 +29,7 @@
|
|||||||
#include "src/json_rpc.c"
|
#include "src/json_rpc.c"
|
||||||
#include <cJSON.h>
|
#include <cJSON.h>
|
||||||
|
|
||||||
#ifdef __LP64__
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#else
|
|
||||||
#include <malloc.h> // Index into CTransaction.vjoinsplit
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
struct CCType *CCTypeRegistry[] = {
|
struct CCType *CCTypeRegistry[] = {
|
||||||
@@ -75,8 +71,7 @@ char *cc_conditionUri(const CC *cond) {
|
|||||||
unsigned char *encoded = base64_encode(fp, 32);
|
unsigned char *encoded = base64_encode(fp, 32);
|
||||||
|
|
||||||
unsigned char *out = calloc(1, 1000);
|
unsigned char *out = calloc(1, 1000);
|
||||||
sprintf(out, "ni:///sha-256;%s?fpt=%s&cost=%lu",
|
sprintf(out, "ni:///sha-256;%s?fpt=%s&cost=%lu",encoded, cc_typeName(cond), cc_getCost(cond));
|
||||||
encoded, cc_typeName(cond), cc_getCost(cond));
|
|
||||||
|
|
||||||
if (cond->type->getSubtypes) {
|
if (cond->type->getSubtypes) {
|
||||||
appendUriSubtypes(cond->type->getSubtypes(cond), out);
|
appendUriSubtypes(cond->type->getSubtypes(cond), out);
|
||||||
@@ -151,7 +146,6 @@ void asnCondition(const CC *cond, Condition_t *asn) {
|
|||||||
// This may look a little weird - we dont have a reference here to the correct
|
// This may look a little weird - we dont have a reference here to the correct
|
||||||
// union choice for the condition type, so we just assign everything to the threshold
|
// union choice for the condition type, so we just assign everything to the threshold
|
||||||
// type. This works out nicely since the union choices have the same binary interface.
|
// type. This works out nicely since the union choices have the same binary interface.
|
||||||
|
|
||||||
CompoundSha256Condition_t *choice = &asn->choice.thresholdSha256;
|
CompoundSha256Condition_t *choice = &asn->choice.thresholdSha256;
|
||||||
choice->cost = cc_getCost(cond);
|
choice->cost = cc_getCost(cond);
|
||||||
choice->fingerprint.buf = cond->type->fingerprint(cond);
|
choice->fingerprint.buf = cond->type->fingerprint(cond);
|
||||||
@@ -199,7 +193,7 @@ CC *fulfillmentToCC(Fulfillment_t *ffill) {
|
|||||||
|
|
||||||
CC *cc_readFulfillmentBinary(const unsigned char *ffill_bin, size_t ffill_bin_len) {
|
CC *cc_readFulfillmentBinary(const unsigned char *ffill_bin, size_t ffill_bin_len) {
|
||||||
CC *cond = 0;
|
CC *cond = 0;
|
||||||
unsigned char *buf = malloc(ffill_bin_len);
|
unsigned char *buf = calloc(1,ffill_bin_len);
|
||||||
Fulfillment_t *ffill = 0;
|
Fulfillment_t *ffill = 0;
|
||||||
asn_dec_rval_t rval = ber_decode(0, &asn_DEF_Fulfillment, (void **)&ffill, ffill_bin, ffill_bin_len);
|
asn_dec_rval_t rval = ber_decode(0, &asn_DEF_Fulfillment, (void **)&ffill, ffill_bin, ffill_bin_len);
|
||||||
if (rval.code != RC_OK) {
|
if (rval.code != RC_OK) {
|
||||||
@@ -236,12 +230,14 @@ int cc_verify(const struct CC *cond, const unsigned char *msg, size_t msgLength,
|
|||||||
const unsigned char *condBin, size_t condBinLength,
|
const unsigned char *condBin, size_t condBinLength,
|
||||||
VerifyEval verifyEval, void *evalContext) {
|
VerifyEval verifyEval, void *evalContext) {
|
||||||
unsigned char targetBinary[1000];
|
unsigned char targetBinary[1000];
|
||||||
|
//fprintf(stderr,"in cc_verify cond.%p msg.%p[%d] dohash.%d condbin.%p[%d]\n",cond,msg,(int32_t)msgLength,doHashMsg,condBin,(int32_t)condBinLength);
|
||||||
const size_t binLength = cc_conditionBinary(cond, targetBinary);
|
const size_t binLength = cc_conditionBinary(cond, targetBinary);
|
||||||
if (0 != memcmp(condBin, targetBinary, binLength)) {
|
if (0 != memcmp(condBin, targetBinary, binLength)) {
|
||||||
|
fprintf(stderr,"cc_verify error A\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cc_ed25519VerifyTree(cond, msg, msgLength)) {
|
if (!cc_ed25519VerifyTree(cond, msg, msgLength)) {
|
||||||
|
fprintf(stderr,"cc_verify error B\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,10 +246,12 @@ int cc_verify(const struct CC *cond, const unsigned char *msg, size_t msgLength,
|
|||||||
else memcpy(msgHash, msg, 32);
|
else memcpy(msgHash, msg, 32);
|
||||||
|
|
||||||
if (!cc_secp256k1VerifyTreeMsg32(cond, msgHash)) {
|
if (!cc_secp256k1VerifyTreeMsg32(cond, msgHash)) {
|
||||||
|
fprintf(stderr,"cc_verify error C\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cc_verifyEval(cond, verifyEval, evalContext)) {
|
if (!cc_verifyEval(cond, verifyEval, evalContext)) {
|
||||||
|
//fprintf(stderr,"cc_verify error D\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ struct CCType CC_Ed25519Type;
|
|||||||
|
|
||||||
static unsigned char *ed25519Fingerprint(const CC *cond) {
|
static unsigned char *ed25519Fingerprint(const CC *cond) {
|
||||||
Ed25519FingerprintContents_t *fp = calloc(1, sizeof(Ed25519FingerprintContents_t));
|
Ed25519FingerprintContents_t *fp = calloc(1, sizeof(Ed25519FingerprintContents_t));
|
||||||
|
//fprintf(stderr,"ed25519 fingerprint %p %p\n",fp,cond->publicKey);
|
||||||
OCTET_STRING_fromBuf(&fp->publicKey, cond->publicKey, 32);
|
OCTET_STRING_fromBuf(&fp->publicKey, cond->publicKey, 32);
|
||||||
return hashFingerprintContents(&asn_DEF_Ed25519FingerprintContents, fp);
|
return hashFingerprintContents(&asn_DEF_Ed25519FingerprintContents, fp);
|
||||||
}
|
}
|
||||||
@@ -62,7 +63,7 @@ static int ed25519Sign(CC *cond, CCVisitor visitor) {
|
|||||||
if (cond->type->typeId != CC_Ed25519Type.typeId) return 1;
|
if (cond->type->typeId != CC_Ed25519Type.typeId) return 1;
|
||||||
CCEd25519SigningData *signing = (CCEd25519SigningData*) visitor.context;
|
CCEd25519SigningData *signing = (CCEd25519SigningData*) visitor.context;
|
||||||
if (0 != memcmp(cond->publicKey, signing->pk, 32)) return 1;
|
if (0 != memcmp(cond->publicKey, signing->pk, 32)) return 1;
|
||||||
if (!cond->signature) cond->signature = malloc(64);
|
if (!cond->signature) cond->signature = calloc(1,64);
|
||||||
ed25519_sign(cond->signature, visitor.msg, visitor.msgLength,
|
ed25519_sign(cond->signature, visitor.msg, visitor.msgLength,
|
||||||
signing->pk, signing->skpk);
|
signing->pk, signing->skpk);
|
||||||
signing->nSigned++;
|
signing->nSigned++;
|
||||||
@@ -141,9 +142,9 @@ static void ed25519ToJSON(const CC *cond, cJSON *params) {
|
|||||||
|
|
||||||
static CC *ed25519FromFulfillment(const Fulfillment_t *ffill) {
|
static CC *ed25519FromFulfillment(const Fulfillment_t *ffill) {
|
||||||
CC *cond = cc_new(CC_Ed25519);
|
CC *cond = cc_new(CC_Ed25519);
|
||||||
cond->publicKey = malloc(32);
|
cond->publicKey = calloc(1,32);
|
||||||
memcpy(cond->publicKey, ffill->choice.ed25519Sha256.publicKey.buf, 32);
|
memcpy(cond->publicKey, ffill->choice.ed25519Sha256.publicKey.buf, 32);
|
||||||
cond->signature = malloc(64);
|
cond->signature = calloc(1,64);
|
||||||
memcpy(cond->signature, ffill->choice.ed25519Sha256.signature.buf, 64);
|
memcpy(cond->signature, ffill->choice.ed25519Sha256.signature.buf, 64);
|
||||||
return cond;
|
return cond;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ struct CCType CC_EvalType;
|
|||||||
|
|
||||||
static unsigned char *evalFingerprint(const CC *cond) {
|
static unsigned char *evalFingerprint(const CC *cond) {
|
||||||
unsigned char *hash = calloc(1, 32);
|
unsigned char *hash = calloc(1, 32);
|
||||||
|
//fprintf(stderr,"evalfingerprint %p %p\n",hash,cond->code);
|
||||||
sha256(cond->code, cond->codeLength, hash);
|
sha256(cond->code, cond->codeLength, hash);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
@@ -68,7 +69,7 @@ static CC *evalFromFulfillment(const Fulfillment_t *ffill) {
|
|||||||
|
|
||||||
OCTET_STRING_t octets = eval->code;
|
OCTET_STRING_t octets = eval->code;
|
||||||
cond->codeLength = octets.size;
|
cond->codeLength = octets.size;
|
||||||
cond->code = malloc(octets.size);
|
cond->code = calloc(1,octets.size);
|
||||||
memcpy(cond->code, octets.buf, octets.size);
|
memcpy(cond->code, octets.buf, octets.size);
|
||||||
|
|
||||||
return cond;
|
return cond;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define BUF_SIZE 1024 * 1024
|
#define BUF_SIZE 4096
|
||||||
|
|
||||||
typedef char bool;
|
typedef char bool;
|
||||||
|
|
||||||
@@ -56,8 +56,8 @@ typedef struct CCType {
|
|||||||
/*
|
/*
|
||||||
* Globals
|
* Globals
|
||||||
*/
|
*/
|
||||||
struct CCType *CCTypeRegistry[32];
|
extern struct CCType *CCTypeRegistry[];
|
||||||
int CCTypeRegistryLength;
|
extern int CCTypeRegistryLength;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -17,11 +17,8 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include <cJSON.h>
|
#include <cJSON.h>
|
||||||
|
|
||||||
#ifdef __LP64__
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#else
|
|
||||||
#include <malloc.h> // Index into CTransaction.vjoinsplit
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static cJSON *jsonCondition(CC *cond) {
|
static cJSON *jsonCondition(CC *cond) {
|
||||||
cJSON *root = cJSON_CreateObject();
|
cJSON *root = cJSON_CreateObject();
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ struct CCType CC_PrefixType;
|
|||||||
|
|
||||||
static int prefixVisitChildren(CC *cond, CCVisitor visitor) {
|
static int prefixVisitChildren(CC *cond, CCVisitor visitor) {
|
||||||
size_t prefixedLength = cond->prefixLength + visitor.msgLength;
|
size_t prefixedLength = cond->prefixLength + visitor.msgLength;
|
||||||
unsigned char *prefixed = malloc(prefixedLength);
|
unsigned char *prefixed = calloc(1,prefixedLength);
|
||||||
memcpy(prefixed, cond->prefix, cond->prefixLength);
|
memcpy(prefixed, cond->prefix, cond->prefixLength);
|
||||||
memcpy(prefixed + cond->prefixLength, visitor.msg, visitor.msgLength);
|
memcpy(prefixed + cond->prefixLength, visitor.msg, visitor.msgLength);
|
||||||
visitor.msg = prefixed;
|
visitor.msg = prefixed;
|
||||||
@@ -39,6 +39,7 @@ static int prefixVisitChildren(CC *cond, CCVisitor visitor) {
|
|||||||
|
|
||||||
static unsigned char *prefixFingerprint(const CC *cond) {
|
static unsigned char *prefixFingerprint(const CC *cond) {
|
||||||
PrefixFingerprintContents_t *fp = calloc(1, sizeof(PrefixFingerprintContents_t));
|
PrefixFingerprintContents_t *fp = calloc(1, sizeof(PrefixFingerprintContents_t));
|
||||||
|
//fprintf(stderr,"prefixfinger %p %p\n",fp,cond->prefix);
|
||||||
asnCondition(cond->subcondition, &fp->subcondition); // TODO: check asnCondition for safety
|
asnCondition(cond->subcondition, &fp->subcondition); // TODO: check asnCondition for safety
|
||||||
fp->maxMessageLength = cond->maxMessageLength;
|
fp->maxMessageLength = cond->maxMessageLength;
|
||||||
OCTET_STRING_fromBuf(&fp->prefix, cond->prefix, cond->prefixLength);
|
OCTET_STRING_fromBuf(&fp->prefix, cond->prefix, cond->prefixLength);
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ static unsigned long preimageCost(const CC *cond) {
|
|||||||
|
|
||||||
static unsigned char *preimageFingerprint(const CC *cond) {
|
static unsigned char *preimageFingerprint(const CC *cond) {
|
||||||
unsigned char *hash = calloc(1, 32);
|
unsigned char *hash = calloc(1, 32);
|
||||||
|
//fprintf(stderr,"preimage %p %p\n",hash,cond->preimage);
|
||||||
sha256(cond->preimage, cond->preimageLength, hash);
|
sha256(cond->preimage, cond->preimageLength, hash);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,9 +45,11 @@ void lockSign() {
|
|||||||
int read = (int) fread(&ent, 1, 32, fp);
|
int read = (int) fread(&ent, 1, 32, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
#endif
|
#endif
|
||||||
if (read != 32) {
|
if (read != 32)
|
||||||
fprintf(stderr, "Could not read 32 bytes entropy from system\n");
|
{
|
||||||
exit(1);
|
int32_t i;
|
||||||
|
for (i=0; i<32; i++)
|
||||||
|
((uint8_t *)ent)[i] = rand();
|
||||||
}
|
}
|
||||||
if (!secp256k1_context_randomize(ec_ctx_sign, ent)) {
|
if (!secp256k1_context_randomize(ec_ctx_sign, ent)) {
|
||||||
fprintf(stderr, "Could not randomize secp256k1 context\n");
|
fprintf(stderr, "Could not randomize secp256k1 context\n");
|
||||||
@@ -73,6 +75,7 @@ void initVerify() {
|
|||||||
|
|
||||||
static unsigned char *secp256k1Fingerprint(const CC *cond) {
|
static unsigned char *secp256k1Fingerprint(const CC *cond) {
|
||||||
Secp256k1FingerprintContents_t *fp = calloc(1, sizeof(Secp256k1FingerprintContents_t));
|
Secp256k1FingerprintContents_t *fp = calloc(1, sizeof(Secp256k1FingerprintContents_t));
|
||||||
|
//fprintf(stderr,"secpfinger %p %p size %d vs %d\n",fp,cond->publicKey,(int32_t)sizeof(Secp256k1FingerprintContents_t),(int32_t)SECP256K1_PK_SIZE);
|
||||||
OCTET_STRING_fromBuf(&fp->publicKey, cond->publicKey, SECP256K1_PK_SIZE);
|
OCTET_STRING_fromBuf(&fp->publicKey, cond->publicKey, SECP256K1_PK_SIZE);
|
||||||
return hashFingerprintContents(&asn_DEF_Secp256k1FingerprintContents, fp);
|
return hashFingerprintContents(&asn_DEF_Secp256k1FingerprintContents, fp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ static int cmpConditionBin(const void *a, const void *b) {
|
|||||||
static unsigned char *thresholdFingerprint(const CC *cond) {
|
static unsigned char *thresholdFingerprint(const CC *cond) {
|
||||||
/* Create fingerprint */
|
/* Create fingerprint */
|
||||||
ThresholdFingerprintContents_t *fp = calloc(1, sizeof(ThresholdFingerprintContents_t));
|
ThresholdFingerprintContents_t *fp = calloc(1, sizeof(ThresholdFingerprintContents_t));
|
||||||
|
//fprintf(stderr,"thresholdfinger %p\n",fp);
|
||||||
fp->threshold = cond->threshold;
|
fp->threshold = cond->threshold;
|
||||||
for (int i=0; i<cond->size; i++) {
|
for (int i=0; i<cond->size; i++) {
|
||||||
Condition_t *asnCond = asnConditionNew(cond->subconditions[i]);
|
Condition_t *asnCond = asnConditionNew(cond->subconditions[i]);
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ static int mod_table[] = {0, 2, 1};
|
|||||||
|
|
||||||
|
|
||||||
void build_decoding_table() {
|
void build_decoding_table() {
|
||||||
decoding_table = malloc(256);
|
decoding_table = calloc(1,256);
|
||||||
for (int i = 0; i < 64; i++)
|
for (int i = 0; i < 64; i++)
|
||||||
decoding_table[(unsigned char) encoding_table[i]] = i;
|
decoding_table[(unsigned char) encoding_table[i]] = i;
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ unsigned char *base64_encode(const unsigned char *data, size_t input_length) {
|
|||||||
|
|
||||||
size_t output_length = 4 * ((input_length + 2) / 3);
|
size_t output_length = 4 * ((input_length + 2) / 3);
|
||||||
|
|
||||||
unsigned char *encoded_data = malloc(output_length + 1);
|
unsigned char *encoded_data = calloc(1,output_length + 1);
|
||||||
if (encoded_data == NULL) return NULL;
|
if (encoded_data == NULL) return NULL;
|
||||||
|
|
||||||
for (int i = 0, j = 0; i < input_length;) {
|
for (int i = 0, j = 0; i < input_length;) {
|
||||||
@@ -90,7 +90,7 @@ unsigned char *base64_decode(const unsigned char *data_,
|
|||||||
|
|
||||||
size_t input_length = strlen(data_);
|
size_t input_length = strlen(data_);
|
||||||
int rem = input_length % 4;
|
int rem = input_length % 4;
|
||||||
unsigned char *data = malloc(input_length + (4-rem));
|
unsigned char *data = calloc(1,input_length + (4-rem));
|
||||||
strcpy(data, data_);
|
strcpy(data, data_);
|
||||||
|
|
||||||
// for unpadded b64
|
// for unpadded b64
|
||||||
@@ -111,7 +111,7 @@ unsigned char *base64_decode(const unsigned char *data_,
|
|||||||
if (data[input_length - 1] == '=') (*output_length)--;
|
if (data[input_length - 1] == '=') (*output_length)--;
|
||||||
if (data[input_length - 2] == '=') (*output_length)--;
|
if (data[input_length - 2] == '=') (*output_length)--;
|
||||||
|
|
||||||
unsigned char *decoded_data = malloc(*output_length);
|
unsigned char *decoded_data = calloc(1,*output_length);
|
||||||
if (decoded_data == NULL) return NULL;
|
if (decoded_data == NULL) return NULL;
|
||||||
|
|
||||||
for (int i = 0, j = 0; i < input_length;) {
|
for (int i = 0, j = 0; i < input_length;) {
|
||||||
@@ -137,6 +137,7 @@ unsigned char *base64_decode(const unsigned char *data_,
|
|||||||
|
|
||||||
void base64_cleanup() {
|
void base64_cleanup() {
|
||||||
free(decoding_table);
|
free(decoding_table);
|
||||||
|
decoding_table = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -217,7 +218,7 @@ unsigned char *hashFingerprintContents(asn_TYPE_descriptor_t *asnType, void *fp)
|
|||||||
fprintf(stderr, "Encoding fingerprint failed\n");
|
fprintf(stderr, "Encoding fingerprint failed\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
unsigned char *hash = malloc(32);
|
unsigned char *hash = calloc(1,32);
|
||||||
sha256(buf, rc.encoded, hash);
|
sha256(buf, rc.encoded, hash);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
@@ -225,7 +226,7 @@ unsigned char *hashFingerprintContents(asn_TYPE_descriptor_t *asnType, void *fp)
|
|||||||
|
|
||||||
char* cc_hex_encode(const uint8_t *bin, size_t len)
|
char* cc_hex_encode(const uint8_t *bin, size_t len)
|
||||||
{
|
{
|
||||||
char* hex = malloc(len*2+1);
|
char* hex = calloc(1,len*2+1);
|
||||||
if (bin == NULL) return hex;
|
if (bin == NULL) return hex;
|
||||||
char map[16] = "0123456789ABCDEF";
|
char map[16] = "0123456789ABCDEF";
|
||||||
for (int i=0; i<len; i++) {
|
for (int i=0; i<len; i++) {
|
||||||
|
|||||||
@@ -427,7 +427,7 @@ void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotar
|
|||||||
errs++;
|
errs++;
|
||||||
if ( fwrite(opretbuf,1,olen,fp) != olen )
|
if ( fwrite(opretbuf,1,olen,fp) != olen )
|
||||||
errs++;
|
errs++;
|
||||||
printf("create ht.%d R opret[%d] sp.%p\n",height,olen,sp);
|
//printf("create ht.%d R opret[%d] sp.%p\n",height,olen,sp);
|
||||||
//komodo_opreturn(height,opretvalue,opretbuf,olen,txhash,vout);
|
//komodo_opreturn(height,opretvalue,opretbuf,olen,txhash,vout);
|
||||||
komodo_eventadd_opreturn(sp,symbol,height,txhash,opretvalue,vout,opretbuf,olen);
|
komodo_eventadd_opreturn(sp,symbol,height,txhash,opretvalue,vout,opretbuf,olen);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1105,7 +1105,6 @@ int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_
|
|||||||
commission must be in coinbase.vout[1] and must be >= 10000 sats
|
commission must be in coinbase.vout[1] and must be >= 10000 sats
|
||||||
PoS stake must be without txfee and in the last tx in the block at vout[0]
|
PoS stake must be without txfee and in the last tx in the block at vout[0]
|
||||||
*/
|
*/
|
||||||
//#define KOMODO_POWMINMULT 16
|
|
||||||
|
|
||||||
uint64_t komodo_commission(const CBlock *pblock)
|
uint64_t komodo_commission(const CBlock *pblock)
|
||||||
{
|
{
|
||||||
@@ -1135,11 +1134,13 @@ uint32_t komodo_segid32(char *coinaddr)
|
|||||||
return(addrhash.uints[0]);
|
return(addrhash.uints[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t komodo_segid(int32_t height)
|
int8_t komodo_segid(int32_t nocache,int32_t height)
|
||||||
{
|
{
|
||||||
CTxDestination voutaddress; CBlock block; CBlockIndex *pindex; uint64_t value; uint32_t txtime; char voutaddr[64],destaddr[64]; int32_t txn_count,vout; uint256 txid; int8_t segid = -1;
|
CTxDestination voutaddress; CBlock block; CBlockIndex *pindex; uint64_t value; uint32_t txtime; char voutaddr[64],destaddr[64]; int32_t txn_count,vout; uint256 txid; int8_t segid = -1;
|
||||||
if ( height > 0 && (pindex= komodo_chainactive(height)) != 0 )
|
if ( height > 0 && (pindex= komodo_chainactive(height)) != 0 )
|
||||||
{
|
{
|
||||||
|
if ( nocache == 0 && pindex->segid >= -1 )
|
||||||
|
return(pindex->segid);
|
||||||
if ( komodo_blockload(block,pindex) == 0 )
|
if ( komodo_blockload(block,pindex) == 0 )
|
||||||
{
|
{
|
||||||
txn_count = block.vtx.size();
|
txn_count = block.vtx.size();
|
||||||
@@ -1154,6 +1155,7 @@ int8_t komodo_segid(int32_t height)
|
|||||||
if ( strcmp(destaddr,voutaddr) == 0 && block.vtx[txn_count-1].vout[0].nValue == value )
|
if ( strcmp(destaddr,voutaddr) == 0 && block.vtx[txn_count-1].vout[0].nValue == value )
|
||||||
{
|
{
|
||||||
segid = komodo_segid32(voutaddr) & 0x3f;
|
segid = komodo_segid32(voutaddr) & 0x3f;
|
||||||
|
//fprintf(stderr,"komodo_segid.(%d) -> %02x\n",height,segid);
|
||||||
}
|
}
|
||||||
} else fprintf(stderr,"komodo_segid ht.%d couldnt extract voutaddress\n",height);
|
} else fprintf(stderr,"komodo_segid ht.%d couldnt extract voutaddress\n",height);
|
||||||
}
|
}
|
||||||
@@ -1173,7 +1175,7 @@ int32_t komodo_segids(uint8_t *hashbuf,int32_t height,int32_t n)
|
|||||||
memset(hashbuf,0xff,n);
|
memset(hashbuf,0xff,n);
|
||||||
for (i=0; i<n; i++)
|
for (i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
hashbuf[i] = (uint8_t)komodo_segid(height+i);
|
hashbuf[i] = (uint8_t)komodo_segid(1,height+i);
|
||||||
//fprintf(stderr,"%02x ",hashbuf[i]);
|
//fprintf(stderr,"%02x ",hashbuf[i]);
|
||||||
}
|
}
|
||||||
if ( n == 100 )
|
if ( n == 100 )
|
||||||
@@ -1224,13 +1226,6 @@ uint32_t komodo_stake(int32_t validateflag,arith_uint256 bnTarget,int32_t nHeigh
|
|||||||
komodo_segids(hashbuf,nHeight-101,100);
|
komodo_segids(hashbuf,nHeight-101,100);
|
||||||
segid32 = komodo_stakehash(&hash,address,hashbuf,txid,vout);
|
segid32 = komodo_stakehash(&hash,address,hashbuf,txid,vout);
|
||||||
segid = ((nHeight + segid32) & 0x3f);
|
segid = ((nHeight + segid32) & 0x3f);
|
||||||
/*vcalc_sha256(0,(uint8_t *)&addrhash,(uint8_t *)address,(int32_t)strlen(address));
|
|
||||||
segid = ((nHeight + addrhash.uints[0]) & 0x3f);
|
|
||||||
komodo_segids(hashbuf,nHeight-101,100);
|
|
||||||
memcpy(&hashbuf[100],&addrhash,sizeof(addrhash));
|
|
||||||
memcpy(&hashbuf[100+sizeof(addrhash)],&txid,sizeof(txid));
|
|
||||||
memcpy(&hashbuf[100+sizeof(addrhash)+sizeof(txid)],&vout,sizeof(vout));
|
|
||||||
vcalc_sha256(0,(uint8_t *)&hash,hashbuf,100 + (int32_t)sizeof(uint256)*2 + sizeof(vout));*/
|
|
||||||
for (iter=0; iter<600; iter++)
|
for (iter=0; iter<600; iter++)
|
||||||
{
|
{
|
||||||
if ( blocktime+iter+segid*2 < txtime+minage )
|
if ( blocktime+iter+segid*2 < txtime+minage )
|
||||||
@@ -1248,12 +1243,8 @@ uint32_t komodo_stake(int32_t validateflag,arith_uint256 bnTarget,int32_t nHeigh
|
|||||||
coinage = (value * diff);
|
coinage = (value * diff);
|
||||||
if ( blocktime+iter+segid*2 > prevtime+480 )
|
if ( blocktime+iter+segid*2 > prevtime+480 )
|
||||||
coinage *= ((blocktime+iter+segid*2) - (prevtime+400));
|
coinage *= ((blocktime+iter+segid*2) - (prevtime+400));
|
||||||
//if ( nHeight >= 2500 && blocktime+iter+segid*2 > prevtime+180 )
|
|
||||||
// coinage *= ((blocktime+iter+segid*2) - (prevtime+60));
|
|
||||||
coinage256 = arith_uint256(coinage+1);
|
coinage256 = arith_uint256(coinage+1);
|
||||||
hashval = ratio * (UintToArith256(hash) / coinage256);
|
hashval = ratio * (UintToArith256(hash) / coinage256);
|
||||||
//if ( nHeight >= 900 && nHeight < 916 )
|
|
||||||
// hashval = (hashval / coinage256);
|
|
||||||
if ( hashval <= bnTarget )
|
if ( hashval <= bnTarget )
|
||||||
{
|
{
|
||||||
winner = 1;
|
winner = 1;
|
||||||
@@ -1308,7 +1299,7 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he
|
|||||||
continue;
|
continue;
|
||||||
if ( (pindex= komodo_chainactive(ht)) != 0 )
|
if ( (pindex= komodo_chainactive(ht)) != 0 )
|
||||||
{
|
{
|
||||||
if ( komodo_segid(ht) >= 0 )
|
if ( komodo_segid(0,ht) >= 0 )
|
||||||
{
|
{
|
||||||
n++;
|
n++;
|
||||||
percPoS++;
|
percPoS++;
|
||||||
@@ -1323,26 +1314,6 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he
|
|||||||
m++;
|
m++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*if ( (pindex= komodo_chainactive(ht)) != 0 )
|
|
||||||
{
|
|
||||||
bnTarget.SetCompact(pindex->nBits,&fNegative,&fOverflow);
|
|
||||||
bnTarget = (bnTarget / arith_uint256(KOMODO_POWMINMULT));
|
|
||||||
hashval = UintToArith256(pindex->GetBlockHash());
|
|
||||||
if ( hashval <= bnTarget ) // PoW is never as easy as PoS/16, some PoS will be counted as PoW
|
|
||||||
{
|
|
||||||
if ( ASSETCHAINS_STAKED < 100 )
|
|
||||||
fprintf(stderr,"1");
|
|
||||||
sum += hashval;
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
n++;
|
|
||||||
percPoS++;
|
|
||||||
if ( ASSETCHAINS_STAKED < 100 )
|
|
||||||
fprintf(stderr,"0");
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
if ( ASSETCHAINS_STAKED < 100 && (i % 10) == 9 )
|
if ( ASSETCHAINS_STAKED < 100 && (i % 10) == 9 )
|
||||||
fprintf(stderr," %d, ",percPoS);
|
fprintf(stderr," %d, ",percPoS);
|
||||||
}
|
}
|
||||||
@@ -1351,20 +1322,21 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he
|
|||||||
if ( ASSETCHAINS_STAKED < 100 )
|
if ( ASSETCHAINS_STAKED < 100 )
|
||||||
fprintf(stderr," -> %d%% percPoS vs goalperc.%d ht.%d\n",percPoS,goalperc,height);
|
fprintf(stderr," -> %d%% percPoS vs goalperc.%d ht.%d\n",percPoS,goalperc,height);
|
||||||
*percPoSp = percPoS;
|
*percPoSp = percPoS;
|
||||||
//target = (target / arith_uint256(KOMODO_POWMINMULT));
|
|
||||||
if ( m > 0 )
|
if ( m > 0 )
|
||||||
{
|
{
|
||||||
ave = (sum / arith_uint256(m));
|
ave = (sum / arith_uint256(m));
|
||||||
if ( ave > target )
|
if ( ave > target )
|
||||||
ave = target;
|
ave = target;
|
||||||
} else ave = easydiff; //else return(target);
|
} else ave = target; //easydiff; //else return(target);
|
||||||
if ( percPoS == 0 )
|
if ( percPoS == 0 )
|
||||||
percPoS = 1;
|
percPoS = 1;
|
||||||
if ( percPoS < goalperc ) // increase PoW diff -> lower bnTarget
|
if ( percPoS < goalperc ) // increase PoW diff -> lower bnTarget
|
||||||
{
|
{
|
||||||
|
//if ( oldflag != 0 )
|
||||||
|
// bnTarget = (ave * arith_uint256(percPoS * percPoS)) / arith_uint256(goalperc * goalperc * goalperc);
|
||||||
if ( oldflag != 0 )
|
if ( oldflag != 0 )
|
||||||
bnTarget = (ave * arith_uint256(percPoS * percPoS)) / arith_uint256(goalperc * goalperc * goalperc);
|
bnTarget = (ave / arith_uint256(goalperc * goalperc * goalperc)) * arith_uint256(percPoS * percPoS);
|
||||||
else bnTarget = (ave / arith_uint256(goalperc * goalperc * goalperc)) * arith_uint256(percPoS * percPoS);
|
else bnTarget = (ave / arith_uint256(goalperc * goalperc * goalperc * goalperc)) * arith_uint256(percPoS * percPoS);
|
||||||
if ( ASSETCHAINS_STAKED < 100 )
|
if ( ASSETCHAINS_STAKED < 100 )
|
||||||
{
|
{
|
||||||
for (i=31; i>=24; i--)
|
for (i=31; i>=24; i--)
|
||||||
@@ -1385,7 +1357,8 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he
|
|||||||
bnTarget = ((ave * arith_uint256(goalperc)) + (easydiff * arith_uint256(percPoS))) / arith_uint256(percPoS + goalperc);
|
bnTarget = ((ave * arith_uint256(goalperc)) + (easydiff * arith_uint256(percPoS))) / arith_uint256(percPoS + goalperc);
|
||||||
//bnTarget = (bnTarget * arith_uint256(percPoS * percPoS * percPoS)) / arith_uint256(goalperc * goalperc);
|
//bnTarget = (bnTarget * arith_uint256(percPoS * percPoS * percPoS)) / arith_uint256(goalperc * goalperc);
|
||||||
bnTarget = (bnTarget / arith_uint256(goalperc * goalperc)) * arith_uint256(percPoS * percPoS * percPoS);
|
bnTarget = (bnTarget / arith_uint256(goalperc * goalperc)) * arith_uint256(percPoS * percPoS * percPoS);
|
||||||
} else bnTarget = (ave / arith_uint256(goalperc * goalperc)) * arith_uint256(percPoS * percPoS * percPoS);
|
}
|
||||||
|
else bnTarget = (ave / arith_uint256(goalperc * goalperc)) * arith_uint256(percPoS * percPoS * percPoS);
|
||||||
if ( bnTarget > easydiff )
|
if ( bnTarget > easydiff )
|
||||||
bnTarget = easydiff;
|
bnTarget = easydiff;
|
||||||
else if ( bnTarget < ave ) // overflow
|
else if ( bnTarget < ave ) // overflow
|
||||||
@@ -1411,11 +1384,18 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he
|
|||||||
return(bnTarget);
|
return(bnTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_uint256 bnTarget)
|
int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_uint256 bnTarget,arith_uint256 bhash)
|
||||||
{
|
{
|
||||||
CBlockIndex *previndex; char voutaddr[64],destaddr[64]; uint256 txid; uint32_t txtime,prevtime=0; int32_t vout,txn_count,eligible=0,isPoS = 0; uint64_t value; CTxDestination voutaddress;
|
CBlockIndex *previndex,*pindex; char voutaddr[64],destaddr[64]; uint256 txid; uint32_t txtime,prevtime=0; int32_t vout,PoSperc,txn_count,eligible=0,isPoS = 0,segid; uint64_t value; CTxDestination voutaddress;
|
||||||
if ( ASSETCHAINS_STAKED == 100 && height <= 10 )
|
if ( ASSETCHAINS_STAKED == 100 && height <= 10 )
|
||||||
return(1);
|
return(1);
|
||||||
|
pindex = mapBlockIndex[pblock->GetHash()];
|
||||||
|
if ( pindex != 0 && pindex->segid >= -1 )
|
||||||
|
{
|
||||||
|
if ( pindex->segid == -1 )
|
||||||
|
return(0);
|
||||||
|
else return(1);
|
||||||
|
}
|
||||||
txn_count = pblock->vtx.size();
|
txn_count = pblock->vtx.size();
|
||||||
if ( txn_count > 1 && pblock->vtx[txn_count-1].vin.size() == 1 && pblock->vtx[txn_count-1].vout.size() == 1 )
|
if ( txn_count > 1 && pblock->vtx[txn_count-1].vin.size() == 1 && pblock->vtx[txn_count-1].vout.size() == 1 )
|
||||||
{
|
{
|
||||||
@@ -1429,29 +1409,59 @@ int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_
|
|||||||
if ( prevtime != 0 )
|
if ( prevtime != 0 )
|
||||||
{
|
{
|
||||||
if ( komodo_isPoS(pblock) != 0 )
|
if ( komodo_isPoS(pblock) != 0 )
|
||||||
|
{
|
||||||
eligible = komodo_stake(1,bnTarget,height,txid,vout,pblock->nTime,prevtime+27,(char *)"");
|
eligible = komodo_stake(1,bnTarget,height,txid,vout,pblock->nTime,prevtime+27,(char *)"");
|
||||||
|
}
|
||||||
if ( eligible == 0 || eligible > pblock->nTime )
|
if ( eligible == 0 || eligible > pblock->nTime )
|
||||||
{
|
{
|
||||||
if ( ASSETCHAINS_STAKED < 100 )
|
if ( 0 && ASSETCHAINS_STAKED < 100 )
|
||||||
fprintf(stderr,"komodo_is_PoSblock PoS failure ht.%d eligible.%u vs blocktime.%u, lag.%d -> check to see if it is PoW block\n",height,eligible,(uint32_t)pblock->nTime,(int32_t)(eligible - pblock->nTime));
|
fprintf(stderr,"komodo_is_PoSblock PoS failure ht.%d eligible.%u vs blocktime.%u, lag.%d -> check to see if it is PoW block\n",height,eligible,(uint32_t)pblock->nTime,(int32_t)(eligible - pblock->nTime));
|
||||||
} else isPoS = 1;
|
if ( slowflag != 0 && pindex != 0 )
|
||||||
|
{
|
||||||
|
pindex->segid = -1;
|
||||||
|
fprintf(stderr,"PoW block detected set segid.%d <- %d\n",height,pindex->segid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isPoS = 2; // 2 means staking utxo validated
|
||||||
|
if ( slowflag != 0 && height > 100 )
|
||||||
|
{
|
||||||
|
segid = -3;
|
||||||
|
if ( pindex != 0 && pindex->segid == -2 && (segid= komodo_segid(1,height)) >= 0 )
|
||||||
|
{
|
||||||
|
pindex->segid = segid;
|
||||||
|
fprintf(stderr,"B set segid.%d <- %d\n",height,pindex->segid);
|
||||||
|
} //else fprintf(stderr,"unexpected null pindex for slowflag set ht.%d segid.%d:%d\n",height,pindex!=0?pindex->segid:-3,segid);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( slowflag == 0 ) // maybe previous block is not seen yet, do the best approx
|
if ( slowflag == 0 && isPoS == 0 ) // maybe previous block is not seen yet, do the best approx
|
||||||
{
|
{
|
||||||
if ( komodo_isPoS(pblock) != 0 )
|
if ( komodo_isPoS(pblock) != 0 )
|
||||||
isPoS = 1;
|
isPoS = 1;
|
||||||
/*txtime = komodo_txtime(&value,txid,vout,destaddr);
|
}
|
||||||
if ( ExtractDestination(pblock->vtx[txn_count-1].vout[0].scriptPubKey,voutaddress) )
|
if ( slowflag != 0 && isPoS != 0 )
|
||||||
|
{
|
||||||
|
if ( isPoS != 2 )
|
||||||
{
|
{
|
||||||
strcpy(voutaddr,CBitcoinAddress(voutaddress).ToString().c_str());
|
fprintf(stderr,"ht.%d isPoS.%d utxo not validated -> must be PoW fake\n",height,isPoS);
|
||||||
if ( strcmp(destaddr,voutaddr) == 0 && pblock->vtx[txn_count-1].vout[0].nValue == value )
|
isPoS = 0;
|
||||||
isPoS = 1; // close enough for a pre-filter
|
}
|
||||||
//else fprintf(stderr,"komodo_is_PoSblock ht.%d (%s) != (%s) or %.8f != %.8f\n",height,destaddr,voutaddr,dstr(value),dstr(pblock->vtx[txn_count-1].vout[0].nValue));
|
else
|
||||||
} else fprintf(stderr,"komodo_is_PoSblock ht.%d couldnt extract voutaddress\n",height);*/
|
{
|
||||||
} //else return(-1);
|
bnTarget = komodo_PoWtarget(&PoSperc,bnTarget,height,ASSETCHAINS_STAKED);
|
||||||
|
if ( bhash < bnTarget )
|
||||||
|
{
|
||||||
|
fprintf(stderr,"ht.%d isPoS but meets PoW diff!\n",height);
|
||||||
|
isPoS = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//else return(-1);
|
||||||
}
|
}
|
||||||
//fprintf(stderr,"slow.%d ht.%d isPoS.%d\n",slowflag,height,isPoS);
|
//fprintf(stderr,"slow.%d ht.%d isPoS.%d\n",slowflag,height,isPoS);
|
||||||
return(isPoS);
|
return(isPoS != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t komodo_checkcommission(CBlock *pblock,int32_t height)
|
int64_t komodo_checkcommission(CBlock *pblock,int32_t height)
|
||||||
@@ -1482,6 +1492,8 @@ bool KOMODO_TEST_ASSETCHAIN_SKIP_POW = 0;
|
|||||||
int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
|
int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
|
||||||
{
|
{
|
||||||
uint256 hash; arith_uint256 bnTarget,bhash; bool fNegative,fOverflow; uint8_t *script,pubkey33[33],pubkeys[64][33]; int32_t i,possible,PoSperc,is_PoSblock=0,n,failed = 0,notaryid = -1; int64_t checktoshis,value; CBlockIndex *pprev;
|
uint256 hash; arith_uint256 bnTarget,bhash; bool fNegative,fOverflow; uint8_t *script,pubkey33[33],pubkeys[64][33]; int32_t i,possible,PoSperc,is_PoSblock=0,n,failed = 0,notaryid = -1; int64_t checktoshis,value; CBlockIndex *pprev;
|
||||||
|
if ( KOMODO_TEST_ASSETCHAIN_SKIP_POW == 0 && Params().NetworkIDString() == "regtest" )
|
||||||
|
KOMODO_TEST_ASSETCHAIN_SKIP_POW = 1;
|
||||||
if ( !CheckEquihashSolution(pblock, Params()) )
|
if ( !CheckEquihashSolution(pblock, Params()) )
|
||||||
{
|
{
|
||||||
fprintf(stderr,"komodo_checkPOW slowflag.%d ht.%d CheckEquihashSolution failed\n",slowflag,height);
|
fprintf(stderr,"komodo_checkPOW slowflag.%d ht.%d CheckEquihashSolution failed\n",slowflag,height);
|
||||||
@@ -1522,13 +1534,13 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
|
|||||||
{
|
{
|
||||||
if ( KOMODO_TEST_ASSETCHAIN_SKIP_POW )
|
if ( KOMODO_TEST_ASSETCHAIN_SKIP_POW )
|
||||||
return(0);
|
return(0);
|
||||||
if ( ASSETCHAINS_STAKED == 0 ) // komodo_is_PoSblock will check bnTarget
|
if ( ASSETCHAINS_STAKED == 0 ) // komodo_is_PoSblock will check bnTarget for staked chains
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( ASSETCHAINS_STAKED != 0 && height >= 2 ) // must PoS or have at least 16x better PoW
|
if ( ASSETCHAINS_STAKED != 0 && height >= 2 ) // must PoS or have at least 16x better PoW
|
||||||
{
|
{
|
||||||
if ( (is_PoSblock= komodo_is_PoSblock(slowflag,height,pblock,bnTarget)) == 0 )
|
if ( (is_PoSblock= komodo_is_PoSblock(slowflag,height,pblock,bnTarget,bhash)) == 0 )
|
||||||
{
|
{
|
||||||
if ( ASSETCHAINS_STAKED == 100 && height > 100 ) // only PoS allowed! POSTEST64
|
if ( ASSETCHAINS_STAKED == 100 && height > 100 ) // only PoS allowed! POSTEST64
|
||||||
return(-1);
|
return(-1);
|
||||||
|
|||||||
@@ -755,6 +755,7 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtim
|
|||||||
if ( height > 1 && checktoshis == 0 )
|
if ( height > 1 && checktoshis == 0 )
|
||||||
{
|
{
|
||||||
checktoshis = ((uint64_t)GetBlockSubsidy(height, Params().GetConsensus()) - block.vtx[0].vout[0].nValue);
|
checktoshis = ((uint64_t)GetBlockSubsidy(height, Params().GetConsensus()) - block.vtx[0].vout[0].nValue);
|
||||||
|
//checktoshis += txn_count * 0.001; // rely on higher level validations to prevent emitting more coins than actual txfees
|
||||||
}
|
}
|
||||||
if ( height >= 2 && (overflow != 0 || total > checktoshis || strangeout != 0) )
|
if ( height >= 2 && (overflow != 0 || total > checktoshis || strangeout != 0) )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ struct komodo_state KOMODO_STATES[34];
|
|||||||
#define _COINBASE_MATURITY 100
|
#define _COINBASE_MATURITY 100
|
||||||
int COINBASE_MATURITY = _COINBASE_MATURITY;//100;
|
int COINBASE_MATURITY = _COINBASE_MATURITY;//100;
|
||||||
|
|
||||||
int32_t IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND;
|
int32_t KOMODO_MININGTHREADS = -1,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND,KOMODO_CONNECTING = -1;
|
||||||
int32_t KOMODO_INSYNC,KOMODO_LASTMINED,prevKOMODO_LASTMINED,JUMBLR_PAUSE = 1;
|
int32_t KOMODO_INSYNC,KOMODO_LASTMINED,prevKOMODO_LASTMINED,JUMBLR_PAUSE = 1;
|
||||||
std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY;
|
std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY;
|
||||||
uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE;
|
uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE;
|
||||||
|
|||||||
@@ -1505,6 +1505,9 @@ void komodo_args(char *argv0)
|
|||||||
extern const char *Notaries_elected1[][2];
|
extern const char *Notaries_elected1[][2];
|
||||||
std::string name,addn; char *dirname,fname[512],arg0str[64],magicstr[9]; uint8_t magic[4],extrabuf[256],*extraptr=0; FILE *fp; uint64_t val; uint16_t port; int32_t i,baseid,len,n,extralen = 0;
|
std::string name,addn; char *dirname,fname[512],arg0str[64],magicstr[9]; uint8_t magic[4],extrabuf[256],*extraptr=0; FILE *fp; uint64_t val; uint16_t port; int32_t i,baseid,len,n,extralen = 0;
|
||||||
IS_KOMODO_NOTARY = GetBoolArg("-notary", false);
|
IS_KOMODO_NOTARY = GetBoolArg("-notary", false);
|
||||||
|
if ( GetBoolArg("-gen", false) != 0 )
|
||||||
|
KOMODO_MININGTHREADS = GetArg("-genproclimit",1);
|
||||||
|
else KOMODO_MININGTHREADS = -1;
|
||||||
if ( (KOMODO_EXCHANGEWALLET= GetBoolArg("-exchange", false)) != 0 )
|
if ( (KOMODO_EXCHANGEWALLET= GetBoolArg("-exchange", false)) != 0 )
|
||||||
fprintf(stderr,"KOMODO_EXCHANGEWALLET mode active\n");
|
fprintf(stderr,"KOMODO_EXCHANGEWALLET mode active\n");
|
||||||
DONATION_PUBKEY = GetArg("-donation", "");
|
DONATION_PUBKEY = GetArg("-donation", "");
|
||||||
|
|||||||
58
src/main.cpp
58
src/main.cpp
@@ -56,7 +56,7 @@ using namespace std;
|
|||||||
|
|
||||||
CCriticalSection cs_main;
|
CCriticalSection cs_main;
|
||||||
extern uint8_t NOTARY_PUBKEY33[33];
|
extern uint8_t NOTARY_PUBKEY33[33];
|
||||||
extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN,KOMODO_INSYNC;
|
extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN,KOMODO_INSYNC,KOMODO_CONNECTING;
|
||||||
int32_t KOMODO_NEWBLOCKS;
|
int32_t KOMODO_NEWBLOCKS;
|
||||||
int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block);
|
int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block);
|
||||||
void komodo_broadcast(CBlock *pblock,int32_t limit);
|
void komodo_broadcast(CBlock *pblock,int32_t limit);
|
||||||
@@ -1263,7 +1263,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
|||||||
if (pfMissingInputs)
|
if (pfMissingInputs)
|
||||||
*pfMissingInputs = false;
|
*pfMissingInputs = false;
|
||||||
|
|
||||||
int nextBlockHeight = chainActive.Height() + 1;
|
int flag=0,nextBlockHeight = chainActive.Height() + 1;
|
||||||
auto consensusBranchId = CurrentEpochBranchId(nextBlockHeight, Params().GetConsensus());
|
auto consensusBranchId = CurrentEpochBranchId(nextBlockHeight, Params().GetConsensus());
|
||||||
|
|
||||||
// Node operator can choose to reject tx by number of transparent inputs
|
// Node operator can choose to reject tx by number of transparent inputs
|
||||||
@@ -1285,7 +1285,6 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
|||||||
}
|
}
|
||||||
if (!CheckTransaction(tx, state, verifier))
|
if (!CheckTransaction(tx, state, verifier))
|
||||||
{
|
{
|
||||||
|
|
||||||
return error("AcceptToMemoryPool: CheckTransaction failed");
|
return error("AcceptToMemoryPool: CheckTransaction failed");
|
||||||
}
|
}
|
||||||
// DoS level set to 10 to be more forgiving.
|
// DoS level set to 10 to be more forgiving.
|
||||||
@@ -1294,7 +1293,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
|||||||
{
|
{
|
||||||
return error("AcceptToMemoryPool: ContextualCheckTransaction failed");
|
return error("AcceptToMemoryPool: ContextualCheckTransaction failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Coinbase is only valid in a block, not as a loose transaction
|
// Coinbase is only valid in a block, not as a loose transaction
|
||||||
if (tx.IsCoinBase())
|
if (tx.IsCoinBase())
|
||||||
{
|
{
|
||||||
@@ -1527,12 +1526,20 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
|||||||
// invalid blocks, however allowing such transactions into the mempool
|
// invalid blocks, however allowing such transactions into the mempool
|
||||||
// can be exploited as a DoS attack.
|
// can be exploited as a DoS attack.
|
||||||
// XXX: is this neccesary for CryptoConditions?
|
// XXX: is this neccesary for CryptoConditions?
|
||||||
|
if ( KOMODO_CONNECTING <= 0 && chainActive.LastTip() != 0 )
|
||||||
|
{
|
||||||
|
flag = 1;
|
||||||
|
KOMODO_CONNECTING = (1<<30) + (int32_t)chainActive.LastTip()->nHeight + 1;
|
||||||
|
}
|
||||||
if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
|
if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
|
||||||
{
|
{
|
||||||
fprintf(stderr,"accept failure.10\n");
|
if ( flag != 0 )
|
||||||
|
KOMODO_CONNECTING = -1;
|
||||||
return error("AcceptToMemoryPool: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
|
return error("AcceptToMemoryPool: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
|
||||||
}
|
}
|
||||||
|
if ( flag != 0 )
|
||||||
|
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++;
|
||||||
@@ -3368,6 +3375,10 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) {
|
|||||||
assert(view.Flush());
|
assert(view.Flush());
|
||||||
DisconnectNotarisations(block);
|
DisconnectNotarisations(block);
|
||||||
}
|
}
|
||||||
|
pindexDelete->segid = -2;
|
||||||
|
pindexDelete->newcoins = 0;
|
||||||
|
pindexDelete->zfunds = 0;
|
||||||
|
|
||||||
LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
|
LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
|
||||||
uint256 anchorAfterDisconnect = pcoinsTip->GetBestAnchor();
|
uint256 anchorAfterDisconnect = pcoinsTip->GetBestAnchor();
|
||||||
// Write the chain state to disk, if necessary.
|
// Write the chain state to disk, if necessary.
|
||||||
@@ -3444,6 +3455,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
|
|||||||
return AbortNode(state, "Failed to read block");
|
return AbortNode(state, "Failed to read block");
|
||||||
pblock = █
|
pblock = █
|
||||||
}
|
}
|
||||||
|
KOMODO_CONNECTING = (int32_t)pindexNew->nHeight;
|
||||||
// Get the current commitment tree
|
// Get the current commitment tree
|
||||||
ZCIncrementalMerkleTree oldTree;
|
ZCIncrementalMerkleTree oldTree;
|
||||||
assert(pcoinsTip->GetAnchorAt(pcoinsTip->GetBestAnchor(), oldTree));
|
assert(pcoinsTip->GetAnchorAt(pcoinsTip->GetBestAnchor(), oldTree));
|
||||||
@@ -3454,6 +3466,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
|
|||||||
{
|
{
|
||||||
CCoinsViewCache view(pcoinsTip);
|
CCoinsViewCache view(pcoinsTip);
|
||||||
bool rv = ConnectBlock(*pblock, state, pindexNew, view, false, true);
|
bool rv = ConnectBlock(*pblock, state, pindexNew, view, false, true);
|
||||||
|
KOMODO_CONNECTING = -1;
|
||||||
GetMainSignals().BlockChecked(*pblock, state);
|
GetMainSignals().BlockChecked(*pblock, state);
|
||||||
if (!rv) {
|
if (!rv) {
|
||||||
if (state.IsInvalid())
|
if (state.IsInvalid())
|
||||||
@@ -4154,17 +4167,32 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
|
|||||||
// Check transactions
|
// Check transactions
|
||||||
if ( ASSETCHAINS_CC != 0 ) // CC contracts might refer to transactions in the current block, from a CC spend within the same block and out of order
|
if ( ASSETCHAINS_CC != 0 ) // CC contracts might refer to transactions in the current block, from a CC spend within the same block and out of order
|
||||||
{
|
{
|
||||||
CValidationState stateDummy;
|
CValidationState stateDummy; int32_t i,j,rejects=0,lastrejects=0;
|
||||||
//fprintf(stderr,"put block's tx into mempool\n");
|
//fprintf(stderr,"put block's tx into mempool\n");
|
||||||
for (int i = 0; i < block.vtx.size(); i++)
|
while ( 1 )
|
||||||
{
|
{
|
||||||
const CTransaction &tx = block.vtx[i];
|
for (i=0; i<block.vtx.size(); i++)
|
||||||
if (tx.IsCoinBase() != 0 )
|
{
|
||||||
continue;
|
CTransaction Tx; const CTransaction &tx = (CTransaction)block.vtx[i];
|
||||||
else if ( ASSETCHAINS_STAKED != 0 && (i == (block.vtx.size() - 1)) && komodo_isPoS((CBlock *)&block) != 0 )
|
if (tx.IsCoinBase() != 0 )
|
||||||
continue;
|
continue;
|
||||||
AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL);
|
else if ( ASSETCHAINS_STAKED != 0 && (i == (block.vtx.size() - 1)) && komodo_isPoS((CBlock *)&block) != 0 )
|
||||||
}
|
continue;
|
||||||
|
Tx = tx;
|
||||||
|
if ( myAddtomempool(Tx) == false ) // can happen with out of order tx in block on resync
|
||||||
|
//if ( AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL) == false )
|
||||||
|
rejects++;
|
||||||
|
}
|
||||||
|
if ( rejects == 0 || rejects == lastrejects )
|
||||||
|
{
|
||||||
|
if ( lastrejects != 0 )
|
||||||
|
fprintf(stderr,"lastrejects.%d -> all tx in mempool\n",lastrejects);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
rejects = 0;
|
||||||
|
}
|
||||||
//fprintf(stderr,"done putting block's tx into mempool\n");
|
//fprintf(stderr,"done putting block's tx into mempool\n");
|
||||||
}
|
}
|
||||||
BOOST_FOREACH(const CTransaction& tx, block.vtx)
|
BOOST_FOREACH(const CTransaction& tx, block.vtx)
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams,
|
|||||||
|
|
||||||
#include "komodo_defs.h"
|
#include "komodo_defs.h"
|
||||||
|
|
||||||
extern int32_t KOMODO_LONGESTCHAIN,ASSETCHAINS_SEED,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAIN_INIT,KOMODO_INITDONE,KOMODO_ON_DEMAND,KOMODO_INITDONE,KOMODO_PASSPORT_INITDONE;
|
extern int32_t KOMODO_MININGTHREADS,KOMODO_LONGESTCHAIN,ASSETCHAINS_SEED,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAIN_INIT,KOMODO_INITDONE,KOMODO_ON_DEMAND,KOMODO_INITDONE,KOMODO_PASSPORT_INITDONE;
|
||||||
extern uint64_t ASSETCHAINS_REWARD,ASSETCHAINS_COMMISSION,ASSETCHAINS_STAKED;
|
extern uint64_t ASSETCHAINS_REWARD,ASSETCHAINS_COMMISSION,ASSETCHAINS_STAKED;
|
||||||
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
||||||
extern std::string NOTARY_PUBKEY,ASSETCHAINS_OVERRIDE_PUBKEY;
|
extern std::string NOTARY_PUBKEY,ASSETCHAINS_OVERRIDE_PUBKEY;
|
||||||
@@ -393,7 +393,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
|||||||
//pblock->nTime = blocktime + 1;
|
//pblock->nTime = blocktime + 1;
|
||||||
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
|
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
|
||||||
//LogPrintf("CreateNewBlock(): total size %u blocktime.%u nBits.%08x\n", nBlockSize,blocktime,pblock->nBits);
|
//LogPrintf("CreateNewBlock(): total size %u blocktime.%u nBits.%08x\n", nBlockSize,blocktime,pblock->nBits);
|
||||||
if ( ASSETCHAINS_SYMBOL[0] != 0 && ASSETCHAINS_STAKED != 0 && GetArg("-genproclimit", 0) == 0 )
|
if ( ASSETCHAINS_SYMBOL[0] != 0 && ASSETCHAINS_STAKED != 0 && KOMODO_MININGTHREADS == 0 )
|
||||||
{
|
{
|
||||||
uint64_t txfees,utxovalue; uint32_t txtime; uint256 utxotxid,revtxid; int32_t i,siglen,numsigs,utxovout; uint8_t utxosig[128],*ptr;
|
uint64_t txfees,utxovalue; uint32_t txtime; uint256 utxotxid,revtxid; int32_t i,siglen,numsigs,utxovout; uint8_t utxosig[128],*ptr;
|
||||||
CMutableTransaction txStaked = CreateNewContextualCMutableTransaction(Params().GetConsensus(), chainActive.Height() + 1);
|
CMutableTransaction txStaked = CreateNewContextualCMutableTransaction(Params().GetConsensus(), chainActive.Height() + 1);
|
||||||
@@ -453,7 +453,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
|||||||
// Fill in header
|
// Fill in header
|
||||||
pblock->hashPrevBlock = pindexPrev->GetBlockHash();
|
pblock->hashPrevBlock = pindexPrev->GetBlockHash();
|
||||||
pblock->hashReserved = uint256();
|
pblock->hashReserved = uint256();
|
||||||
if ( ASSETCHAINS_SYMBOL[0] == 0 || ASSETCHAINS_STAKED == 0 || GetArg("-genproclimit", 0) > 0 )
|
if ( ASSETCHAINS_SYMBOL[0] == 0 || ASSETCHAINS_STAKED == 0 || KOMODO_MININGTHREADS > 0 )
|
||||||
{
|
{
|
||||||
UpdateTime(pblock, Params().GetConsensus(), pindexPrev);
|
UpdateTime(pblock, Params().GetConsensus(), pindexPrev);
|
||||||
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
|
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
|
||||||
@@ -788,7 +788,7 @@ void static BitcoinMiner()
|
|||||||
}
|
}
|
||||||
if (!fvNodesEmpty )//&& !IsInitialBlockDownload())
|
if (!fvNodesEmpty )//&& !IsInitialBlockDownload())
|
||||||
break;
|
break;
|
||||||
MilliSleep(5000);
|
MilliSleep(15000);
|
||||||
//fprintf(stderr,"fvNodesEmpty %d IsInitialBlockDownload(%s) %d\n",(int32_t)fvNodesEmpty,ASSETCHAINS_SYMBOL,(int32_t)IsInitialBlockDownload());
|
//fprintf(stderr,"fvNodesEmpty %d IsInitialBlockDownload(%s) %d\n",(int32_t)fvNodesEmpty,ASSETCHAINS_SYMBOL,(int32_t)IsInitialBlockDownload());
|
||||||
|
|
||||||
} while (true);
|
} while (true);
|
||||||
@@ -950,7 +950,7 @@ void static BitcoinMiner()
|
|||||||
// (x_1, x_2, ...) = A(I, V, n, k)
|
// (x_1, x_2, ...) = A(I, V, n, k)
|
||||||
LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n",solver, pblock->nNonce.ToString());
|
LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n",solver, pblock->nNonce.ToString());
|
||||||
arith_uint256 hashTarget;
|
arith_uint256 hashTarget;
|
||||||
if ( GetArg("-genproclimit", 0) > 0 && ASSETCHAINS_STAKED > 0 && ASSETCHAINS_STAKED < 100 && Mining_height > 10 )
|
if ( KOMODO_MININGTHREADS > 0 && ASSETCHAINS_STAKED > 0 && ASSETCHAINS_STAKED < 100 && Mining_height > 10 )
|
||||||
hashTarget = HASHTarget_POW;
|
hashTarget = HASHTarget_POW;
|
||||||
else hashTarget = HASHTarget;
|
else hashTarget = HASHTarget;
|
||||||
std::function<bool(std::vector<unsigned char>)> validBlock =
|
std::function<bool(std::vector<unsigned char>)> validBlock =
|
||||||
@@ -978,7 +978,7 @@ void static BitcoinMiner()
|
|||||||
fprintf(stderr," POW\n");*/
|
fprintf(stderr," POW\n");*/
|
||||||
if ( h > hashTarget )
|
if ( h > hashTarget )
|
||||||
{
|
{
|
||||||
//if ( ASSETCHAINS_STAKED != 0 && GetArg("-genproclimit", 0) == 0 )
|
//if ( ASSETCHAINS_STAKED != 0 && KOMODO_MININGTHREADS == 0 )
|
||||||
// sleep(1);
|
// sleep(1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex)
|
|||||||
result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits)));
|
result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits)));
|
||||||
result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
|
result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
|
||||||
result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
|
result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
|
||||||
|
result.push_back(Pair("segid", (int64_t)blockindex->segid));
|
||||||
|
|
||||||
if (blockindex->pprev)
|
if (blockindex->pprev)
|
||||||
result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
|
result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
|
||||||
@@ -146,6 +147,7 @@ UniValue blockToDeltasJSON(const CBlock& block, const CBlockIndex* blockindex)
|
|||||||
result.push_back(Pair("height", blockindex->nHeight));
|
result.push_back(Pair("height", blockindex->nHeight));
|
||||||
result.push_back(Pair("version", block.nVersion));
|
result.push_back(Pair("version", block.nVersion));
|
||||||
result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
|
result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
|
||||||
|
result.push_back(Pair("segid", (int64_t)blockindex->segid));
|
||||||
|
|
||||||
UniValue deltas(UniValue::VARR);
|
UniValue deltas(UniValue::VARR);
|
||||||
|
|
||||||
@@ -262,6 +264,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx
|
|||||||
result.push_back(Pair("height", blockindex->nHeight));
|
result.push_back(Pair("height", blockindex->nHeight));
|
||||||
result.push_back(Pair("version", block.nVersion));
|
result.push_back(Pair("version", block.nVersion));
|
||||||
result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
|
result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
|
||||||
|
result.push_back(Pair("segid", (int64_t)blockindex->segid));
|
||||||
UniValue txs(UniValue::VARR);
|
UniValue txs(UniValue::VARR);
|
||||||
BOOST_FOREACH(const CTransaction&tx, block.vtx)
|
BOOST_FOREACH(const CTransaction&tx, block.vtx)
|
||||||
{
|
{
|
||||||
@@ -349,7 +352,7 @@ UniValue getdifficulty(const UniValue& params, bool fHelp)
|
|||||||
bool myIsutxo_spentinmempool(uint256 txid,int32_t vout)
|
bool myIsutxo_spentinmempool(uint256 txid,int32_t vout)
|
||||||
{
|
{
|
||||||
//char *uint256_str(char *str,uint256); char str[65];
|
//char *uint256_str(char *str,uint256); char str[65];
|
||||||
LOCK(mempool.cs);
|
//LOCK(mempool.cs);
|
||||||
BOOST_FOREACH(const CTxMemPoolEntry &e,mempool.mapTx)
|
BOOST_FOREACH(const CTxMemPoolEntry &e,mempool.mapTx)
|
||||||
{
|
{
|
||||||
const CTransaction &tx = e.GetTx();
|
const CTransaction &tx = e.GetTx();
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
extern uint64_t ASSETCHAINS_STAKED;
|
extern uint64_t ASSETCHAINS_STAKED;
|
||||||
|
extern int32_t KOMODO_MININGTHREADS;
|
||||||
arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc);
|
arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -327,6 +328,9 @@ UniValue setgenerate(const UniValue& params, bool fHelp)
|
|||||||
|
|
||||||
mapArgs["-gen"] = (fGenerate ? "1" : "0");
|
mapArgs["-gen"] = (fGenerate ? "1" : "0");
|
||||||
mapArgs ["-genproclimit"] = itostr(nGenProcLimit);
|
mapArgs ["-genproclimit"] = itostr(nGenProcLimit);
|
||||||
|
if ( fGenerate == 0 )
|
||||||
|
KOMODO_MININGTHREADS = -1;
|
||||||
|
else KOMODO_MININGTHREADS = (int32_t)nGenProcLimit;
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit);
|
GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit);
|
||||||
#else
|
#else
|
||||||
@@ -382,6 +386,7 @@ UniValue getmininginfo(const UniValue& params, bool fHelp)
|
|||||||
obj.push_back(Pair("chain", Params().NetworkIDString()));
|
obj.push_back(Pair("chain", Params().NetworkIDString()));
|
||||||
#ifdef ENABLE_MINING
|
#ifdef ENABLE_MINING
|
||||||
obj.push_back(Pair("generate", getgenerate(params, false)));
|
obj.push_back(Pair("generate", getgenerate(params, false)));
|
||||||
|
obj.push_back(Pair("numthreads", (int64_t)KOMODO_MININGTHREADS));
|
||||||
#endif
|
#endif
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@@ -647,7 +652,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
|
|||||||
pblocktemplate = CreateNewBlockWithKey();
|
pblocktemplate = CreateNewBlockWithKey();
|
||||||
#endif
|
#endif
|
||||||
if (!pblocktemplate)
|
if (!pblocktemplate)
|
||||||
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
|
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory or no available utxo for staking");
|
||||||
|
|
||||||
// Need to update only after we know CreateNewBlockWithKey succeeded
|
// Need to update only after we know CreateNewBlockWithKey succeeded
|
||||||
pindexPrev = pindexPrevNew;
|
pindexPrev = pindexPrevNew;
|
||||||
|
|||||||
@@ -952,7 +952,7 @@ bool EvalScript(
|
|||||||
|
|
||||||
if (stack.size() < 2)
|
if (stack.size() < 2)
|
||||||
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
|
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
|
||||||
|
//fprintf(stderr,"check cryptocondition\n");
|
||||||
int fResult = checker.CheckCryptoCondition(stacktop(-1), stacktop(-2), script, consensusBranchId);
|
int fResult = checker.CheckCryptoCondition(stacktop(-1), stacktop(-2), script, consensusBranchId);
|
||||||
if (fResult == -1) {
|
if (fResult == -1) {
|
||||||
return set_error(serror, SCRIPT_ERR_CRYPTOCONDITION_INVALID_FULFILLMENT);
|
return set_error(serror, SCRIPT_ERR_CRYPTOCONDITION_INVALID_FULFILLMENT);
|
||||||
@@ -1313,19 +1313,20 @@ int TransactionSignatureChecker::CheckCryptoCondition(
|
|||||||
} catch (logic_error ex) {
|
} catch (logic_error ex) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
//int32_t z; uint8_t *ptr;
|
/*int32_t z; uint8_t *ptr;
|
||||||
//ptr = (uint8_t *)scriptCode.data();
|
ptr = (uint8_t *)scriptCode.data();
|
||||||
//for (z=0; z<scriptCode.size(); z++)
|
for (z=0; z<scriptCode.size(); z++)
|
||||||
// fprintf(stderr,"%02x",ptr[z]);
|
fprintf(stderr,"%02x",ptr[z]);
|
||||||
//fprintf(stderr," <- CScript\n");
|
fprintf(stderr," <- CScript\n");
|
||||||
//for (z=0; z<32; z++)
|
for (z=0; z<32; z++)
|
||||||
// fprintf(stderr,"%02x",((uint8_t *)&sighash)[z]);
|
fprintf(stderr,"%02x",((uint8_t *)&sighash)[z]);
|
||||||
//fprintf(stderr," sighash nIn.%d nHashType.%d %.8f id.%d\n",(int32_t)nIn,(int32_t)nHashType,(double)amount/COIN,(int32_t)consensusBranchId);
|
fprintf(stderr," sighash nIn.%d nHashType.%d %.8f id.%d\n",(int32_t)nIn,(int32_t)nHashType,(double)amount/COIN,(int32_t)consensusBranchId);
|
||||||
|
*/
|
||||||
VerifyEval eval = [] (CC *cond, void *checker) {
|
VerifyEval eval = [] (CC *cond, void *checker) {
|
||||||
|
//fprintf(stderr,"checker.%p\n",(TransactionSignatureChecker*)checker);
|
||||||
return ((TransactionSignatureChecker*)checker)->CheckEvalCondition(cond);
|
return ((TransactionSignatureChecker*)checker)->CheckEvalCondition(cond);
|
||||||
};
|
};
|
||||||
|
//fprintf(stderr,"non-checker path\n");
|
||||||
int out = cc_verify(cond, (const unsigned char*)&sighash, 32, 0,
|
int out = cc_verify(cond, (const unsigned char*)&sighash, 32, 0,
|
||||||
condBin.data(), condBin.size(), eval, (void*)this);
|
condBin.data(), condBin.size(), eval, (void*)this);
|
||||||
//fprintf(stderr,"out.%d from cc_verify\n",(int32_t)out);
|
//fprintf(stderr,"out.%d from cc_verify\n",(int32_t)out);
|
||||||
|
|||||||
@@ -102,5 +102,6 @@ bool ServerTransactionSignatureChecker::VerifySignature(const std::vector<unsign
|
|||||||
*/
|
*/
|
||||||
int ServerTransactionSignatureChecker::CheckEvalCondition(const CC *cond) const
|
int ServerTransactionSignatureChecker::CheckEvalCondition(const CC *cond) const
|
||||||
{
|
{
|
||||||
|
//fprintf(stderr,"call RunCCeval from ServerTransactionSignatureChecker::CheckEvalCondition\n");
|
||||||
return RunCCEval(cond, *txTo, nIn);
|
return RunCCEval(cond, *txTo, nIn);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -430,7 +430,7 @@ extern UniValue CBlockTreeDB::Snapshot(int top)
|
|||||||
};
|
};
|
||||||
|
|
||||||
int64_t startingHeight = chainActive.Height();
|
int64_t startingHeight = chainActive.Height();
|
||||||
fprintf(stderr, "Starting snapshot at height %li\n", startingHeight);
|
//fprintf(stderr, "Starting snapshot at height %lli\n", startingHeight);
|
||||||
for (iter->SeekToLast(); iter->Valid(); iter->Prev())
|
for (iter->SeekToLast(); iter->Valid(); iter->Prev())
|
||||||
{
|
{
|
||||||
boost::this_thread::interruption_point();
|
boost::this_thread::interruption_point();
|
||||||
@@ -487,7 +487,7 @@ extern UniValue CBlockTreeDB::Snapshot(int top)
|
|||||||
}
|
}
|
||||||
|
|
||||||
UniValue addresses(UniValue::VARR);
|
UniValue addresses(UniValue::VARR);
|
||||||
fprintf(stderr, "total=%f, totalAddresses=%li, utxos=%li, ignored=%li\n", (double) total / COIN, totalAddresses, utxos, ignoredAddresses);
|
//fprintf(stderr, "total=%f, totalAddresses=%li, utxos=%li, ignored=%li\n", (double) total / COIN, totalAddresses, utxos, ignoredAddresses);
|
||||||
|
|
||||||
for (std::pair<std::string, CAmount> element : addressAmounts) {
|
for (std::pair<std::string, CAmount> element : addressAmounts) {
|
||||||
vaddr.push_back( make_pair(element.second, element.first) );
|
vaddr.push_back( make_pair(element.second, element.first) );
|
||||||
|
|||||||
@@ -38,6 +38,8 @@
|
|||||||
|
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
|
#define ERR_RESULT(x) result.push_back(Pair("result", "error")) , result.push_back(Pair("error", x));
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
using namespace libzcash;
|
using namespace libzcash;
|
||||||
@@ -49,6 +51,7 @@ uint32_t komodo_segid32(char *coinaddr);
|
|||||||
|
|
||||||
int64_t nWalletUnlockTime;
|
int64_t nWalletUnlockTime;
|
||||||
static CCriticalSection cs_nWalletUnlockTime;
|
static CCriticalSection cs_nWalletUnlockTime;
|
||||||
|
std::string CCerror;
|
||||||
|
|
||||||
// Private method:
|
// Private method:
|
||||||
UniValue z_getoperationstatus_IMPL(const UniValue&, bool);
|
UniValue z_getoperationstatus_IMPL(const UniValue&, bool);
|
||||||
@@ -4925,11 +4928,13 @@ UniValue diceaddress(const UniValue& params, bool fHelp)
|
|||||||
UniValue faucetaddress(const UniValue& params, bool fHelp)
|
UniValue faucetaddress(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
struct CCcontract_info *cp,C; std::vector<unsigned char> pubkey;
|
struct CCcontract_info *cp,C; std::vector<unsigned char> pubkey;
|
||||||
|
int errno;
|
||||||
cp = CCinit(&C,EVAL_FAUCET);
|
cp = CCinit(&C,EVAL_FAUCET);
|
||||||
if ( fHelp || params.size() > 1 )
|
if ( fHelp || params.size() > 1 )
|
||||||
throw runtime_error("faucetaddress [pubkey]\n");
|
throw runtime_error("faucetaddress [pubkey]\n");
|
||||||
if ( ensure_CCrequirements() < 0 )
|
errno = ensure_CCrequirements();
|
||||||
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
if ( errno < 0 )
|
||||||
|
throw runtime_error(strprintf("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet. ERR=%d\n", errno));
|
||||||
if ( params.size() == 1 )
|
if ( params.size() == 1 )
|
||||||
pubkey = ParseHex(params[0].get_str().c_str());
|
pubkey = ParseHex(params[0].get_str().c_str());
|
||||||
return(CCaddress(cp,(char *)"Faucet",pubkey));
|
return(CCaddress(cp,(char *)"Faucet",pubkey));
|
||||||
@@ -4995,13 +5000,13 @@ UniValue rewardscreatefunding(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 rewards funding transaction"));
|
} else ERR_RESULT("couldnt create rewards funding transaction");
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue rewardslock(const UniValue& params, bool fHelp)
|
UniValue rewardslock(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
UniValue result(UniValue::VOBJ); char *name; uint256 fundingtxid; uint64_t amount; std::string hex;
|
UniValue result(UniValue::VOBJ); char *name; uint256 fundingtxid; int64_t amount; std::string hex;
|
||||||
if ( fHelp || params.size() != 3 )
|
if ( fHelp || params.size() != 3 )
|
||||||
throw runtime_error("rewardslock name fundingtxid amount\n");
|
throw runtime_error("rewardslock name fundingtxid amount\n");
|
||||||
if ( ensure_CCrequirements() < 0 )
|
if ( ensure_CCrequirements() < 0 )
|
||||||
@@ -5012,17 +5017,19 @@ 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 ( hex.size() > 0 )
|
if ( amount > 0 ) {
|
||||||
{
|
if ( hex.size() > 0 )
|
||||||
result.push_back(Pair("result", "success"));
|
{
|
||||||
result.push_back(Pair("hex", hex));
|
result.push_back(Pair("result", "success"));
|
||||||
} else result.push_back(Pair("error", "couldnt create rewards lock transaction"));
|
result.push_back(Pair("hex", hex));
|
||||||
|
} else ERR_RESULT( "couldnt create rewards lock transaction");
|
||||||
|
} else ERR_RESULT("amount must be positive");
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue rewardsaddfunding(const UniValue& params, bool fHelp)
|
UniValue rewardsaddfunding(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
UniValue result(UniValue::VOBJ); char *name; uint256 fundingtxid; uint64_t amount; std::string hex;
|
UniValue result(UniValue::VOBJ); char *name; uint256 fundingtxid; int64_t amount; std::string hex;
|
||||||
if ( fHelp || params.size() != 3 )
|
if ( fHelp || params.size() != 3 )
|
||||||
throw runtime_error("rewardsaddfunding name fundingtxid amount\n");
|
throw runtime_error("rewardsaddfunding name fundingtxid amount\n");
|
||||||
if ( ensure_CCrequirements() < 0 )
|
if ( ensure_CCrequirements() < 0 )
|
||||||
@@ -5033,18 +5040,26 @@ 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 ( hex.size() > 0 )
|
if (amount > 0) {
|
||||||
{
|
if ( hex.size() > 0 )
|
||||||
result.push_back(Pair("result", "success"));
|
{
|
||||||
result.push_back(Pair("hex", hex));
|
result.push_back(Pair("result", "success"));
|
||||||
} else result.push_back(Pair("error", "couldnt create rewards addfunding transaction"));
|
result.push_back(Pair("hex", hex));
|
||||||
|
} else {
|
||||||
|
result.push_back(Pair("result", "error"));
|
||||||
|
result.push_back(Pair("error", "couldnt create rewards addfunding transaction"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.push_back(Pair("result", "error"));
|
||||||
|
result.push_back(Pair("error", "funding amount must be positive"));
|
||||||
|
}
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue rewardsunlock(const UniValue& params, bool fHelp)
|
UniValue rewardsunlock(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
UniValue result(UniValue::VOBJ); std::string hex; char *name; uint256 fundingtxid,txid;
|
UniValue result(UniValue::VOBJ); std::string hex; char *name; uint256 fundingtxid,txid;
|
||||||
if ( fHelp || params.size() > 3 )
|
if ( fHelp || params.size() > 3 || params.size() < 2 )
|
||||||
throw runtime_error("rewardsunlock name fundingtxid [txid]\n");
|
throw runtime_error("rewardsunlock name fundingtxid [txid]\n");
|
||||||
if ( ensure_CCrequirements() < 0 )
|
if ( ensure_CCrequirements() < 0 )
|
||||||
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||||
@@ -5056,11 +5071,12 @@ UniValue rewardsunlock(const UniValue& params, bool fHelp)
|
|||||||
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));
|
||||||
hex = RewardsUnlock(0,name,fundingtxid,txid);
|
hex = RewardsUnlock(0,name,fundingtxid,txid);
|
||||||
if ( hex.size() > 0 )
|
if (CCerror != "") {
|
||||||
{
|
ERR_RESULT(CCerror);
|
||||||
|
} else if ( hex.size() > 0 ) {
|
||||||
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 rewards unlock transaction"));
|
} else ERR_RESULT("couldnt create rewards unlock transaction");
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5138,7 +5154,7 @@ UniValue faucetinfo(const UniValue& params, bool fHelp)
|
|||||||
|
|
||||||
UniValue faucetfund(const UniValue& params, bool fHelp)
|
UniValue faucetfund(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
UniValue result(UniValue::VOBJ); uint64_t funds; std::string hex;
|
UniValue result(UniValue::VOBJ); int64_t funds; std::string hex;
|
||||||
if ( fHelp || params.size() > 1 )
|
if ( fHelp || params.size() > 1 )
|
||||||
throw runtime_error("faucetfund amount\n");
|
throw runtime_error("faucetfund amount\n");
|
||||||
if ( ensure_CCrequirements() < 0 )
|
if ( ensure_CCrequirements() < 0 )
|
||||||
@@ -5146,12 +5162,14 @@ UniValue faucetfund(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);
|
||||||
funds = atof(params[0].get_str().c_str()) * COIN;
|
funds = atof(params[0].get_str().c_str()) * COIN;
|
||||||
hex = FaucetFund(0,funds);
|
if (funds > 0) {
|
||||||
if ( hex.size() > 0 )
|
hex = FaucetFund(0,(uint64_t) funds);
|
||||||
{
|
if ( hex.size() > 0 )
|
||||||
result.push_back(Pair("result", "success"));
|
{
|
||||||
result.push_back(Pair("hex", hex));
|
result.push_back(Pair("result", "success"));
|
||||||
} else result.push_back(Pair("error", "couldnt create faucet funding transaction"));
|
result.push_back(Pair("hex", hex));
|
||||||
|
} else ERR_RESULT("couldnt create faucet funding transaction");
|
||||||
|
} else ERR_RESULT( "funding amount must be positive");
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5165,11 +5183,10 @@ UniValue faucetget(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);
|
||||||
hex = FaucetGet(0);
|
hex = FaucetGet(0);
|
||||||
if ( hex.size() > 0 )
|
if ( hex.size() > 0 ) {
|
||||||
{
|
|
||||||
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 faucet get transaction"));
|
} else ERR_RESULT("couldnt create faucet get transaction");
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5189,17 +5206,20 @@ UniValue dicefund(const UniValue& params, bool fHelp)
|
|||||||
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());
|
||||||
hex = DiceCreateFunding(0,name,funds,minbet,maxbet,maxodds,timeoutblocks);
|
hex = DiceCreateFunding(0,name,funds,minbet,maxbet,maxodds,timeoutblocks);
|
||||||
if ( hex.size() > 0 )
|
if (CCerror != "") {
|
||||||
{
|
ERR_RESULT(CCerror);
|
||||||
|
} else if ( hex.size() > 0 ) {
|
||||||
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 dice funding transaction"));
|
} else {
|
||||||
|
ERR_RESULT( "couldnt create dice funding transaction");
|
||||||
|
}
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue diceaddfunds(const UniValue& params, bool fHelp)
|
UniValue diceaddfunds(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
UniValue result(UniValue::VOBJ); char *name; uint256 fundingtxid; uint64_t amount; std::string hex;
|
UniValue result(UniValue::VOBJ); char *name; uint256 fundingtxid; int64_t amount; std::string hex;
|
||||||
if ( fHelp || params.size() != 3 )
|
if ( fHelp || params.size() != 3 )
|
||||||
throw runtime_error("diceaddfunds name fundingtxid amount\n");
|
throw runtime_error("diceaddfunds name fundingtxid amount\n");
|
||||||
if ( ensure_CCrequirements() < 0 )
|
if ( ensure_CCrequirements() < 0 )
|
||||||
@@ -5209,18 +5229,21 @@ 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;
|
||||||
hex = DiceAddfunding(0,name,fundingtxid,amount);
|
if ( amount > 0 ) {
|
||||||
if ( hex.size() > 0 )
|
hex = DiceAddfunding(0,name,fundingtxid,amount);
|
||||||
{
|
if (CCerror != "") {
|
||||||
result.push_back(Pair("result", "success"));
|
ERR_RESULT(CCerror);
|
||||||
result.push_back(Pair("hex", hex));
|
} else if ( hex.size() > 0 ) {
|
||||||
} else result.push_back(Pair("error", "couldnt create dice addfunding transaction"));
|
result.push_back(Pair("result", "success"));
|
||||||
|
result.push_back(Pair("hex", hex));
|
||||||
|
} else ERR_RESULT("couldnt create dice addfunding transaction");
|
||||||
|
} else ERR_RESULT("amount must be positive");
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue dicebet(const UniValue& params, bool fHelp)
|
UniValue dicebet(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
UniValue result(UniValue::VOBJ); std::string hex; uint256 fundingtxid; uint64_t amount,odds; char *name;
|
UniValue result(UniValue::VOBJ); std::string hex; uint256 fundingtxid; int64_t amount,odds; char *name;
|
||||||
if ( fHelp || params.size() != 4 )
|
if ( fHelp || params.size() != 4 )
|
||||||
throw runtime_error("dicebet name fundingtxid amount odds\n");
|
throw runtime_error("dicebet name fundingtxid amount odds\n");
|
||||||
if ( ensure_CCrequirements() < 0 )
|
if ( ensure_CCrequirements() < 0 )
|
||||||
@@ -5231,18 +5254,22 @@ 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());
|
||||||
hex = DiceBet(0,name,fundingtxid,amount,odds);
|
if (amount > 0 && odds > 0) {
|
||||||
if ( hex.size() > 0 )
|
hex = DiceBet(0,name,fundingtxid,amount,odds);
|
||||||
{
|
if ( hex.size() > 0 )
|
||||||
result.push_back(Pair("result", "success"));
|
{
|
||||||
result.push_back(Pair("hex", hex));
|
result.push_back(Pair("result", "success"));
|
||||||
} else result.push_back(Pair("error", "couldnt create faucet get transaction"));
|
result.push_back(Pair("hex", hex));
|
||||||
|
} else ERR_RESULT("couldnt create faucet get transaction");
|
||||||
|
} else {
|
||||||
|
ERR_RESULT("amount and odds must be positive");
|
||||||
|
}
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue dicefinish(const UniValue& params, bool fHelp)
|
UniValue dicefinish(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
UniValue result(UniValue::VOBJ); char *name; uint256 fundingtxid,bettxid; uint64_t amount; std::string hex; int32_t r;
|
UniValue result(UniValue::VOBJ); char *name; uint256 fundingtxid,bettxid; std::string hex; int32_t r;
|
||||||
if ( fHelp || params.size() != 3 )
|
if ( fHelp || params.size() != 3 )
|
||||||
throw runtime_error("dicefinish name fundingtxid bettxid\n");
|
throw runtime_error("dicefinish name fundingtxid bettxid\n");
|
||||||
if ( ensure_CCrequirements() < 0 )
|
if ( ensure_CCrequirements() < 0 )
|
||||||
@@ -5257,13 +5284,13 @@ UniValue dicefinish(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 dicefinish transaction"));
|
} else ERR_RESULT( "couldnt create dicefinish transaction");
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue dicestatus(const UniValue& params, bool fHelp)
|
UniValue dicestatus(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
UniValue result(UniValue::VOBJ); char *name; uint256 fundingtxid,bettxid; uint64_t amount; std::string status; double winnings;
|
UniValue result(UniValue::VOBJ); char *name; uint256 fundingtxid,bettxid; std::string status; double winnings;
|
||||||
if ( fHelp || (params.size() != 2 && params.size() != 3) )
|
if ( fHelp || (params.size() != 2 && params.size() != 3) )
|
||||||
throw runtime_error("dicestatus name fundingtxid bettxid\n");
|
throw runtime_error("dicestatus name fundingtxid bettxid\n");
|
||||||
if ( ensure_CCrequirements() < 0 )
|
if ( ensure_CCrequirements() < 0 )
|
||||||
@@ -5298,7 +5325,7 @@ UniValue dicestatus(const UniValue& params, bool fHelp)
|
|||||||
result.push_back(Pair("status", "loss"));
|
result.push_back(Pair("status", "loss"));
|
||||||
else result.push_back(Pair("status", "no pending bets"));
|
else result.push_back(Pair("status", "no pending bets"));
|
||||||
}
|
}
|
||||||
} else result.push_back(Pair("status", "invalid bet txid"));
|
} else result.push_back(Pair("status", "bet still pending"));
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5390,20 +5417,32 @@ 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 )
|
||||||
|
{
|
||||||
|
result.push_back(Pair("error", "invalid parameter"));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
if ( params.size() == 3 )
|
if ( params.size() == 3 )
|
||||||
|
{
|
||||||
description = params[2].get_str();
|
description = params[2].get_str();
|
||||||
|
if ( description.size() > 4096 )
|
||||||
|
{
|
||||||
|
result.push_back(Pair("error", "token description longer than 4096"));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
hex = CreateAsset(0,supply,name,description);
|
hex = CreateAsset(0,supply,name,description);
|
||||||
if ( hex.size() > 0 )
|
if ( hex.size() > 0 )
|
||||||
{
|
{
|
||||||
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 transaction"));
|
} else ERR_RESULT("couldnt create transaction");
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue tokentransfer(const UniValue& params, bool fHelp)
|
UniValue tokentransfer(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
UniValue result(UniValue::VOBJ); std::string hex; uint64_t amount; uint256 tokenid;
|
UniValue result(UniValue::VOBJ); std::string hex; int64_t amount; uint256 tokenid;
|
||||||
if ( fHelp || params.size() != 3 )
|
if ( fHelp || params.size() != 3 )
|
||||||
throw runtime_error("tokentransfer tokenid destpubkey amount\n");
|
throw runtime_error("tokentransfer tokenid destpubkey amount\n");
|
||||||
if ( ensure_CCrequirements() < 0 )
|
if ( ensure_CCrequirements() < 0 )
|
||||||
@@ -5413,18 +5452,27 @@ 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());
|
||||||
hex = AssetTransfer(0,tokenid,pubkey,amount);
|
if ( tokenid == zeroid || amount <= 0 )
|
||||||
if ( hex.size() > 0 )
|
|
||||||
{
|
{
|
||||||
result.push_back(Pair("result", "success"));
|
result.push_back(Pair("error", "invalid parameter"));
|
||||||
result.push_back(Pair("hex", hex));
|
return(result);
|
||||||
} else result.push_back(Pair("error", "couldnt transfer assets"));
|
}
|
||||||
|
hex = AssetTransfer(0,tokenid,pubkey,amount);
|
||||||
|
if (amount > 0) {
|
||||||
|
if ( hex.size() > 0 )
|
||||||
|
{
|
||||||
|
result.push_back(Pair("result", "success"));
|
||||||
|
result.push_back(Pair("hex", hex));
|
||||||
|
} else ERR_RESULT("couldnt transfer assets");
|
||||||
|
} else {
|
||||||
|
ERR_RESULT("amount must be positive");
|
||||||
|
}
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue tokenbid(const UniValue& params, bool fHelp)
|
UniValue tokenbid(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
UniValue result(UniValue::VOBJ); uint64_t bidamount,numtokens; std::string hex; double price; uint256 tokenid;
|
UniValue result(UniValue::VOBJ); int64_t bidamount,numtokens; std::string hex; double price; uint256 tokenid;
|
||||||
if ( fHelp || params.size() != 3 )
|
if ( fHelp || params.size() != 3 )
|
||||||
throw runtime_error("tokenbid numtokens tokenid price\n");
|
throw runtime_error("tokenbid numtokens tokenid price\n");
|
||||||
if ( ensure_CCrequirements() < 0 )
|
if ( ensure_CCrequirements() < 0 )
|
||||||
@@ -5435,12 +5483,21 @@ 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;
|
||||||
hex = CreateBuyOffer(0,bidamount,tokenid,numtokens);
|
if ( tokenid == zeroid || tokenid == zeroid || price <= 0 || bidamount <= 0 )
|
||||||
if ( hex.size() > 0 )
|
|
||||||
{
|
{
|
||||||
result.push_back(Pair("result", "success"));
|
result.push_back(Pair("error", "invalid parameter"));
|
||||||
result.push_back(Pair("hex", hex));
|
return(result);
|
||||||
} else result.push_back(Pair("error", "couldnt create bid"));
|
}
|
||||||
|
hex = CreateBuyOffer(0,bidamount,tokenid,numtokens);
|
||||||
|
if (price > 0 && numtokens > 0) {
|
||||||
|
if ( hex.size() > 0 )
|
||||||
|
{
|
||||||
|
result.push_back(Pair("result", "success"));
|
||||||
|
result.push_back(Pair("hex", hex));
|
||||||
|
} else result.push_back(Pair("error", "couldnt create bid"));
|
||||||
|
} else {
|
||||||
|
ERR_RESULT("price and numtokens must be positive");
|
||||||
|
}
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5455,12 +5512,17 @@ UniValue tokencancelbid(const UniValue& params, bool fHelp)
|
|||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
||||||
bidtxid = Parseuint256((char *)params[1].get_str().c_str());
|
bidtxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||||
|
if ( tokenid == zeroid || bidtxid == zeroid )
|
||||||
|
{
|
||||||
|
result.push_back(Pair("error", "invalid parameter"));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
hex = CancelBuyOffer(0,tokenid,bidtxid);
|
hex = CancelBuyOffer(0,tokenid,bidtxid);
|
||||||
if ( hex.size() > 0 )
|
if ( hex.size() > 0 )
|
||||||
{
|
{
|
||||||
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 cancel bid"));
|
} else ERR_RESULT("couldnt cancel bid");
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5476,18 +5538,23 @@ UniValue tokenfillbid(const UniValue& params, bool fHelp)
|
|||||||
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
||||||
bidtxid = Parseuint256((char *)params[1].get_str().c_str());
|
bidtxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||||
fillamount = atol(params[2].get_str().c_str());
|
fillamount = atol(params[2].get_str().c_str());
|
||||||
|
if ( tokenid == zeroid || bidtxid == zeroid || fillamount <= 0 )
|
||||||
|
{
|
||||||
|
result.push_back(Pair("error", "invalid parameter"));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
hex = FillBuyOffer(0,tokenid,bidtxid,fillamount);
|
hex = FillBuyOffer(0,tokenid,bidtxid,fillamount);
|
||||||
if ( hex.size() > 0 )
|
if ( hex.size() > 0 )
|
||||||
{
|
{
|
||||||
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 fill bid"));
|
} else ERR_RESULT("couldnt fill bid");
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue tokenask(const UniValue& params, bool fHelp)
|
UniValue tokenask(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
UniValue result(UniValue::VOBJ); uint64_t askamount,numtokens; std::string hex; double price; uint256 tokenid;
|
UniValue result(UniValue::VOBJ); int64_t askamount,numtokens; std::string hex; double price; uint256 tokenid;
|
||||||
if ( fHelp || params.size() != 3 )
|
if ( fHelp || params.size() != 3 )
|
||||||
throw runtime_error("tokenask numtokens tokenid price\n");
|
throw runtime_error("tokenask numtokens tokenid price\n");
|
||||||
if ( ensure_CCrequirements() < 0 )
|
if ( ensure_CCrequirements() < 0 )
|
||||||
@@ -5498,19 +5565,28 @@ UniValue tokenask(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());
|
||||||
askamount = (price * numtokens) * COIN + 0.0000000049999;
|
askamount = (price * numtokens) * COIN + 0.0000000049999;
|
||||||
hex = CreateSell(0,numtokens,tokenid,askamount);
|
if ( tokenid == zeroid || numtokens <= 0 || price <= 0 || askamount <= 0 )
|
||||||
if ( hex.size() > 0 )
|
|
||||||
{
|
{
|
||||||
result.push_back(Pair("result", "success"));
|
result.push_back(Pair("error", "invalid parameter"));
|
||||||
result.push_back(Pair("hex", hex));
|
return(result);
|
||||||
} else result.push_back(Pair("error", "couldnt create ask"));
|
}
|
||||||
|
hex = CreateSell(0,numtokens,tokenid,askamount);
|
||||||
|
if (price > 0 && numtokens > 0) {
|
||||||
|
if ( hex.size() > 0 )
|
||||||
|
{
|
||||||
|
result.push_back(Pair("result", "success"));
|
||||||
|
result.push_back(Pair("hex", hex));
|
||||||
|
} else ERR_RESULT("couldnt create ask");
|
||||||
|
} else {
|
||||||
|
ERR_RESULT("price and numtokens must be positive");
|
||||||
|
}
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue tokenswapask(const UniValue& params, bool fHelp)
|
UniValue tokenswapask(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
static uint256 zeroid;
|
static uint256 zeroid;
|
||||||
UniValue result(UniValue::VOBJ); uint64_t askamount,numtokens; std::string hex; double price; uint256 tokenid,otherid;
|
UniValue result(UniValue::VOBJ); int64_t askamount,numtokens; std::string hex; double price; uint256 tokenid,otherid;
|
||||||
if ( fHelp || params.size() != 4 )
|
if ( fHelp || params.size() != 4 )
|
||||||
throw runtime_error("tokenswapask numtokens tokenid otherid price\n");
|
throw runtime_error("tokenswapask numtokens tokenid otherid price\n");
|
||||||
if ( ensure_CCrequirements() < 0 )
|
if ( ensure_CCrequirements() < 0 )
|
||||||
@@ -5523,11 +5599,15 @@ UniValue tokenswapask(const UniValue& params, bool fHelp)
|
|||||||
price = atof(params[3].get_str().c_str());
|
price = atof(params[3].get_str().c_str());
|
||||||
askamount = (price * numtokens);
|
askamount = (price * numtokens);
|
||||||
hex = CreateSwap(0,numtokens,tokenid,otherid,askamount);
|
hex = CreateSwap(0,numtokens,tokenid,otherid,askamount);
|
||||||
if ( hex.size() > 0 )
|
if (price > 0 && numtokens > 0) {
|
||||||
{
|
if ( hex.size() > 0 )
|
||||||
result.push_back(Pair("result", "success"));
|
{
|
||||||
result.push_back(Pair("hex", hex));
|
result.push_back(Pair("result", "success"));
|
||||||
} else result.push_back(Pair("error", "couldnt create swap"));
|
result.push_back(Pair("hex", hex));
|
||||||
|
} else ERR_RESULT("couldnt create swap");
|
||||||
|
} else {
|
||||||
|
ERR_RESULT("price and numtokens must be positive");
|
||||||
|
}
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5542,18 +5622,22 @@ UniValue tokencancelask(const UniValue& params, bool fHelp)
|
|||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
||||||
asktxid = Parseuint256((char *)params[1].get_str().c_str());
|
asktxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||||
|
if ( tokenid == zeroid || asktxid == zeroid )
|
||||||
|
{
|
||||||
|
result.push_back(Pair("error", "invalid parameter"));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
hex = CancelSell(0,tokenid,asktxid);
|
hex = CancelSell(0,tokenid,asktxid);
|
||||||
if ( hex.size() > 0 )
|
if ( hex.size() > 0 )
|
||||||
{
|
{
|
||||||
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 cancel bid"));
|
} else ERR_RESULT("couldnt cancel ask");
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue tokenfillask(const UniValue& params, bool fHelp)
|
UniValue tokenfillask(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
static uint256 zeroid;
|
|
||||||
UniValue result(UniValue::VOBJ); uint64_t fillunits; std::string hex; uint256 tokenid,asktxid;
|
UniValue result(UniValue::VOBJ); uint64_t fillunits; std::string hex; uint256 tokenid,asktxid;
|
||||||
if ( fHelp || params.size() != 3 )
|
if ( fHelp || params.size() != 3 )
|
||||||
throw runtime_error("tokenfillask tokenid asktxid fillunits\n");
|
throw runtime_error("tokenfillask tokenid asktxid fillunits\n");
|
||||||
@@ -5564,19 +5648,31 @@ UniValue tokenfillask(const UniValue& params, bool fHelp)
|
|||||||
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
||||||
asktxid = Parseuint256((char *)params[1].get_str().c_str());
|
asktxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||||
fillunits = atol(params[2].get_str().c_str());
|
fillunits = atol(params[2].get_str().c_str());
|
||||||
hex = FillSell(0,tokenid,zeroid,asktxid,fillunits);
|
if ( tokenid == zeroid || asktxid == zeroid || fillunits <= 0 )
|
||||||
if ( hex.size() > 0 )
|
|
||||||
{
|
{
|
||||||
result.push_back(Pair("result", "success"));
|
result.push_back(Pair("error", "invalid parameter"));
|
||||||
result.push_back(Pair("hex", hex));
|
return(result);
|
||||||
} else result.push_back(Pair("error", "couldnt fill bid"));
|
}
|
||||||
|
hex = FillSell(0,tokenid,zeroid,asktxid,fillunits);
|
||||||
|
if (fillunits > 0) {
|
||||||
|
if (CCerror != "") {
|
||||||
|
ERR_RESULT(CCerror);
|
||||||
|
} else if ( hex.size() > 0) {
|
||||||
|
result.push_back(Pair("result", "success"));
|
||||||
|
result.push_back(Pair("hex", hex));
|
||||||
|
} else {
|
||||||
|
ERR_RESULT("couldnt fill bid");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ERR_RESULT("fillunits must be positive");
|
||||||
|
}
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue tokenfillswap(const UniValue& params, bool fHelp)
|
UniValue tokenfillswap(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
static uint256 zeroid;
|
static uint256 zeroid;
|
||||||
UniValue result(UniValue::VOBJ); uint64_t fillunits; std::string hex; uint256 tokenid,otherid,asktxid;
|
UniValue result(UniValue::VOBJ); int64_t fillunits; std::string hex; uint256 tokenid,otherid,asktxid;
|
||||||
if ( fHelp || params.size() != 4 )
|
if ( fHelp || params.size() != 4 )
|
||||||
throw runtime_error("tokenfillswap tokenid otherid asktxid fillunits\n");
|
throw runtime_error("tokenfillswap tokenid otherid asktxid fillunits\n");
|
||||||
if ( ensure_CCrequirements() < 0 )
|
if ( ensure_CCrequirements() < 0 )
|
||||||
@@ -5588,11 +5684,14 @@ UniValue tokenfillswap(const UniValue& params, bool fHelp)
|
|||||||
asktxid = Parseuint256((char *)params[2].get_str().c_str());
|
asktxid = Parseuint256((char *)params[2].get_str().c_str());
|
||||||
fillunits = atol(params[3].get_str().c_str());
|
fillunits = atol(params[3].get_str().c_str());
|
||||||
hex = FillSell(0,tokenid,otherid,asktxid,fillunits);
|
hex = FillSell(0,tokenid,otherid,asktxid,fillunits);
|
||||||
if ( hex.size() > 0 )
|
if (fillunits > 0) {
|
||||||
{
|
if ( hex.size() > 0 ) {
|
||||||
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 fill bid"));
|
} else ERR_RESULT("couldnt fill bid");
|
||||||
|
} else {
|
||||||
|
ERR_RESULT("fillunits must be positive");
|
||||||
|
}
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user