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

EVM in/out refinements #1868

Merged
merged 9 commits into from
Apr 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/amount.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ struct DCT_ID {

static constexpr CAmount COIN = 100000000;
static constexpr CAmount CENT = 1000000;
static constexpr int64_t WEI_IN_GWEI = 1000000000;
static constexpr int64_t CAMOUNT_TO_WEI = 10;

//Converts the given value to decimal format string with COIN precision.
inline std::string GetDecimalString(CAmount nValue)
Expand Down
52 changes: 41 additions & 11 deletions src/masternodes/mn_checks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3834,12 +3834,6 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor {
const auto sumFrom = SumAllTransfers(obj.from);
const auto sumTo = SumAllTransfers(obj.to);

if (obj.type == CTransferBalanceType::EvmIn || obj.type == CTransferBalanceType::EvmOut) {
for (const auto& [id, _] : sumFrom.balances)
if (id != DCT_ID{0})
return Res::Err("For EVM in/out transfers only DFI token is currently supported");
}

if (sumFrom != sumTo)
return Res::Err("sum of inputs (from) != sum of outputs (to)");

Expand All @@ -3851,18 +3845,54 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor {
if (!res)
return res;
} else if (obj.type == CTransferBalanceType::EvmIn) {
for (const auto& [addr, _] : obj.to) {
res = SubBalancesDelShares(obj.from);
if (!res)
return res;

for (const auto& [addr, balances] : obj.to) {
CTxDestination dest;
if (ExtractDestination(addr, dest)) {
if (dest.index() != WitV16KeyEthHashType) {
return Res::Err("To address must be an ETH address in case of \"evmin\" transfertype");
}
}

const auto toAddress = std::get<WitnessV16EthHash>(dest);

for (const auto& [id, amount] : balances.balances) {
if (id != DCT_ID{0}) {
return Res::Err("For EVM out transfers, only DFI token is currently supported");
}

arith_uint256 balanceIn = amount;
balanceIn *= CAMOUNT_TO_WEI * WEI_IN_GWEI;
evm_add_balance(evmContext, HexStr(toAddress.begin(), toAddress.end()), ArithToUint256(balanceIn).ToArrayReversed());
}
}
res = SubBalancesDelShares(obj.from);
if (!res)
return res;
} else if (obj.type == CTransferBalanceType::EvmOut) {
for (const auto& [addr, balances] : obj.from) {
CTxDestination dest;
if (ExtractDestination(addr, dest)) {
if (dest.index() != WitV16KeyEthHashType) {
return Res::Err("Invalid destination");
}
}

const auto fromAddress = std::get<WitnessV16EthHash>(dest);

for (const auto& [id, amount] : balances.balances) {
if (id != DCT_ID{0}) {
return Res::Err("For EVM out transfers, only DFI token is currently supported");
}

arith_uint256 balanceIn = amount;
balanceIn *= CAMOUNT_TO_WEI * WEI_IN_GWEI;
if (!evm_sub_balance(evmContext, HexStr(fromAddress.begin(), fromAddress.end()), ArithToUint256(balanceIn).ToArrayReversed())) {
return Res::Err("Not enough balance in %s to cover EVM out", EncodeDestination(dest));
}
}
}

res = AddBalancesSetShares(obj.to);
if (!res)
return res;
Expand Down Expand Up @@ -4085,7 +4115,7 @@ Res ApplyCustomTx(CCustomCSView &mnview,
PopulateVaultHistoryData(mnview.GetHistoryWriters(), view, txMessage, txType, height, txn, tx.GetHash());
}

res = CustomTxVisit(view, coins, tx, height, consensus, txMessage, time, txn);
res = CustomTxVisit(view, coins, tx, height, consensus, txMessage, time, txn, evmContext);

if (res) {
if (canSpend && txType == CustomTxType::UpdateMasternode) {
Expand Down
3 changes: 0 additions & 3 deletions src/masternodes/rpc_evm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
#include <libain_evm.h>
#include <key_io.h>

const int64_t WEI_IN_GWEI = 1000000000;
const int64_t CAMOUNT_TO_WEI = 10;

UniValue evmtx(const JSONRPCRequest& request) {
auto pwallet = GetWallet(request);

Expand Down
32 changes: 26 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,8 +7,8 @@ use std::error::Error;
#[cxx::bridge]
mod ffi {
extern "Rust" {
fn evm_add_balance(address: &str, amount: [u8; 32]) -> Result<()>;
fn evm_sub_balance(address: &str, amount: [u8; 32]) -> Result<()>;
fn evm_add_balance(context: u64, address: &str, amount: [u8; 32]) -> Result<()>;
fn evm_sub_balance(context: u64, address: &str, amount: [u8; 32]) -> Result<bool>;
fn evm_validate_raw_tx(tx: &str) -> Result<bool>;

fn evm_get_context() -> u64;
Expand All @@ -33,12 +33,32 @@ mod ffi {
}
}

pub fn evm_add_balance(address: &str, amount: [u8; 32]) -> Result<(), Box<dyn Error>> {
RUNTIME.handlers.evm.add_balance(address, amount.into())
pub fn evm_add_balance(
context: u64,
address: &str,
amount: [u8; 32],
) -> Result<(), Box<dyn Error>> {
let address = address.parse()?;
Ok(RUNTIME
.handlers
.evm
.add_balance(context, address, amount.into()))
}

pub fn evm_sub_balance(address: &str, amount: [u8; 32]) -> Result<(), Box<dyn Error>> {
RUNTIME.handlers.evm.sub_balance(address, amount.into())
pub fn evm_sub_balance(
context: u64,
address: &str,
amount: [u8; 32],
) -> Result<bool, Box<dyn Error>> {
let address = address.parse()?;
match RUNTIME
.handlers
.evm
.sub_balance(context, address, amount.into())
{
Ok(_) => Ok(true),
Err(_) => Ok(false),
}
}

pub fn evm_validate_raw_tx(tx: &str) -> Result<bool, Box<dyn Error>> {
Expand Down
Loading