@@ -1,6 +1,6 @@
|
||||
package=googletest
|
||||
$(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)_download_file=release-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=58a6f4277ca2bc8565222b3bbd58a177609e9c488e8a72649359ba51450db7d8
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package=libevent
|
||||
$(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)_download_file=release-$($(package)_version)-stable.tar.gz
|
||||
$(package)_sha256_hash=316ddb401745ac5d222d7c529ef1eada12f58f6376a66c1118eee803cb70f83d
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package=libgmp
|
||||
|
||||
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)_download_file=$($(package)_git_commit).tar.gz
|
||||
$(package)_sha256_hash=193836c1acc9dc00fe2521205d7bbe1ba13263f6cbef6f02584bf6f8b34b108f
|
||||
@@ -9,7 +9,7 @@ $(package)_git_commit=053c03b1cab347671d936f43ef66b48ab5e380ee
|
||||
$(package)_dependencies=
|
||||
$(package)_config_opts=--enable-cxx --disable-shared
|
||||
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)_download_file=$($(package)_git_commit).tar.gz
|
||||
$(package)_sha256_hash=59b2c2b5d58fdf5943bfde1fa709e9eb53e7e072c9699d28dc1c2cbb3c8cc32c
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package=librustzcash
|
||||
$(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)_download_file=$($(package)_git_commit).tar.gz
|
||||
$(package)_sha256_hash=a5760a90d4a1045c8944204f29fa2a3cf2f800afee400f88bf89bbfe2cce1279
|
||||
|
||||
@@ -9,7 +9,7 @@ $(package)_config_opts=
|
||||
else
|
||||
package=libsodium
|
||||
$(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)_sha256_hash=fb6a9e879a2f674592e4328c5d9f79f082405ee4bb05cb6e679b90afe9e178f4
|
||||
$(package)_dependencies=
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
ifeq ($(host_os),mingw32)
|
||||
$(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)_file_name=libzmq-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=0e225b85ce11be23bf7eb7d3f25c6686728bf30d5c31f61c12d37bb646c69962
|
||||
|
||||
@@ -11,6 +11,7 @@ export BITCOIND=${REAL_BITCOIND}
|
||||
#Run the tests
|
||||
|
||||
testScripts=(
|
||||
'cryptoconditions.py'
|
||||
'paymentdisclosure.py'
|
||||
'prioritisetransaction.py'
|
||||
'wallet_treestate.py'
|
||||
|
||||
@@ -13,6 +13,6 @@ EXEEXT="@EXEEXT@"
|
||||
@ENABLE_ZMQ_TRUE@ENABLE_ZMQ=1
|
||||
@ENABLE_PROTON_TRUE@ENABLE_PROTON=1
|
||||
|
||||
REAL_BITCOIND="$BUILDDIR/src/zcashd${EXEEXT}"
|
||||
REAL_BITCOINCLI="$BUILDDIR/src/zcash-cli${EXEEXT}"
|
||||
REAL_BITCOIND="$BUILDDIR/src/komodod${EXEEXT}"
|
||||
REAL_BITCOINCLI="$BUILDDIR/src/komodo-cli${EXEEXT}"
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@ Possible options:
|
||||
|
||||
```
|
||||
-h, --help show this help message and exit
|
||||
--nocleanup Leave bitcoinds and test.* datadir on exit or error
|
||||
--noshutdown Don't stop bitcoinds after the test execution
|
||||
--srcdir=SRCDIR Source directory containing bitcoind/bitcoin-cli (default:
|
||||
--nocleanup Leave komodods and test.* datadir on exit or error
|
||||
--noshutdown Don't stop komodods after the test execution
|
||||
--srcdir=SRCDIR Source directory containing komodod/komodo-cli (default:
|
||||
../../src)
|
||||
--tmpdir=TMPDIR Root directory for datadirs
|
||||
--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
|
||||
is created the first time a regression test is run and
|
||||
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
|
||||
copied into a temporary directory and used as the initial
|
||||
@@ -42,5 +42,5 @@ to recover with:
|
||||
|
||||
```bash
|
||||
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.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",
|
||||
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",
|
||||
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"),
|
||||
help="Root directory for datadirs")
|
||||
parser.add_option("--tracerpc", dest="trace_rpc", default=False, action="store_true",
|
||||
@@ -137,7 +137,7 @@ class BitcoinTestFramework(object):
|
||||
stop_nodes(self.nodes)
|
||||
wait_bitcoinds()
|
||||
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:
|
||||
print("Cleaning up")
|
||||
@@ -151,7 +151,7 @@ class BitcoinTestFramework(object):
|
||||
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:
|
||||
# 1 binary: test binary
|
||||
# 2 binaries: 1 test binary, 1 ref binary
|
||||
@@ -165,10 +165,10 @@ class ComparisonTestFramework(BitcoinTestFramework):
|
||||
|
||||
def add_options(self, parser):
|
||||
parser.add_option("--testbinary", dest="testbinary",
|
||||
default=os.getenv("BITCOIND", "bitcoind"),
|
||||
default=os.getenv("BITCOIND", "komodod"),
|
||||
help="bitcoind binary to test")
|
||||
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)")
|
||||
|
||||
def setup_chain(self):
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Copyright (c) 2018 The SuperNET developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# 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))
|
||||
if not os.path.isdir(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("txindex=1\n");
|
||||
f.write("server=1\n");
|
||||
f.write("showmetrics=0\n");
|
||||
f.write("rpcuser=rt\n");
|
||||
f.write("rpcpassword=rt\n");
|
||||
f.write("port="+str(p2p_port(n))+"\n");
|
||||
f.write("rpcport="+str(rpc_port(n))+"\n");
|
||||
#f.write("port="+str(p2p_port(n))+"\n");
|
||||
#rpcport = str(rpc_port(n))
|
||||
#f.write("rpcport="+rpcport+"\n");
|
||||
#print "RPC port=" + rpcport
|
||||
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
|
||||
|
||||
def initialize_chain(test_dir):
|
||||
"""
|
||||
Create (or copy from cache) a 200-block-long chain and
|
||||
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")):
|
||||
devnull = open("/dev/null", "w+")
|
||||
# Create cache directories, run bitcoinds:
|
||||
# Create cache directories, run komodods:
|
||||
for i in range(4):
|
||||
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:
|
||||
args.append("-connect=127.0.0.1:"+str(p2p_port(0)))
|
||||
bitcoind_processes[i] = subprocess.Popen(args)
|
||||
cmd = os.getenv("BITCOINCLI", "komodo-cli")
|
||||
cmd_args = cmd + " -datadir="+datadir + " -rpcwait getblockcount"
|
||||
if os.getenv("PYTHON_DEBUG", ""):
|
||||
print "initialize_chain: bitcoind started, calling bitcoin-cli -rpcwait getblockcount"
|
||||
subprocess.check_call([ os.getenv("BITCOINCLI", "bitcoin-cli"), "-datadir="+datadir,
|
||||
"-rpcwait", "getblockcount"], stdout=devnull)
|
||||
print "initialize_chain: komodod started, calling: " + cmd_args
|
||||
strcmd = cmd + " " + "-datadir="+datadir + " -rpcwait getblockcount"
|
||||
|
||||
print("Running " + strcmd)
|
||||
subprocess.check_call(strcmd, shell=True);
|
||||
#subprocess.check_call([ cmd, "-rpcwait", "getblockcount"], stdout=devnull)
|
||||
if os.getenv("PYTHON_DEBUG", ""):
|
||||
print "initialize_chain: bitcoin-cli -rpcwait getblockcount completed"
|
||||
print "initialize_chain: komodo-cli -rpcwait getblockcount completed"
|
||||
devnull.close()
|
||||
rpcs = []
|
||||
for i in range(4):
|
||||
@@ -144,7 +162,7 @@ def initialize_chain(test_dir):
|
||||
from_dir = os.path.join("cache", "node"+str(i))
|
||||
to_dir = os.path.join(test_dir, "node"+str(i))
|
||||
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):
|
||||
"""
|
||||
@@ -177,34 +195,50 @@ def _rpchost_to_args(rpchost):
|
||||
|
||||
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))
|
||||
if binary is None:
|
||||
binary = os.getenv("BITCOIND", "bitcoind")
|
||||
binary = os.getenv("BITCOIND", "komodod")
|
||||
args = [ binary, "-datadir="+datadir, "-keypool=1", "-discover=0", "-rest" ]
|
||||
if extra_args is not None: args.extend(extra_args)
|
||||
#print("args=" + ' '.join(args))
|
||||
bitcoind_processes[i] = subprocess.Popen(args)
|
||||
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", ""):
|
||||
print "start_node: bitcoind started, calling bitcoin-cli -rpcwait getblockcount"
|
||||
subprocess.check_call([ os.getenv("BITCOINCLI", "bitcoin-cli"), "-datadir="+datadir] +
|
||||
_rpchost_to_args(rpchost) +
|
||||
["-rpcwait", "getblockcount"], stdout=devnull)
|
||||
print "start_node: komodod started, calling : " + cmd + " " + cmd_args
|
||||
strcmd = cmd + " " + cmd_args
|
||||
|
||||
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", ""):
|
||||
print "start_node: calling bitcoin-cli -rpcwait getblockcount returned"
|
||||
print "start_node: calling komodo-cli -rpcwait getblockcount returned"
|
||||
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:
|
||||
proxy = AuthServiceProxy(url, timeout=timewait)
|
||||
else:
|
||||
proxy = AuthServiceProxy(url)
|
||||
print("created proxy")
|
||||
proxy.url = url # store URL on proxy for info
|
||||
return proxy
|
||||
|
||||
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 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
|
||||
{
|
||||
unitprice = (orig_nValue * COIN) / totalunits;
|
||||
recvunitprice = (received_nValue * COIN) / paidunits;
|
||||
//unitprice = (orig_nValue * COIN) / totalunits;
|
||||
//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 )
|
||||
newunitprice = (remaining_nValue * COIN) / remaining_units;
|
||||
newunitprice = (remaining_nValue / remaining_units);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
@@ -89,8 +93,10 @@ bool SetBidFillamounts(int64_t &received_nValue,int64_t &remaining_units,int64_t
|
||||
return(true);
|
||||
}
|
||||
remaining_units = (totalunits - paidunits);
|
||||
unitprice = (orig_nValue * COIN) / totalunits;
|
||||
received_nValue = (paidunits * unitprice) / COIN;
|
||||
//unitprice = (orig_nValue * COIN) / totalunits;
|
||||
//received_nValue = (paidunits * unitprice) / COIN;
|
||||
unitprice = (orig_nValue / totalunits);
|
||||
received_nValue = (paidunits * unitprice);
|
||||
if ( unitprice > 0 && received_nValue > 0 && received_nValue <= orig_nValue )
|
||||
{
|
||||
remaining_nValue = (orig_nValue - received_nValue);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
******************************************************************************/
|
||||
|
||||
#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)
|
||||
{
|
||||
@@ -60,20 +61,21 @@ UniValue AssetInfo(uint256 assetid)
|
||||
if ( GetTransaction(assetid,vintx,hashBlock,false) == 0 )
|
||||
{
|
||||
fprintf(stderr,"cant find assetid\n");
|
||||
result.push_back(Pair("result","error"));
|
||||
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 )
|
||||
{
|
||||
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("result","success"));
|
||||
result.push_back(Pair("tokenid",uint256_str(str,assetid)));
|
||||
result.push_back(Pair("owner",pubkey33_str(str,origpubkey.data())));
|
||||
result.push_back(Pair("name",name));
|
||||
sprintf(numstr,"%.8f",(double)vintx.vout[0].nValue/COIN);
|
||||
result.push_back(Pair("supply",numstr));
|
||||
result.push_back(Pair("supply",vintx.vout[0].nValue));
|
||||
result.push_back(Pair("description",description));
|
||||
return(result);
|
||||
}
|
||||
@@ -182,13 +184,13 @@ std::string CreateAsset(int64_t txfee,int64_t assetsupply,std::string name,std::
|
||||
if ( assetsupply < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative assetsupply %lld\n",(long long)assetsupply);
|
||||
return(0);
|
||||
return("");
|
||||
}
|
||||
cp = CCinit(&C,EVAL_ASSETS);
|
||||
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());
|
||||
return(0);
|
||||
return("");
|
||||
}
|
||||
if ( txfee == 0 )
|
||||
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));
|
||||
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)
|
||||
@@ -208,7 +210,7 @@ std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector<uint8_t> des
|
||||
if ( total < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative total %lld\n",(long long)total);
|
||||
return(0);
|
||||
return("");
|
||||
}
|
||||
cp = CCinit(&C,EVAL_ASSETS);
|
||||
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,"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)
|
||||
@@ -243,17 +245,17 @@ std::string CreateBuyOffer(int64_t txfee,int64_t bidamount,uint256 assetid,int64
|
||||
if ( bidamount < 0 || pricetotal < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative bidamount %lld, pricetotal %lld\n",(long long)bidamount,(long long)pricetotal);
|
||||
return(0);
|
||||
return("");
|
||||
}
|
||||
if ( GetTransaction(assetid,vintx,hashBlock,false) == 0 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
fprintf(stderr,"assetid isnt assetcreation txid\n");
|
||||
return(0);
|
||||
return("");
|
||||
}
|
||||
cp = CCinit(&C,EVAL_ASSETS);
|
||||
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)));
|
||||
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)
|
||||
@@ -273,7 +275,7 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p
|
||||
if ( askamount < 0 || pricetotal < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative askamount %lld, askamount %lld\n",(long long)pricetotal,(long long)askamount);
|
||||
return(0);
|
||||
return("");
|
||||
}
|
||||
cp = CCinit(&C,EVAL_ASSETS);
|
||||
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");
|
||||
}
|
||||
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)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C;
|
||||
fprintf(stderr,"asset swaps disabled\n");
|
||||
return(0);
|
||||
return("");
|
||||
if ( askamount < 0 || pricetotal < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative askamount %lld, askamount %lld\n",(long long)pricetotal,(long long)askamount);
|
||||
return(0);
|
||||
return("");
|
||||
}
|
||||
cp = CCinit(&C,EVAL_ASSETS);
|
||||
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");
|
||||
}
|
||||
fprintf(stderr,"need some native coins to place ask\n");
|
||||
return(0);
|
||||
return("");
|
||||
}
|
||||
|
||||
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(0);
|
||||
return("");
|
||||
}
|
||||
|
||||
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(0);
|
||||
return("");
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
fprintf(stderr,"negative fillamount %lld\n",(long long)fillamount);
|
||||
return(0);
|
||||
return("");
|
||||
}
|
||||
cp = CCinit(&C,EVAL_ASSETS);
|
||||
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;
|
||||
if ( fillunits < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative fillunits %lld\n",(long long)fillunits);
|
||||
return(0);
|
||||
CCerror = strprintf("negative fillunits %lld\n",(long long)fillunits);
|
||||
fprintf(stderr,"%s\n",CCerror.c_str());
|
||||
return("");
|
||||
}
|
||||
if ( assetid2 != zeroid )
|
||||
{
|
||||
fprintf(stderr,"asset swaps disabled\n");
|
||||
return(0);
|
||||
CCerror = "asset swaps disabled";
|
||||
fprintf(stderr,"%s\n",CCerror.c_str());
|
||||
return("");
|
||||
}
|
||||
|
||||
cp = CCinit(&C,EVAL_ASSETS);
|
||||
@@ -472,8 +476,11 @@ std::string FillSell(int64_t txfee,uint256 assetid,uint256 assetid2,uint256 askt
|
||||
if ( CCchange != 0 )
|
||||
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)));
|
||||
} 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("");
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "CCinclude.h"
|
||||
|
||||
#define EVAL_FAUCET 0xe4
|
||||
#define FAUCETSIZE (COIN / 10)
|
||||
|
||||
bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ bool myAddtomempool(CTransaction &tx);
|
||||
bool myIsutxo_spentinmempool(uint256 txid,int32_t vout);
|
||||
int32_t myIsutxo_spent(uint256 &spenttxid,uint256 txid,int32_t vout);
|
||||
bool mySendrawtransaction(std::string res);
|
||||
int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex);
|
||||
|
||||
// CCcustom
|
||||
CPubKey GetUnspendable(struct CCcontract_info *cp,uint8_t *unspendablepriv);
|
||||
@@ -100,5 +101,6 @@ bits256 curve25519_shared(bits256 privkey,bits256 otherpub);
|
||||
bits256 curve25519_basepoint9();
|
||||
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);
|
||||
bits256 bits256_doublesha256(char *deprecated,uint8_t *data,int32_t datalen);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -79,6 +79,12 @@ winner:
|
||||
timeout:
|
||||
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"
|
||||
@@ -313,18 +319,21 @@ uint256 DiceGetEntropy(CTransaction tx,uint8_t reffuncid)
|
||||
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 ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 )
|
||||
return(tx.vout[v].nValue);
|
||||
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 && (numvouts= tx.vout.size()) > 0 )
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
numvins = tx.vin.size();
|
||||
@@ -338,7 +347,7 @@ int64_t DiceAmounts(uint64_t &inputs,uint64_t &outputs,struct CCcontract_info *c
|
||||
return eval->Invalid("always should find vin, but didnt");
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -346,7 +355,7 @@ int64_t DiceAmounts(uint64_t &inputs,uint64_t &outputs,struct CCcontract_info *c
|
||||
for (i=0; i<numvouts; i++)
|
||||
{
|
||||
//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;
|
||||
}
|
||||
return(inputs - outputs);
|
||||
@@ -487,6 +496,7 @@ bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
||||
DiceQueue(iswin,sbits,fundingtxid,txid);
|
||||
}
|
||||
break;
|
||||
// make sure all funding txid are from matching sbits and fundingtxid!!
|
||||
case 'L':
|
||||
case 'W':
|
||||
case 'T':
|
||||
@@ -496,7 +506,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'
|
||||
//vout.1: tag to owner address for entropy funds
|
||||
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 )
|
||||
return eval->Invalid("vin0 or vin1 normal vin for bet");
|
||||
else if ( tx.vin[1].prevout.hash != tx.vin[2].prevout.hash )
|
||||
@@ -567,7 +577,7 @@ bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
||||
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;
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
@@ -589,14 +599,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 == '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 )
|
||||
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
||||
totalinputs += it->second.satoshis;
|
||||
n++;
|
||||
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
|
||||
break;
|
||||
if ( funcid == 'F' || funcid == 'E' || funcid == 'W' || funcid == 'L' || funcid == 'T' )
|
||||
{
|
||||
if ( total != 0 && maxinputs != 0 )
|
||||
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
||||
totalinputs += it->second.satoshis;
|
||||
n++;
|
||||
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else fprintf(stderr,"null funcid\n");
|
||||
}
|
||||
@@ -626,13 +642,11 @@ int64_t DicePlanFunds(uint64_t &entropyval,uint256 &entropytxid,uint64_t refsbit
|
||||
{
|
||||
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' )
|
||||
{
|
||||
n++;
|
||||
fprintf(stderr,"%s.(%c %.8f) ",uint256_str(str,txid),funcid,(double)nValue/COIN);
|
||||
}
|
||||
totalinputs += nValue;
|
||||
if ( first == 0 && (funcid == 'E' || funcid == 'W' || funcid == 'L') )
|
||||
{
|
||||
@@ -897,7 +911,7 @@ std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet
|
||||
|
||||
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;
|
||||
//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 )
|
||||
@@ -960,21 +974,23 @@ std::string DiceBetFinish(int32_t *resultp,uint64_t txfee,char *planstr,uint256
|
||||
fprintf(stderr,"illegal odds.%d vs maxodds.%d\n",(int32_t)odds,(int32_t)maxodds);
|
||||
return("");
|
||||
}
|
||||
CCchange = betTx.vout[0].nValue;
|
||||
fundsneeded = txfee + odds*betTx.vout[1].nValue;
|
||||
if ( (inputs= AddDiceInputs(cp,mtx,dicepk,fundsneeded,60)) > 0 )
|
||||
CCchange = betTx.vout[0].nValue + betTx.vout[1].nValue;
|
||||
fundsneeded = txfee + (odds+1)*betTx.vout[1].nValue;
|
||||
if ( CCchange >= fundsneeded )
|
||||
CCchange -= fundsneeded;
|
||||
else if ( (inputs= AddDiceInputs(cp,mtx,dicepk,fundsneeded,60,sbits,fundingtxid)) > 0 )
|
||||
{
|
||||
if ( 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
|
||||
{
|
||||
fprintf(stderr,"not enough inputs for %.8f\n",(double)fundsneeded/COIN);
|
||||
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
|
||||
{
|
||||
@@ -1047,14 +1063,19 @@ double DiceStatus(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettx
|
||||
}
|
||||
else
|
||||
{
|
||||
char str[65];
|
||||
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.);
|
||||
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 )
|
||||
res = DiceBetFinish(&result,txfee,planstr,fundingtxid,bettxid,1);
|
||||
@@ -1065,15 +1086,17 @@ double DiceStatus(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettx
|
||||
sleep(1);
|
||||
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.);
|
||||
else return((double)spenttx.vout[2].nValue/COIN);
|
||||
} else return(0.);
|
||||
}
|
||||
fprintf(stderr,"didnt find dicefinish tx\n");
|
||||
} else return(-1.);
|
||||
}
|
||||
return(-1.);
|
||||
}
|
||||
return(0.);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ bool RunCCEval(const CC *cond, const CTransaction &tx, unsigned int nIn)
|
||||
pthread_mutex_lock(&KOMODO_CC_mutex);
|
||||
bool out = eval->Dispatch(cond, tx, nIn);
|
||||
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);
|
||||
|
||||
if (eval->state.IsValid()) return true;
|
||||
|
||||
@@ -69,17 +69,18 @@ bool FaucetExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction
|
||||
if ( (assetoshis= IsFaucetvout(cp,tx,i)) != 0 )
|
||||
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);
|
||||
return eval->Invalid("mismatched inputs != outputs + COIN + txfee");
|
||||
return eval->Invalid("mismatched inputs != outputs + FAUCETSIZE + txfee");
|
||||
}
|
||||
else return(true);
|
||||
}
|
||||
|
||||
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();
|
||||
numvouts = tx.vout.size();
|
||||
preventCCvins = preventCCvouts = -1;
|
||||
@@ -87,7 +88,6 @@ bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
|
||||
return eval->Invalid("no vouts");
|
||||
else
|
||||
{
|
||||
//fprintf(stderr,"check vins\n");
|
||||
for (i=0; i<numvins; i++)
|
||||
{
|
||||
if ( IsCCInput(tx.vin[0].scriptSig) == 0 )
|
||||
@@ -110,8 +110,24 @@ bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
|
||||
preventCCvouts++;
|
||||
i = 1;
|
||||
} 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");
|
||||
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);
|
||||
if ( retval != 0 )
|
||||
fprintf(stderr,"faucetget validated\n");
|
||||
@@ -154,7 +170,7 @@ int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub
|
||||
|
||||
std::string FaucetGet(uint64_t txfee)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,faucetpk; CScript opret; int64_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);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -167,7 +183,27 @@ std::string FaucetGet(uint64_t txfee)
|
||||
if ( CCchange != 0 )
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_FAUCET,CCchange,faucetpk));
|
||||
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");
|
||||
return("");
|
||||
}
|
||||
|
||||
@@ -66,10 +66,12 @@
|
||||
|
||||
*/
|
||||
|
||||
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;
|
||||
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 )
|
||||
{
|
||||
fprintf(stderr,"duration %llu < minseconds %llu\n",(long long)duration,(long long)minseconds);
|
||||
@@ -77,8 +79,12 @@ int64_t RewardsCalc(int64_t amount,uint256 txid,uint64_t APR,uint64_t minseconds
|
||||
//duration = (uint32_t)time(NULL) - (1532713903 - 3600 * 24);
|
||||
} else if ( duration > maxseconds )
|
||||
duration = maxseconds;
|
||||
reward = (((amount * APR) / COIN) * duration) / (365*24*3600LL * 100);
|
||||
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);
|
||||
if ( 0 ) // amount * APR * duration / COIN * 100 * 365*24*3600
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -182,7 +188,7 @@ bool RewardsExactAmounts(struct CCcontract_info *cp,Eval *eval,const CTransactio
|
||||
}
|
||||
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");
|
||||
}
|
||||
else return(true);
|
||||
@@ -235,19 +241,27 @@ bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
|
||||
case 'U':
|
||||
//vin.0: locked funds CC vout.0 from lock
|
||||
//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.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++)
|
||||
{
|
||||
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) == 0 )
|
||||
return eval->Invalid("unexpected normal vin for unlock");
|
||||
}
|
||||
if ( RewardsExactAmounts(cp,eval,tx,txfee+tx.vout[1].nValue,sbits,fundingtxid) == 0 )
|
||||
return false;
|
||||
else if ( eval->GetTxUnconfirmed(tx.vin[0].prevout.hash,vinTx,hashBlock) == 0 )
|
||||
return eval->Invalid("always should find vin.0, but didnt");
|
||||
else if ( vinTx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
||||
if ( numvouts == 1 && numvins == 1 )
|
||||
{
|
||||
if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||
return eval->Invalid("unlock recover tx vout.0 is not normal output");
|
||||
else if ( tx.vout[0].scriptPubKey != vinTx.vout[1].scriptPubKey )
|
||||
return eval->Invalid("unlock recover tx vout.0 mismatched scriptPubKey");
|
||||
else if ( tx.vout[0].nValue > vinTx.vout[0].nValue )
|
||||
return eval->Invalid("unlock recover tx vout.0 mismatched amounts");
|
||||
else return(true);
|
||||
}
|
||||
if ( vinTx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
||||
return eval->Invalid("lock tx vout.0 is normal output");
|
||||
else if ( tx.vout.size() < 3 )
|
||||
return eval->Invalid("unlock tx not enough vouts");
|
||||
@@ -259,7 +273,9 @@ bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
|
||||
return eval->Invalid("unlock tx vout.1 mismatched scriptPubKey");
|
||||
amount = vinTx.vout[0].nValue;
|
||||
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");
|
||||
preventCCvouts = 1;
|
||||
break;
|
||||
@@ -270,10 +286,38 @@ bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
|
||||
return(true);
|
||||
}
|
||||
|
||||
// 'L' vs 'F' and 'A'
|
||||
int64_t AddRewardsInputs(CScript &scriptPubKey,int32_t fundsflag,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs,uint64_t refsbits,uint256 reffundingtxid)
|
||||
uint64_t myIs_unlockedtx_inmempool(uint256 &txid,int32_t &vout,uint64_t refsbits,uint256 reffundingtxid,uint64_t needed)
|
||||
{
|
||||
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;
|
||||
GetCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
@@ -283,7 +327,7 @@ int64_t AddRewardsInputs(CScript &scriptPubKey,int32_t fundsflag,struct CCcontra
|
||||
vout = (int32_t)it->first.index;
|
||||
if ( it->second.satoshis < 1000000 )
|
||||
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++)
|
||||
if ( txid == mtx.vin[j].prevout.hash && vout == mtx.vin[j].prevout.n )
|
||||
break;
|
||||
@@ -295,14 +339,17 @@ int64_t AddRewardsInputs(CScript &scriptPubKey,int32_t fundsflag,struct CCcontra
|
||||
{
|
||||
if ( sbits != refsbits || fundingtxid != reffundingtxid )
|
||||
continue;
|
||||
fprintf(stderr,"fundsflag.%d (%c) %.8f %.8f\n",fundsflag,funcid,(double)tx.vout[vout].nValue/COIN,(double)it->second.satoshis/COIN);
|
||||
if ( fundsflag != 0 && funcid != 'F' && funcid != 'A' && funcid != 'U' )
|
||||
continue;
|
||||
else if ( fundsflag == 0 && (funcid != 'L' || tx.vout.size() < 4) )
|
||||
if ( maxseconds == 0 && funcid != 'F' && funcid != 'A' && funcid != 'U' )
|
||||
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 ( fundsflag == 0 )
|
||||
if ( maxseconds != 0 )
|
||||
scriptPubKey = tx.vout[1].scriptPubKey;
|
||||
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
||||
}
|
||||
@@ -313,13 +360,25 @@ int64_t AddRewardsInputs(CScript &scriptPubKey,int32_t fundsflag,struct CCcontra
|
||||
} 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);
|
||||
}
|
||||
|
||||
int64_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; int64_t nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t vout; uint8_t funcid;
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
lockedfunds = 0;
|
||||
GetCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
@@ -328,12 +387,16 @@ int64_t RewardsPlanFunds(uint64_t refsbits,struct CCcontract_info *cp,CPubKey pk
|
||||
vout = (int32_t)it->first.index;
|
||||
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,sbits,fundingtxid)) > 0 )
|
||||
totalinputs += nValue;
|
||||
if ( (nValue= IsRewardsvout(cp,tx,vout,sbits,fundingtxid)) > 0 )
|
||||
{
|
||||
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,"else case\n");
|
||||
} else fprintf(stderr,"funcid.%d %c skipped %.8f\n",funcid,funcid,(double)tx.vout[vout].nValue/COIN);
|
||||
@@ -367,16 +430,18 @@ bool RewardsPlanExists(struct CCcontract_info *cp,uint64_t refsbits,CPubKey rewa
|
||||
|
||||
UniValue RewardsInfo(uint256 rewardsid)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); uint256 hashBlock; CTransaction vintx; uint64_t 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 )
|
||||
{
|
||||
fprintf(stderr,"cant find fundingtxid\n");
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","cant find fundingtxid"));
|
||||
return(result);
|
||||
}
|
||||
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");
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","fundingtxid isnt rewards creation txid"));
|
||||
return(result);
|
||||
}
|
||||
@@ -393,9 +458,11 @@ UniValue RewardsInfo(uint256 rewardsid)
|
||||
result.push_back(Pair("mindeposit",numstr));
|
||||
cp = CCinit(&C,EVAL_REWARDS);
|
||||
rewardspk = GetUnspendable(cp,0);
|
||||
funding = RewardsPlanFunds(sbits,cp,rewardspk,rewardsid);
|
||||
funding = RewardsPlanFunds(lockedfunds,sbits,cp,rewardspk,rewardsid);
|
||||
sprintf(numstr,"%.8f",(double)funding/COIN);
|
||||
result.push_back(Pair("funding",numstr));
|
||||
sprintf(numstr,"%.8f",(double)lockedfunds/COIN);
|
||||
result.push_back(Pair("locked",numstr));
|
||||
return(result);
|
||||
}
|
||||
|
||||
@@ -483,10 +550,10 @@ std::string RewardsAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,i
|
||||
|
||||
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;
|
||||
if ( deposit < 0 )
|
||||
CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t lockedfunds,sbits,funding,APR,minseconds,maxseconds,mindeposit; struct CCcontract_info *cp,C;
|
||||
if ( deposit < txfee )
|
||||
{
|
||||
fprintf(stderr,"negative parameter error\n");
|
||||
fprintf(stderr,"deposit amount less than txfee\n");
|
||||
return("");
|
||||
}
|
||||
cp = CCinit(&C,EVAL_REWARDS);
|
||||
@@ -505,16 +572,16 @@ std::string RewardsLock(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t
|
||||
fprintf(stderr,"Rewards plan %s deposit %.8f < mindeposit %.8f\n",planstr,(double)deposit/COIN,(double)mindeposit/COIN);
|
||||
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 )
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,deposit,rewardspk));
|
||||
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||
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("");
|
||||
}
|
||||
|
||||
@@ -530,17 +597,19 @@ std::string RewardsUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint2
|
||||
if ( RewardsPlanExists(cp,sbits,rewardspk,APR,minseconds,maxseconds,mindeposit) == 0 )
|
||||
{
|
||||
fprintf(stderr,"Rewards plan %s doesnt exist\n",planstr);
|
||||
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);
|
||||
if ( locktxid == zeroid )
|
||||
amount = AddRewardsInputs(scriptPubKey,0,cp,mtx,rewardspk,(1LL << 30),1,sbits,fundingtxid);
|
||||
amount = AddRewardsInputs(scriptPubKey,maxseconds,cp,mtx,rewardspk,(1LL << 30),1,sbits,fundingtxid);
|
||||
else
|
||||
{
|
||||
GetCCaddress(cp,coinaddr,rewardspk);
|
||||
if ( (amount= CCutxovalue(coinaddr,locktxid,0)) == 0 )
|
||||
{
|
||||
fprintf(stderr,"%s locktxid/v0 is spent\n",coinaddr);
|
||||
CCerror = "locktxid/v0 is spent";
|
||||
return("");
|
||||
}
|
||||
if ( GetTransaction(locktxid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && tx.vout[1].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
||||
@@ -551,21 +620,50 @@ std::string RewardsUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint2
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"%s no normal vout.1 in locktxid\n",coinaddr);
|
||||
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,sbits,fundingtxid)) > 0 )
|
||||
reward = RewardsCalc(amount,mtx.vin[0].prevout.hash,APR,minseconds,maxseconds,mindeposit);
|
||||
if ( scriptPubKey.size() > 0 )
|
||||
{
|
||||
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)));
|
||||
if ( reward > txfee )
|
||||
{
|
||||
if ( (inputs= AddRewardsInputs(ignore,0,cp,mtx,rewardspk,reward+txfee,30,sbits,fundingtxid)) > 0 )
|
||||
{
|
||||
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
|
||||
{
|
||||
mtx.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,mtx,mypk,txfee,opret));
|
||||
}
|
||||
}
|
||||
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);
|
||||
return("");
|
||||
|
||||
@@ -55,6 +55,7 @@ static void anonToJSON(const CC *cond, cJSON *params) {
|
||||
|
||||
static unsigned char *anonFingerprint(const CC *cond) {
|
||||
unsigned char *out = calloc(1, 32);
|
||||
fprintf(stderr,"anon fingerprint %p %p\n",out,cond->fingerprint);
|
||||
memcpy(out, cond->fingerprint, 32);
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -29,11 +29,7 @@
|
||||
#include "src/json_rpc.c"
|
||||
#include <cJSON.h>
|
||||
|
||||
#ifdef __LP64__
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
#include <malloc.h> // Index into CTransaction.vjoinsplit
|
||||
#endif
|
||||
|
||||
|
||||
struct CCType *CCTypeRegistry[] = {
|
||||
@@ -75,8 +71,7 @@ char *cc_conditionUri(const CC *cond) {
|
||||
unsigned char *encoded = base64_encode(fp, 32);
|
||||
|
||||
unsigned char *out = calloc(1, 1000);
|
||||
sprintf(out, "ni:///sha-256;%s?fpt=%s&cost=%lu",
|
||||
encoded, cc_typeName(cond), cc_getCost(cond));
|
||||
sprintf(out, "ni:///sha-256;%s?fpt=%s&cost=%lu",encoded, cc_typeName(cond), cc_getCost(cond));
|
||||
|
||||
if (cond->type->getSubtypes) {
|
||||
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
|
||||
// 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.
|
||||
|
||||
CompoundSha256Condition_t *choice = &asn->choice.thresholdSha256;
|
||||
choice->cost = cc_getCost(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 *cond = 0;
|
||||
unsigned char *buf = malloc(ffill_bin_len);
|
||||
unsigned char *buf = calloc(1,ffill_bin_len);
|
||||
Fulfillment_t *ffill = 0;
|
||||
asn_dec_rval_t rval = ber_decode(0, &asn_DEF_Fulfillment, (void **)&ffill, ffill_bin, ffill_bin_len);
|
||||
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,
|
||||
VerifyEval verifyEval, void *evalContext) {
|
||||
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);
|
||||
if (0 != memcmp(condBin, targetBinary, binLength)) {
|
||||
fprintf(stderr,"cc_verify error A\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!cc_ed25519VerifyTree(cond, msg, msgLength)) {
|
||||
fprintf(stderr,"cc_verify error B\n");
|
||||
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);
|
||||
|
||||
if (!cc_secp256k1VerifyTreeMsg32(cond, msgHash)) {
|
||||
fprintf(stderr,"cc_verify error C\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!cc_verifyEval(cond, verifyEval, evalContext)) {
|
||||
//fprintf(stderr,"cc_verify error D\n");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
||||
@@ -27,6 +27,7 @@ struct CCType CC_Ed25519Type;
|
||||
|
||||
static unsigned char *ed25519Fingerprint(const CC *cond) {
|
||||
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);
|
||||
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;
|
||||
CCEd25519SigningData *signing = (CCEd25519SigningData*) visitor.context;
|
||||
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,
|
||||
signing->pk, signing->skpk);
|
||||
signing->nSigned++;
|
||||
@@ -141,9 +142,9 @@ static void ed25519ToJSON(const CC *cond, cJSON *params) {
|
||||
|
||||
static CC *ed25519FromFulfillment(const Fulfillment_t *ffill) {
|
||||
CC *cond = cc_new(CC_Ed25519);
|
||||
cond->publicKey = malloc(32);
|
||||
cond->publicKey = calloc(1,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);
|
||||
return cond;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ struct CCType CC_EvalType;
|
||||
|
||||
static unsigned char *evalFingerprint(const CC *cond) {
|
||||
unsigned char *hash = calloc(1, 32);
|
||||
//fprintf(stderr,"evalfingerprint %p %p\n",hash,cond->code);
|
||||
sha256(cond->code, cond->codeLength, hash);
|
||||
return hash;
|
||||
}
|
||||
@@ -68,7 +69,7 @@ static CC *evalFromFulfillment(const Fulfillment_t *ffill) {
|
||||
|
||||
OCTET_STRING_t octets = eval->code;
|
||||
cond->codeLength = octets.size;
|
||||
cond->code = malloc(octets.size);
|
||||
cond->code = calloc(1,octets.size);
|
||||
memcpy(cond->code, octets.buf, octets.size);
|
||||
|
||||
return cond;
|
||||
|
||||
@@ -28,7 +28,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define BUF_SIZE 1024 * 1024
|
||||
#define BUF_SIZE 4096
|
||||
|
||||
typedef char bool;
|
||||
|
||||
@@ -56,8 +56,8 @@ typedef struct CCType {
|
||||
/*
|
||||
* Globals
|
||||
*/
|
||||
struct CCType *CCTypeRegistry[32];
|
||||
int CCTypeRegistryLength;
|
||||
extern struct CCType *CCTypeRegistry[];
|
||||
extern int CCTypeRegistryLength;
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -17,11 +17,8 @@
|
||||
#include "internal.h"
|
||||
#include <cJSON.h>
|
||||
|
||||
#ifdef __LP64__
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
#include <malloc.h> // Index into CTransaction.vjoinsplit
|
||||
#endif
|
||||
|
||||
|
||||
static cJSON *jsonCondition(CC *cond) {
|
||||
cJSON *root = cJSON_CreateObject();
|
||||
|
||||
@@ -26,7 +26,7 @@ struct CCType CC_PrefixType;
|
||||
|
||||
static int prefixVisitChildren(CC *cond, CCVisitor visitor) {
|
||||
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->prefixLength, visitor.msg, visitor.msgLength);
|
||||
visitor.msg = prefixed;
|
||||
@@ -39,6 +39,7 @@ static int prefixVisitChildren(CC *cond, CCVisitor visitor) {
|
||||
|
||||
static unsigned char *prefixFingerprint(const CC *cond) {
|
||||
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
|
||||
fp->maxMessageLength = cond->maxMessageLength;
|
||||
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) {
|
||||
unsigned char *hash = calloc(1, 32);
|
||||
//fprintf(stderr,"preimage %p %p\n",hash,cond->preimage);
|
||||
sha256(cond->preimage, cond->preimageLength, hash);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@ void initVerify() {
|
||||
|
||||
static unsigned char *secp256k1Fingerprint(const CC *cond) {
|
||||
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);
|
||||
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) {
|
||||
/* Create fingerprint */
|
||||
ThresholdFingerprintContents_t *fp = calloc(1, sizeof(ThresholdFingerprintContents_t));
|
||||
//fprintf(stderr,"thresholdfinger %p\n",fp);
|
||||
fp->threshold = cond->threshold;
|
||||
for (int i=0; i<cond->size; i++) {
|
||||
Condition_t *asnCond = asnConditionNew(cond->subconditions[i]);
|
||||
|
||||
@@ -39,7 +39,7 @@ static int mod_table[] = {0, 2, 1};
|
||||
|
||||
|
||||
void build_decoding_table() {
|
||||
decoding_table = malloc(256);
|
||||
decoding_table = calloc(1,256);
|
||||
for (int i = 0; i < 64; 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);
|
||||
|
||||
unsigned char *encoded_data = malloc(output_length + 1);
|
||||
unsigned char *encoded_data = calloc(1,output_length + 1);
|
||||
if (encoded_data == NULL) return NULL;
|
||||
|
||||
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_);
|
||||
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_);
|
||||
|
||||
// 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 - 2] == '=') (*output_length)--;
|
||||
|
||||
unsigned char *decoded_data = malloc(*output_length);
|
||||
unsigned char *decoded_data = calloc(1,*output_length);
|
||||
if (decoded_data == NULL) return NULL;
|
||||
|
||||
for (int i = 0, j = 0; i < input_length;) {
|
||||
@@ -137,6 +137,7 @@ unsigned char *base64_decode(const unsigned char *data_,
|
||||
|
||||
void base64_cleanup() {
|
||||
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");
|
||||
return 0;
|
||||
}
|
||||
unsigned char *hash = malloc(32);
|
||||
unsigned char *hash = calloc(1,32);
|
||||
sha256(buf, rc.encoded, 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* hex = malloc(len*2+1);
|
||||
char* hex = calloc(1,len*2+1);
|
||||
if (bin == NULL) return hex;
|
||||
char map[16] = "0123456789ABCDEF";
|
||||
for (int i=0; i<len; i++) {
|
||||
|
||||
@@ -1327,14 +1327,16 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he
|
||||
ave = (sum / arith_uint256(m));
|
||||
if ( ave > target )
|
||||
ave = target;
|
||||
} else ave = easydiff; //else return(target);
|
||||
} else ave = target; //easydiff; //else return(target);
|
||||
if ( percPoS == 0 )
|
||||
percPoS = 1;
|
||||
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 )
|
||||
bnTarget = (ave * arith_uint256(percPoS * percPoS)) / arith_uint256(goalperc * goalperc * goalperc);
|
||||
else bnTarget = (ave / arith_uint256(goalperc * goalperc * goalperc)) * arith_uint256(percPoS * percPoS);
|
||||
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 )
|
||||
{
|
||||
for (i=31; i>=24; i--)
|
||||
@@ -1355,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 = (bnTarget * arith_uint256(percPoS * percPoS * percPoS)) / arith_uint256(goalperc * goalperc);
|
||||
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 )
|
||||
bnTarget = easydiff;
|
||||
else if ( bnTarget < ave ) // overflow
|
||||
|
||||
@@ -45,7 +45,7 @@ struct komodo_state KOMODO_STATES[34];
|
||||
#define _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;
|
||||
int32_t KOMODO_INSYNC,KOMODO_LASTMINED,prevKOMODO_LASTMINED,JUMBLR_PAUSE = 1;
|
||||
std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY;
|
||||
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];
|
||||
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);
|
||||
if ( GetBoolArg("-gen", false) != 0 )
|
||||
KOMODO_MININGTHREADS = GetArg("-genproclimit",1);
|
||||
else KOMODO_MININGTHREADS = -1;
|
||||
if ( (KOMODO_EXCHANGEWALLET= GetBoolArg("-exchange", false)) != 0 )
|
||||
fprintf(stderr,"KOMODO_EXCHANGEWALLET mode active\n");
|
||||
DONATION_PUBKEY = GetArg("-donation", "");
|
||||
|
||||
@@ -106,7 +106,7 @@ void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams,
|
||||
|
||||
#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 char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
||||
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->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
|
||||
//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;
|
||||
CMutableTransaction txStaked = CreateNewContextualCMutableTransaction(Params().GetConsensus(), chainActive.Height() + 1);
|
||||
@@ -453,7 +453,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
|
||||
// Fill in header
|
||||
pblock->hashPrevBlock = pindexPrev->GetBlockHash();
|
||||
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);
|
||||
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
|
||||
@@ -788,7 +788,7 @@ void static BitcoinMiner()
|
||||
}
|
||||
if (!fvNodesEmpty )//&& !IsInitialBlockDownload())
|
||||
break;
|
||||
MilliSleep(5000);
|
||||
MilliSleep(15000);
|
||||
//fprintf(stderr,"fvNodesEmpty %d IsInitialBlockDownload(%s) %d\n",(int32_t)fvNodesEmpty,ASSETCHAINS_SYMBOL,(int32_t)IsInitialBlockDownload());
|
||||
|
||||
} while (true);
|
||||
@@ -950,7 +950,7 @@ void static BitcoinMiner()
|
||||
// (x_1, x_2, ...) = A(I, V, n, k)
|
||||
LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n",solver, pblock->nNonce.ToString());
|
||||
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;
|
||||
else hashTarget = HASHTarget;
|
||||
std::function<bool(std::vector<unsigned char>)> validBlock =
|
||||
@@ -978,7 +978,7 @@ void static BitcoinMiner()
|
||||
fprintf(stderr," POW\n");*/
|
||||
if ( h > hashTarget )
|
||||
{
|
||||
//if ( ASSETCHAINS_STAKED != 0 && GetArg("-genproclimit", 0) == 0 )
|
||||
//if ( ASSETCHAINS_STAKED != 0 && KOMODO_MININGTHREADS == 0 )
|
||||
// sleep(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -121,6 +121,7 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex)
|
||||
result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits)));
|
||||
result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
|
||||
result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
|
||||
result.push_back(Pair("segid", (int64_t)blockindex->segid));
|
||||
|
||||
if (blockindex->pprev)
|
||||
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("version", block.nVersion));
|
||||
result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
|
||||
result.push_back(Pair("segid", (int64_t)blockindex->segid));
|
||||
|
||||
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("version", block.nVersion));
|
||||
result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
|
||||
result.push_back(Pair("segid", (int64_t)blockindex->segid));
|
||||
UniValue txs(UniValue::VARR);
|
||||
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)
|
||||
{
|
||||
//char *uint256_str(char *str,uint256); char str[65];
|
||||
LOCK(mempool.cs);
|
||||
//LOCK(mempool.cs);
|
||||
BOOST_FOREACH(const CTxMemPoolEntry &e,mempool.mapTx)
|
||||
{
|
||||
const CTransaction &tx = e.GetTx();
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
using namespace std;
|
||||
|
||||
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);
|
||||
|
||||
/**
|
||||
@@ -327,6 +328,9 @@ UniValue setgenerate(const UniValue& params, bool fHelp)
|
||||
|
||||
mapArgs["-gen"] = (fGenerate ? "1" : "0");
|
||||
mapArgs ["-genproclimit"] = itostr(nGenProcLimit);
|
||||
if ( fGenerate == 0 )
|
||||
KOMODO_MININGTHREADS = -1;
|
||||
else KOMODO_MININGTHREADS = (int32_t)nGenProcLimit;
|
||||
#ifdef ENABLE_WALLET
|
||||
GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit);
|
||||
#else
|
||||
@@ -382,6 +386,7 @@ UniValue getmininginfo(const UniValue& params, bool fHelp)
|
||||
obj.push_back(Pair("chain", Params().NetworkIDString()));
|
||||
#ifdef ENABLE_MINING
|
||||
obj.push_back(Pair("generate", getgenerate(params, false)));
|
||||
obj.push_back(Pair("numthreads", (int64_t)KOMODO_MININGTHREADS));
|
||||
#endif
|
||||
return obj;
|
||||
}
|
||||
@@ -647,7 +652,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
|
||||
pblocktemplate = CreateNewBlockWithKey();
|
||||
#endif
|
||||
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
|
||||
pindexPrev = pindexPrevNew;
|
||||
|
||||
@@ -952,7 +952,7 @@ bool EvalScript(
|
||||
|
||||
if (stack.size() < 2)
|
||||
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
|
||||
|
||||
//fprintf(stderr,"check cryptocondition\n");
|
||||
int fResult = checker.CheckCryptoCondition(stacktop(-1), stacktop(-2), script, consensusBranchId);
|
||||
if (fResult == -1) {
|
||||
return set_error(serror, SCRIPT_ERR_CRYPTOCONDITION_INVALID_FULFILLMENT);
|
||||
@@ -1313,19 +1313,20 @@ int TransactionSignatureChecker::CheckCryptoCondition(
|
||||
} catch (logic_error ex) {
|
||||
return 0;
|
||||
}
|
||||
//int32_t z; uint8_t *ptr;
|
||||
//ptr = (uint8_t *)scriptCode.data();
|
||||
//for (z=0; z<scriptCode.size(); z++)
|
||||
// fprintf(stderr,"%02x",ptr[z]);
|
||||
//fprintf(stderr," <- CScript\n");
|
||||
//for (z=0; z<32; 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);
|
||||
|
||||
/*int32_t z; uint8_t *ptr;
|
||||
ptr = (uint8_t *)scriptCode.data();
|
||||
for (z=0; z<scriptCode.size(); z++)
|
||||
fprintf(stderr,"%02x",ptr[z]);
|
||||
fprintf(stderr," <- CScript\n");
|
||||
for (z=0; z<32; 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);
|
||||
*/
|
||||
VerifyEval eval = [] (CC *cond, void *checker) {
|
||||
//fprintf(stderr,"checker.%p\n",(TransactionSignatureChecker*)checker);
|
||||
return ((TransactionSignatureChecker*)checker)->CheckEvalCondition(cond);
|
||||
};
|
||||
|
||||
//fprintf(stderr,"non-checker path\n");
|
||||
int out = cc_verify(cond, (const unsigned char*)&sighash, 32, 0,
|
||||
condBin.data(), condBin.size(), eval, (void*)this);
|
||||
//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
|
||||
{
|
||||
//fprintf(stderr,"call RunCCeval from ServerTransactionSignatureChecker::CheckEvalCondition\n");
|
||||
return RunCCEval(cond, *txTo, nIn);
|
||||
}
|
||||
|
||||
@@ -430,7 +430,7 @@ extern UniValue CBlockTreeDB::Snapshot(int top)
|
||||
};
|
||||
|
||||
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())
|
||||
{
|
||||
boost::this_thread::interruption_point();
|
||||
@@ -487,7 +487,7 @@ extern UniValue CBlockTreeDB::Snapshot(int top)
|
||||
}
|
||||
|
||||
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) {
|
||||
vaddr.push_back( make_pair(element.second, element.first) );
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
|
||||
#include <numeric>
|
||||
|
||||
#define ERR_RESULT(x) result.push_back(Pair("result", "error")) , result.push_back(Pair("error", x));
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace libzcash;
|
||||
@@ -49,6 +51,7 @@ uint32_t komodo_segid32(char *coinaddr);
|
||||
|
||||
int64_t nWalletUnlockTime;
|
||||
static CCriticalSection cs_nWalletUnlockTime;
|
||||
std::string CCerror;
|
||||
|
||||
// Private method:
|
||||
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)
|
||||
{
|
||||
struct CCcontract_info *cp,C; std::vector<unsigned char> pubkey;
|
||||
int errno;
|
||||
cp = CCinit(&C,EVAL_FAUCET);
|
||||
if ( fHelp || params.size() > 1 )
|
||||
throw runtime_error("faucetaddress [pubkey]\n");
|
||||
if ( ensure_CCrequirements() < 0 )
|
||||
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||
errno = ensure_CCrequirements();
|
||||
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 )
|
||||
pubkey = ParseHex(params[0].get_str().c_str());
|
||||
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("hex", hex));
|
||||
} else result.push_back(Pair("error", "couldnt create rewards funding transaction"));
|
||||
} else ERR_RESULT("couldnt create rewards funding transaction");
|
||||
return(result);
|
||||
}
|
||||
|
||||
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 )
|
||||
throw runtime_error("rewardslock name fundingtxid amount\n");
|
||||
if ( ensure_CCrequirements() < 0 )
|
||||
@@ -5012,17 +5017,19 @@ UniValue rewardslock(const UniValue& params, bool fHelp)
|
||||
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
amount = atof(params[2].get_str().c_str()) * COIN;
|
||||
hex = RewardsLock(0,name,fundingtxid,amount);
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
result.push_back(Pair("hex", hex));
|
||||
} else result.push_back(Pair("error", "couldnt create rewards lock transaction"));
|
||||
if ( amount > 0 ) {
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
result.push_back(Pair("hex", hex));
|
||||
} else ERR_RESULT( "couldnt create rewards lock transaction");
|
||||
} else ERR_RESULT("amount must be positive");
|
||||
return(result);
|
||||
}
|
||||
|
||||
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 )
|
||||
throw runtime_error("rewardsaddfunding name fundingtxid amount\n");
|
||||
if ( ensure_CCrequirements() < 0 )
|
||||
@@ -5033,11 +5040,19 @@ UniValue rewardsaddfunding(const UniValue& params, bool fHelp)
|
||||
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
amount = atof(params[2].get_str().c_str()) * COIN;
|
||||
hex = RewardsAddfunding(0,name,fundingtxid,amount);
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
result.push_back(Pair("hex", hex));
|
||||
} else result.push_back(Pair("error", "couldnt create rewards addfunding transaction"));
|
||||
if (amount > 0) {
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -5056,11 +5071,12 @@ UniValue rewardsunlock(const UniValue& params, bool fHelp)
|
||||
txid = Parseuint256((char *)params[2].get_str().c_str());
|
||||
else memset(&txid,0,sizeof(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("hex", hex));
|
||||
} else result.push_back(Pair("error", "couldnt create rewards unlock transaction"));
|
||||
} else ERR_RESULT("couldnt create rewards unlock transaction");
|
||||
return(result);
|
||||
}
|
||||
|
||||
@@ -5138,7 +5154,7 @@ UniValue faucetinfo(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 )
|
||||
throw runtime_error("faucetfund amount\n");
|
||||
if ( ensure_CCrequirements() < 0 )
|
||||
@@ -5146,12 +5162,14 @@ UniValue faucetfund(const UniValue& params, bool fHelp)
|
||||
const CKeyStore& keystore = *pwalletMain;
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
funds = atof(params[0].get_str().c_str()) * COIN;
|
||||
hex = FaucetFund(0,funds);
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
result.push_back(Pair("hex", hex));
|
||||
} else result.push_back(Pair("error", "couldnt create faucet funding transaction"));
|
||||
if (funds > 0) {
|
||||
hex = FaucetFund(0,(uint64_t) funds);
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
result.push_back(Pair("hex", hex));
|
||||
} else ERR_RESULT("couldnt create faucet funding transaction");
|
||||
} else ERR_RESULT( "funding amount must be positive");
|
||||
return(result);
|
||||
}
|
||||
|
||||
@@ -5165,11 +5183,10 @@ UniValue faucetget(const UniValue& params, bool fHelp)
|
||||
const CKeyStore& keystore = *pwalletMain;
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
hex = FaucetGet(0);
|
||||
if ( hex.size() > 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 faucet get transaction"));
|
||||
} else ERR_RESULT("couldnt create faucet get transaction");
|
||||
return(result);
|
||||
}
|
||||
|
||||
@@ -5189,17 +5206,20 @@ UniValue dicefund(const UniValue& params, bool fHelp)
|
||||
maxodds = atol(params[4].get_str().c_str());
|
||||
timeoutblocks = atol(params[5].get_str().c_str());
|
||||
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("hex", hex));
|
||||
} else result.push_back(Pair("error", "couldnt create dice funding transaction"));
|
||||
} else {
|
||||
ERR_RESULT( "couldnt create dice funding transaction");
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
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 )
|
||||
throw runtime_error("diceaddfunds name fundingtxid amount\n");
|
||||
if ( ensure_CCrequirements() < 0 )
|
||||
@@ -5209,18 +5229,21 @@ UniValue diceaddfunds(const UniValue& params, bool fHelp)
|
||||
name = (char *)params[0].get_str().c_str();
|
||||
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
amount = atof(params[2].get_str().c_str()) * COIN;
|
||||
hex = DiceAddfunding(0,name,fundingtxid,amount);
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
result.push_back(Pair("hex", hex));
|
||||
} else result.push_back(Pair("error", "couldnt create dice addfunding transaction"));
|
||||
if ( amount > 0 ) {
|
||||
hex = DiceAddfunding(0,name,fundingtxid,amount);
|
||||
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 create dice addfunding transaction");
|
||||
} else ERR_RESULT("amount must be positive");
|
||||
return(result);
|
||||
}
|
||||
|
||||
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 )
|
||||
throw runtime_error("dicebet name fundingtxid amount odds\n");
|
||||
if ( ensure_CCrequirements() < 0 )
|
||||
@@ -5231,18 +5254,22 @@ UniValue dicebet(const UniValue& params, bool fHelp)
|
||||
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
amount = atof(params[2].get_str().c_str()) * COIN;
|
||||
odds = atol(params[3].get_str().c_str());
|
||||
hex = DiceBet(0,name,fundingtxid,amount,odds);
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
result.push_back(Pair("hex", hex));
|
||||
} else result.push_back(Pair("error", "couldnt create faucet get transaction"));
|
||||
if (amount > 0 && odds > 0) {
|
||||
hex = DiceBet(0,name,fundingtxid,amount,odds);
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
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);
|
||||
}
|
||||
|
||||
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 )
|
||||
throw runtime_error("dicefinish name fundingtxid bettxid\n");
|
||||
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("hex", hex));
|
||||
} else result.push_back(Pair("error", "couldnt create dicefinish transaction"));
|
||||
} else ERR_RESULT( "couldnt create dicefinish transaction");
|
||||
return(result);
|
||||
}
|
||||
|
||||
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) )
|
||||
throw runtime_error("dicestatus name fundingtxid bettxid\n");
|
||||
if ( ensure_CCrequirements() < 0 )
|
||||
@@ -5298,7 +5325,7 @@ UniValue dicestatus(const UniValue& params, bool fHelp)
|
||||
result.push_back(Pair("status", "loss"));
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -5390,20 +5417,32 @@ UniValue tokencreate(const UniValue& params, bool fHelp)
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
name = params[0].get_str();
|
||||
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 )
|
||||
{
|
||||
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);
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
result.push_back(Pair("hex", hex));
|
||||
} else result.push_back(Pair("error", "couldnt create transaction"));
|
||||
} else ERR_RESULT("couldnt create transaction");
|
||||
return(result);
|
||||
}
|
||||
|
||||
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 )
|
||||
throw runtime_error("tokentransfer tokenid destpubkey amount\n");
|
||||
if ( ensure_CCrequirements() < 0 )
|
||||
@@ -5413,18 +5452,27 @@ UniValue tokentransfer(const UniValue& params, bool fHelp)
|
||||
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
std::vector<unsigned char> pubkey(ParseHex(params[1].get_str().c_str()));
|
||||
amount = atol(params[2].get_str().c_str());
|
||||
hex = AssetTransfer(0,tokenid,pubkey,amount);
|
||||
if ( hex.size() > 0 )
|
||||
if ( tokenid == zeroid || amount <= 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
result.push_back(Pair("hex", hex));
|
||||
} else result.push_back(Pair("error", "couldnt transfer assets"));
|
||||
result.push_back(Pair("error", "invalid parameter"));
|
||||
return(result);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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 )
|
||||
throw runtime_error("tokenbid numtokens tokenid price\n");
|
||||
if ( ensure_CCrequirements() < 0 )
|
||||
@@ -5435,12 +5483,21 @@ UniValue tokenbid(const UniValue& params, bool fHelp)
|
||||
tokenid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
price = atof(params[2].get_str().c_str());
|
||||
bidamount = (price * numtokens) * COIN + 0.0000000049999;
|
||||
hex = CreateBuyOffer(0,bidamount,tokenid,numtokens);
|
||||
if ( hex.size() > 0 )
|
||||
if ( tokenid == zeroid || tokenid == zeroid || price <= 0 || bidamount <= 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
result.push_back(Pair("hex", hex));
|
||||
} else result.push_back(Pair("error", "couldnt create bid"));
|
||||
result.push_back(Pair("error", "invalid parameter"));
|
||||
return(result);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -5455,12 +5512,17 @@ UniValue tokencancelbid(const UniValue& params, bool fHelp)
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
tokenid = Parseuint256((char *)params[0].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);
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
result.push_back(Pair("hex", hex));
|
||||
} else result.push_back(Pair("error", "couldnt cancel bid"));
|
||||
} else ERR_RESULT("couldnt cancel bid");
|
||||
return(result);
|
||||
}
|
||||
|
||||
@@ -5476,18 +5538,23 @@ UniValue tokenfillbid(const UniValue& params, bool fHelp)
|
||||
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
bidtxid = Parseuint256((char *)params[1].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);
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
result.push_back(Pair("hex", hex));
|
||||
} else result.push_back(Pair("error", "couldnt fill bid"));
|
||||
} else ERR_RESULT("couldnt fill bid");
|
||||
return(result);
|
||||
}
|
||||
|
||||
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 )
|
||||
throw runtime_error("tokenask numtokens tokenid price\n");
|
||||
if ( ensure_CCrequirements() < 0 )
|
||||
@@ -5498,19 +5565,28 @@ UniValue tokenask(const UniValue& params, bool fHelp)
|
||||
tokenid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
price = atof(params[2].get_str().c_str());
|
||||
askamount = (price * numtokens) * COIN + 0.0000000049999;
|
||||
hex = CreateSell(0,numtokens,tokenid,askamount);
|
||||
if ( hex.size() > 0 )
|
||||
if ( tokenid == zeroid || numtokens <= 0 || price <= 0 || askamount <= 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
result.push_back(Pair("hex", hex));
|
||||
} else result.push_back(Pair("error", "couldnt create ask"));
|
||||
result.push_back(Pair("error", "invalid parameter"));
|
||||
return(result);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
UniValue tokenswapask(const UniValue& params, bool fHelp)
|
||||
{
|
||||
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 )
|
||||
throw runtime_error("tokenswapask numtokens tokenid otherid price\n");
|
||||
if ( ensure_CCrequirements() < 0 )
|
||||
@@ -5523,11 +5599,15 @@ UniValue tokenswapask(const UniValue& params, bool fHelp)
|
||||
price = atof(params[3].get_str().c_str());
|
||||
askamount = (price * numtokens);
|
||||
hex = CreateSwap(0,numtokens,tokenid,otherid,askamount);
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
result.push_back(Pair("hex", hex));
|
||||
} else result.push_back(Pair("error", "couldnt create swap"));
|
||||
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 swap");
|
||||
} else {
|
||||
ERR_RESULT("price and numtokens must be positive");
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
@@ -5542,18 +5622,22 @@ UniValue tokencancelask(const UniValue& params, bool fHelp)
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
tokenid = Parseuint256((char *)params[0].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);
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
result.push_back(Pair("hex", hex));
|
||||
} else result.push_back(Pair("error", "couldnt cancel bid"));
|
||||
} else ERR_RESULT("couldnt cancel ask");
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue tokenfillask(const UniValue& params, bool fHelp)
|
||||
{
|
||||
static uint256 zeroid;
|
||||
UniValue result(UniValue::VOBJ); uint64_t fillunits; std::string hex; uint256 tokenid,asktxid;
|
||||
if ( fHelp || params.size() != 3 )
|
||||
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());
|
||||
asktxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
fillunits = atol(params[2].get_str().c_str());
|
||||
hex = FillSell(0,tokenid,zeroid,asktxid,fillunits);
|
||||
if ( hex.size() > 0 )
|
||||
if ( tokenid == zeroid || asktxid == zeroid || fillunits <= 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
result.push_back(Pair("hex", hex));
|
||||
} else result.push_back(Pair("error", "couldnt fill bid"));
|
||||
result.push_back(Pair("error", "invalid parameter"));
|
||||
return(result);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
UniValue tokenfillswap(const UniValue& params, bool fHelp)
|
||||
{
|
||||
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 )
|
||||
throw runtime_error("tokenfillswap tokenid otherid asktxid fillunits\n");
|
||||
if ( ensure_CCrequirements() < 0 )
|
||||
@@ -5588,11 +5684,14 @@ UniValue tokenfillswap(const UniValue& params, bool fHelp)
|
||||
asktxid = Parseuint256((char *)params[2].get_str().c_str());
|
||||
fillunits = atol(params[3].get_str().c_str());
|
||||
hex = FillSell(0,tokenid,otherid,asktxid,fillunits);
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
result.push_back(Pair("hex", hex));
|
||||
} else result.push_back(Pair("error", "couldnt fill bid"));
|
||||
if (fillunits > 0) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user