mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-01-14 00:58:09 +00:00
WIP: implemented submitblock.
This commit is contained in:
parent
bbb78c76a0
commit
57ab5c7255
@ -3,7 +3,9 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <arith_uint256.h>
|
||||
#include <primitives/block.h>
|
||||
#include <streams.h>
|
||||
|
||||
#include <hash.h>
|
||||
#include <tinyformat.h>
|
||||
@ -20,7 +22,25 @@ uint256 CBlockHeader::GetHash() const
|
||||
uint256 CBlockHeader::GetPoWHash() const
|
||||
{
|
||||
uint256 thash;
|
||||
cn_slow_hash(BEGIN(nVersion), 80, BEGIN(thash), 2, 0, 0);
|
||||
if (hashPrevBlock.IsNull()) {
|
||||
// Genesis block
|
||||
cn_slow_hash(BEGIN(nVersion), 80, BEGIN(thash), 2, 0, 0);
|
||||
return thash;
|
||||
}
|
||||
arith_uint256 blockHash = UintToArith256(GetHash());
|
||||
arith_uint256 expectedHash = UintToArith256(cnHeader.prev_id);
|
||||
// blockHash should be the same as expectedHash. If so, after the
|
||||
// following XOR operatiosn, the value of expectedHash is not changed.
|
||||
blockHash ^= expectedHash;
|
||||
expectedHash ^= blockHash;
|
||||
CryptoNoteHeader header = cnHeader;
|
||||
// Cryptonote prev_id is used to store kevacoin block hash.
|
||||
header.prev_id = ArithToUint256(expectedHash);
|
||||
|
||||
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
|
||||
stream << header;
|
||||
std::string blob = stream.str();
|
||||
cn_slow_hash(blob.data(), blob.size(), BEGIN(thash), 2, 0, 0);
|
||||
return thash;
|
||||
}
|
||||
|
||||
|
@ -971,6 +971,7 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
UniValue submitblock(const JSONRPCRequest& request)
|
||||
{
|
||||
// We allow 2 arguments for compliance with BIP22. Argument 2 is ignored.
|
||||
@ -1041,6 +1042,115 @@ UniValue submitblock(const JSONRPCRequest& request)
|
||||
}
|
||||
return BIP22ValidationResult(sc.state);
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint256 CryptoHashToUint256(const crypto::hash& hash)
|
||||
{
|
||||
std::vector<unsigned char> prev_id((unsigned char*)(&hash), (unsigned char*)&(hash) + sizeof(crypto::hash));
|
||||
return uint256(prev_id);
|
||||
}
|
||||
|
||||
// Cryptonote RPC call, only one parameter allowed.
|
||||
UniValue submitblock(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() != 1) {
|
||||
throw std::runtime_error(
|
||||
"submitblock \"hexdata\"\n"
|
||||
"\nAttempts to submit new block to network.\n"
|
||||
"See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"
|
||||
|
||||
"\nArguments\n"
|
||||
"1. \"hexdata\" (string, required) the hex-encoded block data to submit\n"
|
||||
"2. \"dummy\" (optional) dummy value, for compatibility with BIP22. This value is ignored.\n"
|
||||
"\nResult:\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("submitblock", "\"mydata\"")
|
||||
+ HelpExampleRpc("submitblock", "\"mydata\"")
|
||||
);
|
||||
}
|
||||
|
||||
cryptonote::blobdata blockblob;
|
||||
if(!epee::string_tools::parse_hexstr_to_binbuff(request.params[0].get_str(), blockblob))
|
||||
{
|
||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Wrong block blob");
|
||||
}
|
||||
|
||||
cryptonote::block cnblock = AUTO_VAL_INIT(cnblock);
|
||||
if(!cryptonote::parse_and_validate_block_from_blob(blockblob, cnblock))
|
||||
{
|
||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Wrong block blob");
|
||||
}
|
||||
|
||||
cryptonote::tx_extra_keva_block keva_block_blob;
|
||||
if (!cryptonote::get_keva_block_from_extra(cnblock.miner_tx.extra, keva_block_blob)) {
|
||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Could not get Kevacoin block");
|
||||
}
|
||||
|
||||
std::shared_ptr<CBlock> blockptr = std::make_shared<CBlock>();
|
||||
CBlock& block = *blockptr;
|
||||
if (!DecodeHexBlk(block, keva_block_blob.keva_block)) {
|
||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
|
||||
}
|
||||
|
||||
if (block.vtx.empty() || !block.vtx[0]->IsCoinBase()) {
|
||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block does not start with a coinbase");
|
||||
}
|
||||
|
||||
block.cnHeader.major_version = cnblock.major_version;
|
||||
block.cnHeader.minor_version = cnblock.minor_version;
|
||||
block.cnHeader.prev_id = CryptoHashToUint256(cnblock.prev_id);
|
||||
|
||||
block.cnHeader.nonce = cnblock.nonce;
|
||||
crypto::hash tree_root_hash = get_tx_tree_hash(cnblock);
|
||||
block.cnHeader.merkle_root = CryptoHashToUint256(tree_root_hash);
|
||||
uint256 hash = block.GetHash();
|
||||
|
||||
// Cryptonote prev_id is used to store the block hash of kevacoin.
|
||||
if (hash != block.cnHeader.prev_id) {
|
||||
throw JSONRPCError(RPC_VERIFY_ERROR, "Kevacoin block hash does not match cryptnote hash");
|
||||
}
|
||||
|
||||
// TODO: fix the return message.
|
||||
bool fBlockPresent = false;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
BlockMap::iterator mi = mapBlockIndex.find(hash);
|
||||
if (mi != mapBlockIndex.end()) {
|
||||
CBlockIndex *pindex = mi->second;
|
||||
if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) {
|
||||
return "duplicate";
|
||||
}
|
||||
if (pindex->nStatus & BLOCK_FAILED_MASK) {
|
||||
return "duplicate-invalid";
|
||||
}
|
||||
// Otherwise, we might only have the header - process the block before returning
|
||||
fBlockPresent = true;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
LOCK(cs_main);
|
||||
BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
|
||||
if (mi != mapBlockIndex.end()) {
|
||||
UpdateUncommittedBlockStructures(block, mi->second, Params().GetConsensus());
|
||||
}
|
||||
}
|
||||
|
||||
submitblock_StateCatcher sc(block.GetHash());
|
||||
RegisterValidationInterface(&sc);
|
||||
bool fAccepted = ProcessNewBlock(Params(), blockptr, true, nullptr);
|
||||
UnregisterValidationInterface(&sc);
|
||||
if (fBlockPresent) {
|
||||
if (fAccepted && !sc.found) {
|
||||
return "duplicate-inconclusive";
|
||||
}
|
||||
return "duplicate";
|
||||
}
|
||||
if (!sc.found) {
|
||||
return "inconclusive";
|
||||
}
|
||||
return BIP22ValidationResult(sc.state);
|
||||
}
|
||||
|
||||
UniValue estimatefee(const JSONRPCRequest& request)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user