@@ -524,6 +524,11 @@ if GLIBC_BACK_COMPAT
|
||||
libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp
|
||||
endif
|
||||
|
||||
if ENABLE_TESTS
|
||||
libbitcoin_server_a_SOURCES += rpc/testtransactions.cpp
|
||||
endif
|
||||
|
||||
|
||||
# cli: zcash-cli
|
||||
libbitcoin_cli_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||
libbitcoin_cli_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
|
||||
@@ -51,3 +51,4 @@ echo $pubkey
|
||||
./komodod -pubkey=$pubkey -ac_name=MORTY -ac_supply=90000000000 -ac_reward=100000000 -ac_cc=3 -addnode=138.201.136.145 &
|
||||
./komodod -pubkey=$pubkey -ac_name=VOTE2019 -ac_supply=123651638 -ac_public=1 -addnode=95.213.238.98 &
|
||||
./komodod -pubkey=$pubkey -ac_name=KOIN -ac_supply=125000000 -addnode=3.0.32.10 &
|
||||
~/hush3/src/komodod -pubkey=$pubkey -ac_name=HUSH3 -ac_sapling=1 -ac_reward=0,1125000000,562500000 -ac_halving=129,340000,840000 -ac_end=128,340000,5422111 -ac_eras=3 -ac_blocktime=150 -ac_cc=2 -ac_ccenable=228,234,235,236,241 -ac_founders=1 -ac_supply=6178674 -ac_perc=11111111 -clientname=GoldenSandtrout -addnode=188.165.212.101 -ac_cclib=hush3 -ac_script=76a9145eb10cf64f2bab1b457f1f25e658526155928fac88ac &
|
||||
|
||||
@@ -18,17 +18,24 @@
|
||||
#define CC_PAYMENTS_H
|
||||
|
||||
#include "CCinclude.h"
|
||||
#include <gmp.h>
|
||||
|
||||
#define PAYMENTS_TXFEE 10000
|
||||
#define PAYMENTS_MERGEOFSET 10 // 100?
|
||||
extern std::vector <std::pair<CAmount, CTxDestination>> vAddressSnapshot;
|
||||
extern int32_t lastSnapShotHeight;
|
||||
|
||||
bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
|
||||
// CCcustom
|
||||
UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsMerge(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsTxidopret(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsCreate(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -17,34 +17,41 @@
|
||||
#ifndef CC_PRICES_H
|
||||
#define CC_PRICES_H
|
||||
|
||||
#include "komodo_defs.h"
|
||||
#include "CCinclude.h"
|
||||
int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblocks);
|
||||
extern void GetKomodoEarlytxidScriptPub();
|
||||
extern CScript KOMODO_EARLYTXID_SCRIPTPUB;
|
||||
|
||||
#define PRICES_DAYWINDOW ((3600*24/ASSETCHAINS_BLOCKTIME) + 1)
|
||||
// #define PRICES_DAYWINDOW ((3600*24/ASSETCHAINS_BLOCKTIME) + 1) // defined in komodo_defs.h
|
||||
#define PRICES_TXFEE 10000
|
||||
#define PRICES_MAXLEVERAGE 777
|
||||
#define PRICES_SMOOTHWIDTH 1
|
||||
#define KOMODO_MAXPRICES 2048 // must be power of 2 and less than 8192
|
||||
#define KOMODO_PRICEMASK (~(KOMODO_MAXPRICES - 1))
|
||||
#define PRICES_WEIGHT (KOMODO_MAXPRICES * 1)
|
||||
#define PRICES_MULT (KOMODO_MAXPRICES * 2)
|
||||
#define PRICES_DIV (KOMODO_MAXPRICES * 3)
|
||||
#define PRICES_INV (KOMODO_MAXPRICES * 4)
|
||||
#define PRICES_MDD (KOMODO_MAXPRICES * 5)
|
||||
#define PRICES_MMD (KOMODO_MAXPRICES * 6)
|
||||
#define PRICES_MMM (KOMODO_MAXPRICES * 7)
|
||||
#define PRICES_DDD (KOMODO_MAXPRICES * 8)
|
||||
#define KOMODO_PRICEMASK (~(KOMODO_MAXPRICES - 1)) // actually 1111 1000 0000 0000
|
||||
#define PRICES_WEIGHT (KOMODO_MAXPRICES * 1) // 0000 1000 0000 0000
|
||||
#define PRICES_MULT (KOMODO_MAXPRICES * 2) // 0001 0000 0000 0000
|
||||
#define PRICES_DIV (KOMODO_MAXPRICES * 3) // 0001 1000 0000 0000
|
||||
#define PRICES_INV (KOMODO_MAXPRICES * 4) // 0010 0000 0000 0000
|
||||
#define PRICES_MDD (KOMODO_MAXPRICES * 5) // 0010 1000 0000 0000
|
||||
#define PRICES_MMD (KOMODO_MAXPRICES * 6) // 0011 0000 0000 0000
|
||||
#define PRICES_MMM (KOMODO_MAXPRICES * 7) // 0011 1000 0000 0000
|
||||
#define PRICES_DDD (KOMODO_MAXPRICES * 8) // 0100 0000 0000 0000
|
||||
|
||||
#define PRICES_NORMFACTOR (int64_t)(SATOSHIDEN)
|
||||
#define PRICES_POINTFACTOR (int64_t)10000
|
||||
|
||||
bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
|
||||
// CCcustom
|
||||
UniValue PricesBet(uint64_t txfee,int64_t amount,int16_t leverage,std::vector<std::string> synthetic);
|
||||
UniValue PricesAddFunding(uint64_t txfee,uint256 bettxid,int64_t amount);
|
||||
UniValue PricesSetcostbasis(uint64_t txfee,uint256 bettxid);
|
||||
UniValue PricesRekt(uint64_t txfee,uint256 bettxid,int32_t rektheight);
|
||||
UniValue PricesCashout(uint64_t txfee,uint256 bettxid);
|
||||
UniValue PricesBet(int64_t txfee,int64_t amount,int16_t leverage,std::vector<std::string> synthetic);
|
||||
UniValue PricesAddFunding(int64_t txfee,uint256 bettxid,int64_t amount);
|
||||
UniValue PricesSetcostbasis(int64_t txfee,uint256 bettxid);
|
||||
UniValue PricesRekt(int64_t txfee,uint256 bettxid,int32_t rektheight);
|
||||
UniValue PricesCashout(int64_t txfee,uint256 bettxid);
|
||||
UniValue PricesInfo(uint256 bettxid,int32_t refheight);
|
||||
UniValue PricesList();
|
||||
UniValue PricesList(uint32_t filter, CPubKey mypk);
|
||||
UniValue PricesGetOrderbook();
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -229,7 +229,7 @@ uint256 DiceHashEntropy(uint256 &entropy,uint256 _txidpriv,int32_t entropyvout,i
|
||||
CTxOut MakeCC1vout(uint8_t evalcode,CAmount nValue,CPubKey pk, std::vector<std::vector<unsigned char>>* vData = NULL);
|
||||
CTxOut MakeCC1of2vout(uint8_t evalcode,CAmount nValue,CPubKey pk,CPubKey pk2, std::vector<std::vector<unsigned char>>* vData = NULL);
|
||||
int32_t has_opret(const CTransaction &tx, uint8_t evalcode);
|
||||
CScript getCCopret(const CScript &scriptPubKey);
|
||||
bool getCCopret(const CScript &scriptPubKey, CScript &opret);
|
||||
bool makeCCopret(CScript &opret, std::vector<std::vector<unsigned char>> &vData);
|
||||
CC *MakeCCcond1(uint8_t evalcode,CPubKey pk);
|
||||
CC *MakeCCcond1of2(uint8_t evalcode,CPubKey pk1,CPubKey pk2);
|
||||
@@ -298,6 +298,7 @@ UniValue ValueFromAmount(const CAmount& amount);
|
||||
|
||||
int64_t TotalPubkeyNormalInputs(const CTransaction &tx, const CPubKey &pubkey);
|
||||
int64_t TotalPubkeyCCInputs(const CTransaction &tx, const CPubKey &pubkey);
|
||||
inline std::string STR_TOLOWER(const std::string &str) { std::string out; for (std::string::const_iterator i = str.begin(); i != str.end(); i++) out += std::tolower(*i); return out; }
|
||||
|
||||
// bitcoin LogPrintStr with category "-debug" cmdarg support for C++ ostringstream:
|
||||
#define CCLOG_INFO 0
|
||||
|
||||
@@ -63,25 +63,28 @@ int32_t has_opret(const CTransaction &tx, uint8_t evalcode)
|
||||
int i = 0;
|
||||
for ( auto vout : tx.vout )
|
||||
{
|
||||
if ( vout.scriptPubKey[0] == OP_RETURN && vout.scriptPubKey[1] == evalcode )
|
||||
//fprintf(stderr, "[txid.%s] 1.%i 2.%i 3.%i 4.%i\n",tx.GetHash().GetHex().c_str(), vout.scriptPubKey[0], vout.scriptPubKey[1], vout.scriptPubKey[2], vout.scriptPubKey[3]);
|
||||
if ( vout.scriptPubKey.size() > 3 && vout.scriptPubKey[0] == OP_RETURN && vout.scriptPubKey[2] == evalcode )
|
||||
return i;
|
||||
i++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
CScript getCCopret(const CScript &scriptPubKey)
|
||||
bool getCCopret(const CScript &scriptPubKey, CScript &opret)
|
||||
{
|
||||
std::vector<std::vector<unsigned char>> vParams = std::vector<std::vector<unsigned char>>();
|
||||
CScript dummy; CScript opret;
|
||||
if ( scriptPubKey.IsPayToCryptoCondition(&dummy, vParams) )
|
||||
CScript dummy; bool ret = false;
|
||||
if ( scriptPubKey.IsPayToCryptoCondition(&dummy, vParams) != 0 )
|
||||
{
|
||||
//opret << E_MARSHAL(ss << vParams[0]);
|
||||
opret = CScript(vParams[0].begin()+6, vParams[0].end());
|
||||
ret = true;
|
||||
if ( vParams.size() == 1)
|
||||
{
|
||||
opret = CScript(vParams[0].begin()+6, vParams[0].end());
|
||||
//fprintf(stderr, "vparams.%s\n", HexStr(vParams[0].begin(), vParams[0].end()).c_str());
|
||||
}
|
||||
}
|
||||
//fprintf(stderr, "params_size.%li parmas_hexstr.%s\n", vParams.size(), HexStr(vParams[0].begin(),vParams[0].end()).c_str());
|
||||
//opret = CScript(vParams[0].begin(), vParams[0].end());
|
||||
return opret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool makeCCopret(CScript &opret, std::vector<std::vector<unsigned char>> &vData)
|
||||
|
||||
116
src/cc/COptCCParams.cpp
Normal file
116
src/cc/COptCCParams.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
/*Descriptson and examples of COptCCParams class found in:
|
||||
script/standard.h/cpp
|
||||
class COptCCParams
|
||||
|
||||
structure of data in vData payload attached to end of CCvout:
|
||||
param
|
||||
OP_1
|
||||
param
|
||||
OP_2 ... etc until OP_16
|
||||
OP_PUSHDATA4 is the last OP code to tell things its at the end.
|
||||
|
||||
taken from standard.cpp line 22: COptCCParams::COptCCParams(std::vector<unsigned char> &vch)
|
||||
|
||||
EXAMPLE taken from Verus how to create scriptPubKey from COptCCParams class:
|
||||
EXAMPLE taken from Verus how to decode scriptPubKey from COptCCParams class:
|
||||
*/
|
||||
|
||||
bool MakeGuardedOutput(CAmount value, CPubKey &dest, CTransaction &stakeTx, CTxOut &vout)
|
||||
{
|
||||
CCcontract_info *cp, C;
|
||||
cp = CCinit(&C,EVAL_STAKEGUARD);
|
||||
|
||||
CPubKey ccAddress = CPubKey(ParseHex(cp->CChexstr));
|
||||
|
||||
// return an output that is bound to the stake transaction and can be spent by presenting either a signed condition by the original
|
||||
// destination address or a properly signed stake transaction of the same utxo on a fork
|
||||
vout = MakeCC1of2vout(EVAL_STAKEGUARD, value, dest, ccAddress);
|
||||
|
||||
std::vector<CPubKey> vPubKeys = std::vector<CPubKey>();
|
||||
vPubKeys.push_back(dest);
|
||||
vPubKeys.push_back(ccAddress);
|
||||
|
||||
std::vector<std::vector<unsigned char>> vData = std::vector<std::vector<unsigned char>>();
|
||||
|
||||
CVerusHashWriter hw = CVerusHashWriter(SER_GETHASH, PROTOCOL_VERSION);
|
||||
|
||||
hw << stakeTx.vin[0].prevout.hash;
|
||||
hw << stakeTx.vin[0].prevout.n;
|
||||
|
||||
uint256 utxo = hw.GetHash();
|
||||
vData.push_back(std::vector<unsigned char>(utxo.begin(), utxo.end())); // Can we use any data here to construct vector?
|
||||
|
||||
CStakeParams p;
|
||||
if (GetStakeParams(stakeTx, p))
|
||||
{
|
||||
// prev block hash and height is here to make validation easy
|
||||
vData.push_back(std::vector<unsigned char>(p.prevHash.begin(), p.prevHash.end()));
|
||||
std::vector<unsigned char> height = std::vector<unsigned char>(4);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
height[i] = (p.blkHeight >> (8 * i)) & 0xff;
|
||||
}
|
||||
vData.push_back(height);
|
||||
|
||||
COptCCParams ccp = COptCCParams(COptCCParams::VERSION, EVAL_STAKEGUARD, 1, 2, vPubKeys, vData);
|
||||
|
||||
vout.scriptPubKey << ccp.AsVector() << OP_DROP;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ValidateMatchingStake(const CTransaction &ccTx, uint32_t voutNum, const CTransaction &stakeTx, bool &cheating)
|
||||
{
|
||||
// an invalid or non-matching stake transaction cannot cheat
|
||||
cheating = false;
|
||||
|
||||
//printf("ValidateMatchingStake: ccTx.vin[0].prevout.hash: %s, ccTx.vin[0].prevout.n: %d\n", ccTx.vin[0].prevout.hash.GetHex().c_str(), ccTx.vin[0].prevout.n);
|
||||
|
||||
if (ccTx.IsCoinBase())
|
||||
{
|
||||
CStakeParams p;
|
||||
if (ValidateStakeTransaction(stakeTx, p))
|
||||
{
|
||||
std::vector<std::vector<unsigned char>> vParams = std::vector<std::vector<unsigned char>>();
|
||||
CScript dummy;
|
||||
|
||||
if (ccTx.vout[voutNum].scriptPubKey.IsPayToCryptoCondition(&dummy, vParams) && vParams.size() > 0)
|
||||
{
|
||||
COptCCParams ccp = COptCCParams(vParams[0]);
|
||||
if (ccp.IsValid() & ccp.vData.size() >= 3 && ccp.vData[2].size() <= 4)
|
||||
{
|
||||
CVerusHashWriter hw = CVerusHashWriter(SER_GETHASH, PROTOCOL_VERSION);
|
||||
|
||||
hw << stakeTx.vin[0].prevout.hash;
|
||||
hw << stakeTx.vin[0].prevout.n;
|
||||
uint256 utxo = hw.GetHash();
|
||||
|
||||
uint32_t height = 0;
|
||||
int i, dataLen = ccp.vData[2].size();
|
||||
for (i = dataLen - 1; i >= 0; i--)
|
||||
{
|
||||
height = (height << 8) + ccp.vData[2][i];
|
||||
}
|
||||
// for debugging strange issue
|
||||
// printf("iterator: %d, height: %d, datalen: %d\n", i, height, dataLen);
|
||||
|
||||
if (utxo == uint256(ccp.vData[0]))
|
||||
{
|
||||
if (p.prevHash != uint256(ccp.vData[1]) && p.blkHeight >= height)
|
||||
{
|
||||
cheating = true;
|
||||
return true;
|
||||
}
|
||||
// if block height is equal and we are at the else, prevHash must have been equal
|
||||
else if (p.blkHeight == height)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -82,12 +82,12 @@ UniValue custom_func1(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
bool custom_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx)
|
||||
{
|
||||
char expectedaddress[64]; CPubKey pk;
|
||||
CScript opret; int32_t numvout;
|
||||
CScript opret; int32_t numvout = 0;
|
||||
if ( has_opret(tx, EVAL_CUSTOM) == 0 )
|
||||
{
|
||||
std::vector<std::vector<unsigned char>> vParams = std::vector<std::vector<unsigned char>>();
|
||||
opret = getCCopret(tx.vout[0].scriptPubKey);
|
||||
numvout = 1;
|
||||
if ( getCCopret(tx.vout[0].scriptPubKey,opret) )
|
||||
numvout = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -53,6 +53,15 @@ bool RunCCEval(const CC *cond, const CTransaction &tx, unsigned int nIn)
|
||||
eval->state.GetRejectReason().data(),
|
||||
tx.vin[nIn].prevout.hash.GetHex().data());
|
||||
if (eval->state.IsError()) fprintf(stderr, "Culprit: %s\n", EncodeHexTx(tx).data());
|
||||
CTransaction tmp;
|
||||
if (mempool.lookup(tx.GetHash(), tmp))
|
||||
{
|
||||
// This is to remove a payments airdrop if it gets stuck in the mempool.
|
||||
// Miner will mine 1 invalid block, but doesnt stop them mining until a restart.
|
||||
// This would almost never happen in normal use.
|
||||
std::list<CTransaction> dummy;
|
||||
mempool.remove(tx,dummy,true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
65
src/cc/hempcoin_notes.txt
Normal file
65
src/cc/hempcoin_notes.txt
Normal file
@@ -0,0 +1,65 @@
|
||||
How this works:
|
||||
- earlytxid must be a transaction included in the chain before block 100. The chain MUST not have any other of these type of tx before block 100, or someone may be able to change it and mess things up.
|
||||
- When it gets to block 100, it takes the txid specified by the -earlytxid param (does not affect magic)
|
||||
- Looks up the transaction searches for the opreturn, then permenantly appends it to the end of ac_script in RAM.
|
||||
- After every daemon restart, the first time the daemon mines a block, or receives a block that pays ac_script it will look up the op_return and save it again.
|
||||
- this enables it to always reach consensus but doesnt need to constantly keep looking up the tx in the chain.
|
||||
- The trick is to use ac_founders=101 or higher so that nothing is ever paid to the unspendable CC address. Although it should still work without this it burns coins.
|
||||
|
||||
-ac_script can be any Global CC address you can spend to with an OP_RETURN. Here we use example of paymentsCC being used to fund a rewards plan, and a set of founders address's.
|
||||
you can get the ac_script from another chain, but the op_return payload must generated on the chain itself. this command gives you the needed info to get the scripPubKey Hex:
|
||||
./komodo-cli -ac_name=TEST paymentsfund '["5d536f54332db09f2be04593c54f764cf569e225f4d8df5155658c679e663682",1000]'
|
||||
append: b8, to the end of ac_script, this changes magic value for -earlytxid chains vs normal ac_script and allows bypass of ac_supply paid to the scritpt as it would be unspendable and you would be unable to create the needed plans with no coins.
|
||||
-ac_script=2ea22c8020987fad30df055db6fd922c3a57e55d76601229ed3da3b31340112e773df3d0d28103120c008203000401ccb8
|
||||
|
||||
-testnode=1 is not affecting magic and allows mining on a single node, we can use this to bootstrap the chain before syncing a second node to save time.
|
||||
|
||||
start chain and make sure to do the following steps before block 100 (set generate false/true is a good idea between steps)
|
||||
./komodod -ac_name=TESTHC -ac_supply=1000000 -ac_reward=100000000000 -ac_cc=2 -ac_script=2ea22c8020987fad30df055db6fd922c3a57e55d76601229ed3da3b31340112e773df3d0d28103120c008203000401ccb8 -ac_founders=150 -ac_blocktime=20 -ac_nk=96,5 -testnode=1
|
||||
|
||||
create rewards plan and fund it with all or a % of the premine. Must be some amount. eg.
|
||||
./komodo-cli -ac_name=TESTHC rewardscreatefunding test 50000 25 0 2 500
|
||||
|
||||
do rewards add funding:
|
||||
./komodo-cli -ac_name=TESTHC rewardsaddfunding test 47a3150150bd196bd2086cae5e0c6b01a23785a04139fa660d169121a534b38e 1000
|
||||
|
||||
and get the script pubkey and op_return from this tx (no need to send it)
|
||||
./komodo-cli -ac_name=TESTHC decoderawtransaction 010000000204ca4c7aaae62bb8fc9412ac010e047fa8d33c3f87d2adeb3e02170642ddfe370000000049483045022100d7b9a
|
||||
4f28ca3a35f34dcdb6075e905cde1eaa962bd0619d0a8ed8e17e952bc99022077308e12325fc2a02c752ec3df9aeee1fc219ea54a4d3884834582b75c89815e01ffffffff08800132da3233d80c65e87b6db6a76dcf
|
||||
188e4fdfa23198d69f647e67754cfb0000000049483045022100d6a8f7a1c4f6013f5897768ae0117fe61dfb72352d3e6652e64a6588db3ffcb102202aa1d041b24f9cbbf7028295b7c5e7f18b4f95ae39c13031dab
|
||||
7f06634438e6801ffffffff0300e8764817000000302ea22c802065686d47a4049c2c845a71895a915eb84c04445896eec5dc0be40df0b31372da8103120c008203000401ccf0c0764817000000232103bbec93af84
|
||||
0933ae2d35fc56eff24f34dbe26871402552f84c44f690945ccd79ac00000000000000002c6a2ae54174657374000000008eb334a52191160d66fa3941a08537a2016b0c5eae6c08d26b19bd500115a34700000000
|
||||
|
||||
From the return of this you need the scriptpubkey hex of vout 0:
|
||||
scriptPubKey: 2ea22c802065686d47a4049c2c845a71895a915eb84c04445896eec5dc0be40df0b31372da8103120c008203000401cc
|
||||
and the scriptpubkey hex of the OP_RETURN in vout 2.
|
||||
OP_RETURN: 6a2ae54174657374000000008eb334a52191160d66fa3941a08537a2016b0c5eae6c08d26b19bd500115a347
|
||||
|
||||
create txidopreturn for this payment:
|
||||
./komodo-cli -ac_name=TESTHC paymentstxidopret '[50,"2ea22c802065686d47a4049c2c845a71895a915eb84c04445896eec5dc0be40df0b31372da8103120c008203000401cc","6a2ae54174657374000000008eb334a52191160d66fa3941a08537a2016b0c5eae6c08d26b19bd500115a347"]'
|
||||
|
||||
create the txidopret for the founders reward(s) pubkeys: should be able to be a few here, not sure of max number yet. These can pay anything that does not need an opreturn. allocation and scriptpubkey hex.
|
||||
./komodo-cli -ac_name=TESTHC paymentstxidopret '[50,"76a9146bf5dd9f679c87a3f83ea176f82148d26653c04388ac"]'
|
||||
|
||||
create payments plan:
|
||||
./komodo-cli -ac_name=TESTHC paymentscreate '[0,0,"61f55f2f87dad3a37d42731a8cb73b3ebea1817abfa176218162c360a8bd7145","0550014823ffa0aa99d7dd7ca5292f4dd0a1b9156eddec03412c953f095181bc"]'
|
||||
gives plan txid: ee7765be874fb084c00538b1b0488e8ecb857de253f09a9ba6ea8d3579b77d33
|
||||
|
||||
paymentsfund:
|
||||
To do this you first need to change the type of tx generated by paymentsfund RPC. in payments.cpp go to line: 639 and comment it out, then uncomment the block of code under this.
|
||||
change the line 646 to line 647 with comments, and line 650/651 aswell. This enables the RPC to generate the ccvout opreturn payload you need without sending the payment on the chain. Just decode the raw hex.
|
||||
./komodo-cli -ac_name=TESTHC paymentsfund '["ee7765be874fb084c00538b1b0488e8ecb857de253f09a9ba6ea8d3579b77d33",1000,1]'
|
||||
|
||||
get the payment fund scriptpubkey hex from vout 0: (the split it at OP_CHECKCRYPTOCONDITION or 'cc' )
|
||||
2ea22c8020987fad30df055db6fd922c3a57e55d76601229ed3da3b31340112e773df3d0d28103120c008203000401cc 2a0401f00101246a22f046337db779358deaa69b9af053e27d85cb8e8e48b0b13805c084b04f87be6577ee75
|
||||
|
||||
put the second half into an OP_RETURN: (the remaining part of the the above scriptpubkey) eg.
|
||||
./komodo-cli -ac_name=TESTHC opreturn_burn 1 2a0401f00101246a22f046337db779358deaa69b9af053e27d85cb8e8e48b0b13805c084b04f87be6577ee75
|
||||
opret_burn takes any burn amount and arbitrary hex string. (RPC works, but may have bugs, likely use this for LABS too with some fixes)
|
||||
this gives a raw hex. Decode it and check the OP_RETURN is right before sending.
|
||||
-earlytxid=810bd62fb8353fad20267ff2050684b8829affa3edf6b366633931530791dfce
|
||||
restart the chain with earlytxid param before height 100 on all nodes (if not using -testnode=1)
|
||||
./komodod -ac_name=TESTHC -ac_supply=1000000 -ac_reward=100000000000 -ac_cc=2 -ac_script=2ea22c8020987fad30df055db6fd922c3a57e55d76601229ed3da3b31340112e773df3d0d28103120c008203000401ccb8 -ac_founders=150 -ac_blocktime=20 -ac_nk=96,5 -earlytxid=810bd62fb8353fad20267ff2050684b8829affa3edf6b366633931530791dfce
|
||||
|
||||
once the payments plan has been funded with the mined coinbase you can issue payments release when conditions of the plan are met to fund founders reward/rewards plan. eg.
|
||||
./komodo-cli -ac_name=TESTHC paymentsrelease '["ee7765be874fb084c00538b1b0488e8ecb857de253f09a9ba6ea8d3579b77d33",500]'
|
||||
@@ -535,6 +535,8 @@ bool CheckMigration(Eval *eval, const CTransaction &importTx, const CTransaction
|
||||
|
||||
uint256 tokenid = zeroid;
|
||||
if (vimportOpret.begin()[0] == EVAL_TOKENS) { // for tokens (new opret with tokens)
|
||||
if ( is_STAKED(ASSETCHAINS_SYMBOL) == 1 )
|
||||
return eval->Invalid("no-tokens-migrate-on-LABS");
|
||||
struct CCcontract_info *cpTokens, CCtokens_info;
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets;
|
||||
uint8_t evalCodeInOpret;
|
||||
|
||||
@@ -4,6 +4,8 @@ rm *.so rogue/rogue games/tetris games/prices
|
||||
echo rogue
|
||||
make -f Makefile_rogue
|
||||
./makerogue
|
||||
rm ../libcc.so
|
||||
cp librogue.so ../libcc.so
|
||||
|
||||
echo sudoku/musig/dilithium
|
||||
gcc -O3 -std=c++11 -I../secp256k1/include -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared -c -o sudokucc.so cclib.cpp
|
||||
@@ -16,4 +18,3 @@ echo games prices
|
||||
|
||||
echo customcc stub
|
||||
gcc -O3 -DBUILD_CUSTOMCC -std=c++11 -I../secp256k1/include -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared -c -o customcc.so cclib.cpp
|
||||
|
||||
|
||||
@@ -4,4 +4,3 @@ cp customcc.so ../libcc.so
|
||||
cd ..
|
||||
make
|
||||
cd cc
|
||||
|
||||
|
||||
@@ -935,13 +935,13 @@ UniValue OracleFormat(uint8_t *data,int32_t datalen,char *format,int32_t formatl
|
||||
if ( j >= datalen )
|
||||
break;
|
||||
}
|
||||
return(obj);
|
||||
return(str);
|
||||
}
|
||||
|
||||
UniValue OracleDataSamples(uint256 reforacletxid,uint256 batontxid,int32_t num)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); CTransaction tx,oracletx; uint256 hashBlock,btxid,oracletxid;
|
||||
CPubKey pk; std::string name,description,format; int32_t numvouts,n=0; std::vector<uint8_t> data; char *formatstr = 0;
|
||||
UniValue result(UniValue::VOBJ),b(UniValue::VARR); CTransaction tx,oracletx; uint256 hashBlock,btxid,oracletxid;
|
||||
CPubKey pk; std::string name,description,format; int32_t numvouts,n=0; std::vector<uint8_t> data; char str[67], *formatstr = 0;
|
||||
|
||||
result.push_back(Pair("result","success"));
|
||||
if ( GetTransaction(reforacletxid,oracletx,hashBlock,false) != 0 && (numvouts=oracletx.vout.size()) > 0 )
|
||||
@@ -954,15 +954,18 @@ UniValue OracleDataSamples(uint256 reforacletxid,uint256 batontxid,int32_t num)
|
||||
{
|
||||
if ( (formatstr= (char *)format.c_str()) == 0 )
|
||||
formatstr = (char *)"";
|
||||
UniValue a(UniValue::VARR);
|
||||
a.push_back(OracleFormat((uint8_t *)data.data(),(int32_t)data.size(),formatstr,(int32_t)format.size()));
|
||||
a.push_back(uint256_str(str,batontxid));
|
||||
b.push_back(a);
|
||||
batontxid = btxid;
|
||||
if ( ++n >= num )
|
||||
if ( ++n >= num && num != 0)
|
||||
break;
|
||||
} else break;
|
||||
}
|
||||
}
|
||||
}
|
||||
result.push_back(Pair("samples",a));
|
||||
result.push_back(Pair("samples",b));
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
1012
src/cc/payments.cpp
1012
src/cc/payments.cpp
File diff suppressed because it is too large
Load Diff
2248
src/cc/prices.cpp
2248
src/cc/prices.cpp
File diff suppressed because it is too large
Load Diff
13
src/chain.h
13
src/chain.h
@@ -28,6 +28,7 @@ class CChainPower;
|
||||
#include "pow.h"
|
||||
#include "tinyformat.h"
|
||||
#include "uint256.h"
|
||||
extern int8_t is_STAKED(const char *chain_name);
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -36,6 +37,8 @@ class CChainPower;
|
||||
static const int SPROUT_VALUE_VERSION = 1001400;
|
||||
static const int SAPLING_VALUE_VERSION = 1010100;
|
||||
extern int32_t ASSETCHAINS_LWMAPOS;
|
||||
extern char ASSETCHAINS_SYMBOL[65];
|
||||
extern uint64_t ASSETCHAINS_NOTARY_PAY[];
|
||||
|
||||
struct CDiskBlockPos
|
||||
{
|
||||
@@ -118,7 +121,7 @@ enum BlockStatus: uint32_t {
|
||||
BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD,
|
||||
|
||||
BLOCK_ACTIVATES_UPGRADE = 128, //! block activates a network upgrade
|
||||
BLOCK_IN_TMPFILE = 256
|
||||
BLOCK_IN_TMPFILE = 256
|
||||
};
|
||||
|
||||
//! Short-hand for the highest consensus validity we implement.
|
||||
@@ -238,7 +241,7 @@ public:
|
||||
CBlockIndex* pskip;
|
||||
|
||||
//! height of the entry in the chain. The genesis block has height 0
|
||||
int64_t newcoins,zfunds,sproutfunds; int8_t segid; // jl777 fields
|
||||
int64_t newcoins,zfunds,sproutfunds,nNotaryPay; int8_t segid; // jl777 fields
|
||||
//! Which # file this block is stored in (blk?????.dat)
|
||||
int nFile;
|
||||
|
||||
@@ -309,6 +312,7 @@ public:
|
||||
phashBlock = NULL;
|
||||
newcoins = zfunds = 0;
|
||||
segid = -2;
|
||||
nNotaryPay = 0;
|
||||
pprev = NULL;
|
||||
pskip = NULL;
|
||||
nFile = 0;
|
||||
@@ -543,6 +547,11 @@ public:
|
||||
if ((s.GetType() & SER_DISK) && (nVersion >= SAPLING_VALUE_VERSION)) {
|
||||
READWRITE(nSaplingValue);
|
||||
}
|
||||
if ( (s.GetType() & SER_DISK) && (is_STAKED(ASSETCHAINS_SYMBOL) != 0) && ASSETCHAINS_NOTARY_PAY[0] != 0 )
|
||||
{
|
||||
READWRITE(nNotaryPay);
|
||||
READWRITE(segid);
|
||||
}
|
||||
}
|
||||
|
||||
uint256 GetBlockHash() const
|
||||
|
||||
13
src/init.cpp
13
src/init.cpp
@@ -35,6 +35,7 @@
|
||||
#include "httprpc.h"
|
||||
#include "key.h"
|
||||
#include "notarisationdb.h"
|
||||
|
||||
#ifdef ENABLE_MINING
|
||||
#include "key_io.h"
|
||||
#endif
|
||||
@@ -55,6 +56,7 @@
|
||||
#ifdef ENABLE_WALLET
|
||||
#include "wallet/wallet.h"
|
||||
#include "wallet/walletdb.h"
|
||||
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -89,9 +91,11 @@
|
||||
using namespace std;
|
||||
|
||||
extern void ThreadSendAlert();
|
||||
extern bool komodo_dailysnapshot(int32_t height);
|
||||
extern int32_t KOMODO_LOADINGBLOCKS;
|
||||
extern bool VERUS_MINTBLOCKS;
|
||||
extern char ASSETCHAINS_SYMBOL[];
|
||||
extern int32_t KOMODO_SNAPSHOT_INTERVAL;
|
||||
|
||||
ZCJoinSplit* pzcashParams = NULL;
|
||||
|
||||
@@ -1622,6 +1626,15 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
strLoadError = _("You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain");
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ASSETCHAINS_CC != 0 && KOMODO_SNAPSHOT_INTERVAL != 0 && chainActive.Height() >= KOMODO_SNAPSHOT_INTERVAL )
|
||||
{
|
||||
if ( !komodo_dailysnapshot(chainActive.Height()) )
|
||||
{
|
||||
strLoadError = _("daily snapshot failed, please reindex your chain.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fReindex) {
|
||||
uiInterface.InitMessage(_("Rewinding blocks if needed..."));
|
||||
|
||||
@@ -29,6 +29,7 @@ int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notar
|
||||
unsigned int lwmaGetNextPOSRequired(const CBlockIndex* pindexLast, const Consensus::Params& params);
|
||||
bool EnsureWalletIsAvailable(bool avoidException);
|
||||
extern bool fRequestShutdown;
|
||||
extern CScript KOMODO_EARLYTXID_SCRIPTPUB;
|
||||
|
||||
int32_t MarmaraSignature(uint8_t *utxosig,CMutableTransaction &txNew);
|
||||
uint8_t DecodeMaramaraCoinbaseOpRet(const CScript scriptPubKey,CPubKey &pk,int32_t &height,int32_t &unlockht);
|
||||
@@ -2045,9 +2046,77 @@ uint64_t komodo_checknotarypay(CBlock *pblock,int32_t height)
|
||||
return(0);
|
||||
}
|
||||
|
||||
bool komodo_appendACscriptpub()
|
||||
{
|
||||
static bool didinit = false;
|
||||
if ( didinit )
|
||||
return didinit;
|
||||
if ( ASSETCHAINS_SCRIPTPUB[ASSETCHAINS_SCRIPTPUB.back()] == 49 && ASSETCHAINS_SCRIPTPUB[ASSETCHAINS_SCRIPTPUB.back()-1] == 51 )
|
||||
{
|
||||
CTransaction tx; uint256 blockhash;
|
||||
// get transaction and check that it occured before height 100.
|
||||
if ( myGetTransaction(KOMODO_EARLYTXID,tx,blockhash) && mapBlockIndex[blockhash]->GetHeight() < 100 )
|
||||
{
|
||||
for (int i = 0; i < tx.vout.size(); i++)
|
||||
{
|
||||
if ( tx.vout[i].scriptPubKey[0] == OP_RETURN )
|
||||
{
|
||||
ASSETCHAINS_SCRIPTPUB.pop_back(); ASSETCHAINS_SCRIPTPUB.pop_back(); // remove last 2 chars.
|
||||
// get OP_RETURN from txid and append the HexStr of it to scriptpub
|
||||
ASSETCHAINS_SCRIPTPUB.append(HexStr(tx.vout[i].scriptPubKey.begin()+3, tx.vout[i].scriptPubKey.end()));
|
||||
//fprintf(stderr, "ac_script.%s\n",ASSETCHAINS_SCRIPTPUB.c_str());
|
||||
didinit = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "could not get KOMODO_EARLYTXID.%s OP_RETURN data. Restart with correct txid!\n", KOMODO_EARLYTXID.GetHex().c_str());
|
||||
StartShutdown();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void GetKomodoEarlytxidScriptPub()
|
||||
{
|
||||
if ( KOMODO_EARLYTXID == zeroid )
|
||||
{
|
||||
fprintf(stderr, "Restart deamon with -earlytxid.\n");
|
||||
StartShutdown();
|
||||
return;
|
||||
}
|
||||
if ( ASSETCHAINS_EARLYTXIDCONTRACT == EVAL_PRICES && KOMODO_SNAPSHOT_INTERVAL == 0 )
|
||||
{
|
||||
fprintf(stderr, "Prices->paymentsCC contract must have -ac_snapshot enabled to pay out.\n");
|
||||
StartShutdown();
|
||||
return;
|
||||
}
|
||||
if ( chainActive.Height() < 100 )
|
||||
{
|
||||
fprintf(stderr, "Cannot fetch -earlytxid before block 100.\n");
|
||||
StartShutdown();
|
||||
return;
|
||||
}
|
||||
CTransaction tx; uint256 blockhash; int32_t i;
|
||||
// get transaction and check that it occured before height 100.
|
||||
if ( myGetTransaction(KOMODO_EARLYTXID,tx,blockhash) && mapBlockIndex[blockhash]->GetHeight() < 100 )
|
||||
{
|
||||
for (i = 0; i < tx.vout.size(); i++)
|
||||
if ( tx.vout[i].scriptPubKey[0] == OP_RETURN )
|
||||
break;
|
||||
if ( i < tx.vout.size() )
|
||||
{
|
||||
KOMODO_EARLYTXID_SCRIPTPUB = CScript(tx.vout[i].scriptPubKey.begin()+3, tx.vout[i].scriptPubKey.end());
|
||||
fprintf(stderr, "KOMODO_EARLYTXID_SCRIPTPUB.%s\n", HexStr(KOMODO_EARLYTXID_SCRIPTPUB.begin(),KOMODO_EARLYTXID_SCRIPTPUB.end()).c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "INVALID -earlytxid, restart daemon with correct txid.\n");
|
||||
StartShutdown();
|
||||
}
|
||||
|
||||
int64_t komodo_checkcommission(CBlock *pblock,int32_t height)
|
||||
{
|
||||
int64_t checktoshis=0; uint8_t *script,scripthex[8192]; int32_t scriptlen,matched = 0;
|
||||
int64_t checktoshis=0; uint8_t *script,scripthex[8192]; int32_t scriptlen,matched = 0; static bool didinit = false;
|
||||
if ( ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 )
|
||||
{
|
||||
checktoshis = komodo_commission(pblock,height);
|
||||
@@ -2069,6 +2138,12 @@ int64_t komodo_checkcommission(CBlock *pblock,int32_t height)
|
||||
}
|
||||
if ( ASSETCHAINS_SCRIPTPUB.size() > 1 )
|
||||
{
|
||||
static bool didinit = false;
|
||||
if ( !didinit && height > 100 && KOMODO_EARLYTXID != zeroid && komodo_appendACscriptpub() )
|
||||
{
|
||||
fprintf(stderr, "appended CC_op_return to ASSETCHAINS_SCRIPTPUB.%s\n", ASSETCHAINS_SCRIPTPUB.c_str());
|
||||
didinit = true;
|
||||
}
|
||||
if ( ASSETCHAINS_SCRIPTPUB.size()/2 == scriptlen && scriptlen < sizeof(scripthex) )
|
||||
{
|
||||
decode_hex(scripthex,scriptlen,(char *)ASSETCHAINS_SCRIPTPUB.c_str());
|
||||
@@ -2205,11 +2280,11 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
|
||||
else if ( ASSETCHAINS_STAKED != 0 )
|
||||
failed = 0;
|
||||
}
|
||||
if ( failed == 0 && ASSETCHAINS_COMMISSION != 0 ) //ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 )
|
||||
if ( failed == 0 && ASSETCHAINS_COMMISSION != 0 )
|
||||
{
|
||||
if ( height == 1 )
|
||||
{
|
||||
if ( ASSETCHAINS_SCRIPTPUB.size() > 1 )
|
||||
if ( ASSETCHAINS_SCRIPTPUB.size() > 1 && ASSETCHAINS_SCRIPTPUB[ASSETCHAINS_SCRIPTPUB.back()] != 49 && ASSETCHAINS_SCRIPTPUB[ASSETCHAINS_SCRIPTPUB.back()-1] != 51 )
|
||||
{
|
||||
int32_t scriptlen; uint8_t scripthex[10000];
|
||||
script = (uint8_t *)&pblock->vtx[0].vout[0].scriptPubKey[0];
|
||||
@@ -2221,7 +2296,7 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
|
||||
return(-1);
|
||||
} else return(-1);
|
||||
}
|
||||
else
|
||||
else if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 )
|
||||
{
|
||||
script = (uint8_t *)&pblock->vtx[0].vout[0].scriptPubKey[0];
|
||||
scriptlen = (int32_t)pblock->vtx[0].vout[0].scriptPubKey.size();
|
||||
|
||||
@@ -38,7 +38,12 @@
|
||||
#define KOMODO_MAXNVALUE (((uint64_t)1 << 63) - 1)
|
||||
#define KOMODO_BIT63SET(x) ((x) & ((uint64_t)1 << 63))
|
||||
#define KOMODO_VALUETOOBIG(x) ((x) > (uint64_t)10000000001*COIN)
|
||||
|
||||
//#ifndef TESTMODE
|
||||
#define PRICES_DAYWINDOW ((3600*24/ASSETCHAINS_BLOCKTIME) + 1)
|
||||
//#else
|
||||
//#define PRICES_DAYWINDOW (7)
|
||||
//#endif
|
||||
|
||||
extern uint8_t ASSETCHAINS_TXPOW,ASSETCHAINS_PUBLIC;
|
||||
int32_t MAX_BLOCK_SIZE(int32_t height);
|
||||
@@ -63,7 +68,7 @@ extern uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS
|
||||
extern std::vector<std::string> ASSETCHAINS_PRICES,ASSETCHAINS_STOCKS;
|
||||
|
||||
extern int32_t VERUS_BLOCK_POSUNITS, VERUS_CONSECUTIVE_POS_THRESHOLD, VERUS_NOPOS_THRESHHOLD;
|
||||
|
||||
extern uint256 KOMODO_EARLYTXID;
|
||||
|
||||
extern int32_t KOMODO_CONNECTING,KOMODO_CCACTIVATE,KOMODO_DEALERNODE;
|
||||
extern uint32_t ASSETCHAINS_CC;
|
||||
@@ -78,7 +83,8 @@ extern std::string DONATION_PUBKEY;
|
||||
extern uint8_t ASSETCHAINS_PRIVATE;
|
||||
extern int32_t USE_EXTERNAL_PUBKEY;
|
||||
extern char NOTARYADDRS[64][64];
|
||||
extern int32_t KOMODO_TESTNODE;
|
||||
extern int32_t KOMODO_TESTNODE, KOMODO_SNAPSHOT_INTERVAL;
|
||||
extern int32_t ASSETCHAINS_EARLYTXIDCONTRACT;
|
||||
int tx_height( const uint256 &hash );
|
||||
extern std::vector<std::string> vWhiteListAddress;
|
||||
void komodo_netevent(std::vector<uint8_t> payload);
|
||||
@@ -101,7 +107,7 @@ int32_t komodo_dpowconfs(int32_t height,int32_t numconfs);
|
||||
int8_t komodo_segid(int32_t nocache,int32_t height);
|
||||
int32_t komodo_heightpricebits(uint64_t *seedp,uint32_t *heightbits,int32_t nHeight);
|
||||
char *komodo_pricename(char *name,int32_t ind);
|
||||
int32_t komodo_priceind(char *symbol);
|
||||
int32_t komodo_priceind(const char *symbol);
|
||||
int32_t komodo_pricesinit();
|
||||
int64_t komodo_priceave(int64_t *tmpbuf,int64_t *correlated,int32_t cskip);
|
||||
int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int32_t rawskip,uint32_t *nonzprices,int32_t smoothwidth);
|
||||
|
||||
@@ -2400,8 +2400,8 @@ char *komodo_pricename(char *name,int32_t ind)
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int32_t komodo_priceind(char *symbol)
|
||||
// finds index for its symbol name
|
||||
int32_t komodo_priceind(const char *symbol)
|
||||
{
|
||||
char name[65]; int32_t i,n = (int32_t)(komodo_cbopretsize(ASSETCHAINS_CBOPRET) / sizeof(uint32_t));
|
||||
for (i=1; i<n; i++)
|
||||
@@ -2412,7 +2412,7 @@ int32_t komodo_priceind(char *symbol)
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
// returns price value which is in a 10% interval for more than 50% points for the preceding 24 hours
|
||||
int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int32_t rawskip,uint32_t *nonzprices,int32_t smoothwidth)
|
||||
{
|
||||
int32_t i,j,k,n,iter,correlation,maxcorrelation=0; int64_t firstprice,price,sum,den,mult,refprice,lowprice,highprice;
|
||||
@@ -2801,4 +2801,3 @@ int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblo
|
||||
pthread_mutex_unlock(&pricemutex);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +109,9 @@ uint64_t PENDING_KOMODO_TX;
|
||||
extern int32_t KOMODO_LOADINGBLOCKS;
|
||||
unsigned int MAX_BLOCK_SIGOPS = 20000;
|
||||
|
||||
int32_t KOMODO_TESTNODE;
|
||||
int32_t KOMODO_TESTNODE, KOMODO_SNAPSHOT_INTERVAL;
|
||||
CScript KOMODO_EARLYTXID_SCRIPTPUB;
|
||||
int32_t ASSETCHAINS_EARLYTXIDCONTRACT;
|
||||
|
||||
struct komodo_kv *KOMODO_KV;
|
||||
pthread_mutex_t KOMODO_KV_mutex,KOMODO_CC_mutex;
|
||||
|
||||
@@ -1539,7 +1539,7 @@ uint16_t komodo_port(char *symbol,uint64_t supply,uint32_t *magicp,uint8_t *extr
|
||||
printf("ports\n");
|
||||
}*/
|
||||
|
||||
char *iguanafmtstr = (char *)"curl --url \"http://127.0.0.1:7776\" --data \"{\\\"conf\\\":\\\"%s.conf\\\",\\\"path\\\":\\\"${HOME#\"/\"}/.komodo/%s\\\",\\\"unitval\\\":\\\"20\\\",\\\"zcash\\\":1,\\\"RELAY\\\":-1,\\\"VALIDATE\\\":0,\\\"prefetchlag\\\":-1,\\\"poll\\\":100,\\\"active\\\":1,\\\"agent\\\":\\\"iguana\\\",\\\"method\\\":\\\"addcoin\\\",\\\"startpend\\\":4,\\\"endpend\\\":4,\\\"services\\\":129,\\\"maxpeers\\\":8,\\\"newcoin\\\":\\\"%s\\\",\\\"name\\\":\\\"%s\\\",\\\"hasheaders\\\":1,\\\"useaddmultisig\\\":0,\\\"netmagic\\\":\\\"%s\\\",\\\"p2p\\\":%u,\\\"rpc\\\":%u,\\\"pubval\\\":60,\\\"p2shval\\\":85,\\\"wifval\\\":188,\\\"txfee_satoshis\\\":\\\"10000\\\",\\\"isPoS\\\":0,\\\"minoutput\\\":10000,\\\"minconfirms\\\":2,\\\"genesishash\\\":\\\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\\\",\\\"protover\\\":170002,\\\"genesisblock\\\":\\\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\\\",\\\"debug\\\":0,\\\"seedipaddr\\\":\\\"%s\\\",\\\"sapling\\\":1}\"";
|
||||
char *iguanafmtstr = (char *)"curl --url \"http://127.0.0.1:7776\" --data \"{\\\"conf\\\":\\\"%s.conf\\\",\\\"path\\\":\\\"${HOME#\"/\"}/.komodo/%s\\\",\\\"unitval\\\":\\\"20\\\",\\\"zcash\\\":1,\\\"RELAY\\\":-1,\\\"VALIDATE\\\":0,\\\"prefetchlag\\\":-1,\\\"poll\\\":100,\\\"active\\\":1,\\\"agent\\\":\\\"iguana\\\",\\\"method\\\":\\\"addcoin\\\",\\\"startpend\\\":4,\\\"endpend\\\":4,\\\"services\\\":129,\\\"maxpeers\\\":8,\\\"newcoin\\\":\\\"%s\\\",\\\"name\\\":\\\"%s\\\",\\\"hasheaders\\\":1,\\\"useaddmultisig\\\":0,\\\"netmagic\\\":\\\"%s\\\",\\\"p2p\\\":%u,\\\"rpc\\\":%u,\\\"pubval\\\":60,\\\"p2shval\\\":85,\\\"wifval\\\":188,\\\"txfee_satoshis\\\":\\\"10000\\\",\\\"isPoS\\\":0,\\\"minoutput\\\":10000,\\\"minconfirms\\\":2,\\\"genesishash\\\":\\\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\\\",\\\"protover\\\":170002,\\\"genesisblock\\\":\\\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\\\",\\\"debug\\\":0,\\\"seedipaddr\\\":\\\"%s\\\",\\\"sapling\\\":1,\\\"notarypay\\\":%i}\"";
|
||||
|
||||
|
||||
|
||||
@@ -1752,12 +1752,15 @@ void komodo_args(char *argv0)
|
||||
ASSETCHAINS_BLOCKTIME = GetArg("-ac_blocktime",60);
|
||||
ASSETCHAINS_PUBLIC = GetArg("-ac_public",0);
|
||||
ASSETCHAINS_PRIVATE = GetArg("-ac_private",0);
|
||||
KOMODO_SNAPSHOT_INTERVAL = GetArg("-ac_snapshot",0);
|
||||
Split(GetArg("-ac_nk",""), ASSETCHAINS_NK, 0);
|
||||
if ( (KOMODO_REWIND= GetArg("-rewind",0)) != 0 )
|
||||
{
|
||||
printf("KOMODO_REWIND %d\n",KOMODO_REWIND);
|
||||
}
|
||||
KOMODO_EARLYTXID = Parseuint256(GetArg("-earlytxid","0").c_str());
|
||||
ASSETCHAINS_EARLYTXIDCONTRACT = GetArg("-ac_earlytxidcontract",0);
|
||||
fprintf(stderr, "ASSETCHAINS_EARLYTXIDCONTRACT.%i\n", ASSETCHAINS_EARLYTXIDCONTRACT);
|
||||
if ( name.c_str()[0] != 0 )
|
||||
{
|
||||
std::string selectedAlgo = GetArg("-ac_algo", std::string(ASSETCHAINS_ALGORITHMS[0]));
|
||||
@@ -2012,7 +2015,7 @@ void komodo_args(char *argv0)
|
||||
fprintf(stderr,"-ac_script and -ac_marmara are mutually exclusive\n");
|
||||
StartShutdown();
|
||||
}
|
||||
if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 || ASSETCHAINS_REWARD[0] != 0 || ASSETCHAINS_HALVING[0] != 0 || ASSETCHAINS_DECAY[0] != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 || ASSETCHAINS_FOUNDERS != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1 || ASSETCHAINS_SELFIMPORT.size() > 0 || ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF|| ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH || ASSETCHAINS_LWMAPOS != 0 || ASSETCHAINS_LASTERA > 0 || ASSETCHAINS_BEAMPORT != 0 || ASSETCHAINS_CODAPORT != 0 || ASSETCHAINS_MARMARA != 0 || nonz > 0 || ASSETCHAINS_CCLIB.size() > 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 || ASSETCHAINS_NOTARY_PAY[0] != 0 || ASSETCHAINS_BLOCKTIME != 60 || ASSETCHAINS_CBOPRET != 0 || Mineropret.size() != 0 || (ASSETCHAINS_NK[0] != 0 && ASSETCHAINS_NK[1] != 0) )
|
||||
if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 || ASSETCHAINS_REWARD[0] != 0 || ASSETCHAINS_HALVING[0] != 0 || ASSETCHAINS_DECAY[0] != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 || ASSETCHAINS_FOUNDERS != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1 || ASSETCHAINS_SELFIMPORT.size() > 0 || ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF|| ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH || ASSETCHAINS_LWMAPOS != 0 || ASSETCHAINS_LASTERA > 0 || ASSETCHAINS_BEAMPORT != 0 || ASSETCHAINS_CODAPORT != 0 || ASSETCHAINS_MARMARA != 0 || nonz > 0 || ASSETCHAINS_CCLIB.size() > 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 || ASSETCHAINS_NOTARY_PAY[0] != 0 || ASSETCHAINS_BLOCKTIME != 60 || ASSETCHAINS_CBOPRET != 0 || Mineropret.size() != 0 || (ASSETCHAINS_NK[0] != 0 && ASSETCHAINS_NK[1] != 0) || KOMODO_SNAPSHOT_INTERVAL != 0 || ASSETCHAINS_EARLYTXIDCONTRACT != 0 )
|
||||
{
|
||||
fprintf(stderr,"perc %.4f%% ac_pub=[%02x%02x%02x...] acsize.%d\n",dstr(ASSETCHAINS_COMMISSION)*100,ASSETCHAINS_OVERRIDE_PUBKEY33[0],ASSETCHAINS_OVERRIDE_PUBKEY33[1],ASSETCHAINS_OVERRIDE_PUBKEY33[2],(int32_t)ASSETCHAINS_SCRIPTPUB.size());
|
||||
extraptr = extrabuf;
|
||||
@@ -2072,6 +2075,7 @@ void komodo_args(char *argv0)
|
||||
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_FOUNDERS),(void *)&ASSETCHAINS_FOUNDERS);
|
||||
if ( ASSETCHAINS_FOUNDERS_REWARD != 0 )
|
||||
{
|
||||
fprintf(stderr, "set founders reward.%li\n",ASSETCHAINS_FOUNDERS_REWARD);
|
||||
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_FOUNDERS_REWARD),(void *)&ASSETCHAINS_FOUNDERS_REWARD);
|
||||
}
|
||||
}
|
||||
@@ -2147,6 +2151,14 @@ void komodo_args(char *argv0)
|
||||
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_NK[0]),(void *)&ASSETCHAINS_NK[0]);
|
||||
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_NK[1]),(void *)&ASSETCHAINS_NK[1]);
|
||||
}
|
||||
if ( KOMODO_SNAPSHOT_INTERVAL != 0 )
|
||||
{
|
||||
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(KOMODO_SNAPSHOT_INTERVAL),(void *)&KOMODO_SNAPSHOT_INTERVAL);
|
||||
}
|
||||
if ( ASSETCHAINS_EARLYTXIDCONTRACT != 0 )
|
||||
{
|
||||
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_EARLYTXIDCONTRACT),(void *)&ASSETCHAINS_EARLYTXIDCONTRACT);
|
||||
}
|
||||
}
|
||||
|
||||
addn = GetArg("-seednode","");
|
||||
@@ -2214,7 +2226,10 @@ void komodo_args(char *argv0)
|
||||
sprintf(fname,"%s_7776",ASSETCHAINS_SYMBOL);
|
||||
if ( (fp= fopen(fname,"wb")) != 0 )
|
||||
{
|
||||
fprintf(fp,iguanafmtstr,name.c_str(),name.c_str(),name.c_str(),name.c_str(),magicstr,ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,"78.47.196.146");
|
||||
int8_t notarypay = 0;
|
||||
if ( ASSETCHAINS_NOTARY_PAY[0] != 0 )
|
||||
notarypay = 1;
|
||||
fprintf(fp,iguanafmtstr,name.c_str(),name.c_str(),name.c_str(),name.c_str(),magicstr,ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,"78.47.196.146",notarypay);
|
||||
fclose(fp);
|
||||
//printf("created (%s)\n",fname);
|
||||
} else printf("error creating (%s)\n",fname);
|
||||
|
||||
121
src/main.cpp
121
src/main.cpp
@@ -642,6 +642,102 @@ UniValue komodo_snapshot(int top)
|
||||
return(result);
|
||||
}
|
||||
|
||||
bool komodo_snapshot2(std::map <std::string, CAmount> &addressAmounts)
|
||||
{
|
||||
if ( fAddressIndex && pblocktree != 0 )
|
||||
{
|
||||
return pblocktree->Snapshot2(addressAmounts, 0);
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
int32_t lastSnapShotHeight = 0;
|
||||
std::vector <std::pair<CAmount, CTxDestination>> vAddressSnapshot;
|
||||
|
||||
bool komodo_dailysnapshot(int32_t height)
|
||||
{
|
||||
int reorglimit = 10; // CHANGE BACK TO 100 AFTER TESTING!
|
||||
uint256 notarized_hash,notarized_desttxid; int32_t prevMoMheight,notarized_height,undo_height,extraoffset;
|
||||
if ( (extraoffset= height % KOMODO_SNAPSHOT_INTERVAL) != 0 )
|
||||
{
|
||||
// we are on chain init, and need to scan all the way back to the correct height, other wise our node will have a diffrent snapshot to online nodes.
|
||||
// use the notarizationsDB to scan back from the consesnus height to get the offset we need.
|
||||
std::string symbol; Notarisation nota;
|
||||
symbol.assign(ASSETCHAINS_SYMBOL);
|
||||
if ( ScanNotarisationsDB(height-extraoffset, symbol, 100, nota) == 0 )
|
||||
undo_height = height-extraoffset-reorglimit;
|
||||
else undo_height = nota.second.height;
|
||||
//fprintf(stderr, "height.%i-extraoffset.%i = startscanfrom.%i to get undo_height.%i\n", height, extraoffset, height-extraoffset, undo_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we are at the right height in connect block to scan back to last notarized height.
|
||||
notarized_height = komodo_notarized_height(&prevMoMheight,¬arized_hash,¬arized_desttxid);
|
||||
notarized_height > height-reorglimit ? undo_height = notarized_height : undo_height = height-reorglimit;
|
||||
}
|
||||
fprintf(stderr, "doing snapshot for height.%i undo_height.%i\n", height, undo_height);
|
||||
// if we already did this height dont bother doing it again, this is just a reorg. The actual snapshot height cannot be reorged.
|
||||
if ( undo_height == lastSnapShotHeight )
|
||||
return true;
|
||||
std::map <std::string, int64_t> addressAmounts;
|
||||
if ( !komodo_snapshot2(addressAmounts) )
|
||||
return false;
|
||||
|
||||
// undo blocks in reverse order
|
||||
for (int32_t n = height; n > undo_height; n--)
|
||||
{
|
||||
//fprintf(stderr, "undoing block.%i\n",n);
|
||||
CBlockIndex *pindex; CBlock block;
|
||||
if ( (pindex= komodo_chainactive(n)) == 0 || komodo_blockload(block, pindex) != 0 )
|
||||
return false;
|
||||
// undo transactions in reverse order
|
||||
for (int32_t i = block.vtx.size() - 1; i >= 0; i--)
|
||||
{
|
||||
const CTransaction &tx = block.vtx[i];
|
||||
CTxDestination vDest;
|
||||
// loop vouts reverse order, remove value recieved.
|
||||
for (unsigned int k = tx.vout.size(); k-- > 0;)
|
||||
{
|
||||
const CTxOut &out = tx.vout[k];
|
||||
if ( ExtractDestination(out.scriptPubKey, vDest) )
|
||||
{
|
||||
addressAmounts[CBitcoinAddress(vDest).ToString()] -= out.nValue;
|
||||
if ( addressAmounts[CBitcoinAddress(vDest).ToString()] < 1 )
|
||||
addressAmounts.erase(CBitcoinAddress(vDest).ToString());
|
||||
//fprintf(stderr, "VOUT: address.%s remove_coins.%li\n",CBitcoinAddress(vDest).ToString().c_str(), out.nValue);
|
||||
}
|
||||
}
|
||||
// loop vins in reverse order, get prevout and return the sent balance.
|
||||
for (unsigned int j = tx.vin.size(); j-- > 0;)
|
||||
{
|
||||
uint256 blockhash; CTransaction txin;
|
||||
if ( !tx.IsCoinImport() && !tx.IsCoinBase() && myGetTransaction(tx.vin[j].prevout.hash,txin,blockhash) )
|
||||
{
|
||||
int vout = tx.vin[j].prevout.n;
|
||||
if ( ExtractDestination(txin.vout[vout].scriptPubKey, vDest) )
|
||||
{
|
||||
//fprintf(stderr, "VIN: address.%s add_coins.%li\n",CBitcoinAddress(vDest).ToString().c_str(), txin.vout[vout].nValue);
|
||||
addressAmounts[CBitcoinAddress(vDest).ToString()] += txin.vout[vout].nValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
vAddressSnapshot.clear(); // clear existing snapshot
|
||||
// convert address string to destination for easier conversion to what ever is required, eg, scriptPubKey.
|
||||
for ( auto element : addressAmounts)
|
||||
vAddressSnapshot.push_back(make_pair(element.second, DecodeDestination(element.first)));
|
||||
// sort the vector by amount, highest at top.
|
||||
std::sort(vAddressSnapshot.rbegin(), vAddressSnapshot.rend());
|
||||
//for (int j = 0; j < 50; j++)
|
||||
// fprintf(stderr, "j.%i address.%s nValue.%li\n",j, CBitcoinAddress(vAddressSnapshot[j].second).ToString().c_str(), vAddressSnapshot[j].first );
|
||||
// include only top 5000 address.
|
||||
if ( vAddressSnapshot.size() > 3999 ) vAddressSnapshot.resize(3999);
|
||||
lastSnapShotHeight = undo_height;
|
||||
fprintf(stderr, "vAddressSnapshot.size.%li\n", vAddressSnapshot.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// mapOrphanTransactions
|
||||
@@ -3096,7 +3192,6 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
|
||||
uint160 addrHash = addr.size() == 20 ? uint160(addr) : Hash160(addr);
|
||||
// undo spending activity
|
||||
addressIndex.push_back(make_pair(CAddressIndexKey(keyType, addrHash, pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
|
||||
|
||||
// restore unspent index
|
||||
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(keyType, addrHash, input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
|
||||
}
|
||||
@@ -3269,7 +3364,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
auto verifier = libzcash::ProofVerifier::Strict();
|
||||
auto disabledVerifier = libzcash::ProofVerifier::Disabled();
|
||||
int32_t futureblock;
|
||||
CAmount blockReward = 0;
|
||||
CAmount blockReward = 0; uint64_t notarypaycheque = 0;
|
||||
// Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in
|
||||
if (!CheckBlock(&futureblock,pindex->GetHeight(),pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck) || futureblock != 0 )
|
||||
{
|
||||
@@ -3307,7 +3402,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
return state.DoS(100, error("ConnectBlock(): Notaries have not been paid!"),
|
||||
REJECT_INVALID, "bad-cb-amount");
|
||||
// calculate the notaries compensation and validate the amounts and pubkeys are correct.
|
||||
uint64_t notarypaycheque = komodo_checknotarypay((CBlock *)&block,(int32_t)pindex->GetHeight());
|
||||
notarypaycheque = komodo_checknotarypay((CBlock *)&block,(int32_t)pindex->GetHeight());
|
||||
//fprintf(stderr, "notarypaycheque.%lu\n", notarypaycheque);
|
||||
if ( notarypaycheque > 0 )
|
||||
blockReward += notarypaycheque;
|
||||
@@ -3497,8 +3592,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
fprintf(stderr,"valueout %.8f too big\n",(double)valueout/COIN);
|
||||
return state.DoS(100, error("ConnectBlock(): GetValueOut too big"),REJECT_INVALID,"tx valueout is too big");
|
||||
}
|
||||
prevsum = voutsum;
|
||||
voutsum += valueout;
|
||||
//prevsum = voutsum;
|
||||
//voutsum += valueout;
|
||||
/*if ( KOMODO_VALUETOOBIG(voutsum) != 0 )
|
||||
{
|
||||
fprintf(stderr,"voutsum %.8f too big\n",(double)voutsum/COIN);
|
||||
@@ -3714,6 +3809,12 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
|
||||
//FlushStateToDisk();
|
||||
komodo_connectblock(false,pindex,*(CBlock *)&block); // dPoW state update.
|
||||
if ( ASSETCHAINS_NOTARY_PAY[0] != 0 )
|
||||
{
|
||||
// Update the notary pay with the latest payment.
|
||||
pindex->nNotaryPay = pindex->pprev->nNotaryPay + notarypaycheque;
|
||||
//fprintf(stderr, "total notary pay.%li\n", pindex->nNotaryPay);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3923,6 +4024,7 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) {
|
||||
DisconnectNotarisations(block);
|
||||
}
|
||||
pindexDelete->segid = -2;
|
||||
pindexDelete->nNotaryPay = 0;
|
||||
pindexDelete->newcoins = 0;
|
||||
pindexDelete->zfunds = 0;
|
||||
|
||||
@@ -4156,6 +4258,13 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
|
||||
komodo_pricesupdate(pindexNew->GetHeight(),pblock);
|
||||
if ( ASSETCHAINS_SAPLING <= 0 && pindexNew->nTime > KOMODO_SAPLING_ACTIVATION - 24*3600 )
|
||||
komodo_activate_sapling(pindexNew);
|
||||
if ( ASSETCHAINS_CC != 0 && KOMODO_SNAPSHOT_INTERVAL != 0 && (pindexNew->GetHeight() % KOMODO_SNAPSHOT_INTERVAL) == 0 && pindexNew->GetHeight() >= KOMODO_SNAPSHOT_INTERVAL )
|
||||
{
|
||||
uint64_t start = time(NULL);
|
||||
if ( !komodo_dailysnapshot(pindexNew->GetHeight()) )
|
||||
fprintf(stderr, "daily snapshot failed, please reindex your chain\n"); // maybe force shutdown here?
|
||||
fprintf(stderr, "snapshot completed in: %lu seconds\n", time(NULL)-start);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -6095,7 +6204,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
|
||||
}
|
||||
|
||||
LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.Height() - pindexState->GetHeight(), nGoodTransactions);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 100;
|
||||
/** Default for -maxorphantx, maximum number of orphan transactions kept in memory */
|
||||
static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100;
|
||||
/** Default for -txexpirydelta, in number of blocks */
|
||||
static const unsigned int DEFAULT_TX_EXPIRY_DELTA = 20;
|
||||
static const unsigned int DEFAULT_TX_EXPIRY_DELTA = 200;
|
||||
/** The maximum size of a blk?????.dat file (since 0.8) */
|
||||
static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB
|
||||
static const unsigned int MAX_TEMPFILE_SIZE = 0x1000000; // 16 MiB 0x8000000
|
||||
|
||||
@@ -156,6 +156,7 @@ uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector<int8_t> &Notar
|
||||
int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);
|
||||
int32_t komodo_getnotarizedheight(uint32_t timestamp,int32_t height, uint8_t *script, int32_t len);
|
||||
CScript komodo_mineropret(int32_t nHeight);
|
||||
bool komodo_appendACscriptpub();
|
||||
|
||||
CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32_t gpucount, bool isStake)
|
||||
{
|
||||
@@ -290,9 +291,9 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
|
||||
txvalue = tx.GetValueOut();
|
||||
if ( KOMODO_VALUETOOBIG(txvalue) != 0 )
|
||||
continue;
|
||||
if ( KOMODO_VALUETOOBIG(txvalue + voutsum) != 0 )
|
||||
continue;
|
||||
voutsum += txvalue;
|
||||
//if ( KOMODO_VALUETOOBIG(txvalue + voutsum) != 0 ) // has been commented from main.cpp ?
|
||||
// continue;
|
||||
//voutsum += txvalue;
|
||||
if ( ASSETCHAINS_SYMBOL[0] == 0 && komodo_validate_interest(tx,nHeight,(uint32_t)pblock->nTime,0) < 0 )
|
||||
{
|
||||
//fprintf(stderr,"CreateNewBlock: komodo_validate_interest failure nHeight.%d nTime.%u vs locktime.%u\n",nHeight,(uint32_t)pblock->nTime,(uint32_t)tx.nLockTime);
|
||||
@@ -652,6 +653,12 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
|
||||
txNew.vout[1].nValue = commission;
|
||||
if ( ASSETCHAINS_SCRIPTPUB.size() > 1 )
|
||||
{
|
||||
static bool didinit = false;
|
||||
if ( !didinit && nHeight > 100 && KOMODO_EARLYTXID != zeroid && komodo_appendACscriptpub() )
|
||||
{
|
||||
fprintf(stderr, "appended ccopreturn to ASSETCHAINS_SCRIPTPUB.%s\n", ASSETCHAINS_SCRIPTPUB.c_str());
|
||||
didinit = true;
|
||||
}
|
||||
//fprintf(stderr,"mine to -ac_script\n");
|
||||
//txNew.vout[1].scriptPubKey = CScript() << ParseHex();
|
||||
int32_t len = strlen(ASSETCHAINS_SCRIPTPUB.c_str());
|
||||
@@ -721,7 +728,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
fprintf(stderr, "Created notary payment coinbase totalsat.%lu\n",totalsats);
|
||||
//fprintf(stderr, "Created notary payment coinbase totalsat.%lu\n",totalsats);
|
||||
} else fprintf(stderr, "vout 2 of notarisation is not OP_RETURN scriptlen.%i\n", scriptlen);
|
||||
}
|
||||
if ( ASSETCHAINS_CBOPRET != 0 )
|
||||
@@ -895,14 +902,14 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int&
|
||||
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, int32_t nHeight, int32_t gpucount, bool isStake)
|
||||
{
|
||||
CPubKey pubkey; CScript scriptPubKey; uint8_t *script,*ptr; int32_t i,len;
|
||||
if ( nHeight == 1 && ASSETCHAINS_COMMISSION != 0 )
|
||||
if ( nHeight == 1 && ASSETCHAINS_COMMISSION != 0 && ASSETCHAINS_SCRIPTPUB[ASSETCHAINS_SCRIPTPUB.back()] != 49 && ASSETCHAINS_SCRIPTPUB[ASSETCHAINS_SCRIPTPUB.back()-1] != 51 )
|
||||
{
|
||||
if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 )
|
||||
{
|
||||
pubkey = ParseHex(ASSETCHAINS_OVERRIDE_PUBKEY);
|
||||
scriptPubKey = CScript() << ParseHex(HexStr(pubkey)) << OP_CHECKSIG;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
len = strlen(ASSETCHAINS_SCRIPTPUB.c_str());
|
||||
len >>= 1;
|
||||
|
||||
@@ -18,7 +18,7 @@ int8_t is_STAKED(const char *chain_name)
|
||||
if (doneinit == 1 && ASSETCHAINS_SYMBOL[0] != 0)
|
||||
return(STAKED);
|
||||
else STAKED = 0;
|
||||
if ( (strcmp(chain_name, "LABS") == 0) || (strcmp(chain_name, "LABSTH") == 0) )
|
||||
if ( (strcmp(chain_name, "LABS") == 0) || (strcmp(chain_name, "LABSRCTEST") == 0) )
|
||||
STAKED = 1; // These chains are allowed coin emissions.
|
||||
else if ( (strncmp(chain_name, "LABS", 4) == 0) )
|
||||
STAKED = 2; // These chains have no coin emission, block subsidy is always 0, and comission is 0. Notary pay is allowed.
|
||||
|
||||
@@ -43,6 +43,9 @@
|
||||
|
||||
#include <regex>
|
||||
|
||||
#include "cc/CCinclude.h"
|
||||
#include "cc/CCPrices.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
|
||||
@@ -1155,17 +1158,17 @@ UniValue paxprice(const UniValue& params, bool fHelp)
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// fills pricedata with raw price, correlated and smoothed values for numblock
|
||||
/*int32_t prices_extract(int64_t *pricedata,int32_t firstheight,int32_t numblocks,int32_t ind)
|
||||
{
|
||||
int32_t height,i,n,width,numpricefeeds = -1; uint64_t seed,ignore,rngval; uint32_t rawprices[1440*6],*ptr; int64_t *tmpbuf;
|
||||
width = numblocks+PRICES_DAYWINDOW*2+PRICES_SMOOTHWIDTH;
|
||||
width = numblocks+PRICES_DAYWINDOW*2+PRICES_SMOOTHWIDTH; // need 2*PRICES_DAYWINDOW previous raw price points to calc PRICES_DAYWINDOW correlated points to calc, in turn, smoothed point
|
||||
komodo_heightpricebits(&seed,rawprices,firstheight + numblocks - 1);
|
||||
if ( firstheight < width )
|
||||
return(-1);
|
||||
for (i=0; i<width; i++)
|
||||
{
|
||||
if ( (n= komodo_heightpricebits(&ignore,rawprices,firstheight + numblocks - 1 - i)) < 0 )
|
||||
if ( (n= komodo_heightpricebits(&ignore,rawprices,firstheight + numblocks - 1 - i)) < 0 ) // stores raw prices in backward order
|
||||
return(-1);
|
||||
if ( numpricefeeds < 0 )
|
||||
numpricefeeds = n;
|
||||
@@ -1176,16 +1179,18 @@ UniValue paxprice(const UniValue& params, bool fHelp)
|
||||
ptr[1] = rawprices[0]; // timestamp
|
||||
}
|
||||
rngval = seed;
|
||||
for (i=0; i<numblocks+PRICES_DAYWINDOW+PRICES_SMOOTHWIDTH; i++)
|
||||
for (i=0; i<numblocks+PRICES_DAYWINDOW+PRICES_SMOOTHWIDTH; i++) // calculates +PRICES_DAYWINDOW more correlated values
|
||||
{
|
||||
rngval = (rngval*11109 + 13849);
|
||||
ptr = (uint32_t *)&pricedata[i*3];
|
||||
if ( (pricedata[i*3+1]= komodo_pricecorrelated(rngval,ind,(uint32_t *)&pricedata[i*3],6,0,PRICES_SMOOTHWIDTH)) < 0 )
|
||||
// takes previous PRICES_DAYWINDOW raw prices and calculates correlated price value
|
||||
if ( (pricedata[i*3+1]= komodo_pricecorrelated(rngval,ind,(uint32_t *)&pricedata[i*3],6,0,PRICES_SMOOTHWIDTH)) < 0 ) // skip is 6 == sizeof(int64_t)/sizeof(int32_t)*3
|
||||
return(-3);
|
||||
}
|
||||
tmpbuf = (int64_t *)calloc(sizeof(int64_t),2*PRICES_DAYWINDOW);
|
||||
for (i=0; i<numblocks; i++)
|
||||
pricedata[i*3+2] = komodo_priceave(tmpbuf,&pricedata[i*3+1],3);
|
||||
// takes previous PRICES_DAYWINDOW correlated price values and calculates smoothed value
|
||||
pricedata[i*3+2] = komodo_priceave(tmpbuf,&pricedata[i*3+1],3);
|
||||
free(tmpbuf);
|
||||
return(0);
|
||||
}*/
|
||||
@@ -1315,6 +1320,139 @@ UniValue prices(const UniValue& params, bool fHelp)
|
||||
return ret;
|
||||
}
|
||||
|
||||
// pricesbet rpc implementation
|
||||
UniValue pricesbet(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 3)
|
||||
throw runtime_error("pricesbet amount leverage \"synthetic-expression\"\n"
|
||||
"amount is in coins\n"
|
||||
"leverage is integer non-zero value, positive for long, negative for short position\n"
|
||||
"synthetic-expression example \"BTC_USD, 1\"\n");
|
||||
LOCK(cs_main);
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
|
||||
if (ASSETCHAINS_CBOPRET == 0)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices");
|
||||
|
||||
CAmount txfee = 10000;
|
||||
CAmount amount = atof(params[0].get_str().c_str()) * COIN;
|
||||
int16_t leverage = (int16_t)atoi(params[1].get_str().c_str());
|
||||
if (leverage == 0)
|
||||
throw runtime_error("invalid leverage\n");
|
||||
|
||||
std::string sexpr = params[2].get_str();
|
||||
std::vector<std::string> vexpr;
|
||||
SplitStr(sexpr, vexpr);
|
||||
|
||||
// debug print parsed strings:
|
||||
std::cerr << "parsed synthetic: ";
|
||||
for (auto s : vexpr)
|
||||
std::cerr << s << " ";
|
||||
std::cerr << std::endl;
|
||||
|
||||
return PricesBet(txfee, amount, leverage, vexpr);
|
||||
}
|
||||
|
||||
// pricesaddfunding rpc implementation
|
||||
UniValue pricesaddfunding(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 2)
|
||||
throw runtime_error("pricesaddfunding bettxid amount\n"
|
||||
"where amount is in coins\n");
|
||||
LOCK(cs_main);
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
|
||||
if (ASSETCHAINS_CBOPRET == 0)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices");
|
||||
|
||||
CAmount txfee = 10000;
|
||||
uint256 bettxid = Parseuint256(params[0].get_str().c_str());
|
||||
if (bettxid.IsNull())
|
||||
throw runtime_error("invalid bettxid\n");
|
||||
|
||||
CAmount amount = atof(params[1].get_str().c_str()) * COIN;
|
||||
if (amount <= 0)
|
||||
throw runtime_error("invalid amount\n");
|
||||
|
||||
return PricesAddFunding(txfee, bettxid, amount);
|
||||
}
|
||||
|
||||
// rpc pricessetcostbasis implementation
|
||||
UniValue pricessetcostbasis(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error("pricessetcostbasis bettxid\n");
|
||||
LOCK(cs_main);
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
|
||||
if (ASSETCHAINS_CBOPRET == 0)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices");
|
||||
|
||||
uint256 bettxid = Parseuint256(params[0].get_str().c_str());
|
||||
if (bettxid.IsNull())
|
||||
throw runtime_error("invalid bettxid\n");
|
||||
|
||||
int64_t txfee = 10000;
|
||||
|
||||
return PricesSetcostbasis(txfee, bettxid);
|
||||
}
|
||||
|
||||
// pricescashout rpc implementation
|
||||
UniValue pricescashout(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error("pricescashout bettxid\n");
|
||||
LOCK(cs_main);
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
|
||||
if (ASSETCHAINS_CBOPRET == 0)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices");
|
||||
|
||||
uint256 bettxid = Parseuint256(params[0].get_str().c_str());
|
||||
if (bettxid.IsNull())
|
||||
throw runtime_error("invalid bettxid\n");
|
||||
|
||||
int64_t txfee = 10000;
|
||||
|
||||
return PricesCashout(txfee, bettxid);
|
||||
}
|
||||
|
||||
// pricesrekt rpc implementation
|
||||
UniValue pricesrekt(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 2)
|
||||
throw runtime_error("pricesrekt bettxid height\n");
|
||||
LOCK(cs_main);
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
|
||||
if (ASSETCHAINS_CBOPRET == 0)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices");
|
||||
|
||||
uint256 bettxid = Parseuint256(params[0].get_str().c_str());
|
||||
if (bettxid.IsNull())
|
||||
throw runtime_error("invalid bettxid\n");
|
||||
|
||||
int32_t height = atoi(params[0].get_str().c_str());
|
||||
|
||||
int64_t txfee = 10000;
|
||||
|
||||
return PricesRekt(txfee, bettxid, height);
|
||||
}
|
||||
|
||||
// pricesrekt rpc implementation
|
||||
UniValue pricesgetorderbook(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error("pricesgetorderbook\n");
|
||||
LOCK(cs_main);
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
|
||||
if (ASSETCHAINS_CBOPRET == 0)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices");
|
||||
|
||||
return PricesGetOrderbook();
|
||||
}
|
||||
|
||||
UniValue gettxout(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() < 2 || params.size() > 3)
|
||||
@@ -1944,4 +2082,4 @@ void RegisterBlockchainRPCCommands(CRPCTable &tableRPC)
|
||||
{
|
||||
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
|
||||
tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
|
||||
}
|
||||
}
|
||||
@@ -300,6 +300,9 @@ UniValue migrate_createburntransaction(const UniValue& params, bool fHelp)
|
||||
uint256 tokenid = zeroid;
|
||||
if( params.size() == 4 )
|
||||
tokenid = Parseuint256(params[3].get_str().c_str());
|
||||
|
||||
if ( tokenid != zeroid && strcmp("LABS", targetSymbol.c_str()))
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "There is no tokens support on LABS.");
|
||||
|
||||
CPubKey myPubKey = Mypubkey();
|
||||
struct CCcontract_info *cpTokens, C;
|
||||
@@ -312,8 +315,8 @@ UniValue migrate_createburntransaction(const UniValue& params, bool fHelp)
|
||||
|
||||
if (tokenid.IsNull()) { // coins
|
||||
int64_t inputs;
|
||||
if ((inputs = AddNormalinputs(mtx, myPubKey, burnAmount + txfee, 60)) == 0) {
|
||||
throw runtime_error("Cannot find normal inputs\n");
|
||||
if ((inputs = AddNormalinputs(mtx, myPubKey, burnAmount + txfee, 10)) == 0) {
|
||||
throw runtime_error("not enough funds, or need to merge utxos first\n");
|
||||
}
|
||||
|
||||
CTxDestination txdest = DecodeDestination(dest_addr_or_pubkey.c_str());
|
||||
@@ -1145,36 +1148,43 @@ UniValue getNotarisationsForBlock(const UniValue& params, bool fHelp)
|
||||
//out.push_back(make_pair("blocktime",(int)));
|
||||
UniValue labs(UniValue::VARR);
|
||||
UniValue kmd(UniValue::VARR);
|
||||
// Gets KMD notaries on KMD... but LABS notaries on labs chains needs to be fixed so LABS are identified on KMD.
|
||||
int8_t numNN = 0; uint8_t notarypubkeys[64][33] = {0};
|
||||
int8_t numNN = 0, numSN = 0; uint8_t notarypubkeys[64][33] = {0}; uint8_t LABSpubkeys[64][33] = {0};
|
||||
numNN = komodo_notaries(notarypubkeys, height, chainActive[height]->nTime);
|
||||
|
||||
numSN = numStakedNotaries(LABSpubkeys,STAKED_era(chainActive[height]->nTime));
|
||||
|
||||
BOOST_FOREACH(const Notarisation& n, nibs)
|
||||
{
|
||||
UniValue item(UniValue::VOBJ); UniValue notaryarr(UniValue::VARR); std::vector<int8_t> NotarisationNotaries;
|
||||
if ( is_STAKED(n.second.symbol) != 0 )
|
||||
continue; // for now just skip this... need to fetch diff pubkeys for these chains. labs.push_back(item);
|
||||
uint256 hash; CTransaction tx;
|
||||
if ( GetTransaction(n.first,tx,hash,false) )
|
||||
{
|
||||
if ( !GetNotarisationNotaries(notarypubkeys, numNN, tx.vin, NotarisationNotaries) )
|
||||
continue;
|
||||
if ( NotarisationNotaries.size() < numNN/5 )
|
||||
continue;
|
||||
if ( is_STAKED(n.second.symbol) != 0 )
|
||||
{
|
||||
if ( !GetNotarisationNotaries(LABSpubkeys, numSN, tx.vin, NotarisationNotaries) )
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !GetNotarisationNotaries(notarypubkeys, numNN, tx.vin, NotarisationNotaries) )
|
||||
continue;
|
||||
}
|
||||
}
|
||||
item.push_back(make_pair("txid", n.first.GetHex()));
|
||||
item.push_back(make_pair("chain", n.second.symbol));
|
||||
item.push_back(make_pair("height", (int)n.second.height));
|
||||
item.push_back(make_pair("blockhash", n.second.blockHash.GetHex()));
|
||||
item.push_back(make_pair("KMD_height", height)); // for when timstamp input is used.
|
||||
//item.push_back(make_pair("KMD_height", height)); // for when timstamp input is used.
|
||||
|
||||
for ( auto notary : NotarisationNotaries )
|
||||
notaryarr.push_back(notary);
|
||||
item.push_back(make_pair("notaries",notaryarr));
|
||||
kmd.push_back(item);
|
||||
if ( is_STAKED(n.second.symbol) != 0 )
|
||||
labs.push_back(item);
|
||||
else
|
||||
kmd.push_back(item);
|
||||
}
|
||||
out.push_back(make_pair("KMD", kmd));
|
||||
//out.push_back(make_pair("LABS", labs));
|
||||
out.push_back(make_pair("LABS", labs));
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -1308,7 +1318,7 @@ UniValue getimports(const UniValue& params, bool fHelp)
|
||||
UniValue objTx(UniValue::VOBJ);
|
||||
objTx.push_back(Pair("txid",tx.GetHash().ToString()));
|
||||
ImportProof proof; CTransaction burnTx; std::vector<CTxOut> payouts; CTxDestination importaddress;
|
||||
TotalImported += tx.vout[1].nValue;
|
||||
TotalImported += tx.vout[0].nValue; // were vouts swapped?
|
||||
objTx.push_back(Pair("amount", ValueFromAmount(tx.vout[1].nValue)));
|
||||
if (ExtractDestination(tx.vout[1].scriptPubKey, importaddress))
|
||||
{
|
||||
@@ -1481,4 +1491,4 @@ UniValue getwalletburntransactions(const UniValue& params, bool fHelp)
|
||||
ret.push_backV(arrTmp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
109
src/rpc/misc.cpp
109
src/rpc/misc.cpp
@@ -75,6 +75,8 @@ uint32_t komodo_segid32(char *coinaddr);
|
||||
int64_t komodo_coinsupply(int64_t *zfundsp,int64_t *sproutfundsp,int32_t height);
|
||||
int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heightp);
|
||||
int8_t StakedNotaryID(std::string ¬aryname, char *Raddress);
|
||||
uint64_t komodo_notarypayamount(int32_t nHeight, int64_t notarycount);
|
||||
int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);
|
||||
|
||||
#define KOMODO_VERSION "0.3.3b"
|
||||
#define VERUS_VERSION "0.4.0g"
|
||||
@@ -168,7 +170,7 @@ UniValue geterablockheights(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
"getnotarysendmany\n"
|
||||
"geterablockheights\n"
|
||||
"Returns a JSON object with the first block in each era.\n"
|
||||
);
|
||||
|
||||
@@ -1216,6 +1218,106 @@ UniValue getaddressdeltas(const UniValue& params, bool fHelp)
|
||||
}
|
||||
}
|
||||
|
||||
CAmount checkburnaddress(CAmount &received, int64_t &nNotaryPay, int32_t &height, std::string sAddress)
|
||||
{
|
||||
CBitcoinAddress address(sAddress);
|
||||
uint160 hashBytes; int type = 0; CAmount balance = 0;
|
||||
if (address.GetIndexKey(hashBytes, type, false))
|
||||
{
|
||||
std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
|
||||
if (GetAddressIndex(hashBytes, type, addressIndex))
|
||||
{
|
||||
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++)
|
||||
{
|
||||
if (it->second > 0)
|
||||
received += it->second;
|
||||
balance += it->second;
|
||||
}
|
||||
// Get notary pay from current chain tip
|
||||
CBlockIndex* pindex = chainActive.LastTip();
|
||||
nNotaryPay = pindex->nNotaryPay;
|
||||
height = pindex->GetHeight();
|
||||
}
|
||||
}
|
||||
return balance;
|
||||
}
|
||||
|
||||
UniValue checknotarization(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
"checknotarization\n"
|
||||
"\nReturns true if burn address balance is greater than total notary pay. (requires addressindex to be enabled).\n"
|
||||
);
|
||||
|
||||
UniValue result(UniValue::VOBJ); CAmount balance = 0, received = 0; int64_t nNotaryPay = 0; int32_t height;
|
||||
|
||||
// helper to test burn address's
|
||||
/*uint8_t priv[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t pub[33] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
char coinaddr[64]; uint8_t buf33[33];
|
||||
//pubkey2addr(coinaddr, pub);
|
||||
priv2addr(coinaddr,buf33,priv);
|
||||
fprintf(stderr, "what.%s\n", coinaddr);
|
||||
result.push_back(Pair("address", coinaddr));
|
||||
return result;
|
||||
*/
|
||||
|
||||
if ( ASSETCHAINS_NOTARY_PAY[0] == 0 )
|
||||
throw runtime_error("only works for ac_notarypay chains");
|
||||
// pubkey 020000000000000000000000000000000
|
||||
balance = checkburnaddress(received, nNotaryPay, height, "REDVp3ox1pbcWYCzySadfHhk8UU3HM4k5x");
|
||||
if ( nNotaryPay >= balance || received != balance )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
UniValue getnotarypayinfo(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
"getnotarypayinfo\n"
|
||||
"\nReturns infomation about ac_notaypay status (requires addressindex to be enabled).\n"
|
||||
"\nResult:\n"
|
||||
"{\n"
|
||||
" \"height\" (number) The current block height\n"
|
||||
" \"balance\" (number) The current balance of the burn address\n"
|
||||
" \"spent\" (bool) true if coins have been spent from the burn address\n"
|
||||
" \"Total_NotaryPay\" (number) Total amount paid to notaries\n"
|
||||
" \"Estimated_Notarizations_Left\" (number) the estimated amount of notarizations left before the balance is consumed\n"
|
||||
" \"Estimated_Days_Left\" (number) the estimated amount of days the current balance will last\n"
|
||||
" \"Estimated_Height\" (number) the estimated block height funds will run out\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
if ( ASSETCHAINS_NOTARY_PAY[0] == 0 )
|
||||
throw runtime_error("only works for ac_notarypay chains");
|
||||
|
||||
UniValue result(UniValue::VOBJ); CAmount balance = 0, received = 0; int64_t TotalNotaryPay = 0, NotaryPay, notaleft = 0, daysleft = 0, notarycount; int32_t height, endheight = 0; uint8_t notarypubkeys[64][33] = {0};
|
||||
|
||||
// pubkey 020000000000000000000000000000000
|
||||
balance = checkburnaddress(received, TotalNotaryPay, height, "REDVp3ox1pbcWYCzySadfHhk8UU3HM4k5x");
|
||||
|
||||
notarycount = komodo_notaries(notarypubkeys, height, chainActive[height]->GetBlockTime());
|
||||
NotaryPay = komodo_notarypayamount(height, notarycount)*notarycount;
|
||||
bool spent = (received != balance);
|
||||
if ( !spent )
|
||||
{
|
||||
notaleft = ((int64_t)balance - TotalNotaryPay) / NotaryPay;
|
||||
daysleft = (((ASSETCHAINS_BLOCKTIME * 5) * notaleft) / 3600) / 24;
|
||||
endheight = (notaleft * 5) + height;
|
||||
}
|
||||
|
||||
result.push_back(Pair("height", height));
|
||||
result.push_back(Pair("balance", ValueFromAmount(balance)));
|
||||
result.push_back(Pair("spent", spent));
|
||||
result.push_back(Pair("Total_NotaryPay", ValueFromAmount(TotalNotaryPay)));
|
||||
result.push_back(Pair("Estimated_Notarizations_Left", notaleft));
|
||||
result.push_back(Pair("Estimated_Days_Left", daysleft));
|
||||
result.push_back(Pair("Estimated_Height", endheight));
|
||||
return result;
|
||||
}
|
||||
|
||||
UniValue getaddressbalance(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp ||params.size() > 2 || params.size() == 0)
|
||||
@@ -1281,8 +1383,9 @@ UniValue getsnapshot(const UniValue& params, bool fHelp)
|
||||
|
||||
if (params.size() > 0 && !params[0].isNull()) {
|
||||
top = atoi(params[0].get_str().c_str());
|
||||
if (top <= 0)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, top must be a positive integer");
|
||||
if (top < 0)
|
||||
//throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, top must be a positive integer");
|
||||
top = -1;
|
||||
}
|
||||
|
||||
if ( fHelp || params.size() > 1)
|
||||
|
||||
@@ -35,6 +35,10 @@ void RegisterMiningRPCCommands(CRPCTable &tableRPC);
|
||||
/** Register raw transaction RPC commands */
|
||||
void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC);
|
||||
|
||||
/** Register test transaction RPC commands */
|
||||
void RegisterTesttransactionsRPCCommands(CRPCTable &tableRPC);
|
||||
|
||||
|
||||
static inline void RegisterAllCoreRPCCommands(CRPCTable &tableRPC)
|
||||
{
|
||||
RegisterBlockchainRPCCommands(tableRPC);
|
||||
@@ -42,6 +46,9 @@ static inline void RegisterAllCoreRPCCommands(CRPCTable &tableRPC)
|
||||
RegisterMiscRPCCommands(tableRPC);
|
||||
RegisterMiningRPCCommands(tableRPC);
|
||||
RegisterRawTransactionRPCCommands(tableRPC);
|
||||
#ifdef TESTMODE
|
||||
RegisterTesttransactionsRPCCommands(tableRPC);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -463,7 +463,15 @@ static const CRPCCommand vRPCCommands[] =
|
||||
{ "prices", "prices", &prices, true },
|
||||
{ "prices", "pricesaddress", &pricesaddress, true },
|
||||
{ "prices", "priceslist", &priceslist, true },
|
||||
{ "prices", "mypriceslist", &mypriceslist, true },
|
||||
{ "prices", "pricesinfo", &pricesinfo, true },
|
||||
{ "prices", "pricesbet", &pricesbet, true },
|
||||
{ "prices", "pricessetcostbasis", &pricessetcostbasis, true },
|
||||
{ "prices", "pricescashout", &pricescashout, true },
|
||||
{ "prices", "pricesrekt", &pricesrekt, true },
|
||||
{ "prices", "pricesaddfunding", &pricesaddfunding, true },
|
||||
{ "prices", "pricesgetorderbook", &pricesgetorderbook, true },
|
||||
|
||||
|
||||
// Pegs
|
||||
{ "pegs", "pegsaddress", &pegsaddress, true },
|
||||
@@ -480,12 +488,14 @@ static const CRPCCommand vRPCCommands[] =
|
||||
{ "marmara", "marmaralock", &marmara_lock, true },
|
||||
|
||||
// Payments
|
||||
{ "payments", "paymentsaddress", &paymentsaddress, true },
|
||||
{ "payments", "paymentstxidopret", &payments_txidopret, true },
|
||||
{ "payments", "paymentscreate", &payments_create, true },
|
||||
{ "payments", "paymentslist", &payments_list, true },
|
||||
{ "payments", "paymentsinfo", &payments_info, true },
|
||||
{ "payments", "paymentsfund", &payments_fund, true },
|
||||
{ "payments", "paymentsaddress", &paymentsaddress, true },
|
||||
{ "payments", "paymentstxidopret", &payments_txidopret, true },
|
||||
{ "payments", "paymentscreate", &payments_create, true },
|
||||
{ "payments", "paymentsairdrop", &payments_airdrop, true },
|
||||
{ "payments", "paymentslist", &payments_list, true },
|
||||
{ "payments", "paymentsinfo", &payments_info, true },
|
||||
{ "payments", "paymentsfund", &payments_fund, true },
|
||||
{ "payments", "paymentsmerge", &payments_merge, true },
|
||||
{ "payments", "paymentsrelease", &payments_release, true },
|
||||
|
||||
{ "CClib", "cclibaddress", &cclibaddress, true },
|
||||
@@ -542,6 +552,8 @@ static const CRPCCommand vRPCCommands[] =
|
||||
/* Address index */
|
||||
{ "addressindex", "getaddressmempool", &getaddressmempool, true },
|
||||
{ "addressindex", "getaddressutxos", &getaddressutxos, false },
|
||||
{ "addressindex", "checknotarization", &checknotarization, false },
|
||||
{ "addressindex", "getnotarypayinfo", &getnotarypayinfo, false },
|
||||
{ "addressindex", "getaddressdeltas", &getaddressdeltas, false },
|
||||
{ "addressindex", "getaddresstxids", &getaddresstxids, false },
|
||||
{ "addressindex", "getaddressbalance", &getaddressbalance, false },
|
||||
@@ -565,10 +577,6 @@ static const CRPCCommand vRPCCommands[] =
|
||||
{ "util", "reconsiderblock", &reconsiderblock, true },
|
||||
/* Not shown in help */
|
||||
{ "hidden", "setmocktime", &setmocktime, true },
|
||||
{ "hidden", "test_ac", &test_ac, true },
|
||||
{ "hidden", "test_heirmarker", &test_heirmarker, true },
|
||||
{ "hidden", "test_proof", &test_proof, true },
|
||||
{ "hidden", "test_burntx", &test_burntx, true },
|
||||
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
@@ -639,6 +647,7 @@ static const CRPCCommand vRPCCommands[] =
|
||||
{ "wallet", "z_importviewingkey", &z_importviewingkey, true },
|
||||
{ "wallet", "z_exportwallet", &z_exportwallet, true },
|
||||
{ "wallet", "z_importwallet", &z_importwallet, true },
|
||||
{ "wallet", "opreturn_burn", &opreturn_burn, true },
|
||||
|
||||
// TODO: rearrange into another category
|
||||
{ "disclosure", "z_getpaymentdisclosure", &z_getpaymentdisclosure, true },
|
||||
|
||||
@@ -210,6 +210,8 @@ extern UniValue getaddresstxids(const UniValue& params, bool fHelp);
|
||||
extern UniValue getsnapshot(const UniValue& params, bool fHelp);
|
||||
extern UniValue getaddressbalance(const UniValue& params, bool fHelp);
|
||||
extern UniValue getpeerinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue checknotarization(const UniValue& params, bool fHelp);
|
||||
extern UniValue getnotarypayinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue ping(const UniValue& params, bool fHelp);
|
||||
extern UniValue addnode(const UniValue& params, bool fHelp);
|
||||
extern UniValue disconnectnode(const UniValue& params, bool fHelp);
|
||||
@@ -271,6 +273,7 @@ extern UniValue oraclesdata(const UniValue& params, bool fHelp);
|
||||
extern UniValue oraclessamples(const UniValue& params, bool fHelp);
|
||||
extern UniValue pricesaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue priceslist(const UniValue& params, bool fHelp);
|
||||
extern UniValue mypriceslist(const UniValue& params, bool fHelp);
|
||||
extern UniValue pricesinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue pegsaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue marmaraaddress(const UniValue& params, bool fHelp);
|
||||
@@ -285,8 +288,10 @@ extern UniValue marmara_lock(const UniValue& params, bool fHelp);
|
||||
extern UniValue paymentsaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue payments_release(const UniValue& params, bool fHelp);
|
||||
extern UniValue payments_fund(const UniValue& params, bool fHelp);
|
||||
extern UniValue payments_merge(const UniValue& params, bool fHelp);
|
||||
extern UniValue payments_txidopret(const UniValue& params, bool fHelp);
|
||||
extern UniValue payments_create(const UniValue& params, bool fHelp);
|
||||
extern UniValue payments_airdrop(const UniValue& params, bool fHelp);
|
||||
extern UniValue payments_info(const UniValue& params, bool fHelp);
|
||||
extern UniValue payments_list(const UniValue& params, bool fHelp);
|
||||
|
||||
@@ -466,6 +471,7 @@ extern UniValue z_shieldcoinbase(const UniValue& params, bool fHelp); // in rpcw
|
||||
extern UniValue z_getoperationstatus(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_getoperationresult(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_listoperationids(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue opreturn_burn(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_validateaddress(const UniValue& params, bool fHelp); // in rpcmisc.cpp
|
||||
extern UniValue z_getpaymentdisclosure(const UniValue& params, bool fHelp); // in rpcdisclosure.cpp
|
||||
extern UniValue z_validatepaymentdisclosure(const UniValue ¶ms, bool fHelp); // in rpcdisclosure.cpp
|
||||
@@ -497,11 +503,13 @@ extern UniValue paxdeposit(const UniValue& params, bool fHelp);
|
||||
extern UniValue paxwithdraw(const UniValue& params, bool fHelp);
|
||||
|
||||
extern UniValue prices(const UniValue& params, bool fHelp);
|
||||
extern UniValue pricesbet(const UniValue& params, bool fHelp);
|
||||
extern UniValue pricessetcostbasis(const UniValue& params, bool fHelp);
|
||||
extern UniValue pricescashout(const UniValue& params, bool fHelp);
|
||||
extern UniValue pricesrekt(const UniValue& params, bool fHelp);
|
||||
extern UniValue pricesaddfunding(const UniValue& params, bool fHelp);
|
||||
extern UniValue pricesgetorderbook(const UniValue& params, bool fHelp);
|
||||
|
||||
|
||||
// test rpc:
|
||||
extern UniValue test_ac(const UniValue& params, bool fHelp);
|
||||
extern UniValue test_heirmarker(const UniValue& params, bool fHelp);
|
||||
extern UniValue test_burntx(const UniValue& params, bool fHelp);
|
||||
extern UniValue test_proof(const UniValue& params, bool fHelp);
|
||||
|
||||
#endif // BITCOIN_RPCSERVER_H
|
||||
|
||||
268
src/rpc/testtransactions.cpp
Normal file
268
src/rpc/testtransactions.cpp
Normal file
@@ -0,0 +1,268 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
* *
|
||||
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
|
||||
* the top-level directory of this distribution for the individual copyright *
|
||||
* holder information and the developer policies on copyright and licensing. *
|
||||
* *
|
||||
* Unless otherwise agreed in a custom licensing agreement, no part of the *
|
||||
* SuperNET software, including this file may be copied, modified, propagated *
|
||||
* or distributed except according to the terms contained in the LICENSE file *
|
||||
* *
|
||||
* Removal or modification of this copyright notice is prohibited. *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "amount.h"
|
||||
#include "chain.h"
|
||||
#include "chainparams.h"
|
||||
#include "checkpoints.h"
|
||||
#include "crosschain.h"
|
||||
#include "base58.h"
|
||||
#include "consensus/validation.h"
|
||||
#include "cc/eval.h"
|
||||
#include "main.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "rpc/server.h"
|
||||
#include "streams.h"
|
||||
#include "sync.h"
|
||||
#include "util.h"
|
||||
#include "script/script.h"
|
||||
#include "script/script_error.h"
|
||||
#include "script/sign.h"
|
||||
#include "script/standard.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <univalue.h>
|
||||
|
||||
#include <regex>
|
||||
|
||||
|
||||
#include "cc/CCinclude.h"
|
||||
#include "cc/CCPrices.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int32_t ensure_CCrequirements(uint8_t evalcode);
|
||||
|
||||
UniValue test_ac(const UniValue& params, bool fHelp)
|
||||
{
|
||||
// make fake token tx:
|
||||
struct CCcontract_info *cp, C;
|
||||
|
||||
if (fHelp || (params.size() != 4))
|
||||
throw runtime_error("incorrect params\n");
|
||||
if (ensure_CCrequirements(EVAL_HEIR) < 0)
|
||||
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||
|
||||
std::vector<unsigned char> pubkey1;
|
||||
std::vector<unsigned char> pubkey2;
|
||||
|
||||
pubkey1 = ParseHex(params[0].get_str().c_str());
|
||||
pubkey2 = ParseHex(params[1].get_str().c_str());
|
||||
|
||||
CPubKey pk1 = pubkey2pk(pubkey1);
|
||||
CPubKey pk2 = pubkey2pk(pubkey2);
|
||||
|
||||
if (!pk1.IsValid() || !pk2.IsValid())
|
||||
throw runtime_error("invalid pubkey\n");
|
||||
|
||||
int64_t txfee = 10000;
|
||||
int64_t amount = atoll(params[2].get_str().c_str()) * COIN;
|
||||
uint256 fundingtxid = Parseuint256((char *)params[3].get_str().c_str());
|
||||
|
||||
CPubKey myPubkey = pubkey2pk(Mypubkey());
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
|
||||
int64_t normalInputs = AddNormalinputs(mtx, myPubkey, txfee + amount, 60);
|
||||
|
||||
if (normalInputs < txfee + amount)
|
||||
throw runtime_error("not enough normals\n");
|
||||
|
||||
mtx.vout.push_back(MakeCC1of2vout(EVAL_HEIR, amount, pk1, pk2));
|
||||
|
||||
CScript opret;
|
||||
fundingtxid = revuint256(fundingtxid);
|
||||
|
||||
opret << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_HEIR << (uint8_t)'A' << fundingtxid << (uint8_t)0);
|
||||
|
||||
cp = CCinit(&C, EVAL_HEIR);
|
||||
return(FinalizeCCTx(0, cp, mtx, myPubkey, txfee, opret));
|
||||
}
|
||||
|
||||
UniValue test_heirmarker(const UniValue& params, bool fHelp)
|
||||
{
|
||||
// make fake token tx:
|
||||
struct CCcontract_info *cp, C;
|
||||
|
||||
if (fHelp || (params.size() != 1))
|
||||
throw runtime_error("incorrect params\n");
|
||||
if (ensure_CCrequirements(EVAL_HEIR) < 0)
|
||||
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||
|
||||
uint256 fundingtxid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
|
||||
CPubKey myPubkey = pubkey2pk(Mypubkey());
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
|
||||
int64_t normalInputs = AddNormalinputs(mtx, myPubkey, 10000, 60);
|
||||
if (normalInputs < 10000)
|
||||
throw runtime_error("not enough normals\n");
|
||||
|
||||
mtx.vin.push_back(CTxIn(fundingtxid, 1));
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_HEIR, 10000, myPubkey));
|
||||
|
||||
CScript opret;
|
||||
fundingtxid = revuint256(fundingtxid);
|
||||
|
||||
opret << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_HEIR << (uint8_t)'C' << fundingtxid << (uint8_t)0);
|
||||
|
||||
cp = CCinit(&C, EVAL_HEIR);
|
||||
return(FinalizeCCTx(0, cp, mtx, myPubkey, 10000, opret));
|
||||
}
|
||||
|
||||
UniValue test_burntx(const UniValue& params, bool fHelp)
|
||||
{
|
||||
// make fake token tx:
|
||||
struct CCcontract_info *cp, C;
|
||||
|
||||
if (fHelp || (params.size() != 1))
|
||||
throw runtime_error("incorrect params\n");
|
||||
if (ensure_CCrequirements(EVAL_TOKENS) < 0)
|
||||
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||
|
||||
uint256 tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
|
||||
CPubKey myPubkey = pubkey2pk(Mypubkey());
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
|
||||
int64_t normalInputs = AddNormalinputs(mtx, myPubkey, 10000, 60);
|
||||
if (normalInputs < 10000)
|
||||
throw runtime_error("not enough normals\n");
|
||||
|
||||
CPubKey burnpk = pubkey2pk(ParseHex(CC_BURNPUBKEY));
|
||||
|
||||
mtx.vin.push_back(CTxIn(tokenid, 0));
|
||||
mtx.vin.push_back(CTxIn(tokenid, 1));
|
||||
mtx.vout.push_back(MakeTokensCC1vout(EVAL_TOKENS, 1, burnpk));
|
||||
|
||||
std::vector<CPubKey> voutPubkeys;
|
||||
voutPubkeys.push_back(burnpk);
|
||||
|
||||
cp = CCinit(&C, EVAL_TOKENS);
|
||||
|
||||
std::vector<uint8_t> vopret;
|
||||
GetNonfungibleData(tokenid, vopret);
|
||||
if (vopret.size() > 0)
|
||||
cp->additionalTokensEvalcode2 = vopret.begin()[0];
|
||||
|
||||
uint8_t tokenpriv[33];
|
||||
char unspendableTokenAddr[64];
|
||||
CPubKey unspPk = GetUnspendable(cp, tokenpriv);
|
||||
GetCCaddress(cp, unspendableTokenAddr, unspPk);
|
||||
CCaddr2set(cp, EVAL_TOKENS, unspPk, tokenpriv, unspendableTokenAddr);
|
||||
return(FinalizeCCTx(0, cp, mtx, myPubkey, 10000, EncodeTokenOpRet(tokenid, voutPubkeys, std::make_pair(0, vscript_t()))));
|
||||
}
|
||||
|
||||
UniValue test_proof(const UniValue& params, bool fHelp)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ);
|
||||
std::vector<uint8_t>proof;
|
||||
|
||||
if (fHelp || (params.size() != 2))
|
||||
throw runtime_error("incorrect params\n");
|
||||
|
||||
|
||||
proof = ParseHex(params[0].get_str());
|
||||
uint256 cointxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
|
||||
std::vector<uint256> txids;
|
||||
|
||||
CMerkleBlock merkleBlock;
|
||||
if (!E_UNMARSHAL(proof, ss >> merkleBlock)) {
|
||||
result.push_back(Pair("error", "could not unmarshal proof"));
|
||||
return result;
|
||||
}
|
||||
uint256 merkleRoot = merkleBlock.txn.ExtractMatches(txids);
|
||||
|
||||
result.push_back(Pair("source_root", merkleRoot.GetHex()));
|
||||
|
||||
for (int i = 0; i < txids.size(); i++)
|
||||
std::cerr << "merkle block txid=" << txids[0].GetHex() << std::endl;
|
||||
|
||||
|
||||
std::vector<bool> vMatches(txids.size());
|
||||
for (auto v : vMatches) v = true;
|
||||
CPartialMerkleTree verifTree(txids, vMatches);
|
||||
|
||||
result.push_back(Pair("verif_root", verifTree.ExtractMatches(txids).GetHex()));
|
||||
|
||||
if (std::find(txids.begin(), txids.end(), cointxid) == txids.end()) {
|
||||
fprintf(stderr, "invalid proof for this cointxid\n");
|
||||
}
|
||||
|
||||
std::vector<uint256> vMerkleTree;
|
||||
bool f;
|
||||
::BuildMerkleTree(&f, txids, vMerkleTree);
|
||||
|
||||
std::vector<uint256> vMerkleBranch = ::GetMerkleBranch(0, txids.size(), vMerkleTree);
|
||||
|
||||
uint256 ourResult = SafeCheckMerkleBranch(zeroid, vMerkleBranch, 0);
|
||||
result.push_back(Pair("SafeCheckMerkleBranch", ourResult.GetHex()));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
extern CScript prices_costbasisopret(uint256 bettxid, CPubKey mypk, int32_t height, int64_t costbasis);
|
||||
UniValue test_pricesmarker(const UniValue& params, bool fHelp)
|
||||
{
|
||||
// make fake token tx:
|
||||
struct CCcontract_info *cp, C;
|
||||
|
||||
if (fHelp || (params.size() != 1))
|
||||
throw runtime_error("incorrect params\n");
|
||||
if (ensure_CCrequirements(EVAL_PRICES) < 0)
|
||||
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||
|
||||
uint256 bettxid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
|
||||
cp = CCinit(&C, EVAL_PRICES);
|
||||
CPubKey myPubkey = pubkey2pk(Mypubkey());
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
|
||||
int64_t normalInputs = AddNormalinputs(mtx, myPubkey, 10000, 60);
|
||||
if (normalInputs < 10000)
|
||||
throw runtime_error("not enough normals\n");
|
||||
|
||||
mtx.vin.push_back(CTxIn(bettxid, 1));
|
||||
mtx.vout.push_back(CTxOut(1000, CScript() << ParseHex(HexStr(myPubkey)) << OP_CHECKSIG));
|
||||
|
||||
return(FinalizeCCTx(0, cp, mtx, myPubkey, 10000, prices_costbasisopret(bettxid, myPubkey, 100, 100)));
|
||||
}
|
||||
|
||||
|
||||
static const CRPCCommand commands[] =
|
||||
{ // category name actor (function) okSafeMode
|
||||
// --------------------- ------------------------ ----------------------- ----------
|
||||
|
||||
/* Not shown in help */
|
||||
{ "hidden", "test_ac", &test_ac, true },
|
||||
{ "hidden", "test_heirmarker", &test_heirmarker, true },
|
||||
{ "hidden", "test_proof", &test_proof, true },
|
||||
{ "hidden", "test_burntx", &test_burntx, true },
|
||||
{ "hidden", "test_pricesmarker", &test_pricesmarker, true }
|
||||
};
|
||||
|
||||
void RegisterTesttransactionsRPCCommands(CRPCTable &tableRPC)
|
||||
{
|
||||
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
|
||||
tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
|
||||
}
|
||||
104
src/txdb.cpp
104
src/txdb.cpp
@@ -458,13 +458,13 @@ uint32_t komodo_segid32(char *coinaddr);
|
||||
{"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPVMY", 1} \
|
||||
};
|
||||
|
||||
int32_t CBlockTreeDB::Snapshot2(int64_t dustthreshold, int32_t top ,std::vector <std::pair<CAmount, std::string>> &vaddr, UniValue *ret)
|
||||
bool CBlockTreeDB::Snapshot2(std::map <std::string, CAmount> &addressAmounts, UniValue *ret)
|
||||
{
|
||||
int64_t total = 0; int64_t totalAddresses = 0; std::string address;
|
||||
int64_t utxos = 0; int64_t ignoredAddresses = 0, cryptoConditionsUTXOs = 0, cryptoConditionsTotals = 0;
|
||||
DECLARE_IGNORELIST
|
||||
boost::scoped_ptr<CDBIterator> iter(NewIterator());
|
||||
std::map <std::string, CAmount> addressAmounts;
|
||||
//std::map <std::string, CAmount> addressAmounts;
|
||||
for (iter->SeekToLast(); iter->Valid(); iter->Prev())
|
||||
{
|
||||
boost::this_thread::interruption_point();
|
||||
@@ -481,45 +481,46 @@ int32_t CBlockTreeDB::Snapshot2(int64_t dustthreshold, int32_t top ,std::vector
|
||||
try {
|
||||
CAmount nValue;
|
||||
iter->GetValue(nValue);
|
||||
if ( nValue == 0 )
|
||||
continue;
|
||||
getAddressFromIndex(indexKey.type, indexKey.hashBytes, address);
|
||||
if ( indexKey.type == 3 )
|
||||
{
|
||||
cryptoConditionsUTXOs++;
|
||||
cryptoConditionsTotals += nValue;
|
||||
total += nValue;
|
||||
continue;
|
||||
}
|
||||
if ( nValue > dustthreshold )
|
||||
std::map <std::string, int>::iterator ignored = ignoredMap.find(address);
|
||||
if (ignored != ignoredMap.end())
|
||||
{
|
||||
std::map <std::string, int>::iterator ignored = ignoredMap.find(address);
|
||||
if (ignored != ignoredMap.end())
|
||||
{
|
||||
fprintf(stderr,"ignoring %s\n", address.c_str());
|
||||
ignoredAddresses++;
|
||||
continue;
|
||||
}
|
||||
std::map <std::string, CAmount>::iterator pos = addressAmounts.find(address);
|
||||
if ( pos == addressAmounts.end() )
|
||||
{
|
||||
// insert new address + utxo amount
|
||||
//fprintf(stderr, "inserting new address %s with amount %li\n", address.c_str(), nValue);
|
||||
addressAmounts[address] = nValue;
|
||||
totalAddresses++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// update unspent tally for this address
|
||||
//fprintf(stderr, "updating address %s with new utxo amount %li\n", address.c_str(), nValue);
|
||||
addressAmounts[address] += nValue;
|
||||
}
|
||||
//fprintf(stderr,"{\"%s\", %.8f},\n",address.c_str(),(double)nValue/COIN);
|
||||
// total += nValue;
|
||||
utxos++;
|
||||
} //else fprintf(stderr,"ignoring amount=0 UTXO for %s\n", address.c_str());
|
||||
fprintf(stderr,"ignoring %s\n", address.c_str());
|
||||
ignoredAddresses++;
|
||||
continue;
|
||||
}
|
||||
std::map <std::string, CAmount>::iterator pos = addressAmounts.find(address);
|
||||
if ( pos == addressAmounts.end() )
|
||||
{
|
||||
// insert new address + utxo amount
|
||||
//fprintf(stderr, "inserting new address %s with amount %li\n", address.c_str(), nValue);
|
||||
addressAmounts[address] = nValue;
|
||||
totalAddresses++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// update unspent tally for this address
|
||||
//fprintf(stderr, "updating address %s with new utxo amount %li\n", address.c_str(), nValue);
|
||||
addressAmounts[address] += nValue;
|
||||
}
|
||||
//fprintf(stderr,"{\"%s\", %.8f},\n",address.c_str(),(double)nValue/COIN);
|
||||
// total += nValue;
|
||||
utxos++;
|
||||
total += nValue;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
fprintf(stderr, "DONE %s: LevelDB addressindex exception! - %s\n", __func__, e.what());
|
||||
break;
|
||||
return false; //break; this means failiure of DB? we need to exit here if so for consensus code!
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -530,30 +531,18 @@ int32_t CBlockTreeDB::Snapshot2(int64_t dustthreshold, int32_t top ,std::vector
|
||||
}
|
||||
}
|
||||
//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) );
|
||||
std::sort(vaddr.rbegin(), vaddr.rend());
|
||||
int topN = 0;
|
||||
for (std::vector<std::pair<CAmount, std::string>>::iterator it = vaddr.begin(); it!=vaddr.end(); ++it)
|
||||
{
|
||||
total += it->first;
|
||||
topN++;
|
||||
// If requested, only show top N addresses in output JSON
|
||||
if ( top == topN )
|
||||
break;
|
||||
}
|
||||
|
||||
// this is for the snapshot RPC, you can skip this by passing a 0 as the last argument.
|
||||
if (ret)
|
||||
{
|
||||
// Total amount in this snapshot, which is less than circulating supply if top parameter is used
|
||||
// Use the address_total for a total of all address included when using top parameter.
|
||||
ret->push_back(make_pair("total", (double) (total+cryptoConditionsTotals)/ COIN ));
|
||||
// Total circulating supply without CC vouts.
|
||||
ret->push_back(make_pair("total", (double) (total)/ COIN ));
|
||||
// Average amount in each address of this snapshot
|
||||
ret->push_back(make_pair("average",(double) (total/COIN) / totalAddresses ));
|
||||
// Total number of utxos processed in this snaphot
|
||||
ret->push_back(make_pair("utxos", utxos));
|
||||
// Total number of addresses in this snaphot
|
||||
ret->push_back(make_pair("total_addresses", top ? top : totalAddresses ));
|
||||
ret->push_back(make_pair("total_addresses", totalAddresses ));
|
||||
// Total number of ignored addresses in this snaphot
|
||||
ret->push_back(make_pair("ignored_addresses", ignoredAddresses));
|
||||
// Total number of crypto condition utxos we skipped
|
||||
@@ -561,22 +550,39 @@ int32_t CBlockTreeDB::Snapshot2(int64_t dustthreshold, int32_t top ,std::vector
|
||||
// Total value of skipped crypto condition utxos
|
||||
ret->push_back(make_pair("cc_utxo_value", (double) cryptoConditionsTotals / COIN));
|
||||
// total of all the address's, does not count coins in CC vouts.
|
||||
ret->push_back(make_pair("address_total", (double) total/ COIN ));
|
||||
ret->push_back(make_pair("total_includeCCvouts", (double) (total+cryptoConditionsTotals)/ COIN ));
|
||||
// The snapshot finished at this block height
|
||||
ret->push_back(make_pair("ending_height", chainActive.Height()));
|
||||
}
|
||||
return(topN);
|
||||
return true;
|
||||
}
|
||||
|
||||
extern std::vector <std::pair<CAmount, CTxDestination>> vAddressSnapshot;
|
||||
|
||||
UniValue CBlockTreeDB::Snapshot(int top)
|
||||
{
|
||||
int topN = 0;
|
||||
std::vector <std::pair<CAmount, std::string>> vaddr;
|
||||
//std::vector <std::vector <std::pair<CAmount, CScript>>> tokenids;
|
||||
std::map <std::string, CAmount> addressAmounts;
|
||||
UniValue result(UniValue::VOBJ);
|
||||
UniValue addressesSorted(UniValue::VARR);
|
||||
result.push_back(Pair("start_time", (int) time(NULL)));
|
||||
if ( Snapshot2(0,top,vaddr,&result) != 0 )
|
||||
if ( (vAddressSnapshot.size() > 0 && top < 0) || (Snapshot2(addressAmounts,&result) && top >= 0) )
|
||||
{
|
||||
if ( top > -1 )
|
||||
{
|
||||
for (std::pair<std::string, CAmount> element : addressAmounts)
|
||||
vaddr.push_back( make_pair(element.second, element.first) );
|
||||
std::sort(vaddr.rbegin(), vaddr.rend());
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( auto address : vAddressSnapshot )
|
||||
vaddr.push_back(make_pair(address.first, CBitcoinAddress(address.second).ToString()));
|
||||
top = vAddressSnapshot.size();
|
||||
}
|
||||
int topN = 0;
|
||||
for (std::vector<std::pair<CAmount, std::string>>::iterator it = vaddr.begin(); it!=vaddr.end(); ++it)
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
@@ -712,6 +718,8 @@ bool CBlockTreeDB::LoadBlockIndexGuts()
|
||||
pindexNew->nTx = diskindex.nTx;
|
||||
pindexNew->nSproutValue = diskindex.nSproutValue;
|
||||
pindexNew->nSaplingValue = diskindex.nSaplingValue;
|
||||
pindexNew->segid = diskindex.segid;
|
||||
pindexNew->nNotaryPay = diskindex.nNotaryPay;
|
||||
//fprintf(stderr,"loadguts ht.%d\n",pindexNew->GetHeight());
|
||||
// Consistency checks
|
||||
auto header = pindexNew->GetBlockHeader();
|
||||
|
||||
@@ -116,7 +116,7 @@ public:
|
||||
bool LoadBlockIndexGuts();
|
||||
bool blockOnchainActive(const uint256 &hash);
|
||||
UniValue Snapshot(int top);
|
||||
int32_t Snapshot2(int64_t dustthreshold, int32_t top,std::vector <std::pair<CAmount, std::string>> &vaddr, UniValue *ret);
|
||||
bool Snapshot2(std::map <std::string, CAmount> &addressAmounts, UniValue *ret);
|
||||
};
|
||||
|
||||
#endif // BITCOIN_TXDB_H
|
||||
|
||||
28
src/util.cpp
28
src/util.cpp
@@ -394,27 +394,23 @@ void ParseParameters(int argc, const char* const argv[])
|
||||
}
|
||||
}
|
||||
|
||||
// split string using by space or comma as a delimiter char
|
||||
void SplitStr(const std::string& strVal, std::vector<std::string> &outVals)
|
||||
{
|
||||
stringstream ss(strVal);
|
||||
std::string str;
|
||||
|
||||
while ( ss.peek() == ' ' )
|
||||
ss.ignore();
|
||||
|
||||
while ( ss >> str )
|
||||
{
|
||||
if ( str.size() == 0 )
|
||||
continue;
|
||||
if ( str[str.size()-1] == ',' )
|
||||
str.resize(str.size()-1);
|
||||
outVals.push_back(str);
|
||||
while ( ss.peek() == ' ' )
|
||||
ss.ignore();
|
||||
if ( ss.peek() == ',' )
|
||||
ss.ignore();
|
||||
while ( ss.peek() == ' ' )
|
||||
while (!ss.eof()) {
|
||||
int c;
|
||||
std::string str;
|
||||
|
||||
while (std::isspace(ss.peek()))
|
||||
ss.ignore();
|
||||
|
||||
while ((c = ss.get()) != EOF && !std::isspace(c) && c != ',')
|
||||
str += c;
|
||||
|
||||
if (!str.empty())
|
||||
outVals.push_back(str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -287,6 +287,9 @@ template <typename Callable> void TraceThread(const char* name, Callable func)
|
||||
}
|
||||
}
|
||||
|
||||
// split string using by space or comma as a delimiter char
|
||||
void SplitStr(const std::string& strVal, std::vector<std::string> &outVals);
|
||||
|
||||
#define KOMODO_ASSETCHAIN_MAXLEN 65
|
||||
|
||||
|
||||
|
||||
@@ -33,7 +33,9 @@
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
// If CCLIB fails to compile with this, use the one below.
|
||||
#include <db_cxx.h>
|
||||
//#include "../depends/x86_64-unknown-linux-gnu/include/db_cxx.h"
|
||||
|
||||
extern unsigned int nWalletDBUpdated;
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
#include <numeric>
|
||||
|
||||
#include "komodo_defs.h"
|
||||
#include <string.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -5603,6 +5604,19 @@ UniValue payments_fund(const UniValue& params, bool fHelp)
|
||||
return(PaymentsFund(cp,(char *)params[0].get_str().c_str()));
|
||||
}
|
||||
|
||||
UniValue payments_merge(const UniValue& params, bool fHelp)
|
||||
{
|
||||
struct CCcontract_info *cp,C;
|
||||
if ( fHelp || params.size() != 1 )
|
||||
throw runtime_error("paymentsmerge \"[%22createtxid%22]\"\n");
|
||||
if ( ensure_CCrequirements(EVAL_PAYMENTS) < 0 )
|
||||
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||
const CKeyStore& keystore = *pwalletMain;
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
cp = CCinit(&C,EVAL_PAYMENTS);
|
||||
return(PaymentsMerge(cp,(char *)params[0].get_str().c_str()));
|
||||
}
|
||||
|
||||
UniValue payments_txidopret(const UniValue& params, bool fHelp)
|
||||
{
|
||||
struct CCcontract_info *cp,C;
|
||||
@@ -5629,6 +5643,19 @@ UniValue payments_create(const UniValue& params, bool fHelp)
|
||||
return(PaymentsCreate(cp,(char *)params[0].get_str().c_str()));
|
||||
}
|
||||
|
||||
UniValue payments_airdrop(const UniValue& params, bool fHelp)
|
||||
{
|
||||
struct CCcontract_info *cp,C;
|
||||
if ( fHelp || params.size() != 1 )
|
||||
throw runtime_error("paymentsairdrop \"[lockedblocks,minamount,mintoaddress,top,bottom,fixedFlag,%22excludeAddress%22,...,%22excludeAddressN%22]\"\n");
|
||||
if ( ensure_CCrequirements(EVAL_PAYMENTS) < 0 )
|
||||
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||
const CKeyStore& keystore = *pwalletMain;
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
cp = CCinit(&C,EVAL_PAYMENTS);
|
||||
return(PaymentsAirdrop(cp,(char *)params[0].get_str().c_str()));
|
||||
}
|
||||
|
||||
UniValue payments_info(const UniValue& params, bool fHelp)
|
||||
{
|
||||
struct CCcontract_info *cp,C;
|
||||
@@ -6919,25 +6946,61 @@ UniValue faucetget(const UniValue& params, bool fHelp)
|
||||
return(result);
|
||||
}
|
||||
|
||||
uint32_t pricesGetParam(UniValue param) {
|
||||
uint32_t filter = 0;
|
||||
if (STR_TOLOWER(param.get_str()) == "all")
|
||||
filter = 0;
|
||||
else if (STR_TOLOWER(param.get_str()) == "open")
|
||||
filter = 1;
|
||||
else if (STR_TOLOWER(param.get_str()) == "closed")
|
||||
filter = 2;
|
||||
else
|
||||
throw runtime_error("incorrect parameter\n");
|
||||
return filter;
|
||||
}
|
||||
|
||||
UniValue priceslist(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if ( fHelp || params.size() > 0 )
|
||||
throw runtime_error("priceslist\n");
|
||||
if ( fHelp || params.size() != 0 && params.size() != 1)
|
||||
throw runtime_error("priceslist [all|open|closed]\n");
|
||||
if ( ensure_CCrequirements(EVAL_PRICES) < 0 )
|
||||
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||
return(PricesList());
|
||||
uint32_t filter = 0;
|
||||
if (params.size() == 1)
|
||||
filter = pricesGetParam(params[0]);
|
||||
|
||||
CPubKey emptypk;
|
||||
|
||||
return(PricesList(filter, emptypk));
|
||||
}
|
||||
|
||||
UniValue mypriceslist(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0 && params.size() != 1)
|
||||
throw runtime_error("mypriceslist [all|open|closed]\n");
|
||||
if (ensure_CCrequirements(EVAL_PRICES) < 0)
|
||||
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||
|
||||
uint32_t filter = 0;
|
||||
if (params.size() == 1)
|
||||
filter = pricesGetParam(params[0]);
|
||||
CPubKey mypk = pubkey2pk(Mypubkey());
|
||||
|
||||
return(PricesList(filter, mypk));
|
||||
}
|
||||
|
||||
UniValue pricesinfo(const UniValue& params, bool fHelp)
|
||||
{
|
||||
uint256 bettxid; int32_t height;
|
||||
if ( fHelp || params.size() != 2 )
|
||||
throw runtime_error("pricesinfo fundingtxid\n");
|
||||
if ( fHelp || params.size() != 1 && params.size() != 2)
|
||||
throw runtime_error("pricesinfo bettxid [height]\n");
|
||||
if ( ensure_CCrequirements(EVAL_PRICES) < 0 )
|
||||
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||
bettxid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
height = atoi(params[1].get_str().c_str());
|
||||
return(PricesInfo(bettxid,height));
|
||||
height = 0;
|
||||
if (params.size() == 2)
|
||||
height = atoi(params[1].get_str().c_str());
|
||||
return(PricesInfo(bettxid, height));
|
||||
}
|
||||
|
||||
UniValue dicefund(const UniValue& params, bool fHelp)
|
||||
@@ -7939,170 +8002,34 @@ void RegisterWalletRPCCommands(CRPCTable &tableRPC)
|
||||
tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
|
||||
}
|
||||
|
||||
UniValue test_ac(const UniValue& params, bool fHelp)
|
||||
UniValue opreturn_burn(const UniValue& params, bool fHelp)
|
||||
{
|
||||
// make fake token tx:
|
||||
struct CCcontract_info *cp, C;
|
||||
|
||||
if (fHelp || (params.size() != 4))
|
||||
throw runtime_error("incorrect params\n");
|
||||
if (ensure_CCrequirements(EVAL_HEIR) < 0)
|
||||
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||
|
||||
std::vector<unsigned char> pubkey1;
|
||||
std::vector<unsigned char> pubkey2;
|
||||
|
||||
pubkey1 = ParseHex(params[0].get_str().c_str());
|
||||
pubkey2 = ParseHex(params[1].get_str().c_str());
|
||||
|
||||
CPubKey pk1 = pubkey2pk(pubkey1);
|
||||
CPubKey pk2 = pubkey2pk(pubkey2);
|
||||
|
||||
if(!pk1.IsValid() || !pk2.IsValid())
|
||||
throw runtime_error("invalid pubkey\n");
|
||||
|
||||
int64_t txfee = 10000;
|
||||
int64_t amount = atoll(params[2].get_str().c_str()) * COIN;
|
||||
uint256 fundingtxid = Parseuint256((char *)params[3].get_str().c_str());
|
||||
std::vector<uint8_t> vHexStr; CScript opret; int32_t txfee = 10000;
|
||||
if (fHelp || (params.size() != 2))
|
||||
throw runtime_error("amount to burn, hexstring to send\n");
|
||||
struct CCcontract_info *cp, C; UniValue ret(UniValue::VOBJ);
|
||||
if (ensure_CCrequirements(EVAL_PAYMENTS) < 0)
|
||||
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||
cp = CCinit(&C, EVAL_PAYMENTS);
|
||||
|
||||
CAmount nAmount = AmountFromValue(params[0]);
|
||||
if (nAmount <= 10000)
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "must burn at least 10000 sat");
|
||||
vHexStr = ParseHex(params[1].get_str());
|
||||
if ( vHexStr.size() == 0 )
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "hexstring is not valid.");
|
||||
|
||||
CPubKey myPubkey = pubkey2pk(Mypubkey());
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
|
||||
int64_t normalInputs = AddNormalinputs(mtx, myPubkey, txfee + amount, 60);
|
||||
|
||||
if( normalInputs < txfee + amount)
|
||||
int64_t normalInputs = AddNormalinputs(mtx, myPubkey, nAmount, 60);
|
||||
if (normalInputs < nAmount)
|
||||
throw runtime_error("not enough normals\n");
|
||||
|
||||
mtx.vout.push_back(MakeCC1of2vout(EVAL_HEIR, amount, pk1, pk2));
|
||||
|
||||
CScript opret;
|
||||
fundingtxid = revuint256(fundingtxid);
|
||||
|
||||
opret << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_HEIR << (uint8_t)'A' << fundingtxid << (uint8_t)0);
|
||||
|
||||
cp = CCinit(&C, EVAL_HEIR);
|
||||
return(FinalizeCCTx(0, cp, mtx, myPubkey, txfee, opret));
|
||||
}
|
||||
|
||||
UniValue test_heirmarker(const UniValue& params, bool fHelp)
|
||||
{
|
||||
// make fake token tx:
|
||||
struct CCcontract_info *cp, C;
|
||||
|
||||
if (fHelp || (params.size() != 1))
|
||||
throw runtime_error("incorrect params\n");
|
||||
if (ensure_CCrequirements(EVAL_HEIR) < 0)
|
||||
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||
|
||||
uint256 fundingtxid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
|
||||
CPubKey myPubkey = pubkey2pk(Mypubkey());
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
|
||||
int64_t normalInputs = AddNormalinputs(mtx, myPubkey, 10000, 60);
|
||||
if (normalInputs < 10000)
|
||||
throw runtime_error("not enough normals\n");
|
||||
|
||||
mtx.vin.push_back(CTxIn(fundingtxid, 1));
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_HEIR, 10000, myPubkey));
|
||||
|
||||
CScript opret;
|
||||
fundingtxid = revuint256(fundingtxid);
|
||||
|
||||
opret << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_HEIR << (uint8_t)'C' << fundingtxid << (uint8_t)0);
|
||||
|
||||
cp = CCinit(&C, EVAL_HEIR);
|
||||
return(FinalizeCCTx(0, cp, mtx, myPubkey, 10000, opret));
|
||||
}
|
||||
|
||||
UniValue test_burntx(const UniValue& params, bool fHelp)
|
||||
{
|
||||
// make fake token tx:
|
||||
struct CCcontract_info *cp, C;
|
||||
|
||||
if (fHelp || (params.size() != 1))
|
||||
throw runtime_error("incorrect params\n");
|
||||
if (ensure_CCrequirements(EVAL_TOKENS) < 0)
|
||||
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||
|
||||
uint256 tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
|
||||
CPubKey myPubkey = pubkey2pk(Mypubkey());
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
|
||||
int64_t normalInputs = AddNormalinputs(mtx, myPubkey, 10000, 60);
|
||||
if (normalInputs < 10000)
|
||||
throw runtime_error("not enough normals\n");
|
||||
|
||||
CPubKey burnpk = pubkey2pk(ParseHex(CC_BURNPUBKEY));
|
||||
|
||||
mtx.vin.push_back(CTxIn(tokenid, 0));
|
||||
mtx.vin.push_back(CTxIn(tokenid, 1));
|
||||
mtx.vout.push_back(MakeTokensCC1vout(EVAL_TOKENS, 1, burnpk));
|
||||
|
||||
std::vector<CPubKey> voutPubkeys;
|
||||
voutPubkeys.push_back(burnpk);
|
||||
|
||||
cp = CCinit(&C, EVAL_TOKENS);
|
||||
|
||||
std::vector<uint8_t> vopret;
|
||||
GetNonfungibleData(tokenid, vopret);
|
||||
if (vopret.size() > 0)
|
||||
cp->additionalTokensEvalcode2 = vopret.begin()[0];
|
||||
|
||||
uint8_t tokenpriv[33];
|
||||
char unspendableTokenAddr[64];
|
||||
CPubKey unspPk = GetUnspendable(cp, tokenpriv);
|
||||
GetCCaddress(cp, unspendableTokenAddr, unspPk);
|
||||
CCaddr2set(cp, EVAL_TOKENS, unspPk, tokenpriv, unspendableTokenAddr);
|
||||
return(FinalizeCCTx(0, cp, mtx, myPubkey, 10000, EncodeTokenOpRet(tokenid, voutPubkeys, std::make_pair(0, vscript_t()))));
|
||||
}
|
||||
|
||||
UniValue test_proof(const UniValue& params, bool fHelp)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ);
|
||||
std::vector<uint8_t>proof;
|
||||
|
||||
if (fHelp || (params.size() != 2))
|
||||
throw runtime_error("incorrect params\n");
|
||||
|
||||
|
||||
proof = ParseHex(params[0].get_str());
|
||||
uint256 cointxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
|
||||
std::vector<uint256> txids;
|
||||
|
||||
CMerkleBlock merkleBlock;
|
||||
if (!E_UNMARSHAL(proof, ss >> merkleBlock)) {
|
||||
result.push_back(Pair("error", "could not unmarshal proof"));
|
||||
return result;
|
||||
}
|
||||
uint256 merkleRoot = merkleBlock.txn.ExtractMatches(txids);
|
||||
|
||||
result.push_back(Pair("source_root", merkleRoot.GetHex()));
|
||||
|
||||
for (int i = 0; i < txids.size(); i++)
|
||||
std::cerr << "merkle block txid=" << txids[0].GetHex() << std::endl;
|
||||
|
||||
|
||||
std::vector<bool> vMatches(txids.size());
|
||||
for (auto v : vMatches) v = true;
|
||||
CPartialMerkleTree verifTree(txids, vMatches);
|
||||
|
||||
result.push_back(Pair("verif_root", verifTree.ExtractMatches(txids).GetHex()));
|
||||
|
||||
if (std::find(txids.begin(), txids.end(), cointxid) == txids.end()) {
|
||||
fprintf(stderr, "invalid proof for this cointxid\n");
|
||||
}
|
||||
|
||||
std::vector<uint256> vMerkleTree;
|
||||
bool f;
|
||||
::BuildMerkleTree(&f, txids, vMerkleTree);
|
||||
|
||||
std::vector<uint256> vMerkleBranch = ::GetMerkleBranch(0, txids.size(), vMerkleTree);
|
||||
|
||||
uint256 ourResult = SafeCheckMerkleBranch(zeroid, vMerkleBranch, 0);
|
||||
result.push_back(Pair("SafeCheckMerkleBranch", ourResult.GetHex()));
|
||||
|
||||
return result;
|
||||
opret << OP_RETURN << E_MARSHAL(ss << vHexStr);
|
||||
|
||||
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(myPubkey)) << OP_CHECKSIG));
|
||||
mtx.vout.push_back(CTxOut(nAmount,opret));
|
||||
ret.push_back(Pair("hex",FinalizeCCTx(0, cp, mtx, myPubkey, txfee, CScript())));
|
||||
return(ret);
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ CONFIG_SITE="$PWD/depends/$HOST/share/config.site" ./configure "$HARDENING_ARG"
|
||||
WD=$PWD
|
||||
cd src/cc
|
||||
echo $PWD
|
||||
./makerogue
|
||||
./makecclib
|
||||
cd $WD
|
||||
|
||||
"$MAKE" "$@" V=1
|
||||
|
||||
Reference in New Issue
Block a user