mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-03-12 05:31:14 +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;
|
||||
nDefaultPort = 19335;
|
||||
nPruneAfterHeight = 1000;
|
||||
genesis = CreateGenesisBlock(0x5c4fd388, 0x80003898, 0x1e0fffff, 1, 500 * COIN);
|
||||
#if 1
|
||||
genesis = CreateGenesisBlock(1543789622, 1592, 0x1f0ffff0, 1, 500 * COIN);
|
||||
consensus.hashGenesisBlock = genesis.GetHash();
|
||||
assert(consensus.hashGenesisBlock == uint256S("7dc62041b90482eafe70fb1e1f6c8973a8c46b7f9f12b966e101c2bae126b5d4"));
|
||||
assert(consensus.hashGenesisBlock == uint256S("860764b471430b96f15c145a44fd854f89d3be6f9ae054ef46e4c8473259bae3"));
|
||||
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();
|
||||
vSeeds.clear();
|
||||
// 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.honourchat.com");
|
||||
#endif
|
||||
|
||||
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,55); // P
|
||||
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,5);
|
||||
@ -223,8 +232,9 @@ public:
|
||||
base58Prefixes[KEVA_NAMESPACE] = std::vector<unsigned char>(1,53); // N
|
||||
|
||||
bech32_hrp = "tkva";
|
||||
|
||||
#if 0
|
||||
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test));
|
||||
#endif
|
||||
|
||||
fDefaultConsistencyChecks = false;
|
||||
fRequireStandard = false;
|
||||
|
@ -34,4 +34,22 @@ bool validate_address(const char *addr, size_t len) {
|
||||
std::string output = "";
|
||||
uint64_t prefix;
|
||||
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
|
||||
|
||||
#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);
|
||||
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_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
|
||||
|
||||
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) */
|
||||
static const int64_t MAX_BLOCK_SIGOPS_COST = 80000;
|
||||
/** 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;
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <consensus/consensus.h>
|
||||
#include <consensus/params.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <consensus/merkle.h>
|
||||
#include <core_io.h>
|
||||
#include <init.h>
|
||||
#include <validation.h>
|
||||
@ -29,9 +30,11 @@
|
||||
#include <memory>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cryptonote_core/cryptonote_basic.h>
|
||||
#include <cryptonote_core/cryptonote_format_utils.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)
|
||||
{
|
||||
@ -689,7 +692,19 @@ 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(
|
||||
"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"
|
||||
@ -795,8 +810,8 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
|
||||
nStart = GetTime();
|
||||
|
||||
// Create new block
|
||||
CScript scriptDummy = CScript() << OP_TRUE;
|
||||
pblocktemplate = BlockAssembler(Params()).CreateNewBlock(scriptDummy, fSupportsSegwit);
|
||||
CScript scriptPubKey = GetScriptForDestination(walletDest);
|
||||
pblocktemplate = BlockAssembler(Params()).CreateNewBlock(scriptPubKey, fSupportsSegwit);
|
||||
if (!pblocktemplate)
|
||||
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("prevblock");
|
||||
|
||||
UniValue result(UniValue::VOBJ);
|
||||
|
||||
UniValue aRules(UniValue::VARR);
|
||||
UniValue vbavailable(UniValue::VOBJ);
|
||||
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("rules", aRules));
|
||||
result.push_back(Pair("vbavailable", vbavailable));
|
||||
@ -911,6 +931,93 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
|
||||
if (!pblocktemplate->vchCoinbaseCommitment.empty() && fSupportsSegwit) {
|
||||
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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user