diff --git a/src/Makefile.am b/src/Makefile.am index 8b10c06e0..7a9f660e6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -272,6 +272,7 @@ libbitcoin_server_a_SOURCES = \ chain.cpp \ checkpoints.cpp \ crosschain.cpp \ + crosschain_authority.cpp \ deprecation.cpp \ httprpc.cpp \ httpserver.cpp \ diff --git a/src/cc/eval.cpp b/src/cc/eval.cpp index b6fcf57dd..cb9774a7a 100644 --- a/src/cc/eval.cpp +++ b/src/cc/eval.cpp @@ -140,45 +140,17 @@ int32_t Eval::GetNotaries(uint8_t pubkeys[64][33], int32_t height, uint32_t time return komodo_notaries(pubkeys, height, timestamp); } - bool Eval::CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t timestamp) const { if (tx.vin.size() < 11) return false; - uint8_t seenNotaries[64] = {0}; - uint8_t notaries[64][33]; - int nNotaries = GetNotaries(notaries, height, timestamp); + CrosschainAuthority auth; + auth.requiredSigs = 11; + auth.size = GetNotaries(auth.notaries, height, timestamp); - BOOST_FOREACH(const CTxIn &txIn, tx.vin) - { - // Get notary pubkey - CTransaction tx; - uint256 hashBlock; - if (!GetTxUnconfirmed(txIn.prevout.hash, tx, hashBlock)) return false; - if (tx.vout.size() < txIn.prevout.n) return false; - CScript spk = tx.vout[txIn.prevout.n].scriptPubKey; - if (spk.size() != 35) return false; - const unsigned char *pk = spk.data(); - if (pk++[0] != 33) return false; - if (pk[33] != OP_CHECKSIG) return false; - - // Check it's a notary - for (int i=0; i kmdHeight) break; @@ -74,7 +74,7 @@ uint256 CalculateProofRoot(const char* symbol, uint32_t targetCCid, int kmdHeigh if (seenOwnNotarisations == 1) { BOOST_FOREACH(Notarisation& nota, notarisations) { - if (IsTXSCL(nota.second.symbol) == txscl) + if (GetSymbolAuthority(nota.second.symbol) == authority) if (nota.second.ccId == targetCCid) moms.push_back(nota.second.MoM); } diff --git a/src/crosschain.h b/src/crosschain.h index 15452ac63..65be53f92 100644 --- a/src/crosschain.h +++ b/src/crosschain.h @@ -3,6 +3,20 @@ #include "cc/eval.h" +const int CROSSCHAIN_KOMODO = 1; +const int CROSSCHAIN_TXSCL = 2; +const int CROSSCHAIN_STAKED = 3; + +typedef struct CrosschainAuthority { + uint8_t notaries[64][33]; + size_t size; + size_t requiredSigs; +} CrosschainAuthority; + +extern const CrosschainAuthority auth_STAKED; + +int GetSymbolAuthority(const char* symbol); +bool CheckTxAuthority(const CTransaction &tx, CrosschainAuthority auth); /* On assetchain */ TxProof GetAssetchainProof(uint256 hash); diff --git a/src/crosschain_authority.cpp b/src/crosschain_authority.cpp new file mode 100644 index 000000000..5ea277387 --- /dev/null +++ b/src/crosschain_authority.cpp @@ -0,0 +1,72 @@ +#include "cc/eval.h" +#include "crosschain.h" +#include "notarisationdb.h" + + +int GetSymbolAuthority(const char* symbol) +{ + if (strlen(symbol) >= 5 && strncmp(symbol, "TXSCL", 5) == 0) + return CROSSCHAIN_TXSCL; + if (strlen(symbol) >= 6 && strncmp(symbol, "STAKED", 6) == 0) + return CROSSCHAIN_STAKED; + return CROSSCHAIN_KOMODO; +} + + +bool CheckTxAuthority(const CTransaction &tx, CrosschainAuthority auth) +{ + EvalRef eval; + + if (tx.vin.size() < auth.requiredSigs) return false; + + uint8_t seesize[64]; + + BOOST_FOREACH(const CTxIn &txIn, tx.vin) + { + // Get notary pubkey + CTransaction tx; + uint256 hashBlock; + if (!eval->GetTxUnconfirmed(txIn.prevout.hash, tx, hashBlock)) return false; + if (tx.vout.size() < txIn.prevout.n) return false; + CScript spk = tx.vout[txIn.prevout.n].scriptPubKey; + if (spk.size() != 35) return false; + const unsigned char *pk = spk.data(); + if (pk++[0] != 33) return false; + if (pk[33] != OP_CHECKSIG) return false; + + // Check it's a notary + for (int i=0; i @@ -21,36 +22,31 @@ NotarisationsInBlock ScanBlockNotarisations(const CBlock &block, int nHeight) for (unsigned int i = 0; i < block.vtx.size(); i++) { CTransaction tx = block.vtx[i]; - // Special case for TXSCL. Should prob be removed at some point. - bool isTxscl = 0; - { - NotarisationData data; - if (ParseNotarisationOpReturn(tx, data)) - if (IsTXSCL(data.symbol)) - isTxscl = 1; + NotarisationData data; + bool parsed = ParseNotarisationOpReturn(tx, data); + if (!parsed) data = NotarisationData(); + int authority = GetSymbolAuthority(data.symbol); + + if (authority == CROSSCHAIN_KOMODO) { + if (!eval->CheckNotaryInputs(tx, nHeight, block.nTime)) + continue; + } else if (authority == CROSSCHAIN_STAKED) { + if (!CheckTxAuthority(tx, auth_STAKED)) + continue; } - if (isTxscl || eval->CheckNotaryInputs(tx, nHeight, block.nTime)) { - NotarisationData data; - if (ParseNotarisationOpReturn(tx, data)) { - vNotarisations.push_back(std::make_pair(tx.GetHash(), data)); - //printf("Parsed a notarisation for: %s, txid:%s, ccid:%i, momdepth:%i\n", - // data.symbol, tx.GetHash().GetHex().data(), data.ccId, data.MoMDepth); - //if (!data.MoMoM.IsNull()) printf("MoMoM:%s\n", data.MoMoM.GetHex().data()); - } - else - LogPrintf("WARNING: Couldn't parse notarisation for tx: %s at height %i\n", - tx.GetHash().GetHex().data(), nHeight); - } + if (parsed) { + vNotarisations.push_back(std::make_pair(tx.GetHash(), data)); + //printf("Parsed a notarisation for: %s, txid:%s, ccid:%i, momdepth:%i\n", + // data.symbol, tx.GetHash().GetHex().data(), data.ccId, data.MoMDepth); + //if (!data.MoMoM.IsNull()) printf("MoMoM:%s\n", data.MoMoM.GetHex().data()); + } else + LogPrintf("WARNING: Couldn't parse notarisation for tx: %s at height %i\n", + tx.GetHash().GetHex().data(), nHeight); } return vNotarisations; } -bool IsTXSCL(const char* symbol) -{ - return strlen(symbol) >= 5 && strncmp(symbol, "TXSCL", 5) == 0; -} - bool GetBlockNotarisations(uint256 blockHash, NotarisationsInBlock &nibs) {