Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add EVM block header to coinbase #1859

Merged
merged 13 commits into from
Apr 5, 2023
2 changes: 1 addition & 1 deletion src/defid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static bool AppInit(int argc, char* argv[])
util::ThreadRename("init");
init_runtime();
// Test linking to dummy address
Jouzo marked this conversation as resolved.
Show resolved Hide resolved
evm_add_balance("0xf3088943Fa15Ff33D5C3Af9845dc65073Ae2bAc8", 100);
evm_add_balance("0xf3088943Fa15Ff33D5C3Af9845dc65073Ae2bAc8", ArithToUint256(100).ToArrayReversed());
Jouzo marked this conversation as resolved.
Show resolved Hide resolved

//
// Parameters
Expand Down
19 changes: 13 additions & 6 deletions src/masternodes/mn_checks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,7 @@ Res CCustomTxVisitor::IsOnChainGovernanceEnabled() const {
class CCustomTxApplyVisitor : public CCustomTxVisitor {
uint64_t time;
uint32_t txn;
uint64_t evmContext;

public:
CCustomTxApplyVisitor(const CTransaction &tx,
Expand All @@ -779,11 +780,13 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor {
CCustomCSView &mnview,
const Consensus::Params &consensus,
uint64_t time,
uint32_t txn)
uint32_t txn,
const uint64_t evmContext)

: CCustomTxVisitor(tx, height, coins, mnview, consensus),
time(time),
txn(txn) {}
txn(txn),
evmContext(evmContext) {}

Res operator()(const CCreateMasterNodeMessage &obj) const {
Require(CheckMasternodeCreationTx());
Expand Down Expand Up @@ -3862,7 +3865,9 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor {
return Res::Err("evm tx failed to validate");
}

// TODO Execute TX
if (!evm_queue_tx(evmContext, HexStr(obj.evmTx))) {
return Res::Err("evm tx failed to queue");
}

return Res::Ok();
}
Expand Down Expand Up @@ -3945,12 +3950,13 @@ Res CustomTxVisit(CCustomCSView &mnview,
const Consensus::Params &consensus,
const CCustomTxMessage &txMessage,
uint64_t time,
uint32_t txn) {
uint32_t txn,
const uint64_t evmContext) {
if (IsDisabledTx(height, tx, consensus)) {
return Res::ErrCode(CustomTxErrCodes::Fatal, "Disabled custom transaction");
}
try {
return std::visit(CCustomTxApplyVisitor(tx, height, coins, mnview, consensus, time, txn), txMessage);
return std::visit(CCustomTxApplyVisitor(tx, height, coins, mnview, consensus, time, txn, evmContext), txMessage);
} catch (const std::bad_variant_access &e) {
return Res::Err(e.what());
} catch (...) {
Expand Down Expand Up @@ -4035,7 +4041,8 @@ Res ApplyCustomTx(CCustomCSView &mnview,
uint32_t height,
uint64_t time,
uint256 *canSpend,
uint32_t txn) {
uint32_t txn,
const uint64_t evmContext) {
auto res = Res::Ok();
if (tx.IsCoinBase() && height > 0) { // genesis contains custom coinbase txs
return res;
Expand Down
6 changes: 4 additions & 2 deletions src/masternodes/mn_checks.h
Original file line number Diff line number Diff line change
Expand Up @@ -466,15 +466,17 @@ Res ApplyCustomTx(CCustomCSView &mnview,
uint32_t height,
uint64_t time = 0,
uint256 *canSpend = nullptr,
uint32_t txn = 0);
uint32_t txn = 0,
const uint64_t evmContext = 0);
Res CustomTxVisit(CCustomCSView &mnview,
const CCoinsViewCache &coins,
const CTransaction &tx,
uint32_t height,
const Consensus::Params &consensus,
const CCustomTxMessage &txMessage,
uint64_t time,
uint32_t txn = 0);
uint32_t txn = 0,
const uint64_t evmContext = 0);
ResVal<uint256> ApplyAnchorRewardTx(CCustomCSView &mnview,
const CTransaction &tx,
int height,
Expand Down
6 changes: 3 additions & 3 deletions src/masternodes/rpc_evm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ UniValue evmtx(const JSONRPCRequest& request) {
const uint64_t chainID{1};

const arith_uint256 nonceParam = request.params[1].get_int64();
const auto nonce = ArithToUint256(nonceParam).ToArray();
const auto nonce = ArithToUint256(nonceParam);

arith_uint256 gasPriceArith = request.params[2].get_int64(); // Price as GWei
gasPriceArith *= WEI_IN_GWEI; // Convert to Wei
Expand All @@ -79,7 +79,7 @@ UniValue evmtx(const JSONRPCRequest& request) {
}

const arith_uint256 valueParam = AmountFromValue(request.params[5]);
const auto value = ArithToUint256(valueParam * CAMOUNT_TO_WEI * WEI_IN_GWEI).ToArray();
const auto value = ArithToUint256(valueParam * CAMOUNT_TO_WEI * WEI_IN_GWEI);

rust::Vec<uint8_t> input{};
if (!request.params[6].isNull()) {
Expand All @@ -96,7 +96,7 @@ UniValue evmtx(const JSONRPCRequest& request) {
std::array<uint8_t, 32> privKey{};
std::copy(key.begin(), key.end(), privKey.begin());

const auto signedTx = create_and_sign_tx(chainID, nonce, gasPrice.ToArrayReversed(), gasLimit.ToArrayReversed(), to, value, input, privKey);
const auto signedTx = create_and_sign_tx(chainID, nonce.ToArrayReversed(), gasPrice.ToArrayReversed(), gasLimit.ToArrayReversed(), to, value.ToArrayReversed(), input, privKey);
std::vector<uint8_t> evmTx(signedTx.size());
std::copy(signedTx.begin(), signedTx.end(), evmTx.begin());

Expand Down
27 changes: 23 additions & 4 deletions src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <consensus/tx_check.h>
#include <consensus/tx_verify.h>
#include <consensus/validation.h>
#include <libain_evm.h>
#include <masternodes/anchors.h>
#include <masternodes/govvariables/attributes.h>
#include <masternodes/masternodes.h>
Expand Down Expand Up @@ -234,12 +235,20 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
timeOrdering = false;
}

const auto evmContext = evm_get_context();

if (timeOrdering) {
addPackageTxs<entry_time>(nPackagesSelected, nDescendantsUpdated, nHeight, mnview);
addPackageTxs<entry_time>(nPackagesSelected, nDescendantsUpdated, nHeight, mnview, evmContext);
} else {
addPackageTxs<ancestor_score>(nPackagesSelected, nDescendantsUpdated, nHeight, mnview);
addPackageTxs<ancestor_score>(nPackagesSelected, nDescendantsUpdated, nHeight, mnview, evmContext);
}

// TODO Get failed TXs and try to restore to mempool
const auto rustHeader = evm_finalise(evmContext, false);

std::vector<uint8_t> evmHeader{};
evmHeader.resize(rustHeader.size());
std::copy(rustHeader.begin(), rustHeader.end(), evmHeader.begin());

// TXs for the creationTx field in new tokens created via token split
if (nHeight >= chainparams.GetConsensus().FortCanningCrunchHeight) {
Expand Down Expand Up @@ -315,6 +324,16 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
coinbaseTx.vout[0].nValue = CalculateCoinbaseReward(blockReward, consensus.dist.masternode);
}

if (nHeight >= consensus.NextNetworkUpgradeHeight && !evmHeader.empty()) {
const auto headerIndex = coinbaseTx.vout.size();
coinbaseTx.vout.resize(headerIndex + 1);
coinbaseTx.vout[headerIndex].nValue = 0;

CScript script;
script << OP_RETURN << evmHeader;
coinbaseTx.vout[headerIndex].scriptPubKey = script;
}

LogPrint(BCLog::STAKING, "%s: post Eunos logic. Block reward %d Miner share %d foundation share %d\n",
__func__, blockReward, coinbaseTx.vout[0].nValue, foundationValue);
}
Expand Down Expand Up @@ -507,7 +526,7 @@ void BlockAssembler::SortForBlock(const CTxMemPool::setEntries& package, std::ve
// mapModifiedTxs with the next transaction in the mempool to decide what
// transaction package to work on next.
template<class T>
void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated, int nHeight, CCustomCSView &view)
void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated, int nHeight, CCustomCSView &view, const uint64_t evmContext)
{
// mapModifiedTx will store sorted packages after they are modified
// because some of their txs are already in the block
Expand Down Expand Up @@ -655,7 +674,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda

// Only check custom TXs
if (txType != CustomTxType::None) {
auto res = ApplyCustomTx(view, coins, tx, chainparams.GetConsensus(), nHeight, pblock->nTime);
const auto res = ApplyCustomTx(view, coins, tx, chainparams.GetConsensus(), nHeight, pblock->nTime, nullptr, 0, evmContext);

// Not okay invalidate, undo and skip
if (!res.ok) {
Expand Down
2 changes: 1 addition & 1 deletion src/miner.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ class BlockAssembler
* Increments nPackagesSelected / nDescendantsUpdated with corresponding
* statistics from the package selection (for logging statistics). */
template<class T>
void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated, int nHeight, CCustomCSView &view) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs);
void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated, int nHeight, CCustomCSView &view, const uint64_t evmContext) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs);

// helper functions for addPackageTxs()
/** Remove confirmed (inBlock) entries from given set */
Expand Down
4 changes: 4 additions & 0 deletions src/rpc/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,10 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "listgovproposalvotes", 3, "pagination" },
{ "listgovproposals", 2, "cycle" },
{ "listgovproposals", 3, "pagination" },
{ "evmtx", 1, "nonce" },
{ "evmtx", 2, "gasPrice" },
{ "evmtx", 3, "gasLimit" },
{ "evmtx", 5, "value" },
};
// clang-format on

Expand Down
4 changes: 4 additions & 0 deletions src/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/rust/crates/ain-evm-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ ain-evm-runtime = { path = "../ain-evm-runtime" }
ain-evm = { path = "../ain-evm" }
ain-grpc = { path = "../ain-grpc" }

rlp = "0.5.2"

# Build
cxx = "1.0"

Expand Down
39 changes: 33 additions & 6 deletions src/rust/crates/ain-evm-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@ use std::error::Error;
#[cxx::bridge]
mod ffi {
extern "Rust" {
fn evm_add_balance(address: &str, amount: i64) -> Result<()>;
fn evm_sub_balance(address: &str, amount: i64) -> Result<()>;
fn evm_add_balance(address: &str, amount: [u8; 32]) -> Result<()>;
fn evm_sub_balance(address: &str, amount: [u8; 32]) -> Result<()>;
fn evm_validate_raw_tx(tx: &str) -> Result<bool>;

fn evm_get_context() -> u64;
fn evm_discard_context(context: u64);
fn evm_queue_tx(context: u64, raw_tx: &str) -> Result<bool>;
fn evm_finalise(context: u64, update_state: bool) -> Result<Vec<u8>>;

fn init_runtime();
fn start_servers(json_addr: &str, grpc_addr: &str) -> Result<()>;
fn stop_runtime();
Expand All @@ -28,12 +33,12 @@ mod ffi {
}
}

pub fn evm_add_balance(address: &str, amount: i64) -> Result<(), Box<dyn Error>> {
RUNTIME.evm.add_balance(address, amount)
pub fn evm_add_balance(address: &str, amount: [u8; 32]) -> Result<(), Box<dyn Error>> {
RUNTIME.evm.add_balance(address, amount.into())
}

pub fn evm_sub_balance(address: &str, amount: i64) -> Result<(), Box<dyn Error>> {
RUNTIME.evm.sub_balance(address, amount)
pub fn evm_sub_balance(address: &str, amount: [u8; 32]) -> Result<(), Box<dyn Error>> {
RUNTIME.evm.sub_balance(address, amount.into())
}

pub fn evm_validate_raw_tx(tx: &str) -> Result<bool, Box<dyn Error>> {
Expand All @@ -42,3 +47,25 @@ pub fn evm_validate_raw_tx(tx: &str) -> Result<bool, Box<dyn Error>> {
Err(_) => Ok(false),
}
}

pub fn evm_get_context() -> u64 {
RUNTIME.evm.get_context()
}

fn evm_discard_context(context: u64) {
// TODO discard
RUNTIME.evm.discard_context(context)
}

fn evm_queue_tx(context: u64, raw_tx: &str) -> Result<bool, Box<dyn Error>> {
match RUNTIME.evm.queue_tx(context, raw_tx) {
Ok(_) => Ok(true),
Err(_) => Ok(false),
}
}

use rlp::Encodable;
fn evm_finalise(context: u64, update_state: bool) -> Result<Vec<u8>, Box<dyn Error>> {
let (block, _failed_tx) = RUNTIME.evm.finalize_block(context, update_state)?;
Ok(block.header.rlp_bytes().into())
}
2 changes: 2 additions & 0 deletions src/rust/crates/ain-evm-state/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ bincode = "1.3.3"
ethereum = "0.14.0"
hex = "0.4.3"
anyhow = "1.0"
rand = "0.8.5"
rlp = "0.5.2"

ain-evm = { path = "../ain-evm" }
Loading