Merge remote-tracking branch 'origin/jl777' into jl777

This commit is contained in:
jl777
2019-04-16 20:12:33 -11:00
13 changed files with 367 additions and 148 deletions

View File

@@ -226,8 +226,8 @@ bool priv2addr(char *coinaddr,uint8_t buf33[33],uint8_t priv32[32]);
CPubKey buf2pk(uint8_t *buf33); CPubKey buf2pk(uint8_t *buf33);
void endiancpy(uint8_t *dest,uint8_t *src,int32_t len); void endiancpy(uint8_t *dest,uint8_t *src,int32_t len);
uint256 DiceHashEntropy(uint256 &entropy,uint256 _txidpriv,int32_t entropyvout,int32_t usevout); uint256 DiceHashEntropy(uint256 &entropy,uint256 _txidpriv,int32_t entropyvout,int32_t usevout);
CTxOut MakeCC1vout(uint8_t evalcode,CAmount nValue,CPubKey pk); CTxOut MakeCC1vout(uint8_t evalcode,CAmount nValue,CPubKey pk, const std::vector<std::vector<unsigned char>>* vData = NULL);
CTxOut MakeCC1of2vout(uint8_t evalcode,CAmount nValue,CPubKey pk,CPubKey pk2); CTxOut MakeCC1of2vout(uint8_t evalcode,CAmount nValue,CPubKey pk,CPubKey pk2, const std::vector<std::vector<unsigned char>>* vData = NULL);
CC *MakeCCcond1(uint8_t evalcode,CPubKey pk); CC *MakeCCcond1(uint8_t evalcode,CPubKey pk);
CC *MakeCCcond1of2(uint8_t evalcode,CPubKey pk1,CPubKey pk2); CC *MakeCCcond1of2(uint8_t evalcode,CPubKey pk1,CPubKey pk2);
CC* GetCryptoCondition(CScript const& scriptSig); CC* GetCryptoCondition(CScript const& scriptSig);

View File

@@ -58,20 +58,37 @@ CC *MakeCCcond1(uint8_t evalcode,CPubKey pk)
return CCNewThreshold(2, {condCC, Sig}); return CCNewThreshold(2, {condCC, Sig});
} }
CTxOut MakeCC1vout(uint8_t evalcode,CAmount nValue,CPubKey pk) CTxOut MakeCC1vout(uint8_t evalcode,CAmount nValue, CPubKey pk, const std::vector<std::vector<unsigned char>>* vData)
{ {
CTxOut vout; CTxOut vout;
CC *payoutCond = MakeCCcond1(evalcode,pk); CC *payoutCond = MakeCCcond1(evalcode,pk);
vout = CTxOut(nValue,CCPubKey(payoutCond)); vout = CTxOut(nValue,CCPubKey(payoutCond));
if ( vData )
{
std::vector<std::vector<unsigned char>> vtmpData = std::vector<std::vector<unsigned char>>(vData->begin(), vData->end());
std::vector<CPubKey> vPubKeys = std::vector<CPubKey>();
vPubKeys.push_back(pk);
COptCCParams ccp = COptCCParams(COptCCParams::VERSION, evalcode, 1, 1, vPubKeys, vtmpData);
vout.scriptPubKey << ccp.AsVector() << OP_DROP;
}
cc_free(payoutCond); cc_free(payoutCond);
return(vout); return(vout);
} }
CTxOut MakeCC1of2vout(uint8_t evalcode,CAmount nValue,CPubKey pk1,CPubKey pk2) CTxOut MakeCC1of2vout(uint8_t evalcode,CAmount nValue,CPubKey pk1,CPubKey pk2, const std::vector<std::vector<unsigned char>>* vData)
{ {
CTxOut vout; CTxOut vout;
CC *payoutCond = MakeCCcond1of2(evalcode,pk1,pk2); CC *payoutCond = MakeCCcond1of2(evalcode,pk1,pk2);
vout = CTxOut(nValue,CCPubKey(payoutCond)); vout = CTxOut(nValue,CCPubKey(payoutCond));
if ( vData )
{
std::vector<std::vector<unsigned char>> vtmpData = std::vector<std::vector<unsigned char>>(vData->begin(), vData->end());
std::vector<CPubKey> vPubKeys = std::vector<CPubKey>();
vPubKeys.push_back(pk1);
vPubKeys.push_back(pk2);
COptCCParams ccp = COptCCParams(COptCCParams::VERSION, evalcode, 1, 2, vPubKeys, vtmpData);
vout.scriptPubKey << ccp.AsVector() << OP_DROP;
}
cc_free(payoutCond); cc_free(payoutCond);
return(vout); return(vout);
} }

View File

@@ -11,7 +11,7 @@
*/ */
CScript custom_opret(uint8_t funcid,CPubKey pk) CScript custom_opret(uint8_t funcid,CPubKey pk)
{ {
CScript opret; uint8_t evalcode = EVAL_CUSTOM; CScript opret; uint8_t evalcode = EVAL_CUSTOM;
opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << pk); opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << pk);
return(opret); return(opret);
@@ -64,25 +64,54 @@ UniValue custom_func1(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
mypk = pubkey2pk(Mypubkey()); mypk = pubkey2pk(Mypubkey());
if ( AddNormalinputs(mtx,mypk,COIN+txfee,64) >= COIN+txfee ) // add utxo to mtx if ( AddNormalinputs(mtx,mypk,COIN+txfee,64) >= COIN+txfee ) // add utxo to mtx
{ {
mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,mypk)); // make vout0 // make op_return payload as normal.
// add opreturn, change is automatically added and tx is properly signed CScript opret = custom_opret('1',mypk);
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,custom_opret('1',mypk)); std::vector<std::vector<unsigned char>> vData = std::vector<std::vector<unsigned char>>();
vData.push_back(std::vector<unsigned char>(opret.begin(), opret.end()));
// make vout0 with op_return included as payload.
mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,mypk,&vData));
fprintf(stderr, "vout size2.%li\n", mtx.vout.size());
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,CScript());
return(custom_rawtxresult(result,rawtx,broadcastflag)); return(custom_rawtxresult(result,rawtx,broadcastflag));
} }
return(result); return(result);
} }
bool has_opret(const CTransaction &tx, uint8_t evalcode)
{
for ( auto vout : tx.vout )
{
if ( vout.scriptPubKey[0] == OP_RETURN && vout.scriptPubKey[1] == evalcode )
return true;
}
return false;
}
bool custom_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx) bool custom_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx)
{ {
char expectedaddress[64]; CPubKey pk; char expectedaddress[64]; CPubKey pk;
if ( tx.vout.size() != 2 ) // make sure the tx only has 2 outputs CScript opret; int32_t numvout;
if ( !has_opret(tx, EVAL_CUSTOM) )
{
std::vector<std::vector<unsigned char>> vParams = std::vector<std::vector<unsigned char>>();
CScript dummy;
if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition(&dummy, vParams) && vParams.size() == 1 )
{
opret << E_MARSHAL(ss << vParams[0]);
}
numvout = 1;
}
else
{
opret = tx.vout[1].scriptPubKey;
numvout = 2;
}
if ( tx.vout.size() != numvout ) // make sure the tx only has appropriate outputs
return eval->Invalid("invalid number of vouts"); return eval->Invalid("invalid number of vouts");
else if ( custom_opretdecode(pk,tx.vout[1].scriptPubKey) != '1' ) // verify has opreturn else if ( custom_opretdecode(pk,opret) != '1' ) // verify opreturn payload
return eval->Invalid("invalid opreturn"); return eval->Invalid("invalid opreturn");
GetCCaddress(cp,expectedaddress,pk); GetCCaddress(cp,expectedaddress,pk);
if ( IsCClibvout(cp,tx,0,expectedaddress) == COIN ) // make sure amount and destination matches if ( IsCClibvout(cp,tx,0,expectedaddress) == COIN ) // make sure amount and destination matches
return(true); return(true);
else return eval->Invalid("invalid vout0 amount"); else return eval->Invalid("invalid vout0 amount");
} }

View File

