{ "TODO": "Not working. It need a lot of finishing work.", "file": "bytecoin-clone.json", "description": "Changes needed to run Bytecoin clone", "required": [ "core/monero.json" ], "files": [ { "path": "/src/cryptonote_config.h", "changes": [ { "action": "add_below", "marker": "#define CRYPTONOTE_NAME", "parameters": { "text": [ "#define BYTECOIN_CLONE %s" ], "text_alt": [ "#define BYTECOIN_CLONE 0" ], "var": "BYTECOIN_CLONE" } } ] }, { "path": "/src/crypto/hash.h", "changes": [ { "action": "add_above", "marker": "inline void tree_hash(const hash *hashes, std::size_t count, hash &root_hash) {", "parameters": { "text": [ "inline void tree_branch(const hash *hashes, size_t count, hash *branch) {", " tree_branch(reinterpret_cast(hashes), count, reinterpret_cast(branch));", "}", "", "inline void tree_hash_from_branch(const hash *branch, size_t depth, const hash &leaf, const void *path, hash &root_hash) {", " tree_hash_from_branch(reinterpret_cast(branch), depth, reinterpret_cast(&leaf), path, reinterpret_cast(&root_hash));", "}", "" ] } } ] }, { "path": "/src/crypto/hash-ops.h", "changes": [ { "action": "add_above", "marker": "void tree_hash(const char (*hashes)[HASH_SIZE], size_t count, char *root_hash);", "parameters": { "text": [ "size_t tree_depth(size_t count);", "void tree_branch(const char (*hashes)[HASH_SIZE], size_t count, char (*branch)[HASH_SIZE]);", "void tree_hash_from_branch(const char (*branch)[HASH_SIZE], size_t depth, const char *leaf, const void *path, char *root_hash);" ] } } ] }, { "path": "/src/crypto/tree-hash.c", "changes": [ { "action": "add_above", "marker": "void tree_hash(const char (*hashes)[HASH_SIZE], size_t count, char *root_hash) {", "parameters": { "text": [ "", "size_t tree_depth(size_t count) {", " size_t i;", " size_t depth = 0;", " assert(count > 0);", " for (i = sizeof(size_t) << 2; i > 0; i >>= 1) {", " if (count >> i > 0) {", " count >>= i;", " depth += i;", " }", " }", " return depth;", "}", "", "void tree_branch(const char (*hashes)[HASH_SIZE], size_t count, char (*branch)[HASH_SIZE]) {", " size_t i, j;", " size_t cnt = 1;", " size_t depth = 0;", " char (*ints)[HASH_SIZE];", " assert(count > 0);", " for (i = sizeof(size_t) << 2; i > 0; i >>= 1) {", " if (cnt << i <= count) {", " cnt <<= i;", " depth += i;", " }", " }", " assert(cnt == 1ULL << depth);", " assert(depth == tree_depth(count));", " ints = alloca((cnt - 1) * HASH_SIZE);", " memcpy(ints, hashes + 1, (2 * cnt - count - 1) * HASH_SIZE);", " for (i = 2 * cnt - count, j = 2 * cnt - count - 1; j < cnt - 1; i += 2, ++j) {", " cn_fast_hash(hashes[i], 2 * HASH_SIZE, ints[j]);", " }", " assert(i == count);", " while (depth > 0) {", " assert(cnt == 1ULL << depth);", " cnt >>= 1;", " --depth;", " memcpy(branch[depth], ints[0], HASH_SIZE);", " for (i = 1, j = 0; j < cnt - 1; i += 2, ++j) {", " cn_fast_hash(ints[i], 2 * HASH_SIZE, ints[j]);", " }", " }", "}", "", "void tree_hash_from_branch(const char (*branch)[HASH_SIZE], size_t depth, const char *leaf, const void *path, char *root_hash) {", " if (depth == 0) {", " memcpy(root_hash, leaf, HASH_SIZE);", " } else {", " char buffer[2][HASH_SIZE];", " int from_leaf = 1;", " char *leaf_path, *branch_path;", " while (depth > 0) {", " --depth;", " if (path && (((const char *) path)[depth >> 3] & (1 << (depth & 7))) != 0) {", " leaf_path = buffer[1];", " branch_path = buffer[0];", " } else {", " leaf_path = buffer[0];", " branch_path = buffer[1];", " }", " if (from_leaf) {", " memcpy(leaf_path, leaf, HASH_SIZE);", " from_leaf = 0;", " } else {", " cn_fast_hash(buffer, 2 * HASH_SIZE, leaf_path);", " }", " memcpy(branch_path, branch[depth], HASH_SIZE);", " }", " cn_fast_hash(buffer, 2 * HASH_SIZE, root_hash);", " }", "}", "" ] } } ] }, { "path": "/src/cryptonote_basic/cryptonote_format_utils.h", "changes": [ { "action": "add_above", "marker": "bool add_extra_nonce_to_tx_extra(std::vector& tx_extra, const blobdata& extra_nonce);", "parameters": { "text": [ "bool add_merge_mining_tag_to_tx_extra(std::vector& tx_extra, const tx_extra_merge_mining_tag& mm_tag);", "bool get_merge_mining_tag_to_tx_extra(std::vector& tx_extra, const tx_extra_merge_mining_tag& mm_tag);" ] } } ] }, { "path": "/src/cryptonote_basic/cryptonote_format_utils.cpp", "changes": [ { "action": "add_above", "marker": "bool add_extra_nonce_to_tx_extra(std::vector& tx_extra, const blobdata& extra_nonce)", "parameters": { "text": [ "bool add_merge_mining_tag_to_tx_extra(std::vector& tx_extra, const tx_extra_merge_mining_tag& mm_tag) {", " const uint8_t* mm_tag_ptr = reinterpret_cast(&mm_tag);", "", " tx_extra.push_back(TX_EXTRA_MERGE_MINING_TAG);", " std::copy(mm_tag_ptr, mm_tag_ptr + sizeof(mm_tag), std::back_inserter(tx_extra));", " return true;", "}", "", "bool get_merge_mining_tag_to_tx_extra(const std::vector& tx_extra, tx_extra_merge_mining_tag& mm_tag) {", " std::vector tx_extra_fields;", " parse_tx_extra(tx_extra, tx_extra_fields);", "", " return find_tx_extra_field_by_type(tx_extra_fields, mm_tag);", "}", "" ] } } ] }, { "path": "/src/cryptonote_basic/cryptonote_boost_serialization.h", "changes": [ { "action": "add_above", "marker": "#include ", "parameters": { "text": [ "//remove", " #include " ] } }, { "action": "add_above", "marker": "a & b.major_version;", "parameters": { "text": [ "std::ostream &gout00 = std::cout << \"REALLY HERE: \" << std::endl;" ] } }, { "action": "add_above", "marker": "a & b.miner_tx;", "parameters": { "text": [ "std::ostream &gout01 = std::cout << \"REALLY HERE 2: \" << std::endl;" ] } } ] }, { "path": "/src/cryptonote_basic/cryptonote_basic.h", "changes": [ { "action": "add_above", "marker": "#include ", "parameters": { "text": [ "//remove", " #include ", "#include " ] } }, { "action": "add_below", "marker": "#include \"cryptonote_config.h\"", "parameters": { "text": [ "#include \"cryptonote_basic/cryptonote_format_utils.h\"" ] } }, { "action": "replace", "marker": "block(): block_header(), hash_valid(false) {}", "parameters": { "text": [ "block(): block_header(), parent_block(), hash_valid(false), is_input(true) {}" ] } }, { "action": "replace", "marker": "block(const block &b): block_header(b), hash_valid(false), miner_tx(b.miner_tx), tx_hashes(b.tx_hashes) { if (b.is_hash_valid()) { hash = b.hash; set_hash_valid(true); } }", "parameters": { "text": [ " block(const block &b): block_header(b), hash_valid(false), is_input(false), parent_block(b.parent_block), miner_tx(b.miner_tx), tx_hashes(b.tx_hashes) { if (b.is_hash_valid()) { hash = b.hash; set_hash_valid(true); } }" ] } }, { "action": "add_above", "marker": "struct block_header", "parameters": { "text": [ "struct parent_block", "{", " uint8_t major_version;", " uint8_t minor_version;", " crypto::hash previous_block_hash;", " uint16_t transaction_count;", " std::vector base_transaction_branch;", " transaction_prefix base_transaction; //base transaction", " std::vector blockchain_branch;", "};", "", "struct parent_block_serializer {", " parent_block_serializer(parent_block& _parent_block, uint64_t& _timestamp, uint32_t& _nonce, bool _hashing_serialization, bool _header_only, bool _is_input) :", " parent_block(_parent_block), timestamp(_timestamp), nonce(_nonce), hashing_serialization(_hashing_serialization), header_only(_header_only, is_input(_is_input)) { }", "", " parent_block& parent_block;", " uint64_t& timestamp;", " uint32_t& nonce;", " bool hashing_serialization;", " bool header_only;", " bool is_input;", "", " BEGIN_SERIALIZE()", " VARINT_FIELD(parent_block.major_version)", " VARINT_FIELD(parent_block.minor_version)", " VARINT_FIELD(timestamp)", " FIELD(parent_block.previous_block_hash)", " FIELD(nonce)", " if (hashing_serialization) {", " crypto::hash minerTxHash;", " if (!get_transaction_hash(parent_block.base_transaction, minerTxHash)) {", "// throw std::runtime_error(\"Get transaction hash error\");", " }", " crypto::hash merkleRoot;", " crypto::tree_hash_from_branch(parent_block.base_transaction_branch.data(), parent_block.base_transaction_branch.size(), minerTxHash, 0, merkleRoot);", " FIELD(merkleRoot)", " }", " uint64_t txNum = static_cast(parent_block.transaction_count);", " VARINT_FIELD(txNum)", " parent_block.transaction_count = static_cast(txNum);", " if (parent_block.transaction_count < 1) {", "// throw std::runtime_error(\"Wrong transactions number\");", " }", "", " if (header_only) {", " return;", " }", "", " size_t branchSize = crypto::tree_depth(parent_block.transaction_count);", "// if (serializer.type() == ISerializer::OUTPUT) {", " if (is_input) {", " if (parent_block.base_transaction_branch.size() != branchSize) {", "// throw std::runtime_error(\"Wrong miner transaction branch size\");", " }", " } else {", " parent_block.base_transaction_branch.resize(branchSize);", " }", "", "// serializer(parent_block.base_transaction_branch, \"baseTransactionBranch\");", " //TODO: Make arrays with computable size! This code won't work with json serialization!", " for (crypto::hash& hash: parent_block.base_transaction_branch) {", " FIELD(hash)", " }", " FIELD(parent_block.base_transaction)", "", " tx_extra_merge_mining_tag mm_tag;", " if (!get_merge_mining_tag_to_tx_extra(parent_block.base_transaction.extra, mm_tag)) {", " throw std::runtime_error(\"Can't get extra merge mining tag\");", " }", "", " if (mm_tag.depth > 8 * sizeof(crypto::hash)) {", " throw std::runtime_error(\"Wrong merge mining tag depth\");", " }", "", "// if (serializer.type() == ISerializer::OUTPUT) {", " if (is_input) {", " if (mm_tag.depth != parent_block.base_transaction_branch.size()) {", " throw std::runtime_error(\"Blockchain branch size must be equal to merge mining tag depth\");", " }", " } else {", " parent_block.base_transaction_branch.resize(mm_tag.depth);", " }", "", "// serializer(parent_block.base_transaction_branch, \"blockchainBranch\");", " //TODO: Make arrays with computable size! This code won't work with json serialization!", " for (crypto::hash& hash: parent_block.base_transaction_branch) {", " FIELD(hash)", " }", " END_SERIALIZE()", "};", "" ] } }, { "action": "add_above", "marker": "transaction miner_tx;", "parameters": { "text": [ " parent_block parent_block;" ] } }, { "action": "add_above", "marker": "FIELD(miner_tx)", "parameters": { "text": [ "if (major_version >= 2 && BYTECOIN_CLONE == 1) {", "std::ostream &gout21 = std::cout << \"major_version: \" << std::to_string(major_version) << std::endl;", "std::ostream &gout22 = std::cout << \"minor_version: \" << std::to_string(minor_version) << std::endl;", " parent_block_serializer parent_block_serializer = {parent_block, timestamp, nonce, false, false, is_input};", "std::ostream &gout11 = std::cout << \"parent_block.major_version: \" << std::to_string(parent_block.major_version) << std::endl;", "std::ostream &gout12 = std::cout << \"parent_block.minor_version: \" << std::to_string(parent_block.minor_version) << std::endl;", "std::ostream &gout01 = std::cout << \"parentBlock.major_version: \" << std::to_string(parent_block_serializer.parent_block.major_version) << std::endl;", "std::ostream &gout02 = std::cout << \"parentBlock.minor_version: \" << std::to_string(parent_block_serializer.parent_block.minor_version) << std::endl;", "std::ostream &gout03 = std::cout << \"parentBlock.transaction_count: \" << std::to_string(parent_block_serializer.parent_block.transaction_count) << std::endl;", "std::ostream &gout1 = std::cout << \"timestamp: \" << parent_block_serializer.timestamp << std::endl;", "std::ostream &gout2 = std::cout << \"nonce: \" << parent_block_serializer.nonce << std::endl;", "struct parent_block_serializer* strucPtr=&parent_block_serializer;", "unsigned char* charPtr=(unsigned char*)strucPtr;", "int i;", "printf(\"structure size : %zu bytes\\n\",sizeof(struct parent_block_serializer));", "for(i=0;iget_ideal_version();", "parameters": { "text": [ "std::cout << \"BYTECOIN_CLONE: \" << BYTECOIN_CLONE << std::endl;", "std::cout << \"b.major_version: \" << b.major_version << std::endl;", "if (b.major_version == 1 && BYTECOIN_CLONE == 1) {", " // check upgrade height to populate correct minor version", "} else if (b.major_version >= 2 && BYTECOIN_CLONE == 1) {", " // check upgrade height to populate correct minor version", "", " b.parent_block.major_version = 1;", " b.parent_block.minor_version = 0;", " b.parent_block.transaction_count = 1;", "std::ostream &gout01 = std::cout << \"b.parent_block.major_version: \" << std::to_string(b.parent_block.major_version) << std::endl;", "std::ostream &gout02 = std::cout << \"b.parent_block.minor_version: \" << std::to_string(b.parent_block.minor_version) << std::endl;", "", " tx_extra_merge_mining_tag mm_tag = boost::value_initialized();", " if (!add_merge_mining_tag_to_tx_extra(b.parent_block.base_transaction.extra, mm_tag)) {", " LOG_ERROR(\"Failed to append merge mining tag to extra of the parent block miner transaction\");", " return false;", " }", "}", "" ] } } ] }, { "path": "/src/cryptonote_basic/cryptonote_basic.h", "multiline": true, "changes": [ { "action": "replace", "marker": "(struct block: public block_header)[^@]+(mutable std::atomic hash_valid;)", "parameters": { "text": [ " struct block: public block_header", " {", " private:", " // hash cash", " mutable std::atomic hash_valid;", " mutable std::atomic is_input;", " " ] } } ] }, { "path": "/src/cryptonote_basic/cryptonote_basic.h", "multiline": true, "changes": [ { "action": "replace", "marker": " (VARINT_FIELD\\(major_version\\))[^@]+(FIELD\\(nonce\\))", "parameters": { "text": [ " VARINT_FIELD(major_version)", " if (BYTECOIN_CLONE == 1 && major_version > 3) {", " throw std::runtime_error(\"Wrong major version\");", " }", " VARINT_FIELD(minor_version)", " if (BYTECOIN_CLONE == 0 || (BYTECOIN_CLONE == 1&& major_version == 1)) {", " VARINT_FIELD(timestamp)", " FIELD(prev_id)", " FIELD(nonce)", " } else if (major_version >= 2) {", " FIELD(prev_id)", " } else {", " throw std::runtime_error(\"Wrong major version\");", " }" ] } } ] } ] }