multiple authorities
This commit is contained in:
@@ -272,6 +272,7 @@ libbitcoin_server_a_SOURCES = \
|
|||||||
chain.cpp \
|
chain.cpp \
|
||||||
checkpoints.cpp \
|
checkpoints.cpp \
|
||||||
crosschain.cpp \
|
crosschain.cpp \
|
||||||
|
crosschain_authority.cpp \
|
||||||
deprecation.cpp \
|
deprecation.cpp \
|
||||||
httprpc.cpp \
|
httprpc.cpp \
|
||||||
httpserver.cpp \
|
httpserver.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);
|
return komodo_notaries(pubkeys, height, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Eval::CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t timestamp) const
|
bool Eval::CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t timestamp) const
|
||||||
{
|
{
|
||||||
if (tx.vin.size() < 11) return false;
|
if (tx.vin.size() < 11) return false;
|
||||||
|
|
||||||
uint8_t seenNotaries[64] = {0};
|
CrosschainAuthority auth;
|
||||||
uint8_t notaries[64][33];
|
auth.requiredSigs = 11;
|
||||||
int nNotaries = GetNotaries(notaries, height, timestamp);
|
auth.size = GetNotaries(auth.notaries, height, timestamp);
|
||||||
|
|
||||||
BOOST_FOREACH(const CTxIn &txIn, tx.vin)
|
return CheckTxAuthority(tx, auth);
|
||||||
{
|
|
||||||
// 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<nNotaries; i++) {
|
|
||||||
if (!seenNotaries[i]) {
|
|
||||||
if (memcmp(pk, notaries[i], 33) == 0) {
|
|
||||||
seenNotaries[i] = 1;
|
|
||||||
goto found;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
found:;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get MoM from a notarisation tx hash (on KMD)
|
* Get MoM from a notarisation tx hash (on KMD)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ uint256 CalculateProofRoot(const char* symbol, uint32_t targetCCid, int kmdHeigh
|
|||||||
|
|
||||||
int seenOwnNotarisations = 0;
|
int seenOwnNotarisations = 0;
|
||||||
|
|
||||||
bool txscl = IsTXSCL(symbol);
|
int authority = GetSymbolAuthority(symbol);
|
||||||
|
|
||||||
for (int i=0; i<NOTARISATION_SCAN_LIMIT_BLOCKS; i++) {
|
for (int i=0; i<NOTARISATION_SCAN_LIMIT_BLOCKS; i++) {
|
||||||
if (i > kmdHeight) break;
|
if (i > kmdHeight) break;
|
||||||
@@ -74,7 +74,7 @@ uint256 CalculateProofRoot(const char* symbol, uint32_t targetCCid, int kmdHeigh
|
|||||||
|
|
||||||
if (seenOwnNotarisations == 1) {
|
if (seenOwnNotarisations == 1) {
|
||||||
BOOST_FOREACH(Notarisation& nota, notarisations) {
|
BOOST_FOREACH(Notarisation& nota, notarisations) {
|
||||||
if (IsTXSCL(nota.second.symbol) == txscl)
|
if (GetSymbolAuthority(nota.second.symbol) == authority)
|
||||||
if (nota.second.ccId == targetCCid)
|
if (nota.second.ccId == targetCCid)
|
||||||
moms.push_back(nota.second.MoM);
|
moms.push_back(nota.second.MoM);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,20 @@
|
|||||||
|
|
||||||
#include "cc/eval.h"
|
#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 */
|
/* On assetchain */
|
||||||
TxProof GetAssetchainProof(uint256 hash);
|
TxProof GetAssetchainProof(uint256 hash);
|
||||||
|
|||||||
72
src/crosschain_authority.cpp
Normal file
72
src/crosschain_authority.cpp
Normal file
@@ -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<auth.size; i++) {
|
||||||
|
if (!seesize[i]) {
|
||||||
|
if (memcmp(pk, auth.notaries[i], 33) == 0) {
|
||||||
|
seesize[i] = 1;
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
found:;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *notaries_STAKED[4][2] =
|
||||||
|
{
|
||||||
|
{"alright", "03b4f49a1c22087e0a9dfaa87aef98ef496c544f9f86038f6c9fea4550543a7679"},
|
||||||
|
{"alright", "03b4f49a1c22087e0a9dfaa87aef98ef496c544f9f86038f6c9fea4550543a7679"},
|
||||||
|
{"alright", "03b4f49a1c22087e0a9dfaa87aef98ef496c544f9f86038f6c9fea4550543a7679"},
|
||||||
|
{"alright", "03b4f49a1c22087e0a9dfaa87aef98ef496c544f9f86038f6c9fea4550543a7679"}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const CrosschainAuthority auth_STAKED = [&](){
|
||||||
|
CrosschainAuthority auth;
|
||||||
|
auth.size = 4;
|
||||||
|
auth.requiredSigs = 2;
|
||||||
|
for (int n=0; n<auth.size; n++)
|
||||||
|
for (size_t i=0; i<33; i++)
|
||||||
|
sscanf(notaries_STAKED[n][1]+(i*2), "%2hhx", auth.notaries[n]+i);
|
||||||
|
return auth;
|
||||||
|
}();
|
||||||
|
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "notarisationdb.h"
|
#include "notarisationdb.h"
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
#include "cc/eval.h"
|
#include "cc/eval.h"
|
||||||
|
#include "crosschain.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
@@ -21,36 +22,31 @@ NotarisationsInBlock ScanBlockNotarisations(const CBlock &block, int nHeight)
|
|||||||
for (unsigned int i = 0; i < block.vtx.size(); i++) {
|
for (unsigned int i = 0; i < block.vtx.size(); i++) {
|
||||||
CTransaction tx = block.vtx[i];
|
CTransaction tx = block.vtx[i];
|
||||||
|
|
||||||
// Special case for TXSCL. Should prob be removed at some point.
|
NotarisationData data;
|
||||||
bool isTxscl = 0;
|
bool parsed = ParseNotarisationOpReturn(tx, data);
|
||||||
{
|
if (!parsed) data = NotarisationData();
|
||||||
NotarisationData data;
|
int authority = GetSymbolAuthority(data.symbol);
|
||||||
if (ParseNotarisationOpReturn(tx, data))
|
|
||||||
if (IsTXSCL(data.symbol))
|
if (authority == CROSSCHAIN_KOMODO) {
|
||||||
isTxscl = 1;
|
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)) {
|
if (parsed) {
|
||||||
NotarisationData data;
|
vNotarisations.push_back(std::make_pair(tx.GetHash(), data));
|
||||||
if (ParseNotarisationOpReturn(tx, data)) {
|
//printf("Parsed a notarisation for: %s, txid:%s, ccid:%i, momdepth:%i\n",
|
||||||
vNotarisations.push_back(std::make_pair(tx.GetHash(), data));
|
// data.symbol, tx.GetHash().GetHex().data(), data.ccId, data.MoMDepth);
|
||||||
//printf("Parsed a notarisation for: %s, txid:%s, ccid:%i, momdepth:%i\n",
|
//if (!data.MoMoM.IsNull()) printf("MoMoM:%s\n", data.MoMoM.GetHex().data());
|
||||||
// data.symbol, tx.GetHash().GetHex().data(), data.ccId, data.MoMDepth);
|
} else
|
||||||
//if (!data.MoMoM.IsNull()) printf("MoMoM:%s\n", data.MoMoM.GetHex().data());
|
LogPrintf("WARNING: Couldn't parse notarisation for tx: %s at height %i\n",
|
||||||
}
|
tx.GetHash().GetHex().data(), nHeight);
|
||||||
else
|
|
||||||
LogPrintf("WARNING: Couldn't parse notarisation for tx: %s at height %i\n",
|
|
||||||
tx.GetHash().GetHex().data(), nHeight);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return vNotarisations;
|
return vNotarisations;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsTXSCL(const char* symbol)
|
|
||||||
{
|
|
||||||
return strlen(symbol) >= 5 && strncmp(symbol, "TXSCL", 5) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool GetBlockNotarisations(uint256 blockHash, NotarisationsInBlock &nibs)
|
bool GetBlockNotarisations(uint256 blockHash, NotarisationsInBlock &nibs)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user