OpenCBDC Transaction Processor
Loading...
Searching...
No Matches
agent/runners/evm/util.cpp
Go to the documentation of this file.
1// Copyright (c) 2022 MIT Digital Currency Initiative,
2// Federal Reserve Bank of Boston
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include "util.hpp"
7
8#include "crypto/sha256.h"
9#include "format.hpp"
10#include "hash.hpp"
11#include "init_addresses.hpp"
12#include "math.hpp"
13#include "parsec/util.hpp"
14#include "rlp.hpp"
15#include "util/common/hash.hpp"
17
18#include <future>
19#include <optional>
20#include <secp256k1.h>
21
23 auto to_uint64(const evmc::uint256be& v) -> uint64_t {
24 return evmc::load64be(&v.bytes[sizeof(v.bytes) - sizeof(uint64_t)]);
25 }
26
27 auto to_hex(const evmc::address& addr) -> std::string {
28 return evmc::hex(evmc::bytes(addr.bytes, sizeof(addr.bytes)));
29 }
30
31 auto to_hex(const evmc::bytes32& b) -> std::string {
32 return evmc::hex(evmc::bytes(b.bytes, sizeof(b.bytes)));
33 }
34
35 auto to_hex_trimmed(const evmc::bytes32& b, const std::string& prefix)
36 -> std::string {
37 auto b_vec = std::vector<uint8_t>();
38 b_vec.resize(sizeof(b.bytes));
39 std::memcpy(b_vec.data(), &b.bytes[0], sizeof(b.bytes));
40 size_t offset = 0;
41 while(offset < b_vec.size() && b_vec.at(offset) == 0x00) {
42 offset++;
43 }
44 if(offset >= sizeof(b.bytes)) {
45 return prefix + "0";
46 }
47
48 auto str
49 = evmc::hex(evmc::bytes(&b_vec.at(offset), b_vec.size() - offset));
50 if(str.substr(0, 1) == "0") {
51 str = str.substr(1);
52 }
53 return prefix + str;
54 }
55
56 // Taken from: ethereum.github.io/execution-specs/autoapi/ethereum/
57 // frontier/bloom/index.html#logs-bloom
58 void add_to_bloom(cbdc::buffer& bloom, const cbdc::buffer& entry) {
59 auto hash = cbdc::make_buffer(keccak_data(entry.data(), entry.size()));
60
61 for(size_t i = 0; i <= 4; i += 2) {
62 auto uint16_buf = cbdc::buffer();
63 uint16_buf.extend(2);
64 std::memcpy(uint16_buf.data(), hash.data_at(i), 2);
65 uint16_t byte_pair
66 = cbdc::from_buffer<uint16_t>(uint16_buf).value();
67 static constexpr uint16_t bloom_bits = 0x07FF;
68 auto bit_to_set = byte_pair & bloom_bits;
69 auto bit_index = bloom_bits - bit_to_set;
70 constexpr auto bits_in_byte = 8;
71 auto byte_index = static_cast<size_t>(bit_index / bits_in_byte);
72 auto bit_value = static_cast<uint8_t>(
73 1 << ((bits_in_byte - 1) - (bit_index % bits_in_byte)));
74 uint8_t bloom_byte{};
75 std::memcpy(&bloom_byte, bloom.data_at(byte_index), 1);
76 bloom_byte |= bit_value;
77 std::memcpy(bloom.data_at(byte_index), &bloom_byte, 1);
78 }
79 }
80
81 auto uint256be_from_hex(const std::string& hex)
82 -> std::optional<evmc::uint256be> {
83 auto maybe_bytes = cbdc::buffer::from_hex_prefixed(hex);
84 if(!maybe_bytes.has_value()) {
85 return std::nullopt;
86 }
87 auto ret = evmc::uint256be();
88 auto& bytes = maybe_bytes.value();
89 if(bytes.size() > sizeof(ret)) {
90 return std::nullopt;
91 }
92 auto tmp = cbdc::buffer();
93 tmp.extend(sizeof(ret));
94 std::memcpy(tmp.data_at(sizeof(ret) - bytes.size()),
95 bytes.data(),
96 bytes.size());
97 std::memcpy(&ret.bytes[0], tmp.data(), tmp.size());
98 return ret;
99 }
100
102 const std::shared_ptr<logging::log>& log,
103 const std::shared_ptr<parsec::broker::interface>& broker) -> bool {
104 log->info("Initializing init addresses");
105
107 static constexpr uint64_t decimals = 1000000000000000000;
108 static constexpr uint64_t initial_mint = 1000000;
109 acc.m_balance
110 = evmc::uint256be(initial_mint) * evmc::uint256be(decimals);
111 auto acc_buf = cbdc::make_buffer(acc);
112
113 auto successes = std::vector<std::future<bool>>();
114
115 for(const auto& init_addr_hex :
117 log->info("Seeding address ", init_addr_hex);
118 auto init_addr = cbdc::buffer::from_hex(init_addr_hex).value();
119 auto seed_success = std::make_shared<std::promise<bool>>();
120 auto seed_fut = seed_success->get_future();
121 successes.emplace_back(std::move(seed_fut));
122 auto success
123 = cbdc::parsec::put_row(broker,
124 init_addr,
125 acc_buf,
126 [seed_success](bool s) {
127 seed_success->set_value(s);
128 });
129 if(!success) {
130 log->error("Error requesting seeding account");
131 return false;
132 }
133 }
134
135 for(auto& f : successes) {
136 auto seed_res = f.get();
137 if(!seed_res) {
138 log->error("Error during seeding");
139 return false;
140 }
141 }
142
143 return true;
144 }
145}
Buffer to store and retrieve byte data.
Definition buffer.hpp:15
auto data() -> void *
Returns a raw pointer to the start of the buffer data.
Definition buffer.cpp:28
static auto from_hex(const std::string &hex) -> std::optional< cbdc::buffer >
Creates a new buffer from the provided hex string.
Definition buffer.cpp:85
static auto from_hex_prefixed(const std::string &hex, const std::string &prefix="0x") -> std::optional< buffer >
Creates a new buffer from the provided hex string optionally prefixed with a prefix sequence.
Definition buffer.cpp:108
auto size() const -> size_t
Returns the number of bytes contained in the buffer.
Definition buffer.cpp:24
auto data_at(size_t offset) -> void *
Returns a raw pointer to the start of the buffer data.
Definition buffer.cpp:36
auto mint_initial_accounts(const std::shared_ptr< logging::log > &log, const std::shared_ptr< parsec::broker::interface > &broker) -> bool
Mints a set of initial accounts with funds, bypassing the agent.
auto to_hex_trimmed(const evmc::bytes32 &b, const std::string &prefix) -> std::string
auto to_hex(const evmc::address &addr) -> std::string
auto uint256be_from_hex(const std::string &hex) -> std::optional< evmc::uint256be >
Generates a uint256be from a hex string.
void add_to_bloom(cbdc::buffer &bloom, const cbdc::buffer &entry)
Adds an entry to a bloom value.
auto to_uint64(const evmc::uint256be &v) -> uint64_t
Converts an uint256be to a uint64_t, ignoring higher order bits.
const std::vector< std::string > init_addresses_for_testing
List of initial addresses to mint accounts for testing.
auto put_row(const std::shared_ptr< broker::interface > &broker, broker::key_type key, broker::value_type value, const std::function< void(bool)> &result_callback) -> bool
Asynchronously inserts the given row into the cluster.
Definition util.cpp:195
auto from_buffer(nuraft::buffer &buf) -> std::optional< T >
Deserialize object of given type from a nuraft::buffer.
@ buffer
A singular RLP value (byte array)
auto keccak_data(const void *data, size_t len) -> hash_t
Calculates the Keccak256 hash of the specified data.
auto make_buffer(const T &obj) -> std::enable_if_t< std::is_same_v< B, nuraft::ptr< nuraft::buffer > >, nuraft::ptr< nuraft::buffer > >
Serialize object into nuraft::buffer using a cbdc::nuraft_serializer.