mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-09-10 22:12:00 +00:00
WIP: getblocktemplate for cn style return.
This commit is contained in:
parent
9afc758027
commit
aa97d9938c
@ -203,16 +203,25 @@ public:
|
|||||||
pchMessageStart[3] = 0xe4;
|
pchMessageStart[3] = 0xe4;
|
||||||
nDefaultPort = 19335;
|
nDefaultPort = 19335;
|
||||||
nPruneAfterHeight = 1000;
|
nPruneAfterHeight = 1000;
|
||||||
genesis = CreateGenesisBlock(0x5c4fd388, 0x80003898, 0x1e0fffff, 1, 500 * COIN);
|
#if 1
|
||||||
|
genesis = CreateGenesisBlock(1543789622, 1592, 0x1f0ffff0, 1, 500 * COIN);
|
||||||
consensus.hashGenesisBlock = genesis.GetHash();
|
consensus.hashGenesisBlock = genesis.GetHash();
|
||||||
assert(consensus.hashGenesisBlock == uint256S("7dc62041b90482eafe70fb1e1f6c8973a8c46b7f9f12b966e101c2bae126b5d4"));
|
assert(consensus.hashGenesisBlock == uint256S("860764b471430b96f15c145a44fd854f89d3be6f9ae054ef46e4c8473259bae3"));
|
||||||
assert(genesis.hashMerkleRoot == uint256S("3cf6c3b6da3f4058853ee70369ee43d473aca91ae8fc8f44a645beb21c392d80"));
|
assert(genesis.hashMerkleRoot == uint256S("3cf6c3b6da3f4058853ee70369ee43d473aca91ae8fc8f44a645beb21c392d80"));
|
||||||
|
#else
|
||||||
|
genesis = CreateGenesisBlock(1550900037, 3033, 0x1f0fffff, 1, 500 * COIN);
|
||||||
|
consensus.hashGenesisBlock = genesis.GetHash();
|
||||||
|
assert(consensus.hashGenesisBlock == uint256S("584a067cf7ea6daf30c351a46c6b7403d6fdc0e6e953cf7531d11eb7d834546c"));
|
||||||
|
assert(genesis.hashMerkleRoot == uint256S("3cf6c3b6da3f4058853ee70369ee43d473aca91ae8fc8f44a645beb21c392d80"));
|
||||||
|
#endif
|
||||||
|
|
||||||
vFixedSeeds.clear();
|
vFixedSeeds.clear();
|
||||||
vSeeds.clear();
|
vSeeds.clear();
|
||||||
// nodes with support for servicebits filtering should be at the top
|
// nodes with support for servicebits filtering should be at the top
|
||||||
|
#if 0
|
||||||
vSeeds.emplace_back("testnet-seed.kevacoin.org");
|
vSeeds.emplace_back("testnet-seed.kevacoin.org");
|
||||||
vSeeds.emplace_back("testnet-seed.honourchat.com");
|
vSeeds.emplace_back("testnet-seed.honourchat.com");
|
||||||
|
#endif
|
||||||
|
|
||||||
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,55); // P
|
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,55); // P
|
||||||
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,5);
|
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,5);
|
||||||
@ -223,8 +232,9 @@ public:
|
|||||||
base58Prefixes[KEVA_NAMESPACE] = std::vector<unsigned char>(1,53); // N
|
base58Prefixes[KEVA_NAMESPACE] = std::vector<unsigned char>(1,53); // N
|
||||||
|
|
||||||
bech32_hrp = "tkva";
|
bech32_hrp = "tkva";
|
||||||
|
#if 0
|
||||||
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test));
|
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test));
|
||||||
|
#endif
|
||||||
|
|
||||||
fDefaultConsistencyChecks = false;
|
fDefaultConsistencyChecks = false;
|
||||||
fRequireStandard = false;
|
fRequireStandard = false;
|
||||||
|
@ -34,4 +34,22 @@ bool validate_address(const char *addr, size_t len) {
|
|||||||
std::string output = "";
|
std::string output = "";
|
||||||
uint64_t prefix;
|
uint64_t prefix;
|
||||||
return tools::base58::decode_addr(addr, prefix, output);
|
return tools::base58::decode_addr(addr, prefix, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
// equivalent of strstr, but with arbitrary bytes (ie, NULs)
|
||||||
|
// This does not differentiate between "not found" and "found at offset 0"
|
||||||
|
uint64_t slow_memmem(const void* start_buff, size_t buflen,const void* pat,size_t patlen)
|
||||||
|
{
|
||||||
|
const void* buf = start_buff;
|
||||||
|
const void* end=(const char*)buf+buflen;
|
||||||
|
if (patlen > buflen || patlen == 0) return 0;
|
||||||
|
while(buflen>0 && (buf=memchr(buf,((const char*)pat)[0],buflen-patlen+1)))
|
||||||
|
{
|
||||||
|
if(memcmp(buf,pat,patlen)==0)
|
||||||
|
return (const char*)buf - (const char*)start_buff;
|
||||||
|
buf=(const char*)buf+1;
|
||||||
|
buflen = (const char*)end - (const char*)buf;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
@ -1,4 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cryptonote_core/cryptonote_basic.h>
|
||||||
|
#include <cryptonote_core/cryptonote_format_utils.h>
|
||||||
|
|
||||||
uint32_t convert_blob(const char *blob, size_t len, char *out);
|
uint32_t convert_blob(const char *blob, size_t len, char *out);
|
||||||
bool validate_address(const char *addr, size_t len);
|
bool validate_address(const char *addr, size_t len);
|
||||||
|
uint64_t slow_memmem(const void* start_buff, size_t buflen,const void* pat,size_t patlen);
|
@ -13,6 +13,9 @@
|
|||||||
#define TX_EXTRA_NONCE 0x02
|
#define TX_EXTRA_NONCE 0x02
|
||||||
#define TX_EXTRA_MERGE_MINING_TAG 0x03
|
#define TX_EXTRA_MERGE_MINING_TAG 0x03
|
||||||
|
|
||||||
|
#define TX_EXTRA_KEVA_BLOCKHASH_TAG 0xc1
|
||||||
|
#define TX_EXTRA_KEVA_TX_LIST_TAG 0xc2
|
||||||
|
|
||||||
#define TX_EXTRA_NONCE_PAYMENT_ID 0x00
|
#define TX_EXTRA_NONCE_PAYMENT_ID 0x00
|
||||||
|
|
||||||
namespace cryptonote
|
namespace cryptonote
|
||||||
|
@ -16,7 +16,8 @@ static const unsigned int MAX_BLOCK_WEIGHT = 6000000;
|
|||||||
/** The maximum allowed number of signature check operations in a block (network rule) */
|
/** The maximum allowed number of signature check operations in a block (network rule) */
|
||||||
static const int64_t MAX_BLOCK_SIGOPS_COST = 80000;
|
static const int64_t MAX_BLOCK_SIGOPS_COST = 80000;
|
||||||
/** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */
|
/** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */
|
||||||
static const int COINBASE_MATURITY = 100;
|
//static const int COINBASE_MATURITY = 100;
|
||||||
|
static const int COINBASE_MATURITY = 7;
|
||||||
|
|
||||||
static const int WITNESS_SCALE_FACTOR = 4;
|
static const int WITNESS_SCALE_FACTOR = 4;
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <consensus/consensus.h>
|
#include <consensus/consensus.h>
|
||||||
#include <consensus/params.h>
|
#include <consensus/params.h>
|
||||||
#include <consensus/validation.h>
|
#include <consensus/validation.h>
|
||||||
|
#include <consensus/merkle.h>
|
||||||
#include <core_io.h>
|
#include <core_io.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
@ -29,9 +30,11 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <cryptonote_core/cryptonote_basic.h>
|
|
||||||
#include <cryptonote_core/cryptonote_format_utils.h>
|
|
||||||
#include <cnutils.h>
|
#include <cnutils.h>
|
||||||
|
#include <string_tools.h>
|
||||||
|
#define MAX_RESERVE_SIZE 16
|
||||||
|
|
||||||
|
const std::string CN_DUMMY_ADDRESS = "44234234234";
|
||||||
|
|
||||||
unsigned int ParseConfirmTarget(const UniValue& value)
|
unsigned int ParseConfirmTarget(const UniValue& value)
|
||||||
{
|
{
|
||||||
@ -689,7 +692,19 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
|
|||||||
|
|
||||||
UniValue getblocktemplate(const JSONRPCRequest& request)
|
UniValue getblocktemplate(const JSONRPCRequest& request)
|
||||||
{
|
{
|
||||||
if (request.fHelp || request.params.size() > 1)
|
// JSON-RPC2 request
|
||||||
|
// {reserve_size: 8, wallet_address: config.poolServer.poolAddress}
|
||||||
|
std::map<std::string, UniValue> kv;
|
||||||
|
request.params.getObjMap(kv);
|
||||||
|
int reserve_size = kv["reserve_size"].get_int();
|
||||||
|
bool fValidReserveSize = reserve_size > 0 && reserve_size <= MAX_RESERVE_SIZE;
|
||||||
|
std::vector<unsigned char> data;
|
||||||
|
std::string wallet_address = kv["wallet_address"].get_str();
|
||||||
|
CTxDestination walletDest = DecodeDestination(wallet_address);
|
||||||
|
bool fValidWalletAddress = walletDest.which() == 4; // Expect WitnessV0KeyHash
|
||||||
|
bool fInvalidInput = !fValidReserveSize || !fValidWalletAddress;
|
||||||
|
|
||||||
|
if (request.fHelp || fInvalidInput)
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"getblocktemplate ( TemplateRequest )\n"
|
"getblocktemplate ( TemplateRequest )\n"
|
||||||
"\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n"
|
"\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n"
|
||||||
@ -795,8 +810,8 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
|
|||||||
nStart = GetTime();
|
nStart = GetTime();
|
||||||
|
|
||||||
// Create new block
|
// Create new block
|
||||||
CScript scriptDummy = CScript() << OP_TRUE;
|
CScript scriptPubKey = GetScriptForDestination(walletDest);
|
||||||
pblocktemplate = BlockAssembler(Params()).CreateNewBlock(scriptDummy, fSupportsSegwit);
|
pblocktemplate = BlockAssembler(Params()).CreateNewBlock(scriptPubKey, fSupportsSegwit);
|
||||||
if (!pblocktemplate)
|
if (!pblocktemplate)
|
||||||
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
|
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
|
||||||
|
|
||||||
@ -854,8 +869,6 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
|
|||||||
aMutable.push_back("transactions");
|
aMutable.push_back("transactions");
|
||||||
aMutable.push_back("prevblock");
|
aMutable.push_back("prevblock");
|
||||||
|
|
||||||
UniValue result(UniValue::VOBJ);
|
|
||||||
|
|
||||||
UniValue aRules(UniValue::VARR);
|
UniValue aRules(UniValue::VARR);
|
||||||
UniValue vbavailable(UniValue::VOBJ);
|
UniValue vbavailable(UniValue::VOBJ);
|
||||||
for (int j = 0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
|
for (int j = 0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
|
||||||
@ -885,6 +898,13 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update witness commitment after adding the transactions.
|
||||||
|
pblocktemplate->vchCoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, consensusParams);
|
||||||
|
BlockMerkleRoot(*pblock);
|
||||||
|
uint256 blockHash = pblock->GetHash();
|
||||||
|
|
||||||
|
#if 0
|
||||||
result.push_back(Pair("version", pblock->nVersion));
|
result.push_back(Pair("version", pblock->nVersion));
|
||||||
result.push_back(Pair("rules", aRules));
|
result.push_back(Pair("rules", aRules));
|
||||||
result.push_back(Pair("vbavailable", vbavailable));
|
result.push_back(Pair("vbavailable", vbavailable));
|
||||||
@ -911,6 +931,93 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
|
|||||||
if (!pblocktemplate->vchCoinbaseCommitment.empty() && fSupportsSegwit) {
|
if (!pblocktemplate->vchCoinbaseCommitment.empty() && fSupportsSegwit) {
|
||||||
result.push_back(Pair("default_witness_commitment", HexStr(pblocktemplate->vchCoinbaseCommitment.begin(), pblocktemplate->vchCoinbaseCommitment.end())));
|
result.push_back(Pair("default_witness_commitment", HexStr(pblocktemplate->vchCoinbaseCommitment.begin(), pblocktemplate->vchCoinbaseCommitment.end())));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cryptonote::block cn_block;
|
||||||
|
// block_header
|
||||||
|
// const int cn_variant = b.major_version >= 7 ? b.major_version - 6 : 0;
|
||||||
|
cn_block.major_version = 8; // cn variant 2
|
||||||
|
cn_block.minor_version = 0;
|
||||||
|
cn_block.timestamp = pblock->GetBlockTime();
|
||||||
|
memcpy(&(cn_block.prev_id), pblock->hashPrevBlock.begin(), sizeof(pblock->hashPrevBlock));
|
||||||
|
cn_block.nonce = 0;
|
||||||
|
|
||||||
|
// block
|
||||||
|
// Coinbase transaction.
|
||||||
|
const uint32_t height = pindexPrev->nHeight+1;
|
||||||
|
const size_t miner_height = 10000;
|
||||||
|
const size_t median_size = 20000;
|
||||||
|
const uint64_t already_generated_coins = 10000;
|
||||||
|
const size_t current_block_size = 20000;
|
||||||
|
const uint64_t fee = 0;
|
||||||
|
const size_t max_outs = 1;
|
||||||
|
cryptonote::account_public_address miner_address;
|
||||||
|
cryptonote::transaction miner_tx;
|
||||||
|
cryptonote::blobdata extra_nonce;
|
||||||
|
// The reserve_offset is the offset for extra_nonce
|
||||||
|
extra_nonce.resize(reserve_size, 0);
|
||||||
|
|
||||||
|
if(!cryptonote::get_account_address_from_str(miner_address, CN_DUMMY_ADDRESS)) {
|
||||||
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "Internal error: failed to parse wallet address");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!construct_miner_tx(miner_height, median_size, already_generated_coins, current_block_size,
|
||||||
|
fee, miner_address, miner_tx, extra_nonce, max_outs)) {
|
||||||
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "Internal error: failed to construct miner tx");
|
||||||
|
}
|
||||||
|
cn_block.miner_tx = miner_tx;
|
||||||
|
|
||||||
|
cryptonote::blobdata block_blob = cryptonote::t_serializable_object_to_blob(cn_block);
|
||||||
|
crypto::public_key tx_pub_key = cryptonote::get_tx_pub_key_from_extra(cn_block.miner_tx);
|
||||||
|
if(tx_pub_key == cryptonote::null_pkey) {
|
||||||
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "Internal error: failed to tx pub key in coinbase extra");
|
||||||
|
}
|
||||||
|
uint32_t reserved_offset = slow_memmem((void*)block_blob.data(), block_blob.size(), &tx_pub_key, sizeof(tx_pub_key));
|
||||||
|
if(!reserved_offset) {
|
||||||
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "Internal error: Failed to find tx pub key in blockblob");
|
||||||
|
}
|
||||||
|
reserved_offset += sizeof(tx_pub_key) + 2; //2 bytes: tag for TX_EXTRA_NONCE(1 byte), counter in TX_EXTRA_NONCE(1 byte)
|
||||||
|
if(reserved_offset + reserve_size > block_blob.size())
|
||||||
|
{
|
||||||
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "Internal error: Failed to calculate offset");
|
||||||
|
}
|
||||||
|
|
||||||
|
// No transactions other than base one.
|
||||||
|
cn_block.tx_hashes.clear();
|
||||||
|
|
||||||
|
// Copy kevacoin block hash to the extra field, as a proof that the work has
|
||||||
|
// been done for the block.
|
||||||
|
// Copy all the txs to extra so that later we can use them to
|
||||||
|
// reconstruct the block.
|
||||||
|
const uint32_t blockHashSize = blockHash.size();
|
||||||
|
const uint32_t txTotalSize = 1 + blockHashSize + 1 + 4 + pblock->vtx.size() * sizeof(CTransaction);
|
||||||
|
cn_block.miner_tx.extra.resize(cn_block.miner_tx.extra.size() + txTotalSize, 0);
|
||||||
|
size_t lastOffset = cn_block.miner_tx.extra.size();
|
||||||
|
uint8_t miningTag = TX_EXTRA_KEVA_BLOCKHASH_TAG;
|
||||||
|
memcpy(cn_block.miner_tx.extra.data() + lastOffset, &miningTag, 1);
|
||||||
|
lastOffset ++;
|
||||||
|
memcpy(cn_block.miner_tx.extra.data() + lastOffset, blockHash.begin(), blockHashSize);
|
||||||
|
lastOffset += blockHashSize;
|
||||||
|
uint8_t kevaTxsTag = TX_EXTRA_KEVA_TX_LIST_TAG;
|
||||||
|
memcpy(cn_block.miner_tx.extra.data() + lastOffset, &kevaTxsTag, 1);
|
||||||
|
lastOffset ++;
|
||||||
|
uint32_t txsSize = ;
|
||||||
|
// This is not right! Need to serialize the transactions.
|
||||||
|
// Maybe using SerializationOp of CBlock to serialize the all block instead?
|
||||||
|
memcpy(cn_block.miner_tx.extra.data() + lastOffset, pblock->vtx.data(), pblock->vtx.size() * sizeof(CTransaction));
|
||||||
|
|
||||||
|
UniValue result(UniValue::VOBJ);
|
||||||
|
cryptonote::blobdata hashing_blob;
|
||||||
|
cryptonote::get_block_hashing_blob(cn_block, hashing_blob);
|
||||||
|
|
||||||
|
//res.prev_hash = epee::string_tools::pod_to_hex(cn_block.prev_id);
|
||||||
|
//res.blocktemplate_blob = epee::string_tools::buff_to_hex_nodelimer(block_blob);
|
||||||
|
//res.blockhashing_blob = epee::string_tools::buff_to_hex_nodelimer(hashing_blob);
|
||||||
|
|
||||||
|
result.push_back(Pair("blocktemplate_blob", pblock->hashPrevBlock.GetHex()));
|
||||||
|
result.push_back(Pair("difficulty", pblock->hashPrevBlock.GetHex()));
|
||||||
|
result.push_back(Pair("height", std::to_string(height)));
|
||||||
|
result.push_back(Pair("reserved_offset", std::to_string(reserved_offset)));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user