sal1 treasury mint
This commit is contained in:
+78
-3
@@ -86,6 +86,9 @@
|
||||
#define PREMINE_AMOUNT_UPFRONT ((uint64_t)650000000000000ull) // 3.4% of MONEY_SUPPLY
|
||||
#define PREMINE_AMOUNT_MONTHLY ((uint64_t)65000000000000ull) // 8.6%/24 of MONEY_SUPPLY
|
||||
|
||||
#define TREASURY_SAL1_MINT_AMOUNT ((uint64_t)65000000000000ull) // 650K
|
||||
#define TREASURY_SAL1_MINT_COUNT 16 // 16 times
|
||||
|
||||
#define DIFFICULTY_TARGET_V2 120 // seconds
|
||||
#define DIFFICULTY_TARGET_V1 60 // seconds - before first fork
|
||||
#define DIFFICULTY_WINDOW_V2 70 // blocks
|
||||
@@ -238,6 +241,7 @@
|
||||
#define HF_VERSION_AUDIT1_PAUSE 7
|
||||
#define HF_VERSION_AUDIT2 8
|
||||
#define HF_VERSION_AUDIT2_PAUSE 9
|
||||
#define HF_VERSION_TREASURY_SAL1_MINT 10
|
||||
|
||||
#define HF_VERSION_REQUIRE_VIEW_TAGS 255
|
||||
#define HF_VERSION_ENABLE_CONVERT 255
|
||||
@@ -301,9 +305,30 @@ namespace config
|
||||
};
|
||||
|
||||
const uint64_t STAKE_LOCK_PERIOD = 30*24*30;
|
||||
const uint64_t TREASURY_SAL1_MINT_PERIOD = 30*24*30; // 1 month of blocks
|
||||
|
||||
std::string const TREASURY_ADDRESS = "SaLvdZR6w1A21sf2Wh6jYEh1wzY4GSbT7RX6FjyPsnLsffWLrzFQeXUXJcmBLRWDzZC2YXeYe5t7qKsnrg9FpmxmEcxPHsEYfqA";
|
||||
|
||||
// treasury payout {tx-key, output-key} pairs
|
||||
const std::vector<std::pair<std::string, std::string>> TREASURY_SAL1_MINT_OUTPUT_KEYS = {
|
||||
{"a1bdd1da651fbbb845232816e1aa2d4ff29b790f10bbd4f574a012f1199e15a4", "b0733ab6f251b16458efa9ebb3fb99bd54d43173b5768fe9ffc42e0fe46ae3a8"},
|
||||
{"47996eccbcc078b06d0f6ece37bf3a700c2bd60adfdd898b22096f16a9ad315c", "fd6bcceb4799ee067d59b97a6f66a0f9a70f134220259d3b4d6a2278ba4aca4c"},
|
||||
{"a3e6754a849b80c21a77e6065fefdae29eeeabf17c407453356244a00545bdb8", "3d395454df1452d715d27190e022b20395871c99af578f7251c3f9752e0274a6"},
|
||||
{"0d5e97a910e0f9c606ad9c711b6595aaed142d857cde2efa519112b9a29240d5", "56c29e28bdcf4f20b4b45906b93ae7c4bf9ee82e18cd45543cb69a14ce5efb88"},
|
||||
{"495fa363de88915aa8b74818c4b80715a882a688b4f7127ab7cd3b6885f3567a", "d42dfe0da5579c82e8255eba8c0a17170023f14a6a5030da6abf9f10abb52cbb"},
|
||||
{"85ea10ec40390e4f406446fb519e974d89536154045c6df28bb3b538b254e20d", "0ce2b7dd3a8ce8b596889dac8081a62f98fd70f1f043944ab4ac592c3c59e77b"},
|
||||
{"40f201b38a319dda81e7201e57fea7924067a4a332ed71b8e51ec29ac2d67310", "8289aa6963b98d1034e94eae55d8be6b33d0a88f14f174ebcbaec70837986c7c"},
|
||||
{"c5a648cc7846341357b7b4653a58f9eb4800d88b5de587bceec7a5c28f98d05a", "3f308a203845d88e5e728fcebcdcea1f90e2f424d461617993c672a6138ad2d8"},
|
||||
{"4c51d6550b8eeb6cc8f0d395cc83a5f90ec2a4d86501b3f68da48d618ccf5711", "53f0bd8cebeefb3a88fffa5d7f6ad43d4712608ded561732467ca499df940454"},
|
||||
{"ce2f5d82118fed03d5e269e285fc16189a6cd34f38999e5c055a5dea5fce61bc", "f7fc6948b194d9bd6f2df6ecb83f04e6c8d1a2556a63fedb310a4631fe1bfc42"},
|
||||
{"6248028fd77fb02b5c6ea72dea10b417891a2da7aaf9565aed382e063b4981a3", "63986e1177499bdb23cd49afb519ec18f38cb1b0c386220b376d8ffdc2e37890"},
|
||||
{"6adcb695aa5d6d01133c68900f29e501e9549816e827ea0c164bbc78f3534dd6", "6a440ccb18f5e703e8000de3865ac40d4c18f081270d32eef377dc831f28d8d0"},
|
||||
{"b97a4d2259480f34f20e41c489ab5c2e5ae9ee84d8672a7eff8012f2260e121e", "e6eb9147ff40e22209d321d0f1bfbfe20acf5ceb6b9d0bfb13688ad28aa1232e"},
|
||||
{"4fd214602a36902f22d16927244c456e8cc5a406a9570131f138a028214ffdf0", "34060b8bd96009b9b298280ebd84fa9587fa8c9df6fb5ad0270fb6cd2098885c"},
|
||||
{"9d60178ec6d6599d7a31298f2559fb9c3111f2c70494b3a1638db877ea55b808", "7985ed03856a929663e954738d0938713407717835f760c7ca4d54844a128c91"},
|
||||
{"cd65718eab234bf419332e53bd2f48e2ade70af48c5e126ab5080321e1493dfc", "581cb4cca7a0a029ee2cac51dfc00a0c3a657d2eaf67ed3c6ae7bacc11b4f007"},
|
||||
};
|
||||
|
||||
// Hash domain separators
|
||||
const char HASH_KEY_BULLETPROOF_EXPONENT[] = "bulletproof";
|
||||
const char HASH_KEY_BULLETPROOF_PLUS_EXPONENT[] = "bulletproof_plus";
|
||||
@@ -381,6 +406,7 @@ namespace config
|
||||
};
|
||||
|
||||
const uint64_t STAKE_LOCK_PERIOD = 20;
|
||||
const uint64_t TREASURY_SAL1_MINT_PERIOD = 20;
|
||||
|
||||
std::array<std::string, 3> const ORACLE_URLS = {{"oracle.salvium.io:8443", "oracle.salvium.io:8443", "oracle.salvium.io:8443"}};
|
||||
|
||||
@@ -390,6 +416,26 @@ namespace config
|
||||
"-----END PUBLIC KEY-----\n";
|
||||
|
||||
std::string const TREASURY_ADDRESS = "SaLvTyLFta9BiAXeUfFkKvViBkFt4ay5nEUBpWyDKewYggtsoxBbtCUVqaBjtcCDyY1euun8Giv7LLEgvztuurLo5a6Km1zskZn36";
|
||||
|
||||
// treasury payout {tx-key, output-key} pairs
|
||||
const std::vector<std::pair<std::string, std::string>> TREASURY_SAL1_MINT_OUTPUT_KEYS = {
|
||||
{"a1bdd1da651fbbb845232816e1aa2d4ff29b790f10bbd4f574a012f1199e15a4", "b0733ab6f251b16458efa9ebb3fb99bd54d43173b5768fe9ffc42e0fe46ae3a8"},
|
||||
{"47996eccbcc078b06d0f6ece37bf3a700c2bd60adfdd898b22096f16a9ad315c", "fd6bcceb4799ee067d59b97a6f66a0f9a70f134220259d3b4d6a2278ba4aca4c"},
|
||||
{"a3e6754a849b80c21a77e6065fefdae29eeeabf17c407453356244a00545bdb8", "3d395454df1452d715d27190e022b20395871c99af578f7251c3f9752e0274a6"},
|
||||
{"0d5e97a910e0f9c606ad9c711b6595aaed142d857cde2efa519112b9a29240d5", "56c29e28bdcf4f20b4b45906b93ae7c4bf9ee82e18cd45543cb69a14ce5efb88"},
|
||||
{"495fa363de88915aa8b74818c4b80715a882a688b4f7127ab7cd3b6885f3567a", "d42dfe0da5579c82e8255eba8c0a17170023f14a6a5030da6abf9f10abb52cbb"},
|
||||
{"85ea10ec40390e4f406446fb519e974d89536154045c6df28bb3b538b254e20d", "0ce2b7dd3a8ce8b596889dac8081a62f98fd70f1f043944ab4ac592c3c59e77b"},
|
||||
{"40f201b38a319dda81e7201e57fea7924067a4a332ed71b8e51ec29ac2d67310", "8289aa6963b98d1034e94eae55d8be6b33d0a88f14f174ebcbaec70837986c7c"},
|
||||
{"c5a648cc7846341357b7b4653a58f9eb4800d88b5de587bceec7a5c28f98d05a", "3f308a203845d88e5e728fcebcdcea1f90e2f424d461617993c672a6138ad2d8"},
|
||||
{"4c51d6550b8eeb6cc8f0d395cc83a5f90ec2a4d86501b3f68da48d618ccf5711", "53f0bd8cebeefb3a88fffa5d7f6ad43d4712608ded561732467ca499df940454"},
|
||||
{"ce2f5d82118fed03d5e269e285fc16189a6cd34f38999e5c055a5dea5fce61bc", "f7fc6948b194d9bd6f2df6ecb83f04e6c8d1a2556a63fedb310a4631fe1bfc42"},
|
||||
{"6248028fd77fb02b5c6ea72dea10b417891a2da7aaf9565aed382e063b4981a3", "63986e1177499bdb23cd49afb519ec18f38cb1b0c386220b376d8ffdc2e37890"},
|
||||
{"6adcb695aa5d6d01133c68900f29e501e9549816e827ea0c164bbc78f3534dd6", "6a440ccb18f5e703e8000de3865ac40d4c18f081270d32eef377dc831f28d8d0"},
|
||||
{"b97a4d2259480f34f20e41c489ab5c2e5ae9ee84d8672a7eff8012f2260e121e", "e6eb9147ff40e22209d321d0f1bfbfe20acf5ceb6b9d0bfb13688ad28aa1232e"},
|
||||
{"4fd214602a36902f22d16927244c456e8cc5a406a9570131f138a028214ffdf0", "34060b8bd96009b9b298280ebd84fa9587fa8c9df6fb5ad0270fb6cd2098885c"},
|
||||
{"9d60178ec6d6599d7a31298f2559fb9c3111f2c70494b3a1638db877ea55b808", "7985ed03856a929663e954738d0938713407717835f760c7ca4d54844a128c91"},
|
||||
{"cd65718eab234bf419332e53bd2f48e2ade70af48c5e126ab5080321e1493dfc", "581cb4cca7a0a029ee2cac51dfc00a0c3a657d2eaf67ed3c6ae7bacc11b4f007"},
|
||||
};
|
||||
}
|
||||
|
||||
namespace stagenet
|
||||
@@ -409,6 +455,7 @@ namespace config
|
||||
const std::map<uint8_t, std::pair<uint64_t, std::pair<std::string, std::string>>> AUDIT_HARD_FORKS = { {HF_VERSION_AUDIT1, {30, {"SAL", "SAL1"}}} };
|
||||
|
||||
const uint64_t STAKE_LOCK_PERIOD = 20;
|
||||
const uint64_t TREASURY_SAL1_MINT_PERIOD = 20;
|
||||
|
||||
std::array<std::string, 3> const ORACLE_URLS = {{"oracle.salvium.io:8443", "oracle.salvium.io:8443", "oracle.salvium.io:8443"}};
|
||||
|
||||
@@ -418,6 +465,26 @@ namespace config
|
||||
"-----END PUBLIC KEY-----\n";
|
||||
|
||||
std::string const TREASURY_ADDRESS = "fuLMowH85abK8nz9BBMEem7MAfUbQu4aSHHUV9j5Z86o6Go9Lv2U5ZQiJCWPY9R9HA8p5idburazjAhCqDngLo7fYPCD9ciM9ee1A";
|
||||
|
||||
// treasury payout {tx-key, output-key} pairs
|
||||
const std::vector<std::pair<std::string, std::string>> TREASURY_SAL1_MINT_OUTPUT_KEYS = {
|
||||
{"a1bdd1da651fbbb845232816e1aa2d4ff29b790f10bbd4f574a012f1199e15a4", "b0733ab6f251b16458efa9ebb3fb99bd54d43173b5768fe9ffc42e0fe46ae3a8"},
|
||||
{"47996eccbcc078b06d0f6ece37bf3a700c2bd60adfdd898b22096f16a9ad315c", "fd6bcceb4799ee067d59b97a6f66a0f9a70f134220259d3b4d6a2278ba4aca4c"},
|
||||
{"a3e6754a849b80c21a77e6065fefdae29eeeabf17c407453356244a00545bdb8", "3d395454df1452d715d27190e022b20395871c99af578f7251c3f9752e0274a6"},
|
||||
{"0d5e97a910e0f9c606ad9c711b6595aaed142d857cde2efa519112b9a29240d5", "56c29e28bdcf4f20b4b45906b93ae7c4bf9ee82e18cd45543cb69a14ce5efb88"},
|
||||
{"495fa363de88915aa8b74818c4b80715a882a688b4f7127ab7cd3b6885f3567a", "d42dfe0da5579c82e8255eba8c0a17170023f14a6a5030da6abf9f10abb52cbb"},
|
||||
{"85ea10ec40390e4f406446fb519e974d89536154045c6df28bb3b538b254e20d", "0ce2b7dd3a8ce8b596889dac8081a62f98fd70f1f043944ab4ac592c3c59e77b"},
|
||||
{"40f201b38a319dda81e7201e57fea7924067a4a332ed71b8e51ec29ac2d67310", "8289aa6963b98d1034e94eae55d8be6b33d0a88f14f174ebcbaec70837986c7c"},
|
||||
{"c5a648cc7846341357b7b4653a58f9eb4800d88b5de587bceec7a5c28f98d05a", "3f308a203845d88e5e728fcebcdcea1f90e2f424d461617993c672a6138ad2d8"},
|
||||
{"4c51d6550b8eeb6cc8f0d395cc83a5f90ec2a4d86501b3f68da48d618ccf5711", "53f0bd8cebeefb3a88fffa5d7f6ad43d4712608ded561732467ca499df940454"},
|
||||
{"ce2f5d82118fed03d5e269e285fc16189a6cd34f38999e5c055a5dea5fce61bc", "f7fc6948b194d9bd6f2df6ecb83f04e6c8d1a2556a63fedb310a4631fe1bfc42"},
|
||||
{"6248028fd77fb02b5c6ea72dea10b417891a2da7aaf9565aed382e063b4981a3", "63986e1177499bdb23cd49afb519ec18f38cb1b0c386220b376d8ffdc2e37890"},
|
||||
{"6adcb695aa5d6d01133c68900f29e501e9549816e827ea0c164bbc78f3534dd6", "6a440ccb18f5e703e8000de3865ac40d4c18f081270d32eef377dc831f28d8d0"},
|
||||
{"b97a4d2259480f34f20e41c489ab5c2e5ae9ee84d8672a7eff8012f2260e121e", "e6eb9147ff40e22209d321d0f1bfbfe20acf5ceb6b9d0bfb13688ad28aa1232e"},
|
||||
{"4fd214602a36902f22d16927244c456e8cc5a406a9570131f138a028214ffdf0", "34060b8bd96009b9b298280ebd84fa9587fa8c9df6fb5ad0270fb6cd2098885c"},
|
||||
{"9d60178ec6d6599d7a31298f2559fb9c3111f2c70494b3a1638db877ea55b808", "7985ed03856a929663e954738d0938713407717835f760c7ca4d54844a128c91"},
|
||||
{"cd65718eab234bf419332e53bd2f48e2ade70af48c5e126ab5080321e1493dfc", "581cb4cca7a0a029ee2cac51dfc00a0c3a657d2eaf67ed3c6ae7bacc11b4f007"},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,8 +512,10 @@ namespace cryptonote
|
||||
std::array<std::string, 3> const ORACLE_URLS;
|
||||
std::string const ORACLE_PUBLIC_KEY;
|
||||
uint64_t const STAKE_LOCK_PERIOD;
|
||||
uint64_t TREASURY_SAL1_MINT_PERIOD;
|
||||
std::map<uint8_t, std::pair<uint64_t, std::pair<std::string, std::string>>> const AUDIT_HARD_FORKS;
|
||||
std::string TREASURY_ADDRESS;
|
||||
std::vector<std::pair<std::string, std::string>> TREASURY_SAL1_MINT_OUTPUT_KEYS;
|
||||
};
|
||||
inline const config_t& get_config(network_type nettype)
|
||||
{
|
||||
@@ -463,8 +532,10 @@ namespace cryptonote
|
||||
::config::ORACLE_URLS,
|
||||
::config::ORACLE_PUBLIC_KEY,
|
||||
::config::STAKE_LOCK_PERIOD,
|
||||
::config::TREASURY_SAL1_MINT_PERIOD,
|
||||
::config::AUDIT_HARD_FORKS,
|
||||
::config::TREASURY_ADDRESS
|
||||
::config::TREASURY_ADDRESS,
|
||||
::config::TREASURY_SAL1_MINT_OUTPUT_KEYS
|
||||
};
|
||||
static const config_t testnet = {
|
||||
::config::testnet::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX,
|
||||
@@ -479,8 +550,10 @@ namespace cryptonote
|
||||
::config::testnet::ORACLE_URLS,
|
||||
::config::testnet::ORACLE_PUBLIC_KEY,
|
||||
::config::testnet::STAKE_LOCK_PERIOD,
|
||||
::config::testnet::TREASURY_SAL1_MINT_PERIOD,
|
||||
::config::testnet::AUDIT_HARD_FORKS,
|
||||
::config::testnet::TREASURY_ADDRESS
|
||||
::config::testnet::TREASURY_ADDRESS,
|
||||
::config::testnet::TREASURY_SAL1_MINT_OUTPUT_KEYS
|
||||
};
|
||||
static const config_t stagenet = {
|
||||
::config::stagenet::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX,
|
||||
@@ -495,8 +568,10 @@ namespace cryptonote
|
||||
::config::stagenet::ORACLE_URLS,
|
||||
::config::stagenet::ORACLE_PUBLIC_KEY,
|
||||
::config::stagenet::STAKE_LOCK_PERIOD,
|
||||
::config::stagenet::TREASURY_SAL1_MINT_PERIOD,
|
||||
::config::stagenet::AUDIT_HARD_FORKS,
|
||||
::config::stagenet::TREASURY_ADDRESS
|
||||
::config::stagenet::TREASURY_ADDRESS,
|
||||
::config::stagenet::TREASURY_SAL1_MINT_OUTPUT_KEYS
|
||||
};
|
||||
switch (nettype)
|
||||
{
|
||||
|
||||
@@ -1416,14 +1416,74 @@ bool Blockchain::prevalidate_protocol_transaction(const block& b, uint64_t heigh
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
std::tuple<bool, size_t> Blockchain::validate_treasury_payout(const transaction& tx, const uint64_t payout_index, uint8_t hf_version) const {
|
||||
// find the treasury output
|
||||
const auto treasury_output_keys = get_config(m_nettype).TREASURY_SAL1_MINT_OUTPUT_KEYS;
|
||||
const auto expected_output_key = treasury_output_keys[payout_index].second;
|
||||
const auto &output = std::find_if(tx.vout.begin(), tx.vout.end(), [&expected_output_key](const tx_out &o) {
|
||||
std::string output_key;
|
||||
if (o.target.type() == typeid(txout_to_key)) {
|
||||
output_key = epee::string_tools::pod_to_hex(boost::get<txout_to_key>(o.target).key);
|
||||
} else if (o.target.type() == typeid(txout_to_tagged_key)) {
|
||||
output_key = epee::string_tools::pod_to_hex(boost::get<txout_to_tagged_key>(o.target).key);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return output_key == expected_output_key;
|
||||
});
|
||||
|
||||
if (output == tx.vout.end()) {
|
||||
MERROR_VER("Miner transaction does not contain treasury output");
|
||||
return {false, 0};
|
||||
}
|
||||
|
||||
if (output->amount != TREASURY_SAL1_MINT_AMOUNT) {
|
||||
MERROR_VER("Miner transaction contains treasury output with invalid amount");
|
||||
return {false, 0};
|
||||
}
|
||||
|
||||
if (output->target.type() != typeid(txout_to_key)) {
|
||||
MERROR_VER("Miner transaction contains treasury output with invalid target type");
|
||||
return {false, 0};
|
||||
}
|
||||
|
||||
if (boost::get<txout_to_key>(output->target).unlock_time != CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW) {
|
||||
MERROR_VER("Miner transaction contains treasury output with invalid target key");
|
||||
return {false, 0};
|
||||
}
|
||||
|
||||
return {true, output - tx.vout.begin()};
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
// This function validates the miner transaction reward
|
||||
bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_block_weight, uint64_t fee, uint64_t& base_reward, uint64_t already_generated_coins, bool &partial_block_reward, uint8_t version)
|
||||
{
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
|
||||
// validate treasury payout
|
||||
size_t treasury_index_in_tx_outputs;
|
||||
auto [treasury_payout_exist, treasury_payout_index] = check_treasury_payout(m_nettype, boost::get<txin_gen>(b.miner_tx.vin[0]).height, m_hardfork->get_hardforks(), version);
|
||||
if (treasury_payout_exist) {
|
||||
// check the treasury payout
|
||||
auto [valid, index_in_tx_outputs] = validate_treasury_payout(b.miner_tx, treasury_payout_index, version);
|
||||
if (!valid) {
|
||||
MERROR_VER("Miner transaction treasury output was invalid");
|
||||
return false;
|
||||
}
|
||||
treasury_index_in_tx_outputs = index_in_tx_outputs;
|
||||
}
|
||||
|
||||
//validate reward
|
||||
uint64_t money_in_use = 0;
|
||||
for (auto& o: b.miner_tx.vout)
|
||||
money_in_use += o.amount;
|
||||
for(size_t i = 0; i < b.miner_tx.vout.size(); i++)
|
||||
{
|
||||
// skip the treasury output
|
||||
if (treasury_payout_exist && (i == treasury_index_in_tx_outputs)) {
|
||||
continue;
|
||||
}
|
||||
money_in_use += b.miner_tx.vout[i].amount;
|
||||
}
|
||||
partial_block_reward = false;
|
||||
|
||||
switch (version) {
|
||||
@@ -1436,6 +1496,7 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl
|
||||
case HF_VERSION_AUDIT1_PAUSE:
|
||||
case HF_VERSION_AUDIT2:
|
||||
case HF_VERSION_AUDIT2_PAUSE:
|
||||
case HF_VERSION_TREASURY_SAL1_MINT:
|
||||
if (b.miner_tx.amount_burnt > 0) {
|
||||
CHECK_AND_ASSERT_MES(money_in_use + b.miner_tx.amount_burnt > money_in_use, false, "miner transaction is overflowed by amount_burnt");
|
||||
money_in_use += b.miner_tx.amount_burnt;
|
||||
@@ -2002,7 +2063,7 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
|
||||
//make blocks coin-base tx looks close to real coinbase tx to get truthful blob weight
|
||||
uint8_t hf_version = b.major_version;
|
||||
size_t max_outs = hf_version >= 4 ? 1 : 11;
|
||||
bool r = construct_miner_tx(height, median_weight, already_generated_coins, txs_weight, fee, miner_address, b.miner_tx, ex_nonce, max_outs, hf_version);
|
||||
bool r = construct_miner_tx(height, median_weight, already_generated_coins, txs_weight, fee, miner_address, b.miner_tx, m_nettype, m_hardfork->get_hardforks(), ex_nonce, max_outs, hf_version);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to construct miner tx, first chance");
|
||||
size_t cumulative_weight = txs_weight + get_transaction_weight(b.miner_tx);
|
||||
#if defined(DEBUG_CREATE_BLOCK_TEMPLATE)
|
||||
@@ -2011,7 +2072,7 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
|
||||
#endif
|
||||
for (size_t try_count = 0; try_count != 10; ++try_count)
|
||||
{
|
||||
r = construct_miner_tx(height, median_weight, already_generated_coins, cumulative_weight, fee, miner_address, b.miner_tx, ex_nonce, max_outs, hf_version);
|
||||
r = construct_miner_tx(height, median_weight, already_generated_coins, cumulative_weight, fee, miner_address, b.miner_tx, m_nettype, m_hardfork->get_hardforks(), ex_nonce, max_outs, hf_version);
|
||||
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to construct miner tx, second chance");
|
||||
size_t coinbase_weight = get_transaction_weight(b.miner_tx);
|
||||
|
||||
@@ -1492,6 +1492,16 @@ namespace cryptonote
|
||||
*/
|
||||
difficulty_type get_next_difficulty_for_alternative_chain(const std::list<block_extended_info>& alt_chain, block_extended_info& bei) const;
|
||||
|
||||
/**
|
||||
* @brief validates the treasury payout for a block
|
||||
* @param tx transaction to validate
|
||||
* @param payout_index the index of the payout to check
|
||||
* @param hf_version the consensus rules to apply
|
||||
*
|
||||
* @return bool indicating payout valid, and the index of the output within miner transaction outputs.
|
||||
*/
|
||||
std::tuple<bool, size_t> validate_treasury_payout(const transaction& tx, const uint64_t payout_index, uint8_t hf_version) const;
|
||||
|
||||
/**
|
||||
* @brief sanity checks a miner transaction before validating an entire block
|
||||
*
|
||||
|
||||
@@ -335,6 +335,34 @@ namespace cryptonote
|
||||
}
|
||||
*/
|
||||
//---------------------------------------------------------------
|
||||
std::tuple<bool, uint64_t> check_treasury_payout(
|
||||
network_type nettype,
|
||||
uint64_t height,
|
||||
const std::vector<hardfork_t>& hardforks,
|
||||
const uint8_t hf_version
|
||||
) {
|
||||
if (hf_version >= HF_VERSION_TREASURY_SAL1_MINT) {
|
||||
// find the hardfork height
|
||||
const auto& hf = std::find_if(hardforks.begin(), hardforks.end(), [](const hardfork_t& hf) {
|
||||
return hf.version == HF_VERSION_TREASURY_SAL1_MINT;
|
||||
});
|
||||
|
||||
// since we are at least at the hard fork HF_VERSION_TREASURY_SAL1_MINT, we assume height >= hf->height
|
||||
const auto diff = height - hf->height;
|
||||
const auto mint_period = get_config(nettype).TREASURY_SAL1_MINT_PERIOD;
|
||||
|
||||
// pay per period
|
||||
if (diff % mint_period == 0) {
|
||||
const auto payout_index = diff / mint_period;
|
||||
if (payout_index < TREASURY_SAL1_MINT_COUNT) {
|
||||
return {true, payout_index};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {false, 0};
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool construct_protocol_tx(
|
||||
const size_t height,
|
||||
transaction& tx,
|
||||
@@ -389,12 +417,15 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool construct_miner_tx(size_t height, size_t median_weight, uint64_t already_generated_coins, size_t current_block_weight, uint64_t fee, const account_public_address &miner_address, transaction& tx, const blobdata& extra_nonce, size_t max_outs, uint8_t hard_fork_version) {
|
||||
bool construct_miner_tx(size_t height, size_t median_weight, uint64_t already_generated_coins, size_t current_block_weight, uint64_t fee, const account_public_address &miner_address, transaction& tx, network_type nettype, const std::vector<hardfork_t>& hardforks, const blobdata& extra_nonce, size_t max_outs, uint8_t hard_fork_version) {
|
||||
|
||||
// Clear the TX contents
|
||||
tx.set_null();
|
||||
tx.type = cryptonote::transaction_type::MINER;
|
||||
|
||||
// check for treasury payouts
|
||||
auto[treasury_payout_exist, treasury_payout_index] = check_treasury_payout(nettype, height, hardforks, hard_fork_version);
|
||||
|
||||
keypair txkey = keypair::generate(hw::get_device("default"));
|
||||
add_tx_pub_key_to_extra(tx, txkey.pub);
|
||||
if(!extra_nonce.empty())
|
||||
@@ -451,6 +482,7 @@ namespace cryptonote
|
||||
case HF_VERSION_AUDIT1_PAUSE:
|
||||
case HF_VERSION_AUDIT2:
|
||||
case HF_VERSION_AUDIT2_PAUSE:
|
||||
case HF_VERSION_TREASURY_SAL1_MINT:
|
||||
// SRCG: subtract 20% that will be rewarded to staking users
|
||||
CHECK_AND_ASSERT_MES(tx.amount_burnt == 0, false, "while creating outs: amount_burnt is nonzero");
|
||||
tx.amount_burnt = amount / 5;
|
||||
@@ -464,7 +496,7 @@ namespace cryptonote
|
||||
std::string asset_type = "SAL";
|
||||
if (hard_fork_version >= HF_VERSION_SALVIUM_ONE_PROOFS)
|
||||
asset_type = "SAL1";
|
||||
cryptonote::set_tx_out(amount, asset_type, CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, out_eph_public_key, use_view_tags, view_tag, out);
|
||||
cryptonote::set_tx_out(amount, asset_type, CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, out_eph_public_key, !treasury_payout_exist, view_tag, out);
|
||||
tx.vout.push_back(out);
|
||||
|
||||
} else {
|
||||
@@ -477,10 +509,29 @@ namespace cryptonote
|
||||
|
||||
CHECK_AND_ASSERT_MES(summary_amounts == block_reward, false, "Failed to construct miner tx, summary_amounts = " << summary_amounts << " not equal block_reward = " << block_reward);
|
||||
|
||||
// add the treasury payout if needed
|
||||
if (treasury_payout_exist) {
|
||||
std::vector<crypto::public_key> additional_tx_public_keys = {txkey.pub};
|
||||
const auto output_keys = get_config(nettype).TREASURY_SAL1_MINT_OUTPUT_KEYS;
|
||||
const auto keys = output_keys[treasury_payout_index];
|
||||
|
||||
crypto::public_key tx_key;
|
||||
CHECK_AND_ASSERT_MES(epee::string_tools::hex_to_pod(keys.first, tx_key), false, "fail to deserialize treasury tx key");
|
||||
crypto::public_key output_key;
|
||||
CHECK_AND_ASSERT_MES(epee::string_tools::hex_to_pod(keys.second, output_key), false, "fail to deserialize treasury output key");
|
||||
|
||||
// Create the TX output for this payout
|
||||
tx_out out;
|
||||
cryptonote::set_tx_out(TREASURY_SAL1_MINT_AMOUNT, "SAL1", CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, output_key, false, crypto::view_tag{}, out);
|
||||
tx.vout.push_back(out);
|
||||
|
||||
// add tx pub key to tx extra
|
||||
additional_tx_public_keys.push_back(tx_key);
|
||||
add_additional_tx_pub_keys_to_extra(tx.extra, additional_tx_public_keys);
|
||||
}
|
||||
|
||||
tx.version = 2;
|
||||
|
||||
tx.vin.push_back(in);
|
||||
|
||||
tx.invalidate_hashes();
|
||||
|
||||
//LOG_PRINT("MINER_TX generated ok, block_reward=" << print_money(block_reward) << "(" << print_money(block_reward - fee) << "+" << print_money(fee)
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
#include "oracle/pricing_record.h"
|
||||
#include "cryptonote_protocol/enums.h"
|
||||
|
||||
#include "hardforks/hardforks.h"
|
||||
|
||||
namespace cryptonote
|
||||
{
|
||||
/*
|
||||
@@ -72,7 +74,9 @@ namespace cryptonote
|
||||
//---------------------------------------------------------------
|
||||
bool construct_protocol_tx(const size_t height, transaction& tx, std::vector<protocol_data_entry>& protocol_data, const uint8_t hf_version);
|
||||
//---------------------------------------------------------------
|
||||
bool construct_miner_tx(size_t height, size_t median_weight, uint64_t already_generated_coins, size_t current_block_weight, uint64_t fee, const account_public_address &miner_address, transaction& tx, const blobdata& extra_nonce = blobdata(), size_t max_outs = 999, uint8_t hard_fork_version = 1);
|
||||
bool construct_miner_tx(size_t height, size_t median_weight, uint64_t already_generated_coins, size_t current_block_weight, uint64_t fee, const account_public_address &miner_address, transaction& tx, network_type nettype = network_type::FAKECHAIN, const std::vector<hardfork_t>& hardforks = {}, const blobdata& extra_nonce = blobdata(), size_t max_outs = 999, uint8_t hard_fork_version = 1);
|
||||
//---------------------------------------------------------------
|
||||
std::tuple<bool, uint64_t> check_treasury_payout(network_type nettype, uint64_t height, const std::vector<hardfork_t>& hardforks, const uint8_t hf_version);
|
||||
|
||||
struct tx_source_entry
|
||||
{
|
||||
|
||||
+1
-1
@@ -149,7 +149,7 @@ void print_genesis_tx_hex(const cryptonote::network_type nettype) {
|
||||
|
||||
//Prepare genesis_tx
|
||||
cryptonote::transaction tx_genesis;
|
||||
cryptonote::construct_miner_tx(0, 0, 0, 10, 0, miner_acc1.get_keys().m_account_address, tx_genesis, blobdata(), 999, 1);
|
||||
cryptonote::construct_miner_tx(0, 0, 0, 10, 0, miner_acc1.get_keys().m_account_address, tx_genesis, (network_type)nettype, {}, blobdata(), 999, 1);
|
||||
std::cout << "Object:" << std::endl;
|
||||
std::cout << obj_to_json_str(tx_genesis) << std::endl << std::endl;
|
||||
|
||||
|
||||
@@ -89,6 +89,9 @@ const hardfork_t testnet_hard_forks[] = {
|
||||
|
||||
// version 9 (audit 1 complete, whitelist controlling payouts) starts from block 1000
|
||||
{ 9, 1000, 0, 1739280000 },
|
||||
|
||||
// version 10 treasury mint starts from block 1100
|
||||
{10, 1100, 0, 1739780005 },
|
||||
};
|
||||
const size_t num_testnet_hard_forks = sizeof(testnet_hard_forks) / sizeof(testnet_hard_forks[0]);
|
||||
const uint64_t testnet_hard_fork_version_1_till = ((uint64_t)-1);
|
||||
|
||||
@@ -272,7 +272,7 @@ bool test_generator::construct_block(cryptonote::block& blk, uint64_t height, co
|
||||
size_t target_block_weight = txs_weight + get_transaction_weight(blk.miner_tx);
|
||||
while (true)
|
||||
{
|
||||
if (!construct_miner_tx(height, misc_utils::median(block_weights), already_generated_coins, target_block_weight, total_fee, miner_acc.get_keys().m_account_address, blk.miner_tx, blobdata(), 10, hf_ver ? hf_ver.get() : 1))
|
||||
if (!construct_miner_tx(height, misc_utils::median(block_weights), already_generated_coins, target_block_weight, total_fee, miner_acc.get_keys().m_account_address, blk.miner_tx, network_type::FAKECHAIN, {}, blobdata(), 10, hf_ver ? hf_ver.get() : 1))
|
||||
return false;
|
||||
|
||||
size_t actual_block_weight = txs_weight + get_transaction_weight(blk.miner_tx);
|
||||
@@ -375,7 +375,7 @@ bool test_generator::construct_block_manually(block& blk, const block& prev_bloc
|
||||
{
|
||||
size_t current_block_weight = txs_weight + get_transaction_weight(blk.miner_tx);
|
||||
// TODO: This will work, until size of constructed block is less then CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE
|
||||
if (!construct_miner_tx(height, misc_utils::median(block_weights), already_generated_coins, current_block_weight, fees, miner_acc.get_keys().m_account_address, blk.miner_tx, blobdata(), max_outs, hf_version))
|
||||
if (!construct_miner_tx(height, misc_utils::median(block_weights), already_generated_coins, current_block_weight, fees, miner_acc.get_keys().m_account_address, blk.miner_tx, cryptonote::network_type::FAKECHAIN, {}, blobdata(), max_outs, hf_version))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ bool test_block_creation()
|
||||
bool r = get_account_address_from_str(info, MAINNET, "0099be99c70ef10fd534c43c88e9d13d1c8853213df7e362afbec0e4ee6fec4948d0c190b58f4b356cd7feaf8d9d0a76e7c7e5a9a0a497a6b1faf7a765882dd08ac2");
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to import");
|
||||
block b;
|
||||
r = construct_miner_tx(90, epee::misc_utils::median(szs), 3553616528562147, 33094, 10000000, info.address, b.miner_tx, blobdata(), 11);
|
||||
r = construct_miner_tx(90, epee::misc_utils::median(szs), 3553616528562147, 33094, 10000000, info.address, b.miner_tx, cryptonote::network_type::FAKECHAIN, {}, blobdata(), 11);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,16 @@
|
||||
|
||||
#include "cryptonote_basic/account.h"
|
||||
|
||||
|
||||
#include "cryptonote_basic/cryptonote_basic_impl.h"
|
||||
#include "cryptonote_basic/cryptonote_basic.h"
|
||||
#include "cryptonote_basic/subaddress_index.h"
|
||||
#include "cryptonote_basic/cryptonote_format_utils.h"
|
||||
|
||||
#include "string_tools.h"
|
||||
|
||||
using namespace cryptonote;
|
||||
|
||||
TEST(account, encrypt_keys)
|
||||
{
|
||||
cryptonote::keypair recovery_key = cryptonote::keypair::generate(hw::get_device("default"));
|
||||
@@ -69,3 +79,48 @@ TEST(account, encrypt_keys)
|
||||
ASSERT_EQ(account.get_keys().m_spend_secret_key, keys.m_spend_secret_key);
|
||||
ASSERT_EQ(account.get_keys().m_view_secret_key, keys.m_view_secret_key);
|
||||
}
|
||||
|
||||
|
||||
TEST(account, derive_output_key)
|
||||
{
|
||||
const std::string secret_view = "";
|
||||
const std::string addr = "";
|
||||
address_parse_info address_info;
|
||||
bool ok = get_account_address_from_str(address_info, network_type::MAINNET, addr);
|
||||
ASSERT_TRUE(ok);
|
||||
|
||||
std::unordered_map<crypto::public_key, subaddress_index> subaddresses = {{
|
||||
{address_info.address.m_spend_public_key, {0, 0}},
|
||||
}};
|
||||
|
||||
// derive keys
|
||||
std::vector<std::pair<crypto::public_key, crypto::public_key>> txkeys;
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
// tx key
|
||||
keypair txkey = keypair::generate(hw::get_device("default"));
|
||||
|
||||
crypto::key_derivation derivation = AUTO_VAL_INIT(derivation);
|
||||
crypto::public_key out_eph_public_key = AUTO_VAL_INIT(out_eph_public_key);
|
||||
ok = crypto::generate_key_derivation(address_info.address.m_view_public_key, txkey.sec, derivation);
|
||||
ASSERT_TRUE(ok);
|
||||
|
||||
ok = crypto::derive_public_key(derivation, 0, address_info.address.m_spend_public_key, out_eph_public_key);
|
||||
ASSERT_TRUE(ok);
|
||||
|
||||
txkeys.push_back({txkey.pub, out_eph_public_key});
|
||||
}
|
||||
|
||||
// validate we can receive them
|
||||
crypto::secret_key secret_view_key;
|
||||
epee::string_tools::hex_to_pod(secret_view, secret_view_key);
|
||||
size_t i = 0;
|
||||
for (const auto& txkey : txkeys) {
|
||||
crypto::key_derivation derivation;
|
||||
hw::device *hw = &hw::get_device("default");
|
||||
|
||||
ASSERT_TRUE(hw->generate_key_derivation(txkey.first, secret_view_key, derivation));
|
||||
ASSERT_TRUE(is_out_to_acc_precomp(subaddresses, txkey.second, derivation, {}, 0, *hw, boost::none));
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ TEST(parse_and_validate_tx_extra, is_valid_tx_extra_parsed)
|
||||
cryptonote::account_base acc;
|
||||
acc.generate();
|
||||
cryptonote::blobdata b = "dsdsdfsdfsf";
|
||||
ASSERT_TRUE(cryptonote::construct_miner_tx(0, 0, 10000000000000, 1000, TEST_FEE, acc.get_keys().m_account_address, tx, b, 1));
|
||||
ASSERT_TRUE(cryptonote::construct_miner_tx(0, 0, 10000000000000, 1000, TEST_FEE, acc.get_keys().m_account_address, tx, cryptonote::network_type::FAKECHAIN, {}, b, 1));
|
||||
crypto::public_key tx_pub_key = cryptonote::get_tx_pub_key_from_extra(tx);
|
||||
ASSERT_NE(tx_pub_key, crypto::null_pkey);
|
||||
}
|
||||
@@ -151,7 +151,7 @@ TEST(parse_and_validate_tx_extra, fails_on_big_extra_nonce)
|
||||
cryptonote::account_base acc;
|
||||
acc.generate();
|
||||
cryptonote::blobdata b(TX_EXTRA_NONCE_MAX_COUNT + 1, 0);
|
||||
ASSERT_FALSE(cryptonote::construct_miner_tx(0, 0, 10000000000000, 1000, TEST_FEE, acc.get_keys().m_account_address, tx, b, 1));
|
||||
ASSERT_FALSE(cryptonote::construct_miner_tx(0, 0, 10000000000000, 1000, TEST_FEE, acc.get_keys().m_account_address, tx, cryptonote::network_type::FAKECHAIN, {}, b, 1));
|
||||
}
|
||||
TEST(parse_and_validate_tx_extra, fails_on_wrong_size_in_extra_nonce)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user