@@ -92,6 +92,7 @@ static CBlock CreateGenesisBlock(uint32_t nTime, const uint256& nNonce, const st
void *chainparams_commandline(void *ptr); void *chainparams_commandline(void *ptr);
#include "komodo_defs.h" #include "komodo_defs.h"
int32_t ASSETCHAINS_BLOCKTIME = 60; int32_t ASSETCHAINS_BLOCKTIME = 60;
uint64_t ASSETCHAINS_NK[2];
const arith_uint256 maxUint = UintToArith256(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); const arith_uint256 maxUint = UintToArith256(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"));
@@ -282,6 +283,12 @@ void *chainparams_commandline(void *ptr)
mainParams.consensus.nPowTargetSpacing = ASSETCHAINS_BLOCKTIME; mainParams.consensus.nPowTargetSpacing = ASSETCHAINS_BLOCKTIME;
} }
mainParams.SetDefaultPort(ASSETCHAINS_P2PPORT); mainParams.SetDefaultPort(ASSETCHAINS_P2PPORT);
if ( ASSETCHAINS_NK[0] != 0 && ASSETCHAINS_NK[1] != 0 )
{
//BOOST_STATIC_ASSERT(equihash_parameters_acceptable(ASSETCHAINS_NK[0], ASSETCHAINS_NK[1]));
mainParams.SetNValue(ASSETCHAINS_NK[0]);
mainParams.SetKValue(ASSETCHAINS_NK[1]);
}
if ( ASSETCHAINS_RPCPORT == 0 ) if ( ASSETCHAINS_RPCPORT == 0 )
ASSETCHAINS_RPCPORT = ASSETCHAINS_P2PPORT + 1; ASSETCHAINS_RPCPORT = ASSETCHAINS_P2PPORT + 1;
mainParams.pchMessageStart[0] = ASSETCHAINS_MAGIC & 0xff; mainParams.pchMessageStart[0] = ASSETCHAINS_MAGIC & 0xff;

View File

@@ -119,6 +119,8 @@ public:
void SetDefaultPort(uint16_t port) { nDefaultPort = port; } void SetDefaultPort(uint16_t port) { nDefaultPort = port; }
void SetCheckpointData(CCheckpointData checkpointData); void SetCheckpointData(CCheckpointData checkpointData);
void SetNValue(uint64_t n) { nEquihashN = n; }
void SetKValue(uint64_t k) { nEquihashK = k; }
//void setnonce(uint32_t nonce) { memcpy(&genesis.nNonce,&nonce,sizeof(nonce)); } //void setnonce(uint32_t nonce) { memcpy(&genesis.nNonce,&nonce,sizeof(nonce)); }
//void settimestamp(uint32_t timestamp) { genesis.nTime = timestamp; } //void settimestamp(uint32_t timestamp) { genesis.nTime = timestamp; }

View File

