Initial representative weights for bootstrapping
This commit is contained in:
parent
beb3618f25
commit
89339ef08b
7 changed files with 160 additions and 1 deletions
|
@ -230,8 +230,18 @@ else ()
|
|||
error ("Unknown platform: ${CMAKE_SYSTEM_NAME}")
|
||||
endif ()
|
||||
|
||||
# Embed bootstrap representative weights in executable
|
||||
file (READ rep_weights.bin filedata HEX)
|
||||
string (REGEX REPLACE "(..)" "0x\\1," filedata ${filedata})
|
||||
file (WRITE ${CMAKE_BINARY_DIR}/bootstrap_weights.cpp "#include <cstddef>\n\
|
||||
namespace rai {\n\
|
||||
unsigned char rai_bootstrap_weights[] = {${filedata} 0x00};\n\
|
||||
size_t rai_bootstrap_weights_size = sizeof(rai_bootstrap_weights) - 1;\n\
|
||||
}\n")
|
||||
|
||||
add_library (secure
|
||||
${PLATFORM_SECURE_SOURCE}
|
||||
${CMAKE_BINARY_DIR}/bootstrap_weights.cpp
|
||||
rai/config.hpp
|
||||
rai/secure.cpp
|
||||
rai/secure.hpp
|
||||
|
|
63
ci/record_rep_weights.py
Normal file
63
ci/record_rep_weights.py
Normal file
|
@ -0,0 +1,63 @@
|
|||
import requests
|
||||
import argparse
|
||||
import string
|
||||
from binascii import unhexlify
|
||||
from base64 import b32decode
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(description='Generate bootstrap representative weight file.')
|
||||
parser.add_argument("output", type=str, help="output weight file")
|
||||
parser.add_argument("--rpc", help="node rpc host:port", default="http://[::1]:7076")
|
||||
parser.add_argument("--limit", help="percentage of the active supply represented", default=0.99)
|
||||
parser.add_argument("--cutoff", help="stop using bootstrap reps this many blocks before the current block height", default=250000)
|
||||
args = parser.parse_args()
|
||||
|
||||
r = requests.post(args.rpc, data='{"action":"representatives"}')
|
||||
p = r.json()
|
||||
|
||||
reps = [ ]
|
||||
tbl = string.maketrans('13456789abcdefghijkmnopqrstuwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')
|
||||
for acc in p["representatives"]:
|
||||
reps.append({
|
||||
'account': acc,
|
||||
'weight': long(p["representatives"][acc])
|
||||
})
|
||||
|
||||
r = requests.post(args.rpc, data='{"action":"block_count"}')
|
||||
p = r.json()
|
||||
block_height = max(0, int(p["count"]) - args.cutoff)
|
||||
|
||||
print "cutoff block height is %d" % block_height
|
||||
|
||||
reps.sort(key=lambda x: x["weight"], reverse=True)
|
||||
|
||||
supplymax = long(0)
|
||||
for rep in reps:
|
||||
supplymax += rep["weight"]
|
||||
|
||||
supplymax /= long('1000000000000000000000000000000')
|
||||
supplymax = long(supplymax * args.limit)
|
||||
supplymax *= long('1000000000000000000000000000000')
|
||||
|
||||
with open(args.output, 'wb') as of:
|
||||
of.write(unhexlify("%032X" % block_height))
|
||||
|
||||
total = long(0)
|
||||
count = 0
|
||||
for rep in reps:
|
||||
if rep["weight"] == 0:
|
||||
break
|
||||
acc_val = long(hexlify(b32decode(rep["account"].encode("utf-8").replace("xrb_", "").translate(tbl) + "====")), 16)
|
||||
acc_bytes = unhexlify("%064X" % (((acc_val >> 36) & ((1 << 256) - 1))))
|
||||
weight_bytes = unhexlify("%032X" % rep["weight"])
|
||||
of.write(acc_bytes)
|
||||
of.write(weight_bytes)
|
||||
total += rep["weight"]
|
||||
count += 1
|
||||
if total >= supplymax:
|
||||
break
|
||||
|
||||
print "wrote %d rep weights" % count
|
||||
|
||||
of.close()
|
|
@ -1431,3 +1431,38 @@ TEST (ledger, send_open_receive_rollback)
|
|||
ASSERT_EQ (0, ledger.weight (transaction, key3.pub));
|
||||
ASSERT_EQ (rai::genesis_amount - 0, ledger.weight (transaction, rai::test_genesis_key.pub));
|
||||
}
|
||||
|
||||
TEST (ledger, bootstrap_rep_weight)
|
||||
{
|
||||
bool init (false);
|
||||
rai::block_store store (init, rai::unique_path ());
|
||||
ASSERT_TRUE (!init);
|
||||
rai::ledger ledger (store, 40);
|
||||
rai::account_info info1;
|
||||
rai::keypair key2;
|
||||
rai::genesis genesis;
|
||||
{
|
||||
rai::transaction transaction (store.environment, nullptr, true);
|
||||
genesis.initialize (transaction, store);
|
||||
ASSERT_FALSE (store.account_get (transaction, rai::test_genesis_key.pub, info1));
|
||||
rai::send_block send (info1.head, key2.pub, std::numeric_limits<rai::uint128_t>::max () - 50, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0);
|
||||
ledger.process (transaction, send);
|
||||
}
|
||||
{
|
||||
rai::transaction transaction (store.environment, nullptr, false);
|
||||
ledger.bootstrap_weight_max_blocks = 3;
|
||||
ledger.bootstrap_weights[key2.pub] = 1000;
|
||||
ASSERT_EQ (1000, ledger.weight (transaction, key2.pub));
|
||||
}
|
||||
{
|
||||
rai::transaction transaction (store.environment, nullptr, true);
|
||||
genesis.initialize (transaction, store);
|
||||
ASSERT_FALSE (store.account_get (transaction, rai::test_genesis_key.pub, info1));
|
||||
rai::send_block send (info1.head, key2.pub, std::numeric_limits<rai::uint128_t>::max () - 100, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0);
|
||||
ledger.process (transaction, send);
|
||||
}
|
||||
{
|
||||
rai::transaction transaction (store.environment, nullptr, false);
|
||||
ASSERT_EQ (0, ledger.weight (transaction, key2.pub));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1525,6 +1525,37 @@ block_processor_thread ([this]() { this->block_processor.process_blocks (); })
|
|||
genesis.initialize (transaction, store);
|
||||
}
|
||||
}
|
||||
if (rai::rai_network == rai::rai_networks::rai_live_network)
|
||||
{
|
||||
extern const char rai_bootstrap_weights[];
|
||||
extern const size_t rai_bootstrap_weights_size;
|
||||
rai::bufferstream weight_stream ((const uint8_t *)rai_bootstrap_weights, rai_bootstrap_weights_size);
|
||||
rai::uint128_union block_height;
|
||||
if (!rai::read (weight_stream, block_height))
|
||||
{
|
||||
auto max_blocks = (uint64_t)block_height.number ();
|
||||
rai::transaction transaction (store.environment, nullptr, false);
|
||||
if (ledger.store.block_count (transaction).sum () < max_blocks)
|
||||
{
|
||||
ledger.bootstrap_weight_max_blocks = max_blocks;
|
||||
while (true)
|
||||
{
|
||||
rai::account account;
|
||||
if (rai::read (weight_stream, account.bytes))
|
||||
{
|
||||
break;
|
||||
}
|
||||
rai::amount weight;
|
||||
if (rai::read (weight_stream, weight.bytes))
|
||||
{
|
||||
break;
|
||||
}
|
||||
BOOST_LOG (log) << "Using bootstrap rep weight: " << account.to_account () << " -> " << weight.format_balance (Mxrb_ratio, 0, true) << " XRB";
|
||||
ledger.bootstrap_weights[account] = weight.number ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rai::node::~node ()
|
||||
|
|
|
@ -219,7 +219,8 @@ rai::keypair::keypair (std::string const & prv_a)
|
|||
|
||||
rai::ledger::ledger (rai::block_store & store_a, rai::uint128_t const & inactive_supply_a) :
|
||||
store (store_a),
|
||||
inactive_supply (inactive_supply_a)
|
||||
inactive_supply (inactive_supply_a),
|
||||
check_bootstrap_weights (true)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -2424,6 +2425,22 @@ std::string rai::ledger::block_text (rai::block_hash const & hash_a)
|
|||
// Vote weight of an account
|
||||
rai::uint128_t rai::ledger::weight (MDB_txn * transaction_a, rai::account const & account_a)
|
||||
{
|
||||
if (check_bootstrap_weights.load ())
|
||||
{
|
||||
auto blocks = store.block_count (transaction_a);
|
||||
if (blocks.sum () < bootstrap_weight_max_blocks)
|
||||
{
|
||||
auto weight = bootstrap_weights.find (account_a);
|
||||
if (weight != bootstrap_weights.end ())
|
||||
{
|
||||
return weight->second;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
check_bootstrap_weights = false;
|
||||
}
|
||||
}
|
||||
return store.representation_get (transaction_a, account_a);
|
||||
}
|
||||
|
||||
|
|
|
@ -390,6 +390,9 @@ public:
|
|||
static rai::uint128_t const unit;
|
||||
rai::block_store & store;
|
||||
rai::uint128_t inactive_supply;
|
||||
std::unordered_map<rai::account, rai::uint128_t> bootstrap_weights;
|
||||
uint64_t bootstrap_weight_max_blocks;
|
||||
std::atomic<bool> check_bootstrap_weights;
|
||||
};
|
||||
extern rai::keypair const & zero_key;
|
||||
extern rai::keypair const & test_genesis_key;
|
||||
|
|
BIN
rep_weights.bin
Normal file
BIN
rep_weights.bin
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue