Merge pull request #1464 from blackjok3rtt/jl777
payments update, fix bug with op_ret burn
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
|
||||
#define PAYMENTS_TXFEE 10000
|
||||
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);
|
||||
|
||||
|
||||
@@ -16,27 +16,6 @@
|
||||
#include "CCPayments.h"
|
||||
|
||||
/*
|
||||
192.168.0.139: RH side screen.
|
||||
./komodod -ac_name=TESTDP -ac_supply=10000000 -ac_reward=1000000000 -ac_nk=96,5 -ac_blocktime=20 -ac_cc=2 -addndoe=192.168.0.112
|
||||
- TESTDP.tar saved after distributing funds randomly. approx block 120.
|
||||
LH screen:
|
||||
./komodod -ac_name=TESTDP -ac_supply=10000000 -ac_reward=1000000000 -ac_nk=96,5 -ac_blocktime=20 -ac_cc=2 -pubkey=0244a96824fa317433f0eaa6d5b1faf68e802b1958df273c24cb82bce1ef8e1aec -gen -genproclimit=1
|
||||
|
||||
./komodo-cli -ac_name=TESTDP paymentsairdrop '[10,2000,500,"76a9149758abb81ee168dd3824cb55e94df509b35462d788ac",76a9144cfd873dadbfbb4b9c03e77ecaa6cfb74a484f4888ac"]'
|
||||
|
||||
use notarizations DB to scan back from the correct height, then undo ALL blocks back to this notarized height!
|
||||
payments airdrop:
|
||||
- extra RPC to merge all payments inputs to a single utxo, this must be called first and be confirmed before payments release,
|
||||
or tx will be too big, we can check add payments inputs is only 1 input, at RPC and in validation very early on.
|
||||
- do getsnapshot2 every 1440 blocks and save the result into some global sorted vector.
|
||||
-this allows any address balance to be calculated by only iterating each 1439 blocks maximum.
|
||||
- calculate scriptpubkey to pay from each address, set allocations from balance of each address. allocation = balance?
|
||||
|
||||
payments airdrop paying a token:
|
||||
- tokenid, top number of tokens to pay, list of pubkeys to exclude as optional param
|
||||
- token airdrop code should be the same as normal snapshot, but call a diffrent snapshot function that only fetches the info for a specific tokenid given.
|
||||
this should be fine to work in validation/rpc level rather than a global saved result, as a single token id doesnt require iterating the whole DB.
|
||||
|
||||
0) txidopret <- allocation, scriptPubKey, opret
|
||||
1) create <- locked_blocks, minrelease, list of txidopret
|
||||
|
||||
@@ -138,6 +117,26 @@ uint8_t DecodePaymentsFundOpRet(CScript scriptPubKey,uint256 &checktxid)
|
||||
return(0);
|
||||
}
|
||||
|
||||
CScript EncodePaymentsMergeOpRet(uint256 checktxid)
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_PAYMENTS;
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'M' << checktxid);
|
||||
return(opret);
|
||||
}
|
||||
|
||||
uint8_t DecodePaymentsMergeOpRet(CScript scriptPubKey,uint256 &checktxid)
|
||||
{
|
||||
std::vector<uint8_t> vopret; uint8_t *script,e,f;
|
||||
GetOpReturnData(scriptPubKey, vopret);
|
||||
script = (uint8_t *)vopret.data();
|
||||
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> checktxid) != 0 )
|
||||
{
|
||||
if ( e == EVAL_PAYMENTS && f == 'M' )
|
||||
return(f);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
CScript EncodePaymentsOpRet(int32_t lockedblocks,int32_t minrelease,int64_t totalallocations,std::vector<uint256> txidoprets)
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_PAYMENTS;
|
||||
@@ -158,20 +157,19 @@ uint8_t DecodePaymentsOpRet(CScript scriptPubKey,int32_t &lockedblocks,int32_t &
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
CScript EncodePaymentsSnapsShotOpRet(int32_t lockedblocks,int32_t minrelease,int32_t top,std::vector<std::vector<uint8_t>> excludeScriptPubKeys)
|
||||
CScript EncodePaymentsSnapsShotOpRet(int32_t lockedblocks,int32_t minrelease,int32_t top,int32_t bottom,int8_t fixedAmount,std::vector<std::vector<uint8_t>> excludeScriptPubKeys)
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_PAYMENTS;
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'S' << lockedblocks << minrelease << top << excludeScriptPubKeys);
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'S' << lockedblocks << minrelease << top << bottom << fixedAmount << excludeScriptPubKeys);
|
||||
return(opret);
|
||||
}
|
||||
|
||||
uint8_t DecodePaymentsSnapsShotOpRet(CScript scriptPubKey,int32_t &lockedblocks,int32_t &minrelease,int32_t &top,std::vector<std::vector<uint8_t>> &excludeScriptPubKeys)
|
||||
uint8_t DecodePaymentsSnapsShotOpRet(CScript scriptPubKey,int32_t &lockedblocks,int32_t &minrelease,int32_t &top,int32_t &bottom,int8_t &fixedAmount,std::vector<std::vector<uint8_t>> &excludeScriptPubKeys)
|
||||
{
|
||||
std::vector<uint8_t> vopret; uint8_t *script,e,f;
|
||||
GetOpReturnData(scriptPubKey, vopret);
|
||||
script = (uint8_t *)vopret.data();
|
||||
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> lockedblocks; ss >> minrelease; ss >> top; ss >> excludeScriptPubKeys) != 0 )
|
||||
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> lockedblocks; ss >> minrelease; ss >> top; ; ss >> bottom; ss >> fixedAmount; ss >> excludeScriptPubKeys) != 0 )
|
||||
{
|
||||
if ( e == EVAL_PAYMENTS && f == 'S' )
|
||||
return(f);
|
||||
@@ -233,9 +231,9 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
|
||||
// change is/must be in vout[0]
|
||||
// only 'F' or 1of2 txidaddr can be spent
|
||||
// all vouts must match exactly
|
||||
char temp[128], coinaddr[64], txidaddr[64]; std::string scriptpubkey; uint256 createtxid, blockhash, tokenid; CTransaction plantx; uint8_t funcid = 0;
|
||||
char temp[128], coinaddr[64], txidaddr[64]; std::string scriptpubkey; uint256 createtxid, blockhash, tokenid; CTransaction plantx; int8_t funcid=0, fixedAmount=0;
|
||||
int32_t i,lockedblocks,minrelease; int64_t change,totalallocations; std::vector<uint256> txidoprets; bool fHasOpret = false; CPubKey txidpk,Paymentspk;
|
||||
int32_t top; std::vector<std::vector<uint8_t>> excludeScriptPubKeys;
|
||||
int32_t top,bottom=0; std::vector<std::vector<uint8_t>> excludeScriptPubKeys; bool fFixedAmount = false;
|
||||
mpz_t mpzTotalAllocations, mpzAllocation;; mpz_init(mpzTotalAllocations);
|
||||
// user marker vout to get the createtxid
|
||||
if ( tx.vout.size() < 2 )
|
||||
@@ -253,9 +251,9 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
|
||||
// use the createtxid to fetch the tx and all of the plans info.
|
||||
if ( myGetTransaction(createtxid,plantx,blockhash) != 0 && plantx.vout.size() > 0 )
|
||||
{
|
||||
if ( ((funcid= DecodePaymentsOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid)) == 'O') )
|
||||
if ( ((funcid= DecodePaymentsOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,bottom,fixedAmount,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid)) == 'O') )
|
||||
{
|
||||
if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 )
|
||||
if ( lockedblocks < 0 || minrelease < 0 || (totalallocations <= 0 && top <= 0 ) )
|
||||
return(eval->Invalid("negative values"));
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
txidpk = CCtxidaddr(txidaddr,createtxid);
|
||||
@@ -301,32 +299,60 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
|
||||
}
|
||||
else if ( funcid == 'S' )
|
||||
{
|
||||
if ( KOMODO_SNAPSHOT_INTERVAL == 0 )
|
||||
return(eval->Invalid("snapshots not activated on this chain"));
|
||||
if ( vAddressSnapshot.size() == 0 )
|
||||
return(eval->Invalid("need first snapshot"));
|
||||
// need time for TX to me mined before the next snapshot.
|
||||
if ( top > 5000 )
|
||||
if ( top > 3999 )
|
||||
return(eval->Invalid("transaction too big"));
|
||||
for ( auto address : vAddressSnapshot )
|
||||
if ( fixedAmount == 7 )
|
||||
{
|
||||
CScript scriptPubKey = GetScriptForDestination(address.second);
|
||||
for ( auto skipkey : excludeScriptPubKeys )
|
||||
// game setting, randomise bottom and top values
|
||||
uint64_t x;
|
||||
uint256 tmphash = chainActive[lastSnapShotHeight]->GetBlockHash();
|
||||
memcpy(&x,&tmphash,sizeof(x));
|
||||
bottom = ((x & 0xff) % 50);
|
||||
if ( bottom == 0 ) bottom = 1;
|
||||
top = (((x>>8) & 0xff) % 100);
|
||||
if ( top < 50 ) top += 50;
|
||||
bottom = (vAddressSnapshot.size()*bottom)/100;
|
||||
top = (vAddressSnapshot.size()*top)/100;
|
||||
fprintf(stderr, "bottom.%i top.%i\n",bottom,top);
|
||||
fFixedAmount = true;
|
||||
}
|
||||
else if ( fixedAmount != 0 )
|
||||
{
|
||||
fFixedAmount = true;
|
||||
}
|
||||
for (int32_t j = bottom; j < vAddressSnapshot.size(); j++)
|
||||
{
|
||||
auto &address = vAddressSnapshot[j];
|
||||
CScript scriptPubKey = GetScriptForDestination(address.second); bool skip = false;
|
||||
for ( auto skipkey : excludeScriptPubKeys )
|
||||
{
|
||||
//fprintf(stderr, "scriptpubkey.%s\n skipkey.%s", HexStr(scriptPubKey).c_str(), HexStr(CScript(skipkey.begin(), skipkey.end())).c_str());
|
||||
if ( scriptPubKey != CScript(skipkey.begin(), skipkey.end()) )
|
||||
if ( scriptPubKey == CScript(skipkey.begin(), skipkey.end()) )
|
||||
{
|
||||
mpz_init(mpzAllocation);
|
||||
i++;
|
||||
scriptPubKeys.push_back(scriptPubKey);
|
||||
allocations.push_back(address.first);
|
||||
mpz_set_si(mpzAllocation,address.first);
|
||||
mpz_add(mpzTotalAllocations,mpzTotalAllocations,mpzAllocation);
|
||||
mpz_clear(mpzAllocation);
|
||||
}
|
||||
skip = true;
|
||||
//fprintf(stderr, "SKIPPED::: %s\n", CBitcoinAddress(address.second).ToString().c_str());
|
||||
}
|
||||
}
|
||||
if ( i == top ) // we reached top amount to pay, it can be less than this!
|
||||
if ( !skip )
|
||||
{
|
||||
mpz_init(mpzAllocation);
|
||||
i++;
|
||||
scriptPubKeys.push_back(scriptPubKey);
|
||||
allocations.push_back(address.first);
|
||||
mpz_set_si(mpzAllocation,address.first);
|
||||
mpz_add(mpzTotalAllocations,mpzTotalAllocations,mpzAllocation);
|
||||
mpz_clear(mpzAllocation);
|
||||
}
|
||||
if ( i+bottom == top ) // we reached top amount to pay, it can be less than this!
|
||||
break;
|
||||
}
|
||||
if ( i != tx.vout.size()-2 )
|
||||
return(eval->Invalid("pays wrong amount of recipients"));
|
||||
}
|
||||
}
|
||||
else if ( funcid == 'O' )
|
||||
{
|
||||
// tokens snapshot.
|
||||
@@ -355,12 +381,20 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
|
||||
fprintf(stderr, "pays wrong destination destscriptPubKey.%s voutscriptPubKey.%s\n", HexStr(scriptPubKeys[n].begin(),scriptPubKeys[n].end()).c_str(), HexStr(tx.vout[i].scriptPubKey.begin(),tx.vout[i].scriptPubKey.end()).c_str());
|
||||
return(eval->Invalid("pays wrong address"));
|
||||
}
|
||||
mpz_init(mpzAllocation);
|
||||
mpz_set_si(mpzAllocation,allocations[n]);
|
||||
mpz_mul(mpzAllocation,mpzAllocation,mpzCheckamount);
|
||||
mpz_cdiv_q(mpzAllocation,mpzAllocation,mpzTotalAllocations);
|
||||
int64_t test = mpz_get_si(mpzAllocation);
|
||||
mpz_clear(mpzAllocation);
|
||||
int64_t test;
|
||||
if ( fFixedAmount )
|
||||
{
|
||||
test = checkamount / (top-bottom);
|
||||
}
|
||||
else
|
||||
{
|
||||
mpz_init(mpzAllocation);
|
||||
mpz_set_si(mpzAllocation,allocations[n]);
|
||||
mpz_mul(mpzAllocation,mpzAllocation,mpzCheckamount);
|
||||
mpz_cdiv_q(mpzAllocation,mpzAllocation,mpzTotalAllocations);
|
||||
test = mpz_get_si(mpzAllocation);
|
||||
mpz_clear(mpzAllocation);
|
||||
}
|
||||
// Vairance of 1 sat is allowed, for rounding errors.
|
||||
if ( test >= tx.vout[i].nValue+1 && test <= tx.vout[i].nValue-1 )
|
||||
{
|
||||
@@ -571,7 +605,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr)
|
||||
int32_t latestheight,nextheight = komodo_nextheight();
|
||||
CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight); UniValue result(UniValue::VOBJ); uint256 createtxid,hashBlock,tokenid;
|
||||
CTransaction tx,txO; CPubKey mypk,txidpk,Paymentspk; int32_t i,n,m,numoprets=0,lockedblocks,minrelease; int64_t newamount,inputsum,amount,CCchange=0,totalallocations=0,checkallocations=0,allocation; CTxOut vout; CScript onlyopret; char txidaddr[64],destaddr[64]; std::vector<uint256> txidoprets;
|
||||
int32_t top; std::vector<std::vector<uint8_t>> excludeScriptPubKeys; int8_t funcid;
|
||||
int32_t top,bottom=0; std::vector<std::vector<uint8_t>> excludeScriptPubKeys; int8_t funcid,fixedAmount=0; bool fFixedAmount = false;
|
||||
mpz_t mpzTotalAllocations; mpz_init(mpzTotalAllocations);
|
||||
cJSON *params = payments_reparse(&n,jsonstr);
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
@@ -582,9 +616,9 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr)
|
||||
amount = jdouble(jitem(params,1),0) * SATOSHIDEN + 0.0000000049;
|
||||
if ( myGetTransaction(createtxid,tx,hashBlock) != 0 && tx.vout.size() > 0 )
|
||||
{
|
||||
if ( ((funcid= DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid)) == 'O') )
|
||||
if ( ((funcid= DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,bottom,fixedAmount,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid)) == 'O') )
|
||||
{
|
||||
if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 )
|
||||
if ( lockedblocks < 0 || minrelease < 0 || (totalallocations <= 0 && top <= 0 ) )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","negative parameter"));
|
||||
@@ -605,7 +639,8 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr)
|
||||
}
|
||||
txidpk = CCtxidaddr(txidaddr,createtxid);
|
||||
mtx.vout.push_back(MakeCC1of2vout(EVAL_PAYMENTS,0,Paymentspk,txidpk));
|
||||
if ( funcid = 'C' )
|
||||
//fprintf(stderr, "funcid.%i\n", funcid);
|
||||
if ( funcid == 'C' )
|
||||
{
|
||||
// normal payments
|
||||
for (i=0; i<m; i++)
|
||||
@@ -658,75 +693,120 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr)
|
||||
// set totalallocations to a mpz_t bignum, for amounts calculation later.
|
||||
mpz_set_si(mpzTotalAllocations,totalallocations);
|
||||
}
|
||||
else if ( funcid = 'S' )
|
||||
else if ( funcid == 'S' )
|
||||
{
|
||||
// normal snapshot
|
||||
i = 0;
|
||||
if ( top > 5000 )
|
||||
if ( vAddressSnapshot.size() == 0 )
|
||||
{
|
||||
// need to test the maximum number, this is an estimate.
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","cannot pay more than 5000 addresses"));
|
||||
result.push_back(Pair("error","first snapshot has not happened yet"));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
for ( auto address : vAddressSnapshot )
|
||||
if ( top > 3999 )
|
||||
{
|
||||
CScript scriptPubKey = GetScriptForDestination(address.second);
|
||||
for ( auto skipkey : excludeScriptPubKeys )
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","cannot pay more than 3999 addresses"));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
i = 0;
|
||||
//for ( auto address : vAddressSnapshot )
|
||||
if ( fixedAmount == 7 )
|
||||
{
|
||||
// game setting, randomise bottom and top values
|
||||
uint64_t x;
|
||||
uint256 tmphash = chainActive[lastSnapShotHeight]->GetBlockHash();
|
||||
memcpy(&x,&tmphash,sizeof(x));
|
||||
bottom = ((x & 0xff) % 50);
|
||||
if ( bottom == 0 ) bottom = 1;
|
||||
top = (((x>>8) & 0xff) % 100);
|
||||
if ( top < 50 ) top += 50;
|
||||
bottom = (vAddressSnapshot.size()*bottom)/100;
|
||||
top = (vAddressSnapshot.size()*top)/100;
|
||||
fprintf(stderr, "bottom.%i top.%i\n",bottom,top);
|
||||
fFixedAmount = true;
|
||||
}
|
||||
else if ( fixedAmount != 0 )
|
||||
{
|
||||
fFixedAmount = true;
|
||||
}
|
||||
for (int32_t j = bottom; j < vAddressSnapshot.size(); j++)
|
||||
{
|
||||
auto &address = vAddressSnapshot[j];
|
||||
CScript scriptPubKey = GetScriptForDestination(address.second); bool skip = false;
|
||||
for ( auto skipkey : excludeScriptPubKeys )
|
||||
{
|
||||
if ( scriptPubKey != CScript(skipkey.begin(), skipkey.end()) )
|
||||
if ( scriptPubKey == CScript(skipkey.begin(), skipkey.end()) )
|
||||
{
|
||||
mpz_t mpzAllocation; mpz_init(mpzAllocation);
|
||||
i++;
|
||||
//fprintf(stderr, "address: %s nValue.%li \n", CBitcoinAddress(address.second).ToString().c_str(), address.first);
|
||||
vout.nValue = address.first;
|
||||
vout.scriptPubKey = scriptPubKey;
|
||||
mpz_set_si(mpzAllocation,address.first);
|
||||
mpz_add(mpzTotalAllocations,mpzTotalAllocations,mpzAllocation); //totalallocations += address.first;
|
||||
mtx.vout.push_back(vout);
|
||||
mpz_clear(mpzAllocation);
|
||||
} else fprintf(stderr, "SKIPPED::: %s\n", CBitcoinAddress(address.second).ToString().c_str());
|
||||
skip = true;
|
||||
//fprintf(stderr, "SKIPPED::: %s\n", CBitcoinAddress(address.second).ToString().c_str());
|
||||
}
|
||||
}
|
||||
if ( i == top ) // we reached top amount to pay, it can be less than this!
|
||||
if ( !skip )
|
||||
{
|
||||
mpz_t mpzAllocation; mpz_init(mpzAllocation);
|
||||
i++;
|
||||
//fprintf(stderr, "address: %s nValue.%li \n", CBitcoinAddress(address.second).ToString().c_str(), address.first);
|
||||
vout.nValue = address.first;
|
||||
vout.scriptPubKey = scriptPubKey;
|
||||
mpz_set_si(mpzAllocation,address.first);
|
||||
mpz_add(mpzTotalAllocations,mpzTotalAllocations,mpzAllocation);
|
||||
mtx.vout.push_back(vout);
|
||||
mpz_clear(mpzAllocation);
|
||||
}
|
||||
if ( i+bottom == top ) // we reached top amount to pay, it can be less than this!
|
||||
break;
|
||||
}
|
||||
m = i; // this is the amount we got, either top, or all of the address on the chain.
|
||||
}
|
||||
else if ( funcid = 'O' )
|
||||
else if ( funcid == 'O' )
|
||||
{
|
||||
// token snapshot
|
||||
}
|
||||
newamount = amount;
|
||||
int64_t totalamountsent = 0;
|
||||
mpz_t mpzAmount; mpz_init(mpzAmount); mpz_set_si(mpzAmount,amount);
|
||||
fprintf(stderr, "m.%i\n",m);
|
||||
for (i=0; i<m; i++)
|
||||
{
|
||||
mpz_t mpzValue; mpz_init(mpzValue);
|
||||
mpz_set_si(mpzValue,mtx.vout[i+1].nValue);
|
||||
mpz_mul(mpzValue,mpzValue,mpzAmount);
|
||||
mpz_cdiv_q(mpzValue,mpzValue,mpzTotalAllocations);
|
||||
if ( mpz_fits_slong_p(mpzValue) )
|
||||
mtx.vout[i+1].nValue = mpz_get_si(mpzValue);
|
||||
else
|
||||
if ( fFixedAmount )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","value too big, try releasing a smaller amount"));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
mtx.vout[i+1].nValue = amount / (top-bottom);
|
||||
//fprintf(stderr, "amount.%li / top-bottom.%i = value.%li\n", amount, (top-bottom-2), mtx.vout[i+1].nValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
mpz_set_si(mpzValue,mtx.vout[i+1].nValue);
|
||||
mpz_mul(mpzValue,mpzValue,mpzAmount);
|
||||
mpz_cdiv_q(mpzValue,mpzValue,mpzTotalAllocations);
|
||||
if ( mpz_fits_slong_p(mpzValue) )
|
||||
mtx.vout[i+1].nValue = mpz_get_si(mpzValue);
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","value too big, try releasing a smaller amount"));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
}
|
||||
//fprintf(stderr, "nValue.%li \n", mtx.vout[i+1].nValue);
|
||||
mpz_clear(mpzValue);
|
||||
/*
|
||||
replace this with default dust threshold of 10ksat
|
||||
if ( mtx.vout[i+1].nValue < PAYMENTS_TXFEE )
|
||||
{
|
||||
newamount += (PAYMENTS_TXFEE - mtx.vout[i+1].nValue);
|
||||
mtx.vout[i+1].nValue = PAYMENTS_TXFEE;
|
||||
}
|
||||
} */
|
||||
totalamountsent += mtx.vout[i+1].nValue;
|
||||
}
|
||||
//fprintf(stderr, "newamount.%li totalamountsent.%li\n", newamount, totalamountsent);
|
||||
if ( totalamountsent < amount ) newamount = totalamountsent;
|
||||
fprintf(stderr, "newamount.%li totalamountsent.%li\n", newamount, totalamountsent);
|
||||
mpz_clear(mpzAmount); mpz_clear(mpzTotalAllocations);
|
||||
}
|
||||
else
|
||||
@@ -750,7 +830,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr)
|
||||
free_json(params);
|
||||
result.push_back(Pair("amount",ValueFromAmount(amount)));
|
||||
result.push_back(Pair("newamount",ValueFromAmount(newamount)));
|
||||
return(payments_rawtxresult(result,rawtx,0));
|
||||
return(payments_rawtxresult(result,rawtx,1));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -778,8 +858,8 @@ UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr)
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); UniValue result(UniValue::VOBJ);
|
||||
CPubKey Paymentspk,mypk,txidpk; uint256 txid,hashBlock; int64_t amount,totalallocations; CScript opret; CTransaction tx; char txidaddr[64]; std::string rawtx; int32_t n,useopret = 0,lockedblocks,minrelease; std::vector<uint256> txidoprets;
|
||||
int32_t top; std::vector<std::vector<uint8_t>> excludeScriptPubKeys; // snapshot
|
||||
uint256 tokenid;
|
||||
int32_t top,bottom; std::vector<std::vector<uint8_t>> excludeScriptPubKeys; // snapshot
|
||||
uint256 tokenid; int8_t fixedAmount;
|
||||
cJSON *params = payments_reparse(&n,jsonstr);
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
@@ -789,14 +869,14 @@ UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr)
|
||||
amount = jdouble(jitem(params,1),0) * SATOSHIDEN + 0.0000000049;
|
||||
if ( n == 3 )
|
||||
useopret = jint(jitem(params,2),0) != 0;
|
||||
if ( myGetTransaction(txid,tx,hashBlock) == 0 || tx.vout.size() == 1 || (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 0 && DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys) == 0 && DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid) == 0) )
|
||||
if ( myGetTransaction(txid,tx,hashBlock) == 0 || tx.vout.size() == 1 || (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 0 && DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,bottom,fixedAmount,excludeScriptPubKeys) == 0 && DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid) == 0) )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","invalid createtxid"));
|
||||
}
|
||||
else if ( AddNormalinputs(mtx,mypk,amount+PAYMENTS_TXFEE,60) > 0 )
|
||||
{
|
||||
if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 )
|
||||
if ( lockedblocks < 0 || minrelease < 0 || (totalallocations <= 0 && top <= 0 ) )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","negative parameter"));
|
||||
@@ -961,43 +1041,54 @@ UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr)
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
UniValue result(UniValue::VOBJ);
|
||||
uint256 hashBlock; CTransaction tx; CPubKey Paymentspk,mypk; char markeraddr[64]; std::string rawtx;
|
||||
int32_t lockedblocks,minrelease,top,n,i; std::vector<std::vector<uint8_t>> excludeScriptPubKeys;
|
||||
int32_t lockedblocks,minrelease,top,bottom,n,i; std::vector<std::vector<uint8_t>> excludeScriptPubKeys; int8_t fixedAmount;
|
||||
if ( KOMODO_SNAPSHOT_INTERVAL == 0 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","cannot use airdrop wihtout -ac_snapshot set."));
|
||||
return(result);
|
||||
}
|
||||
cJSON *params = payments_reparse(&n,jsonstr);
|
||||
if ( params != 0 && n >= 4 )
|
||||
if ( params != 0 && n >= 5 )
|
||||
{
|
||||
lockedblocks = juint(jitem(params,0),0);
|
||||
minrelease = juint(jitem(params,1),0);
|
||||
top = juint(jitem(params,2),0);
|
||||
if ( lockedblocks < 0 || minrelease < 0 || top < 0 )
|
||||
bottom = juint(jitem(params,3),0);
|
||||
fixedAmount = juint(jitem(params,4),0); // fixed amount is a flag set to 0 or 1. It means allocations are equal rather than weighted by address balance.
|
||||
if ( lockedblocks < 0 || minrelease < 0 || top <= 0 || bottom < 0 || fixedAmount < 0 || top > 3999 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","negative parameter"));
|
||||
result.push_back(Pair("error","negative parameter, or top over 3999"));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
for (i=0; i<n-3; i++)
|
||||
if ( n > 5 )
|
||||
{
|
||||
/* TODO: Change this RPC to take an address. Because a tokens airdrop needs its own RPC anyway.
|
||||
CTxDestination destination = DecodeDestination(name_);
|
||||
CScript scriptPubKey = GetScriptForDestination(destination);
|
||||
*/
|
||||
char *inputhex = jstri(params,3+i);
|
||||
std::vector<uint8_t> scriptPubKey;
|
||||
int32_t len = strlen(inputhex)/2;
|
||||
scriptPubKey.resize(len);
|
||||
decode_hex((uint8_t *)scriptPubKey.data(),len,(char *)inputhex);
|
||||
excludeScriptPubKeys.push_back(scriptPubKey);
|
||||
for (i=0; i<n-5; i++)
|
||||
{
|
||||
/* TODO: Change this RPC to take an address. Because a tokens airdrop needs its own RPC anyway.
|
||||
CTxDestination destination = DecodeDestination(name_);
|
||||
CScript scriptPubKey = GetScriptForDestination(destination);
|
||||
*/
|
||||
char *inputhex = jstri(params,3+i);
|
||||
std::vector<uint8_t> scriptPubKey;
|
||||
int32_t len = strlen(inputhex)/2;
|
||||
scriptPubKey.resize(len);
|
||||
decode_hex((uint8_t *)scriptPubKey.data(),len,(char *)inputhex);
|
||||
excludeScriptPubKeys.push_back(scriptPubKey);
|
||||
}
|
||||
}
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
if ( AddNormalinputs(mtx,mypk,2*PAYMENTS_TXFEE,60) > 0 )
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,PAYMENTS_TXFEE,Paymentspk,Paymentspk));
|
||||
rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,EncodePaymentsSnapsShotOpRet(lockedblocks,minrelease,top,excludeScriptPubKeys));
|
||||
rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,EncodePaymentsSnapsShotOpRet(lockedblocks,minrelease,top,bottom,fixedAmount,excludeScriptPubKeys));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(payments_rawtxresult(result,rawtx,0));
|
||||
return(payments_rawtxresult(result,rawtx,1));
|
||||
}
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","not enough normal funds"));
|
||||
@@ -1015,8 +1106,8 @@ UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr)
|
||||
UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); CTransaction tx,txO; CPubKey Paymentspk,txidpk; int32_t i,j,n,flag=0,numoprets=0,lockedblocks,minrelease; std::vector<uint256> txidoprets; int64_t funds,fundsopret,totalallocations=0,allocation; char fundsaddr[64],fundsopretaddr[64],txidaddr[64],*outstr; uint256 createtxid,hashBlock;
|
||||
int32_t top; std::vector<std::vector<uint8_t>> excludeScriptPubKeys; // snapshot
|
||||
uint256 tokenid;
|
||||
int32_t top,bottom; std::vector<std::vector<uint8_t>> excludeScriptPubKeys; // snapshot
|
||||
uint256 tokenid; int8_t fixedAmount;
|
||||
cJSON *params = payments_reparse(&n,jsonstr);
|
||||
if ( params != 0 && n == 1 )
|
||||
{
|
||||
@@ -1071,9 +1162,9 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr)
|
||||
result.push_back(Pair("error","too many opreturns"));
|
||||
} else result.push_back(Pair("txidoprets",a));
|
||||
}
|
||||
else if ( DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys) != 0 )
|
||||
else if ( DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,bottom,fixedAmount,excludeScriptPubKeys) != 0 )
|
||||
{
|
||||
if ( lockedblocks < 0 || minrelease < 0 || top <= 0 )
|
||||
if ( lockedblocks < 0 || minrelease < 0 || top <= 0 || bottom < 0 || fixedAmount < 0 || top > 3999 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","negative parameter"));
|
||||
@@ -1085,6 +1176,9 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr)
|
||||
result.push_back(Pair("lockedblocks",(int64_t)lockedblocks));
|
||||
result.push_back(Pair("minrelease",(int64_t)minrelease));
|
||||
result.push_back(Pair("top",(int64_t)top));
|
||||
result.push_back(Pair("bottom",(int64_t)bottom));
|
||||
result.push_back(Pair("fixedFlag",(int64_t)fixedAmount));
|
||||
// TODO: convert to show addresses instead of scriptpubkey.
|
||||
for ( auto scriptPubKey : excludeScriptPubKeys )
|
||||
a.push_back(HexStr(scriptPubKey.begin(),scriptPubKey.end()));
|
||||
result.push_back(Pair("excludeScriptPubkeys",a));
|
||||
@@ -1104,6 +1198,7 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr)
|
||||
result.push_back(Pair("minrelease",(int64_t)minrelease));
|
||||
result.push_back(Pair("top",(int64_t)top));
|
||||
result.push_back(Pair("tokenid",tokenid.ToString()));
|
||||
// TODO: show pubkeys instead of scriptpubkeys
|
||||
for ( auto scriptPubKey : excludeScriptPubKeys )
|
||||
a.push_back(HexStr(scriptPubKey.begin(),scriptPubKey.end()));
|
||||
result.push_back(Pair("excludeScriptPubkeys",a));
|
||||
@@ -1146,8 +1241,8 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr)
|
||||
UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr)
|
||||
{
|
||||
std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex; uint256 txid,hashBlock,tokenid;
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); char markeraddr[64],str[65]; CPubKey Paymentspk; CTransaction tx; int32_t lockedblocks,minrelease; std::vector<uint256> txidoprets; int64_t totalallocations;
|
||||
int32_t top; std::vector<std::vector<uint8_t>> excludeScriptPubKeys;
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); char markeraddr[64],str[65]; CPubKey Paymentspk; CTransaction tx; int32_t lockedblocks,minrelease; std::vector<uint256> txidoprets; int64_t totalallocations=0;
|
||||
int32_t top=0,bottom=0; std::vector<std::vector<uint8_t>> excludeScriptPubKeys; int8_t fixedAmount = 0;
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
GetCCaddress1of2(cp,markeraddr,Paymentspk,Paymentspk);
|
||||
SetCCtxids(addressIndex,markeraddr,true);
|
||||
@@ -1156,9 +1251,9 @@ UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr)
|
||||
txid = it->first.txhash;
|
||||
if ( it->first.index == 0 && myGetTransaction(txid,tx,hashBlock) != 0 )
|
||||
{
|
||||
if ( tx.vout.size() > 0 && (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 'C' || DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys) == 'S' || DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid) == 'O') )
|
||||
if ( tx.vout.size() > 0 && (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 'C' || DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,bottom,fixedAmount,excludeScriptPubKeys) == 'S' || DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid) == 'O') )
|
||||
{
|
||||
if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 || txidoprets.size() < 2 )
|
||||
if ( lockedblocks < 0 || minrelease < 0 || (totalallocations <= 0 && top <= 0 ) || bottom < 0 || fixedAmount < 0 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","negative parameter"));
|
||||
@@ -1169,6 +1264,6 @@ UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr)
|
||||
}
|
||||
}
|
||||
result.push_back(Pair("result","success"));
|
||||
result.push_back(Pair("createtxids",a));
|
||||
return(result);
|
||||
result.push_back(Pair("createtxids",a));
|
||||
return(result);
|
||||
}
|
||||
|
||||
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..."));
|
||||
|
||||
@@ -2063,7 +2063,7 @@ bool komodo_appendACscriptpub()
|
||||
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
|
||||
// encoded opreturn incorrectly on TESTHC chain, once we no longer need this it can be changed to a straight +1 to drop OP_RETURN opcode.
|
||||
ASSETCHAINS_SCRIPTPUB.append(HexStr(tx.vout[i].scriptPubKey.begin()+(strcmp("TESTHC",ASSETCHAINS_SYMBOL) == 0 ? 3 : 1), tx.vout[i].scriptPubKey.end()));
|
||||
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;
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#define ASSETCHAINS_MINHEIGHT 128
|
||||
#define ASSETCHAINS_MAX_ERAS 3
|
||||
#define KOMODO_ELECTION_GAP 2000
|
||||
#define KOMODO_SNAPSHOT_INTERVAL 1440 // 1440 is approx 1 day. Maybe this can be -ac param to allow for diffrent block times etc.?
|
||||
#define ROUNDROBIN_DELAY 61
|
||||
#define KOMODO_ASSETCHAIN_MAXLEN 65
|
||||
#define KOMODO_LIMITED_NETWORKSIZE 4
|
||||
@@ -79,7 +78,7 @@ 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;
|
||||
int tx_height( const uint256 &hash );
|
||||
extern std::vector<std::string> vWhiteListAddress;
|
||||
void komodo_netevent(std::vector<uint8_t> payload);
|
||||
|
||||
@@ -109,7 +109,7 @@ 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;
|
||||
|
||||
struct komodo_kv *KOMODO_KV;
|
||||
pthread_mutex_t KOMODO_KV_mutex,KOMODO_CC_mutex;
|
||||
|
||||
@@ -1752,6 +1752,7 @@ 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 )
|
||||
{
|
||||
@@ -2012,7 +2013,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 )
|
||||
{
|
||||
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;
|
||||
@@ -2148,6 +2149,11 @@ 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);
|
||||
fprintf(stderr, "snapshot interval.%i\n",KOMODO_SNAPSHOT_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
addn = GetArg("-seednode","");
|
||||
|
||||
16
src/main.cpp
16
src/main.cpp
@@ -673,7 +673,7 @@ bool komodo_dailysnapshot(int32_t height)
|
||||
{
|
||||
// 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-100 ? undo_height = notarized_height : undo_height = height-reorglimit;
|
||||
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.
|
||||
@@ -732,7 +732,7 @@ bool komodo_dailysnapshot(int32_t height)
|
||||
//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() > 5000 ) vAddressSnapshot.resize(5000);
|
||||
if ( vAddressSnapshot.size() > 3999 ) vAddressSnapshot.resize(3999);
|
||||
lastSnapShotHeight = undo_height;
|
||||
fprintf(stderr, "vAddressSnapshot.size.%li\n", vAddressSnapshot.size());
|
||||
return true;
|
||||
@@ -3592,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);
|
||||
@@ -4251,7 +4251,7 @@ 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 && (pindexNew->GetHeight() % KOMODO_SNAPSHOT_INTERVAL) == 0 )
|
||||
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()) )
|
||||
@@ -6198,12 +6198,6 @@ 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);
|
||||
|
||||
if ( ASSETCHAINS_CC != 0 && chainActive.Height() > KOMODO_SNAPSHOT_INTERVAL )
|
||||
{
|
||||
if ( !komodo_dailysnapshot(chainActive.Height()) )
|
||||
fprintf(stderr, "daily snapshot failed, please reindex your chain\n"); // maybe force shutdown here?
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -291,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);
|
||||
|
||||
@@ -5633,7 +5633,7 @@ UniValue payments_airdrop(const UniValue& params, bool fHelp)
|
||||
{
|
||||
struct CCcontract_info *cp,C;
|
||||
if ( fHelp || params.size() != 1 )
|
||||
throw runtime_error("paymentsairdrop \"[lockedblocks,minamount,top,%22paytxid0%22,...,%22paytxidN%22]\"\n");
|
||||
throw runtime_error("paymentsairdrop \"[lockedblocks,minamount,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;
|
||||
@@ -8045,14 +8045,21 @@ UniValue opreturn_burn(const UniValue& params, bool fHelp)
|
||||
int64_t normalInputs = AddNormalinputs(mtx, myPubkey, nAmount, 60);
|
||||
if (normalInputs < nAmount)
|
||||
throw runtime_error("not enough normals\n");
|
||||
|
||||
CScript opret; uint8_t *ptr;
|
||||
opret << OP_RETURN;
|
||||
|
||||
CScript opret; uint8_t scripthex[8192];
|
||||
|
||||
decode_hex(scripthex,strHex.size()/2,(char *)strHex.c_str());
|
||||
std::string test;
|
||||
test.append((char*)scripthex);
|
||||
std::vector<uint8_t> opretdata(test.begin(), test.end());
|
||||
opret << OP_RETURN << E_MARSHAL(ss << opretdata);
|
||||
/*CScript opret; uint8_t *ptr;
|
||||
opret << OP_RETURN << 0;
|
||||
int32_t len = strlen(strHex.c_str());
|
||||
len >>=1;
|
||||
opret.resize(len+1);
|
||||
opret.resize(len+2);
|
||||
ptr = (uint8_t *)&opret[1];
|
||||
decode_hex(ptr,len,(char *)strHex.c_str());
|
||||
decode_hex(ptr,len,(char *)strHex.c_str()); */
|
||||
mtx.vout.push_back(CTxOut(nAmount,opret));
|
||||
ret.push_back(Pair("hex",FinalizeCCTx(0, cp, mtx, myPubkey, 10000, CScript())));
|
||||
return(ret);
|
||||
|
||||
Reference in New Issue
Block a user