@@ -54,33 +54,84 @@
#define __BYTE_ORDER BYTE_ORDER #define __BYTE_ORDER BYTE_ORDER
#endif #endif
*/ */
static EhSolverCancelledException solver_cancelled; static EhSolverCancelledException solver_cancelled;
int8_t ZeroizeUnusedBits(size_t N, unsigned char* hash, size_t hLen)
{
uint8_t rem = N % 8;
if (rem)
{
// clear lowest 8-rem bits
const size_t step = GetSizeInBytes(N);
for (size_t i = step - 1; i < hLen; i += step)
{
uint8_t b = 0xff << (8-rem);
hash[i] &= b;
}
}
return(0);
}
template<unsigned int N, unsigned int K> template<unsigned int N, unsigned int K>
int Equihash<N,K>::InitialiseState(eh_HashState& base_state) int Equihash<N,K>::InitialiseState(eh_HashState& base_state)
{ {
uint32_t le_N = htole32(N); uint32_t le_N = htole32(N);
uint32_t le_K = htole32(K); uint32_t le_K = htole32(K);
unsigned char personalization[crypto_generichash_blake2b_PERSONALBYTES] = {}; unsigned char personalization[crypto_generichash_blake2b_PERSONALBYTES] = {};
memcpy(personalization, "ZcashPoW", 8); if ( ASSETCHAINS_NK[0] == 0 && ASSETCHAINS_NK[1] == 0 )
memcpy(personalization, "ZcashPoW", 8);
else
memcpy(personalization, "NandKPoW", 8);
memcpy(personalization+8, &le_N, 4); memcpy(personalization+8, &le_N, 4);
memcpy(personalization+12, &le_K, 4); memcpy(personalization+12, &le_K, 4);
const uint8_t outlen = (512 / N) * GetSizeInBytes(N);
BOOST_STATIC_ASSERT(!((!outlen) || (outlen > BLAKE2B_OUTBYTES)));
return crypto_generichash_blake2b_init_salt_personal(&base_state, return crypto_generichash_blake2b_init_salt_personal(&base_state,
NULL, 0, // No key. NULL, 0, // No key.
(512/N)*N/8, outlen,
NULL, // No salt. NULL, // No salt.
personalization); personalization);
} }
void GenerateHash(const eh_HashState& base_state, eh_index g, void GenerateHash(const eh_HashState& base_state, eh_index g,
unsigned char* hash, size_t hLen) unsigned char* hash, size_t hLen, size_t N)
{ {
eh_HashState state; if ( ASSETCHAINS_NK[0] == 0 && ASSETCHAINS_NK[1] == 0 )
state = base_state; {
eh_index lei = htole32(g); eh_HashState state;
crypto_generichash_blake2b_update(&state, (const unsigned char*) &lei, state = base_state;
sizeof(eh_index)); eh_index lei = htole32(g);
crypto_generichash_blake2b_final(&state, hash, hLen); crypto_generichash_blake2b_update(&state, (const unsigned char*) &lei,
sizeof(eh_index));
crypto_generichash_blake2b_final(&state, hash, hLen);
}
else
{
uint32_t myHash[16] = {0};
uint32_t startIndex = g & 0xFFFFFFF0;
for (uint32_t g2 = startIndex; g2 <= g; g2++) {
uint32_t tmpHash[16] = {0};
eh_HashState state;
state = base_state;
eh_index lei = htole32(g2);
crypto_generichash_blake2b_update(&state, (const unsigned char*) &lei,
sizeof(eh_index));
crypto_generichash_blake2b_final(&state, (unsigned char*)&tmpHash[0], static_cast<uint8_t>(hLen));
for (uint32_t idx = 0; idx < 16; idx++) myHash[idx] += tmpHash[idx];
}
memcpy(hash, &myHash[0], hLen);
ZeroizeUnusedBits(N, hash, hLen);
}
} }
void ExpandArray(const unsigned char* in, size_t in_len, void ExpandArray(const unsigned char* in, size_t in_len,
@@ -88,7 +139,7 @@ void ExpandArray(const unsigned char* in, size_t in_len,
size_t bit_len, size_t byte_pad) size_t bit_len, size_t byte_pad)
{ {
assert(bit_len >= 8); assert(bit_len >= 8);
assert(8*sizeof(uint32_t) >= 7+bit_len); assert(8*sizeof(uint32_t) >= bit_len);
size_t out_width { (bit_len+7)/8 + byte_pad }; size_t out_width { (bit_len+7)/8 + byte_pad };
assert(out_len == 8*out_width*in_len/bit_len); assert(out_len == 8*out_width*in_len/bit_len);
@@ -131,10 +182,10 @@ void CompressArray(const unsigned char* in, size_t in_len,
size_t bit_len, size_t byte_pad) size_t bit_len, size_t byte_pad)
{ {
assert(bit_len >= 8); assert(bit_len >= 8);
assert(8*sizeof(uint32_t) >= 7+bit_len); assert(8*sizeof(uint32_t) >= bit_len);
size_t in_width { (bit_len+7)/8 + byte_pad }; size_t in_width { (bit_len+7)/8 + byte_pad };
assert(out_len == bit_len*in_len/(8*in_width)); assert(out_len == (bit_len*in_len/in_width + 7)/8);
uint32_t bit_len_mask { ((uint32_t)1 << bit_len) - 1 }; uint32_t bit_len_mask { ((uint32_t)1 << bit_len) - 1 };
@@ -148,17 +199,23 @@ void CompressArray(const unsigned char* in, size_t in_len,
// When we have fewer than 8 bits left in the accumulator, read the next // When we have fewer than 8 bits left in the accumulator, read the next
// input element. // input element.
if (acc_bits < 8) { if (acc_bits < 8) {
if (j < in_len) {
acc_value = acc_value << bit_len; acc_value = acc_value << bit_len;
for (size_t x = byte_pad; x < in_width; x++) { for (size_t x = byte_pad; x < in_width; x++) {
acc_value = acc_value | ( acc_value = acc_value | (
( (
// Apply bit_len_mask across byte boundaries // Apply bit_len_mask across byte boundaries
in[j+x] & ((bit_len_mask >> (8*(in_width-x-1))) & 0xFF) in[j + x] & ((bit_len_mask >> (8 * (in_width - x - 1))) & 0xFF)
) << (8*(in_width-x-1))); // Big-endian ) << (8 * (in_width - x - 1))); // Big-endian
} }
j += in_width; j += in_width;
acc_bits += bit_len; acc_bits += bit_len;
} }
else {
acc_value <<= 8 - acc_bits;
acc_bits += 8 - acc_bits;;
}
}
acc_bits -= 8; acc_bits -= 8;
out[i] = (acc_value >> acc_bits) & 0xFF; out[i] = (acc_value >> acc_bits) & 0xFF;
@@ -207,7 +264,7 @@ std::vector<eh_index> GetIndicesFromMinimal(std::vector<unsigned char> minimal,
ExpandArray(minimal.data(), minimal.size(), ExpandArray(minimal.data(), minimal.size(),
array.data(), lenIndices, cBitLen+1, bytePad); array.data(), lenIndices, cBitLen+1, bytePad);
std::vector<eh_index> ret; std::vector<eh_index> ret;
for (int i = 0; i < lenIndices; i += sizeof(eh_index)) { for (size_t i = 0; i < lenIndices; i += sizeof(eh_index)) {
ret.push_back(ArrayToEhIndex(array.data()+i)); ret.push_back(ArrayToEhIndex(array.data()+i));
} }
return ret; return ret;
@@ -221,7 +278,7 @@ std::vector<unsigned char> GetMinimalFromIndices(std::vector<eh_index> indices,
size_t minLen { (cBitLen+1)*lenIndices/(8*sizeof(eh_index)) }; size_t minLen { (cBitLen+1)*lenIndices/(8*sizeof(eh_index)) };
size_t bytePad { sizeof(eh_index) - ((cBitLen+1)+7)/8 }; size_t bytePad { sizeof(eh_index) - ((cBitLen+1)+7)/8 };
std::vector<unsigned char> array(lenIndices); std::vector<unsigned char> array(lenIndices);
for (int i = 0; i < indices.size(); i++) { for (size_t i = 0; i < indices.size(); i++) {
EhIndexToArray(indices[i], array.data()+(i*sizeof(eh_index))); EhIndexToArray(indices[i], array.data()+(i*sizeof(eh_index)));
} }
std::vector<unsigned char> ret(minLen); std::vector<unsigned char> ret(minLen);
@@ -254,12 +311,12 @@ FullStepRow<WIDTH>::FullStepRow(const unsigned char* hashIn, size_t hInLen,
} }
template<size_t WIDTH> template<size_t W> template<size_t WIDTH> template<size_t W>
FullStepRow<WIDTH>::FullStepRow(const FullStepRow<W>& a, const FullStepRow<W>& b, size_t len, size_t lenIndices, int trim) : FullStepRow<WIDTH>::FullStepRow(const FullStepRow<W>& a, const FullStepRow<W>& b, size_t len, size_t lenIndices, size_t trim) :
StepRow<WIDTH> {a} StepRow<WIDTH> {a}
{ {
assert(len+lenIndices <= W); assert(len+lenIndices <= W);
assert(len-trim+(2*lenIndices) <= WIDTH); assert(len-trim+(2*lenIndices) <= WIDTH);
for (int i = trim; i < len; i++) for (size_t i = trim; i < len; i++)
hash[i-trim] = a.hash[i] ^ b.hash[i]; hash[i-trim] = a.hash[i] ^ b.hash[i];
if (a.IndicesBefore(b, len, lenIndices)) { if (a.IndicesBefore(b, len, lenIndices)) {
std::copy(a.hash+len, a.hash+len+lenIndices, hash+len-trim); std::copy(a.hash+len, a.hash+len+lenIndices, hash+len-trim);
@@ -281,7 +338,7 @@ template<size_t WIDTH>
bool StepRow<WIDTH>::IsZero(size_t len) bool StepRow<WIDTH>::IsZero(size_t len)
{ {
// This doesn't need to be constant time. // This doesn't need to be constant time.
for (int i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
if (hash[i] != 0) if (hash[i] != 0)
return false; return false;
} }
@@ -301,10 +358,10 @@ std::vector<unsigned char> FullStepRow<WIDTH>::GetIndices(size_t len, size_t len
} }
template<size_t WIDTH> template<size_t WIDTH>
bool HasCollision(StepRow<WIDTH>& a, StepRow<WIDTH>& b, int l) bool HasCollision(StepRow<WIDTH>& a, StepRow<WIDTH>& b, size_t l)
{ {
// This doesn't need to be constant time. // This doesn't need to be constant time.
for (int j = 0; j < l; j++) { for (size_t j = 0; j < l; j++) {
if (a.hash[j] != b.hash[j]) if (a.hash[j] != b.hash[j])
return false; return false;
} }
@@ -326,7 +383,7 @@ TruncatedStepRow<WIDTH>::TruncatedStepRow(const TruncatedStepRow<W>& a, const Tr
{ {
assert(len+lenIndices <= W); assert(len+lenIndices <= W);
assert(len-trim+(2*lenIndices) <= WIDTH); assert(len-trim+(2*lenIndices) <= WIDTH);
for (int i = trim; i < len; i++) for (size_t i = static_cast<size_t>(trim); i < len; i++)
hash[i-trim] = a.hash[i] ^ b.hash[i]; hash[i-trim] = a.hash[i] ^ b.hash[i];
if (a.IndicesBefore(b, len, lenIndices)) { if (a.IndicesBefore(b, len, lenIndices)) {
std::copy(a.hash+len, a.hash+len+lenIndices, hash+len-trim); std::copy(a.hash+len, a.hash+len+lenIndices, hash+len-trim);
@@ -355,10 +412,10 @@ std::shared_ptr<eh_trunc> TruncatedStepRow<WIDTH>::GetTruncatedIndices(size_t le
#ifdef ENABLE_MINING #ifdef ENABLE_MINING
template<unsigned int N, unsigned int K> template<unsigned int N, unsigned int K>
bool Equihash<N,K>::BasicSolve(const eh_HashState& base_state, bool Equihash<N,K>::BasicSolve(const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock, const std::function<bool(const std::vector<unsigned char>&)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled) const std::function<bool(EhSolverCancelCheck)> cancelled)
{ {
eh_index init_size { 1 << (CollisionBitLength + 1) }; eh_index init_size { 1U << (CollisionBitLength + 1) };
// 1) Generate first list // 1) Generate first list
LogPrint("pow", "Generating first list\n"); LogPrint("pow", "Generating first list\n");
@@ -368,16 +425,16 @@ bool Equihash<N,K>::BasicSolve(const eh_HashState& base_state,
X.reserve(init_size); X.reserve(init_size);
unsigned char tmpHash[HashOutput]; unsigned char tmpHash[HashOutput];
for (eh_index g = 0; X.size() < init_size; g++) { for (eh_index g = 0; X.size() < init_size; g++) {
GenerateHash(base_state, g, tmpHash, HashOutput); GenerateHash(base_state, g, tmpHash, HashOutput, N);
for (eh_index i = 0; i < IndicesPerHashOutput && X.size() < init_size; i++) { for (eh_index i = 0; i < IndicesPerHashOutput && X.size() < init_size; i++) {
X.emplace_back(tmpHash+(i*N/8), N/8, HashLength, X.emplace_back(tmpHash+(i*GetSizeInBytes(N)), GetSizeInBytes(N), HashLength,
CollisionBitLength, (g*IndicesPerHashOutput)+i); CollisionBitLength, static_cast<int>(g*IndicesPerHashOutput)+i);
} }
if (cancelled(ListGeneration)) throw solver_cancelled; if (cancelled(ListGeneration)) throw solver_cancelled;
} }
// 3) Repeat step 2 until 2n/(k+1) bits remain // 3) Repeat step 2 until 2n/(k+1) bits remain
for (int r = 1; r < K && X.size() > 0; r++) { for (unsigned int r = 1; r < K && X.size() > 0; r++) {
LogPrint("pow", "Round %d:\n", r); LogPrint("pow", "Round %d:\n", r);
// 2a) Sort the list // 2a) Sort the list
LogPrint("pow", "- Sorting list\n"); LogPrint("pow", "- Sorting list\n");
@@ -385,20 +442,20 @@ bool Equihash<N,K>::BasicSolve(const eh_HashState& base_state,
if (cancelled(ListSorting)) throw solver_cancelled; if (cancelled(ListSorting)) throw solver_cancelled;
LogPrint("pow", "- Finding collisions\n"); LogPrint("pow", "- Finding collisions\n");
int i = 0; size_t i = 0;
int posFree = 0; size_t posFree = 0;
std::vector<FullStepRow<FullWidth>> Xc; std::vector<FullStepRow<FullWidth>> Xc;
while (i < X.size() - 1) { while (i < X.size() - 1) {
// 2b) Find next set of unordered pairs with collisions on the next n/(k+1) bits // 2b) Find next set of unordered pairs with collisions on the next n/(k+1) bits
int j = 1; size_t j = 1;
while (i+j < X.size() && while (i+j < X.size() &&
HasCollision(X[i], X[i+j], CollisionByteLength)) { HasCollision(X[i], X[i+j], CollisionByteLength)) {
j++; j++;
} }
// 2c) Calculate tuples (X_i ^ X_j, (i, j)) // 2c) Calculate tuples (X_i ^ X_j, (i, j))
for (int l = 0; l < j - 1; l++) { for (size_t l = 0; l < j - 1; l++) {
for (int m = l + 1; m < j; m++) { for (size_t m = l + 1; m < j; m++) {
if (DistinctIndices(X[i+l], X[i+m], hashLen, lenIndices)) { if (DistinctIndices(X[i+l], X[i+m], hashLen, lenIndices)) {
Xc.emplace_back(X[i+l], X[i+m], hashLen, lenIndices, CollisionByteLength); Xc.emplace_back(X[i+l], X[i+m], hashLen, lenIndices, CollisionByteLength);
} }
@@ -442,16 +499,16 @@ bool Equihash<N,K>::BasicSolve(const eh_HashState& base_state,
std::sort(X.begin(), X.end(), CompareSR(hashLen)); std::sort(X.begin(), X.end(), CompareSR(hashLen));
if (cancelled(FinalSorting)) throw solver_cancelled; if (cancelled(FinalSorting)) throw solver_cancelled;
LogPrint("pow", "- Finding collisions\n"); LogPrint("pow", "- Finding collisions\n");
int i = 0; size_t i = 0;
while (i < X.size() - 1) { while (i < X.size() - 1) {
int j = 1; size_t j = 1;
while (i+j < X.size() && while (i+j < X.size() &&
HasCollision(X[i], X[i+j], hashLen)) { HasCollision(X[i], X[i+j], hashLen)) {
j++; j++;
} }
for (int l = 0; l < j - 1; l++) { for (size_t l = 0; l < j - 1; l++) {
for (int m = l + 1; m < j; m++) { for (size_t m = l + 1; m < j; m++) {
FullStepRow<FinalFullWidth> res(X[i+l], X[i+m], hashLen, lenIndices, 0); FullStepRow<FinalFullWidth> res(X[i+l], X[i+m], hashLen, lenIndices, 0);
if (DistinctIndices(X[i+l], X[i+m], hashLen, lenIndices)) { if (DistinctIndices(X[i+l], X[i+m], hashLen, lenIndices)) {
auto soln = res.GetIndices(hashLen, 2*lenIndices, CollisionBitLength); auto soln = res.GetIndices(hashLen, 2*lenIndices, CollisionBitLength);
@@ -475,20 +532,21 @@ bool Equihash<N,K>::BasicSolve(const eh_HashState& base_state,
template<size_t WIDTH> template<size_t WIDTH>
void CollideBranches(std::vector<FullStepRow<WIDTH>>& X, const size_t hlen, const size_t lenIndices, const unsigned int clen, const unsigned int ilen, const eh_trunc lt, const eh_trunc rt) void CollideBranches(std::vector<FullStepRow<WIDTH>>& X, const size_t hlen, const size_t lenIndices, const unsigned int clen, const unsigned int ilen, const eh_trunc lt, const eh_trunc rt)
{ {
int i = 0; size_t i = 0;
int posFree = 0; size_t posFree = 0;
assert(X.size() > 0);
std::vector<FullStepRow<WIDTH>> Xc; std::vector<FullStepRow<WIDTH>> Xc;
while (i < X.size() - 1) { while (i < X.size() - 1) {
// 2b) Find next set of unordered pairs with collisions on the next n/(k+1) bits // 2b) Find next set of unordered pairs with collisions on the next n/(k+1) bits
int j = 1; size_t j = 1;
while (i+j < X.size() && while (i+j < X.size() &&
HasCollision(X[i], X[i+j], clen)) { HasCollision(X[i], X[i+j], clen)) {
j++; j++;
} }
// 2c) Calculate tuples (X_i ^ X_j, (i, j)) // 2c) Calculate tuples (X_i ^ X_j, (i, j))
for (int l = 0; l < j - 1; l++) { for (size_t l = 0; l < j - 1; l++) {
for (int m = l + 1; m < j; m++) { for (size_t m = l + 1; m < j; m++) {
if (DistinctIndices(X[i+l], X[i+m], hlen, lenIndices)) { if (DistinctIndices(X[i+l], X[i+m], hlen, lenIndices)) {
if (IsValidBranch(X[i+l], hlen, ilen, lt) && IsValidBranch(X[i+m], hlen, ilen, rt)) { if (IsValidBranch(X[i+l], hlen, ilen, lt) && IsValidBranch(X[i+m], hlen, ilen, rt)) {
Xc.emplace_back(X[i+l], X[i+m], hlen, lenIndices, clen); Xc.emplace_back(X[i+l], X[i+m], hlen, lenIndices, clen);
@@ -526,10 +584,10 @@ void CollideBranches(std::vector<FullStepRow<WIDTH>>& X, const size_t hlen, cons
template<unsigned int N, unsigned int K> template<unsigned int N, unsigned int K>
bool Equihash<N,K>::OptimisedSolve(const eh_HashState& base_state, bool Equihash<N,K>::OptimisedSolve(const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock, const std::function<bool(const std::vector<unsigned char>&)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled) const std::function<bool(EhSolverCancelCheck)> cancelled)
{ {
eh_index init_size { 1 << (CollisionBitLength + 1) }; eh_index init_size { 1U << (CollisionBitLength + 1) };
eh_index recreate_size { UntruncateIndex(1, 0, CollisionBitLength + 1) }; eh_index recreate_size { UntruncateIndex(1, 0, CollisionBitLength + 1) };
// First run the algorithm with truncated indices // First run the algorithm with truncated indices
@@ -547,16 +605,16 @@ bool Equihash<N,K>::OptimisedSolve(const eh_HashState& base_state,
Xt.reserve(init_size); Xt.reserve(init_size);
unsigned char tmpHash[HashOutput]; unsigned char tmpHash[HashOutput];
for (eh_index g = 0; Xt.size() < init_size; g++) { for (eh_index g = 0; Xt.size() < init_size; g++) {
GenerateHash(base_state, g, tmpHash, HashOutput); GenerateHash(base_state, g, tmpHash, HashOutput, N);
for (eh_index i = 0; i < IndicesPerHashOutput && Xt.size() < init_size; i++) { for (eh_index i = 0; i < IndicesPerHashOutput && Xt.size() < init_size; i++) {
Xt.emplace_back(tmpHash+(i*N/8), N/8, HashLength, CollisionBitLength, Xt.emplace_back(tmpHash+(i*GetSizeInBytes(N)), GetSizeInBytes(N), HashLength, CollisionBitLength,
(g*IndicesPerHashOutput)+i, CollisionBitLength + 1); static_cast<eh_index>(g*IndicesPerHashOutput)+i, static_cast<unsigned int>(CollisionBitLength + 1));
} }
if (cancelled(ListGeneration)) throw solver_cancelled; if (cancelled(ListGeneration)) throw solver_cancelled;
} }
// 3) Repeat step 2 until 2n/(k+1) bits remain // 3) Repeat step 2 until 2n/(k+1) bits remain
for (int r = 1; r < K && Xt.size() > 0; r++) { for (unsigned int r = 1; r < K && Xt.size() > 0; r++) {
LogPrint("pow", "Round %d:\n", r); LogPrint("pow", "Round %d:\n", r);
// 2a) Sort the list // 2a) Sort the list
LogPrint("pow", "- Sorting list\n"); LogPrint("pow", "- Sorting list\n");
@@ -564,21 +622,21 @@ bool Equihash<N,K>::OptimisedSolve(const eh_HashState& base_state,
if (cancelled(ListSorting)) throw solver_cancelled; if (cancelled(ListSorting)) throw solver_cancelled;
LogPrint("pow", "- Finding collisions\n"); LogPrint("pow", "- Finding collisions\n");
int i = 0; size_t i = 0;
int posFree = 0; size_t posFree = 0;
std::vector<TruncatedStepRow<TruncatedWidth>> Xc; std::vector<TruncatedStepRow<TruncatedWidth>> Xc;
while (i < Xt.size() - 1) { while (i < Xt.size() - 1) {
// 2b) Find next set of unordered pairs with collisions on the next n/(k+1) bits // 2b) Find next set of unordered pairs with collisions on the next n/(k+1) bits
int j = 1; size_t j = 1;
while (i+j < Xt.size() && while (i+j < Xt.size() &&
HasCollision(Xt[i], Xt[i+j], CollisionByteLength)) { HasCollision(Xt[i], Xt[i+j], CollisionByteLength)) {
j++; j++;
} }
// 2c) Calculate tuples (X_i ^ X_j, (i, j)) // 2c) Calculate tuples (X_i ^ X_j, (i, j))
bool checking_for_zero = (i == 0 && Xt[0].IsZero(hashLen)); //bool checking_for_zero = (i == 0 && Xt[0].IsZero(hashLen));
for (int l = 0; l < j - 1; l++) { for (size_t l = 0; l < j - 1; l++) {
for (int m = l + 1; m < j; m++) { for (size_t m = l + 1; m < j; m++) {
// We truncated, so don't check for distinct indices here // We truncated, so don't check for distinct indices here
TruncatedStepRow<TruncatedWidth> Xi {Xt[i+l], Xt[i+m], TruncatedStepRow<TruncatedWidth> Xi {Xt[i+l], Xt[i+m],
hashLen, lenIndices, hashLen, lenIndices,
@@ -628,16 +686,16 @@ bool Equihash<N,K>::OptimisedSolve(const eh_HashState& base_state,
std::sort(Xt.begin(), Xt.end(), CompareSR(hashLen)); std::sort(Xt.begin(), Xt.end(), CompareSR(hashLen));
if (cancelled(FinalSorting)) throw solver_cancelled; if (cancelled(FinalSorting)) throw solver_cancelled;
LogPrint("pow", "- Finding collisions\n"); LogPrint("pow", "- Finding collisions\n");
int i = 0; size_t i = 0;
while (i < Xt.size() - 1) { while (i < Xt.size() - 1) {
int j = 1; size_t j = 1;
while (i+j < Xt.size() && while (i+j < Xt.size() &&
HasCollision(Xt[i], Xt[i+j], hashLen)) { HasCollision(Xt[i], Xt[i+j], hashLen)) {
j++; j++;
} }
for (int l = 0; l < j - 1; l++) { for (size_t l = 0; l < j - 1; l++) {
for (int m = l + 1; m < j; m++) { for (size_t m = l + 1; m < j; m++) {
TruncatedStepRow<FinalTruncatedWidth> res(Xt[i+l], Xt[i+m], TruncatedStepRow<FinalTruncatedWidth> res(Xt[i+l], Xt[i+m],
hashLen, lenIndices, 0); hashLen, lenIndices, 0);
auto soln = res.GetTruncatedIndices(hashLen, 2*lenIndices); auto soln = res.GetTruncatedIndices(hashLen, 2*lenIndices);
@@ -676,10 +734,10 @@ bool Equihash<N,K>::OptimisedSolve(const eh_HashState& base_state,
eh_index newIndex { UntruncateIndex(partialSoln.get()[i], j, CollisionBitLength + 1) }; eh_index newIndex { UntruncateIndex(partialSoln.get()[i], j, CollisionBitLength + 1) };
if (j == 0 || newIndex % IndicesPerHashOutput == 0) { if (j == 0 || newIndex % IndicesPerHashOutput == 0) {
GenerateHash(base_state, newIndex/IndicesPerHashOutput, GenerateHash(base_state, newIndex/IndicesPerHashOutput,
tmpHash, HashOutput); tmpHash, HashOutput, N);
} }
icv.emplace_back(tmpHash+((newIndex % IndicesPerHashOutput) * N/8), icv.emplace_back(tmpHash+((newIndex % IndicesPerHashOutput) * GetSizeInBytes(N)),
N/8, HashLength, CollisionBitLength, newIndex); GetSizeInBytes(N), HashLength, CollisionBitLength, newIndex);
if (cancelled(PartialGeneration)) throw solver_cancelled; if (cancelled(PartialGeneration)) throw solver_cancelled;
} }
boost::optional<std::vector<FullStepRow<FinalFullWidth>>> ic = icv; boost::optional<std::vector<FullStepRow<FinalFullWidth>>> ic = icv;
@@ -697,7 +755,7 @@ bool Equihash<N,K>::OptimisedSolve(const eh_HashState& base_state,
ic->insert(ic->end(), X[r]->begin(), X[r]->end()); ic->insert(ic->end(), X[r]->begin(), X[r]->end());
std::sort(ic->begin(), ic->end(), CompareSR(hashLen)); std::sort(ic->begin(), ic->end(), CompareSR(hashLen));
if (cancelled(PartialSorting)) throw solver_cancelled; if (cancelled(PartialSorting)) throw solver_cancelled;
size_t lti = rti-(1<<r); size_t lti = rti-(static_cast<size_t>(1)<<r);
CollideBranches(*ic, hashLen, lenIndices, CollideBranches(*ic, hashLen, lenIndices,
CollisionByteLength, CollisionByteLength,
CollisionBitLength + 1, CollisionBitLength + 1,
@@ -760,16 +818,16 @@ bool Equihash<N,K>::IsValidSolution(const eh_HashState& base_state, std::vector<
X.reserve(1 << K); X.reserve(1 << K);
unsigned char tmpHash[HashOutput]; unsigned char tmpHash[HashOutput];
for (eh_index i : GetIndicesFromMinimal(soln, CollisionBitLength)) { for (eh_index i : GetIndicesFromMinimal(soln, CollisionBitLength)) {
GenerateHash(base_state, i/IndicesPerHashOutput, tmpHash, HashOutput); GenerateHash(base_state, i/IndicesPerHashOutput, tmpHash, HashOutput, N);
X.emplace_back(tmpHash+((i % IndicesPerHashOutput) * N/8), X.emplace_back(tmpHash+((i % IndicesPerHashOutput) * GetSizeInBytes(N)),
N/8, HashLength, CollisionBitLength, i); GetSizeInBytes(N), HashLength, CollisionBitLength, i);
} }
size_t hashLen = HashLength; size_t hashLen = HashLength;
size_t lenIndices = sizeof(eh_index); size_t lenIndices = sizeof(eh_index);
while (X.size() > 1) { while (X.size() > 1) {
std::vector<FullStepRow<FinalFullWidth>> Xc; std::vector<FullStepRow<FinalFullWidth>> Xc;
for (int i = 0; i < X.size(); i += 2) { for (size_t i = 0; i < X.size(); i += 2) {
if (!HasCollision(X[i], X[i+1], CollisionByteLength)) { if (!HasCollision(X[i], X[i+1], CollisionByteLength)) {
LogPrint("pow", "Invalid solution: invalid collision length between StepRows\n"); LogPrint("pow", "Invalid solution: invalid collision length between StepRows\n");
LogPrint("pow", "X[i] = %s\n", X[i].GetHex(hashLen)); LogPrint("pow", "X[i] = %s\n", X[i].GetHex(hashLen));
@@ -795,50 +853,74 @@ bool Equihash<N,K>::IsValidSolution(const eh_HashState& base_state, std::vector<
return X[0].IsZero(hashLen); return X[0].IsZero(hashLen);
} }
// Explicit instantiations for Equihash<96,3>
template int Equihash<96,3>::InitialiseState(eh_HashState& base_state);
#ifdef ENABLE_MINING
template bool Equihash<96,3>::BasicSolve(const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled);
template bool Equihash<96,3>::OptimisedSolve(const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled);
#endif
template bool Equihash<96,3>::IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln);
// Explicit instantiations for Equihash<200,9> // Explicit instantiations for Equihash<200,9>
template int Equihash<200,9>::InitialiseState(eh_HashState& base_state); template int Equihash<200,9>::InitialiseState(eh_HashState& base_state);
#ifdef ENABLE_MINING #ifdef ENABLE_MINING
template bool Equihash<200,9>::BasicSolve(const eh_HashState& base_state, template bool Equihash<200,9>::BasicSolve(const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock, const std::function<bool(const std::vector<unsigned char>&)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled); const std::function<bool(EhSolverCancelCheck)> cancelled);
template bool Equihash<200,9>::OptimisedSolve(const eh_HashState& base_state, template bool Equihash<200,9>::OptimisedSolve(const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock, const std::function<bool(const std::vector<unsigned char>&)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled); const std::function<bool(EhSolverCancelCheck)> cancelled);
#endif #endif
template bool Equihash<200,9>::IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln); template bool Equihash<200,9>::IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln);
// Explicit instantiations for Equihash<96,5> // Explicit instantiations for Equihash<96,3>
template int Equihash<96,5>::InitialiseState(eh_HashState& base_state); template int Equihash<150,5>::InitialiseState(eh_HashState& base_state);
#ifdef ENABLE_MINING #ifdef ENABLE_MINING
template bool Equihash<96,5>::BasicSolve(const eh_HashState& base_state, template bool Equihash<150,5>::BasicSolve(const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock, const std::function<bool(const std::vector<unsigned char>&)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled); const std::function<bool(EhSolverCancelCheck)> cancelled);
template bool Equihash<96,5>::OptimisedSolve(const eh_HashState& base_state, template bool Equihash<150,5>::OptimisedSolve(const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock, const std::function<bool(const std::vector<unsigned char>&)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled); const std::function<bool(EhSolverCancelCheck)> cancelled);
#endif #endif
template bool Equihash<96,5>::IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln); template bool Equihash<150,5>::IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln);
// Explicit instantiations for Equihash<48,5> // Explicit instantiations for Equihash<48,5>
template int Equihash<144,5>::InitialiseState(eh_HashState& base_state);
#ifdef ENABLE_MINING
template bool Equihash<144,5>::BasicSolve(const eh_HashState& base_state,
const std::function<bool(const std::vector<unsigned char>&)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled);
template bool Equihash<144,5>::OptimisedSolve(const eh_HashState& base_state,
const std::function<bool(const std::vector<unsigned char>&)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled);
#endif
template bool Equihash<144,5>::IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln);
// Explicit instantiations for Equihash<96,5>
template int Equihash<ASSETCHAINS_N,ASSETCHAINS_K>::InitialiseState(eh_HashState& base_state);
#ifdef ENABLE_MINING
template bool Equihash<ASSETCHAINS_N,ASSETCHAINS_K>::BasicSolve(const eh_HashState& base_state,
const std::function<bool(const std::vector<unsigned char>&)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled);
template bool Equihash<ASSETCHAINS_N,ASSETCHAINS_K>::OptimisedSolve(const eh_HashState& base_state,
const std::function<bool(const std::vector<unsigned char>&)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled);
#endif
template bool Equihash<ASSETCHAINS_N,ASSETCHAINS_K>::IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln);
// Explicit instantiations for Equihash<96,5>
template int Equihash<48,5>::InitialiseState(eh_HashState& base_state); template int Equihash<48,5>::InitialiseState(eh_HashState& base_state);
#ifdef ENABLE_MINING #ifdef ENABLE_MINING
template bool Equihash<48,5>::BasicSolve(const eh_HashState& base_state, template bool Equihash<48,5>::BasicSolve(const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock, const std::function<bool(const std::vector<unsigned char>&)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled); const std::function<bool(EhSolverCancelCheck)> cancelled);
template bool Equihash<48,5>::OptimisedSolve(const eh_HashState& base_state, template bool Equihash<48,5>::OptimisedSolve(const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock, const std::function<bool(const std::vector<unsigned char>&)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled); const std::function<bool(EhSolverCancelCheck)> cancelled);
#endif #endif
template bool Equihash<48,5>::IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln); template bool Equihash<48,5>::IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln);
// Explicit instantiations for Equihash<48,5>
template int Equihash<210,9>::InitialiseState(eh_HashState& base_state);
#ifdef ENABLE_MINING
template bool Equihash<210,9>::BasicSolve(const eh_HashState& base_state,
const std::function<bool(const std::vector<unsigned char>&)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled);
template bool Equihash<210,9>::OptimisedSolve(const eh_HashState& base_state,
const std::function<bool(const std::vector<unsigned char>&)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled);
#endif
template bool Equihash<210,9>::IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln);

View File

@@ -10,6 +10,7 @@
#include "utilstrencodings.h" #include "utilstrencodings.h"
#include "sodium.h" #include "sodium.h"
#include "komodo_nk.h"
#include <cstring> #include <cstring>
#include <exception> #include <exception>
@@ -24,6 +25,9 @@ typedef crypto_generichash_blake2b_state eh_HashState;
typedef uint32_t eh_index; typedef uint32_t eh_index;
typedef uint8_t eh_trunc; typedef uint8_t eh_trunc;
#define BLAKE2B_OUTBYTES 64
extern uint64_t ASSETCHAINS_NK[2];
void ExpandArray(const unsigned char* in, size_t in_len, void ExpandArray(const unsigned char* in, size_t in_len,
unsigned char* out, size_t out_len, unsigned char* out, size_t out_len,
size_t bit_len, size_t byte_pad=0); size_t bit_len, size_t byte_pad=0);
@@ -61,7 +65,7 @@ public:
std::string GetHex(size_t len) { return HexStr(hash, hash+len); } std::string GetHex(size_t len) { return HexStr(hash, hash+len); }
template<size_t W> template<size_t W>
friend bool HasCollision(StepRow<W>& a, StepRow<W>& b, int l); friend bool HasCollision(StepRow<W>& a, StepRow<W>& b, size_t l);
}; };
class CompareSR class CompareSR
@@ -77,7 +81,7 @@ public:
}; };
template<size_t WIDTH> template<size_t WIDTH>
bool HasCollision(StepRow<WIDTH>& a, StepRow<WIDTH>& b, int l); bool HasCollision(StepRow<WIDTH>& a, StepRow<WIDTH>& b, size_t l);
template<size_t WIDTH> template<size_t WIDTH>
class FullStepRow : public StepRow<WIDTH> class FullStepRow : public StepRow<WIDTH>
@@ -94,7 +98,7 @@ public:
FullStepRow(const FullStepRow<WIDTH>& a) : StepRow<WIDTH> {a} { } FullStepRow(const FullStepRow<WIDTH>& a) : StepRow<WIDTH> {a} { }
template<size_t W> template<size_t W>
FullStepRow(const FullStepRow<W>& a, const FullStepRow<W>& b, size_t len, size_t lenIndices, int trim); FullStepRow(const FullStepRow<W>& a, const FullStepRow<W>& b, size_t len, size_t lenIndices, size_t trim);
FullStepRow& operator=(const FullStepRow<WIDTH>& a); FullStepRow& operator=(const FullStepRow<WIDTH>& a);
inline bool IndicesBefore(const FullStepRow<WIDTH>& a, size_t len, size_t lenIndices) const { return memcmp(hash+len, a.hash+len, lenIndices) < 0; } inline bool IndicesBefore(const FullStepRow<WIDTH>& a, size_t len, size_t lenIndices) const { return memcmp(hash+len, a.hash+len, lenIndices) < 0; }
@@ -159,17 +163,22 @@ inline constexpr size_t equihash_solution_size(unsigned int N, unsigned int K) {
return (1 << K)*(N/(K+1)+1)/8; return (1 << K)*(N/(K+1)+1)/8;
} }
constexpr uint8_t GetSizeInBytes(size_t N)
{
return static_cast<uint8_t>((N + 7) / 8);
}
template<unsigned int N, unsigned int K> template<unsigned int N, unsigned int K>
class Equihash class Equihash
{ {
private: private:
BOOST_STATIC_ASSERT(K < N); BOOST_STATIC_ASSERT(K < N);
BOOST_STATIC_ASSERT(N % 8 == 0); //BOOST_STATIC_ASSERT(N % 8 == 0);
BOOST_STATIC_ASSERT((N/(K+1)) + 1 < 8*sizeof(eh_index)); BOOST_STATIC_ASSERT((N/(K+1)) + 1 < 8*sizeof(eh_index));
public: public:
enum : size_t { IndicesPerHashOutput=512/N }; enum : size_t { IndicesPerHashOutput=512/N };
enum : size_t { HashOutput=IndicesPerHashOutput*N/8 }; enum : size_t { HashOutput = IndicesPerHashOutput * GetSizeInBytes(N) };
enum : size_t { CollisionBitLength=N/(K+1) }; enum : size_t { CollisionBitLength=N/(K+1) };
enum : size_t { CollisionByteLength=(CollisionBitLength+7)/8 }; enum : size_t { CollisionByteLength=(CollisionBitLength+7)/8 };
enum : size_t { HashLength=(K+1)*CollisionByteLength }; enum : size_t { HashLength=(K+1)*CollisionByteLength };
@@ -184,79 +193,100 @@ public:
int InitialiseState(eh_HashState& base_state); int InitialiseState(eh_HashState& base_state);
#ifdef ENABLE_MINING #ifdef ENABLE_MINING
bool BasicSolve(const eh_HashState& base_state, bool BasicSolve(const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock, const std::function<bool(const std::vector<unsigned char>&)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled); const std::function<bool(EhSolverCancelCheck)> cancelled);
bool OptimisedSolve(const eh_HashState& base_state, bool OptimisedSolve(const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock, const std::function<bool(const std::vector<unsigned char>&)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled); const std::function<bool(EhSolverCancelCheck)> cancelled);
#endif #endif
bool IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln); bool IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln);
}; };
#include "equihash.tcc" #include "equihash.tcc"
/*
* Equihash 200,9 (KMD/Zcash)
* Equihash 150,5 (beam)
* Equihash 144,5 (SnowGem)
* Equihash 96,5 (Minex)
* Equihash 48,5 (regtest)
* Equihash 210,9 (Aion) */
static Equihash<96,3> Eh96_3;
static Equihash<200,9> Eh200_9; static Equihash<200,9> Eh200_9;
static Equihash<96,5> Eh96_5; static Equihash<150,5> Eh150_5;
static Equihash<144,5> Eh144_5;
static Equihash<ASSETCHAINS_N,ASSETCHAINS_K> Eh96_5;
static Equihash<48,5> Eh48_5; static Equihash<48,5> Eh48_5;
static Equihash<210,9> Eh210_9;
#define EhInitialiseState(n, k, base_state) \ #define EhInitialiseState(n, k, base_state) \
if (n == 96 && k == 3) { \ if (n == 200 && k == 9) { \
Eh96_3.InitialiseState(base_state); \ Eh200_9.InitialiseState(base_state); \
} else if (n == 200 && k == 9) { \ } else if (n == 150 && k == 5) { \
Eh200_9.InitialiseState(base_state); \ Eh150_5.InitialiseState(base_state); \
} else if (n == 96 && k == 5) { \ } else if (n == 144 && k == 5) { \
Eh144_5.InitialiseState(base_state); \
} else if (n == ASSETCHAINS_N && k == ASSETCHAINS_K) { \
Eh96_5.InitialiseState(base_state); \ Eh96_5.InitialiseState(base_state); \
} else if (n == 48 && k == 5) { \ } else if (n == 48 && k == 5) { \
Eh48_5.InitialiseState(base_state); \ Eh48_5.InitialiseState(base_state); \
} else if (n == 210 && k == 9) { \
Eh210_9.InitialiseState(base_state); \
} else { \ } else { \
throw std::invalid_argument("Unsupported Equihash parameters"); \ throw std::invalid_argument("Unsupported Equihash parameters"); \
} }
#ifdef ENABLE_MINING #ifdef ENABLE_MINING
inline bool EhBasicSolve(unsigned int n, unsigned int k, const eh_HashState& base_state, inline bool EhBasicSolve(unsigned int n, unsigned int k, const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock, const std::function<bool(const std::vector<unsigned char>&)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled) const std::function<bool(EhSolverCancelCheck)> cancelled)
{ {
if (n == 96 && k == 3) { if (n == 200 && k == 9) {
return Eh96_3.BasicSolve(base_state, validBlock, cancelled);
} else if (n == 200 && k == 9) {
return Eh200_9.BasicSolve(base_state, validBlock, cancelled); return Eh200_9.BasicSolve(base_state, validBlock, cancelled);
} else if (n == 96 && k == 5) { } else if (n == 150 && k == 5) {
return Eh150_5.BasicSolve(base_state, validBlock, cancelled);
} else if (n == 144 && k == 5) {
return Eh144_5.BasicSolve(base_state, validBlock, cancelled);
} else if (n == ASSETCHAINS_N && k == ASSETCHAINS_K) {
return Eh96_5.BasicSolve(base_state, validBlock, cancelled); return Eh96_5.BasicSolve(base_state, validBlock, cancelled);
} else if (n == 48 && k == 5) { } else if (n == 48 && k == 5) {
return Eh48_5.BasicSolve(base_state, validBlock, cancelled); return Eh48_5.BasicSolve(base_state, validBlock, cancelled);
} else if (n == 210 && k == 9) {
return Eh210_9.BasicSolve(base_state, validBlock, cancelled);
} else { } else {
throw std::invalid_argument("Unsupported Equihash parameters"); throw std::invalid_argument("Unsupported Equihash parameters");
} }
} }
inline bool EhBasicSolveUncancellable(unsigned int n, unsigned int k, const eh_HashState& base_state, inline bool EhBasicSolveUncancellable(unsigned int n, unsigned int k, const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock) const std::function<bool(const std::vector<unsigned char>&)> validBlock)
{ {
return EhBasicSolve(n, k, base_state, validBlock, return EhBasicSolve(n, k, base_state, validBlock,
[](EhSolverCancelCheck pos) { return false; }); [](EhSolverCancelCheck pos) { return false; });
} }
inline bool EhOptimisedSolve(unsigned int n, unsigned int k, const eh_HashState& base_state, inline bool EhOptimisedSolve(unsigned int n, unsigned int k, const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock, const std::function<bool(const std::vector<unsigned char>&)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled) const std::function<bool(EhSolverCancelCheck)> cancelled)
{ {
if (n == 96 && k == 3) { if (n == 200 && k == 9) {
return Eh96_3.OptimisedSolve(base_state, validBlock, cancelled);
} else if (n == 200 && k == 9) {
return Eh200_9.OptimisedSolve(base_state, validBlock, cancelled); return Eh200_9.OptimisedSolve(base_state, validBlock, cancelled);
} else if (n == 96 && k == 5) { } else if (n == 150 && k == 5) {
return Eh150_5.OptimisedSolve(base_state, validBlock, cancelled);
} else if (n == 144 && k == 5) {
return Eh144_5.OptimisedSolve(base_state, validBlock, cancelled);
} else if (n == ASSETCHAINS_N && k == ASSETCHAINS_K) {
return Eh96_5.OptimisedSolve(base_state, validBlock, cancelled); return Eh96_5.OptimisedSolve(base_state, validBlock, cancelled);
} else if (n == 48 && k == 5) { } else if (n == 48 && k == 5) {
return Eh48_5.OptimisedSolve(base_state, validBlock, cancelled); return Eh48_5.OptimisedSolve(base_state, validBlock, cancelled);
} else if (n == 210 && k == 9) {
return Eh210_9.OptimisedSolve(base_state, validBlock, cancelled);
} else { } else {
throw std::invalid_argument("Unsupported Equihash parameters"); throw std::invalid_argument("Unsupported Equihash parameters");
} }
} }
inline bool EhOptimisedSolveUncancellable(unsigned int n, unsigned int k, const eh_HashState& base_state, inline bool EhOptimisedSolveUncancellable(unsigned int n, unsigned int k, const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock) const std::function<bool(const std::vector<unsigned char>&)> validBlock)
{ {
return EhOptimisedSolve(n, k, base_state, validBlock, return EhOptimisedSolve(n, k, base_state, validBlock,
[](EhSolverCancelCheck pos) { return false; }); [](EhSolverCancelCheck pos) { return false; });
@@ -264,14 +294,18 @@ inline bool EhOptimisedSolveUncancellable(unsigned int n, unsigned int k, const
#endif // ENABLE_MINING #endif // ENABLE_MINING
#define EhIsValidSolution(n, k, base_state, soln, ret) \ #define EhIsValidSolution(n, k, base_state, soln, ret) \
if (n == 96 && k == 3) { \ if (n == 200 && k == 9) { \
ret = Eh96_3.IsValidSolution(base_state, soln); \ ret = Eh200_9.IsValidSolution(base_state, soln); \
} else if (n == 200 && k == 9) { \ } else if (n == 150 && k == 5) { \
ret = Eh200_9.IsValidSolution(base_state, soln); \ ret = Eh150_5.IsValidSolution(base_state, soln); \
} else if (n == 96 && k == 5) { \ } else if (n == 144 && k == 5) { \
ret = Eh144_5.IsValidSolution(base_state, soln); \
} else if (n == ASSETCHAINS_N && k == ASSETCHAINS_K) { \
ret = Eh96_5.IsValidSolution(base_state, soln); \ ret = Eh96_5.IsValidSolution(base_state, soln); \
} else if (n == 48 && k == 5) { \ } else if (n == 48 && k == 5) { \
ret = Eh48_5.IsValidSolution(base_state, soln); \ ret = Eh48_5.IsValidSolution(base_state, soln); \
} else if (n == 210 && k == 9) { \
ret = Eh210_9.IsValidSolution(base_state, soln); \
} else { \ } else { \
throw std::invalid_argument("Unsupported Equihash parameters"); \ throw std::invalid_argument("Unsupported Equihash parameters"); \
} }

View File

@@ -15,6 +15,7 @@
#ifndef KOMODO_DEFS_H #ifndef KOMODO_DEFS_H
#define KOMODO_DEFS_H #define KOMODO_DEFS_H
#include "komodo_nk.h"
#define ASSETCHAINS_MINHEIGHT 128 #define ASSETCHAINS_MINHEIGHT 128
#define ASSETCHAINS_MAX_ERAS 3 #define ASSETCHAINS_MAX_ERAS 3
@@ -53,7 +54,7 @@ extern uint32_t ASSETCHAINS_ALGO, ASSETCHAINS_VERUSHASH,ASSETCHAINS_EQUIHASH,KOM
extern int32_t KOMODO_MININGTHREADS,KOMODO_LONGESTCHAIN,ASSETCHAINS_SEED,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,KOMODO_ON_DEMAND,KOMODO_PASSPORT_INITDONE,ASSETCHAINS_STAKED; extern int32_t KOMODO_MININGTHREADS,KOMODO_LONGESTCHAIN,ASSETCHAINS_SEED,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,KOMODO_ON_DEMAND,KOMODO_PASSPORT_INITDONE,ASSETCHAINS_STAKED;
extern uint64_t ASSETCHAINS_COMMISSION, ASSETCHAINS_LASTERA,ASSETCHAINS_CBOPRET; extern uint64_t ASSETCHAINS_COMMISSION, ASSETCHAINS_LASTERA,ASSETCHAINS_CBOPRET;
extern bool VERUS_MINTBLOCKS; extern bool VERUS_MINTBLOCKS;
extern uint64_t ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_NOTARY_PAY[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_TIMELOCKGTE, ASSETCHAINS_NONCEMASK[]; extern uint64_t ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_NOTARY_PAY[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_TIMELOCKGTE, ASSETCHAINS_NONCEMASK[],ASSETCHAINS_NK[2];
extern const char *ASSETCHAINS_ALGORITHMS[]; extern const char *ASSETCHAINS_ALGORITHMS[];
extern int32_t VERUS_MIN_STAKEAGE; extern int32_t VERUS_MIN_STAKEAGE;
extern uint32_t ASSETCHAINS_VERUSHASH, ASSETCHAINS_VERUSHASHV1_1, ASSETCHAINS_NONCESHIFT[], ASSETCHAINS_HASHESPERROUND[]; extern uint32_t ASSETCHAINS_VERUSHASH, ASSETCHAINS_VERUSHASHV1_1, ASSETCHAINS_NONCESHIFT[], ASSETCHAINS_HASHESPERROUND[];

7
src/komodo_nk.h Normal file
View File

@@ -0,0 +1,7 @@
#ifndef KOMODO_NK_H
#define KOMODO_NK_H
#define ASSETCHAINS_N 96
#define ASSETCHAINS_K 5
#endif

View File

@@ -1667,6 +1667,28 @@ extern int64_t MAX_MONEY;
void komodo_cbopretupdate(int32_t forceflag); void komodo_cbopretupdate(int32_t forceflag);
void SplitStr(const std::string& strVal, std::vector<std::string> &outVals); void SplitStr(const std::string& strVal, std::vector<std::string> &outVals);
int8_t equihash_params_possible(uint64_t n, uint64_t k)
{
/* To add more of these you also need to edit:
* equihash.cpp very end of file with the tempate to point to the new param numbers
* equihash.h
* line 210/217 (declaration of equihash class)
* Add this object to the following functions:
* EhInitialiseState
* EhBasicSolve
* EhOptimisedSolve
* EhIsValidSolution
* Alternatively change ASSETCHAINS_N and ASSETCHAINS_K in komodo_nk.h for fast testing.
*/
if ( k == 9 && (n == 200 || n == 210) )
return(0);
if ( k == 5 && (n == 150 || n == 144 || n == 96 || n == 48) )
return(0);
if ( k == ASSETCHAINS_K && n == ASSETCHAINS_N)
return(0);
return(-1);
}
void komodo_args(char *argv0) void komodo_args(char *argv0)
{ {
extern const char *Notaries_elected1[][2]; extern const char *Notaries_elected1[][2];
@@ -1729,6 +1751,7 @@ void komodo_args(char *argv0)
ASSETCHAINS_BLOCKTIME = GetArg("-ac_blocktime",60); ASSETCHAINS_BLOCKTIME = GetArg("-ac_blocktime",60);
ASSETCHAINS_PUBLIC = GetArg("-ac_public",0); ASSETCHAINS_PUBLIC = GetArg("-ac_public",0);
ASSETCHAINS_PRIVATE = GetArg("-ac_private",0); ASSETCHAINS_PRIVATE = GetArg("-ac_private",0);
Split(GetArg("-ac_nk",""), ASSETCHAINS_NK, 0);
if ( (KOMODO_REWIND= GetArg("-rewind",0)) != 0 ) if ( (KOMODO_REWIND= GetArg("-rewind",0)) != 0 )
{ {
printf("KOMODO_REWIND %d\n",KOMODO_REWIND); printf("KOMODO_REWIND %d\n",KOMODO_REWIND);
@@ -1749,6 +1772,14 @@ void komodo_args(char *argv0)
break; break;
} }
} }
if ( ASSETCHAINS_ALGO == ASSETCHAINS_EQUIHASH && ASSETCHAINS_NK[0] != 0 && ASSETCHAINS_NK[1] != 0 )
{
if ( equihash_params_possible(ASSETCHAINS_NK[0], ASSETCHAINS_NK[1]) == -1 )
{
printf("equihash values N.%li and K.%li are not currently available\n", ASSETCHAINS_NK[0], ASSETCHAINS_NK[1]);
exit(0);
} else printf("ASSETCHAINS_ALGO, algorithm set to equihash with N.%li and K.%li\n", ASSETCHAINS_NK[0], ASSETCHAINS_NK[1]);
}
if (i == ASSETCHAINS_NUMALGOS) if (i == ASSETCHAINS_NUMALGOS)
{ {
printf("ASSETCHAINS_ALGO, %s not supported. using equihash\n", selectedAlgo.c_str()); printf("ASSETCHAINS_ALGO, %s not supported. using equihash\n", selectedAlgo.c_str());
@@ -1974,7 +2005,7 @@ void komodo_args(char *argv0)
fprintf(stderr,"-ac_script and -ac_marmara are mutually exclusive\n"); fprintf(stderr,"-ac_script and -ac_marmara are mutually exclusive\n");
StartShutdown(); 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 ) 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) )
{ {
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()); 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; extraptr = extrabuf;
@@ -2104,6 +2135,11 @@ void komodo_args(char *argv0)
komodo_cbopretupdate(1); // will set Mineropret komodo_cbopretupdate(1); // will set Mineropret
fprintf(stderr,"This blockchain uses data produced from CoinDesk Bitcoin Price Index\n"); fprintf(stderr,"This blockchain uses data produced from CoinDesk Bitcoin Price Index\n");
} }
if ( ASSETCHAINS_NK[0] != 0 && ASSETCHAINS_NK[1] != 0 )
{
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]);
}
} }
addn = GetArg("-seednode",""); addn = GetArg("-seednode","");

View File

@@ -796,7 +796,7 @@ bool IsStandardTx(const CTransaction& tx, string& reason, const int nHeight)
else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) { else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) {
reason = "bare-multisig"; reason = "bare-multisig";
return false; return false;
} else if (txout.scriptPubKey.IsPayToCryptoCondition() == 0 && txout.IsDust(::minRelayTxFee)) { } else if (whichType != TX_CRYPTOCONDITION && txout.IsDust(::minRelayTxFee)) {
reason = "dust"; reason = "dust";
return false; return false;
} }

View File

@@ -1608,9 +1608,10 @@ void static BitcoinMiner()
if ( notaryid != My_notaryid ) if ( notaryid != My_notaryid )
My_notaryid = notaryid; My_notaryid = notaryid;
std::string solver; std::string solver;
//if ( notaryid >= 0 || ASSETCHAINS_SYMBOL[0] != 0 ) if ( ASSETCHAINS_NK[0] == 0 && ASSETCHAINS_NK[1] == 0 )
solver = "tromp"; solver = "tromp";
//else solver = "default"; else
solver = "default";
assert(solver == "tromp" || solver == "default"); assert(solver == "tromp" || solver == "default");
LogPrint("pow", "Using Equihash solver \"%s\" with n = %u, k = %u\n", solver, n, k); LogPrint("pow", "Using Equihash solver \"%s\" with n = %u, k = %u\n", solver, n, k);
if ( ASSETCHAINS_SYMBOL[0] != 0 ) if ( ASSETCHAINS_SYMBOL[0] != 0 )
@@ -1951,11 +1952,11 @@ void static BitcoinMiner()
ehSolverRuns.increment(); ehSolverRuns.increment();
if (found) { if (found) {
int32_t i; uint256 hash = pblock->GetHash(); int32_t i; uint256 hash = pblock->GetHash();
for (i=0; i<32; i++) //for (i=0; i<32; i++)
fprintf(stderr,"%02x",((uint8_t *)&hash)[i]); // fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
fprintf(stderr," <- %s Block found %d\n",ASSETCHAINS_SYMBOL,Mining_height); //fprintf(stderr," <- %s Block found %d\n",ASSETCHAINS_SYMBOL,Mining_height);
FOUND_BLOCK = 1; //FOUND_BLOCK = 1;
KOMODO_MAYBEMINED = Mining_height; //KOMODO_MAYBEMINED = Mining_height;
break; break;
} }
} catch (EhSolverCancelledException&) { } catch (EhSolverCancelledException&) {
@@ -1968,12 +1969,12 @@ void static BitcoinMiner()
// Check for stop or if block needs to be rebuilt // Check for stop or if block needs to be rebuilt
boost::this_thread::interruption_point(); boost::this_thread::interruption_point();
// Regtest mode doesn't require peers // Regtest mode doesn't require peers
if ( FOUND_BLOCK != 0 ) /*if ( FOUND_BLOCK != 0 )
{ {
FOUND_BLOCK = 0; FOUND_BLOCK = 0;
fprintf(stderr,"FOUND_BLOCK!\n"); fprintf(stderr,"FOUND_BLOCK!\n");
//sleep(2000); //sleep(2000);
} } */
if (vNodes.empty() && chainparams.MiningRequiresPeers()) if (vNodes.empty() && chainparams.MiningRequiresPeers())
{ {
if ( ASSETCHAINS_SYMBOL[0] == 0 || Mining_height > ASSETCHAINS_MINHEIGHT ) if ( ASSETCHAINS_SYMBOL[0] == 0 || Mining_height > ASSETCHAINS_MINHEIGHT )

View File

@@ -344,6 +344,9 @@ bool CheckEquihashSolution(const CBlockHeader *pblock, const CChainParams& param
{ {
if (ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH) if (ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH)
return true; return true;
if ( ASSETCHAINS_NK[0] != 0 && ASSETCHAINS_NK[1] != 0 && pblock->GetHash().ToString() == "027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71" )
return true;
unsigned int n = params.EquihashN(); unsigned int n = params.EquihashN();
unsigned int k = params.EquihashK(); unsigned int k = params.EquihashK();