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: Deploy DST20 for loan tokens #2258

Merged
merged 32 commits into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
234dd33
Fix DST20 test
shohamc1 Jul 31, 2023
69d8b7a
Deploy DST20 for loan tokens
shohamc1 Jul 31, 2023
39209b1
Merge remote-tracking branch 'origin/master' into evm/dst20-loan-tokens
shohamc1 Jul 31, 2023
9f11c1d
Fix lint
shohamc1 Jul 31, 2023
c384e57
Rename failible dst20 FFI methods
Jouzo Jul 31, 2023
7ac6618
Reduce log level of fee_history
Jouzo Jul 31, 2023
a6f8d67
Fix clippy default_constructed_unit_structs
Jouzo Aug 1, 2023
39789b2
Adds FFI evm_try_dst20_is_deployed method
Jouzo Aug 1, 2023
0f5fae1
Fix clippy useless conversion
Jouzo Aug 1, 2023
bf8a33d
Fix clippy used-underscore-binding
Jouzo Aug 1, 2023
e3aac7a
Create DST20 loan token via attributes
Bushstar Aug 1, 2023
5c4dbb0
Separate LoanCollateralEnabled logic
Bushstar Aug 1, 2023
739e8b1
Merge branch 'master' into evm/dst20-loan-tokens
shohamc1 Aug 2, 2023
9e96865
Set correct queue ID
Bushstar Aug 2, 2023
379f708
Use full path
Bushstar Aug 2, 2023
a2fb841
Merge branch 'master' into evm/dst20-loan-tokens
Bushstar Aug 2, 2023
3477d10
Rename to is_dst20_deployed_or_queued
Jouzo Aug 4, 2023
18774ad
Merge branch master into evm/dst20-loan-tokens
Jouzo Aug 4, 2023
0cc8d94
Merge branch 'master' into evm/dst20-loan-tokens
Jouzo Aug 4, 2023
0072de6
Merge branch master into evm/dst20-loan-tokens
Jouzo Aug 7, 2023
db68693
Merge branch 'master' into evm/dst20-loan-tokens
prasannavl Aug 7, 2023
565c79f
Migrate DST20 tokens on EVM genesis block
Jouzo Aug 8, 2023
0c3f997
Remove unused ProcessDST20Migration parameters
Jouzo Aug 8, 2023
c16a404
Merge branch master into evm/dst20-loan-tokens
Jouzo Aug 8, 2023
71f7924
Fix lint
Jouzo Aug 8, 2023
a53f088
Add target_block to TransactionQueue
Jouzo Aug 8, 2023
7678d86
Use target_block and append to queue before processing
Jouzo Aug 8, 2023
2a9694b
Merge branch 'master' into evm/dst20-loan-tokens
Jouzo Aug 8, 2023
fda389e
Verify loan token is DAT
Bushstar Aug 8, 2023
e30f1fa
Remove second ForEachLoanToken loop
Jouzo Aug 9, 2023
09a12a9
Merge branch 'master' into evm/dst20-loan-tokens
prasannavl Aug 10, 2023
f10de16
Resolve lints
prasannavl Aug 10, 2023
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
4 changes: 2 additions & 2 deletions lib/ain-evm/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::sync::Arc;
use anyhow::format_err;
use ethereum::{BlockAny, TransactionAny};
use keccak_hash::H256;
use log::debug;
use log::{debug, trace};
use primitive_types::U256;
use statrs::statistics::{Data, OrderStatistics};

Expand Down Expand Up @@ -177,7 +177,7 @@ impl BlockService {
let (mut base_fee_per_gas, mut gas_used_ratio): (Vec<U256>, Vec<f64>) = blocks
.iter()
.map(|block| {
debug!("Processing block {}", block.header.number);
trace!("[fee_history] Processing block {}", block.header.number);
let base_fee = block.header.base_fee;

let gas_ratio = if block.header.gas_limit == U256::zero() {
Expand Down
34 changes: 33 additions & 1 deletion lib/ain-evm/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pub struct FinalizedBlockInfo {
pub failed_transactions: Vec<String>,
pub total_burnt_fees: U256,
pub total_priority_fees: U256,
pub block_number: U256,
}

pub struct DeployContractInfo {
Expand Down Expand Up @@ -183,7 +184,7 @@ impl EVMServices {
}

for queue_item in queue.transactions.clone() {
match queue_item.queue_tx {
match queue_item.tx {
QueueTx::SignedTx(signed_tx) => {
let nonce = executor.get_nonce(&signed_tx.sender);
if signed_tx.nonce() != nonce {
Expand Down Expand Up @@ -343,6 +344,7 @@ impl EVMServices {
failed_transactions,
total_burnt_fees,
total_priority_fees,
block_number: current_block_number,
})
}

Expand Down Expand Up @@ -523,4 +525,34 @@ impl EVMServices {
storage: vec![(storage_index, ain_contracts::u256_to_h256(new_balance))],
})
}

pub unsafe fn is_dst20_deployed_or_queued(
&self,
queue_id: u64,
name: &str,
symbol: &str,
token_id: &str,
) -> Result<bool, Box<dyn Error>> {
let address = ain_contracts::dst20_address_from_token_id(token_id)?;
debug!(
"[is_dst20_deployed_or_queued] Fetching address {:#?}",
address
);

let backend = self.core.get_latest_block_backend()?;
// Address already deployed
if backend.get_account(&address).is_some() {
return Ok(true);
}

let deploy_tx = QueueTx::SystemTx(SystemTx::DeployContract(DeployContractData {
name: String::from(name),
symbol: String::from(symbol),
address,
}));

let is_queued = self.core.tx_queues.get(queue_id)?.is_queued(deploy_tx);

Ok(is_queued)
}
}
1 change: 0 additions & 1 deletion lib/ain-evm/src/precompiles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ fn ensure_linear_cost(
Ok(cost)
}

#[derive(Default)]
pub struct MetachainPrecompiles;

// Ethereum precompiles available as of shangai fork :
Expand Down
2 changes: 1 addition & 1 deletion lib/ain-evm/src/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl From<&LegacyTransaction> for LegacyUnsignedTransaction {
}
}

#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SignedTx {
pub transaction: TransactionV2,
pub sender: H160,
Expand Down
8 changes: 4 additions & 4 deletions lib/ain-evm/src/transaction/system.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
use primitive_types::{H160, U256};

#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DeployContractData {
pub name: String,
pub symbol: String,
pub address: H160,
}

#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DST20Data {
pub to: H160,
pub contract: H160,
pub amount: U256,
pub out: bool,
}

#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BalanceUpdate {
pub address: H160,
pub amount: U256,
}

#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SystemTx {
DeployContract(DeployContractData),
DST20Bridge(DST20Data),
Expand Down
19 changes: 14 additions & 5 deletions lib/ain-evm/src/txqueue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,15 +201,15 @@ impl TransactionQueueMap {
}
}

#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum QueueTx {
SignedTx(Box<SignedTx>),
SystemTx(SystemTx),
}

#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct QueueTxItem {
pub queue_tx: QueueTx,
pub tx: QueueTx,
pub tx_hash: NativeTxHash,
pub tx_fee: U256,
pub gas_used: U256,
Expand Down Expand Up @@ -289,7 +289,7 @@ impl TransactionQueue {
data.total_gas_used += gas_used;
}
data.transactions.push(QueueTxItem {
queue_tx: tx,
tx,
tx_hash,
tx_fee: gas_fee,
gas_used,
Expand All @@ -302,7 +302,7 @@ impl TransactionQueue {
let mut fees_to_remove = U256::zero();
let mut gas_used_to_remove = U256::zero();
data.transactions.retain(|item| {
let tx_sender = match &item.queue_tx {
let tx_sender = match &item.tx {
QueueTx::SignedTx(tx) => tx.sender,
QueueTx::SystemTx(tx) => tx.sender().unwrap_or_default(),
};
Expand Down Expand Up @@ -335,6 +335,15 @@ impl TransactionQueue {
pub fn get_total_gas_used(&self) -> U256 {
self.data.lock().unwrap().total_gas_used
}

pub fn is_queued(&self, tx: QueueTx) -> bool {
self.data
.lock()
.unwrap()
.transactions
.iter()
.any(|queued| queued.tx == tx)
}
}

impl From<SignedTx> for QueueTx {
Expand Down
20 changes: 20 additions & 0 deletions lib/ain-rs-exports/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,13 +424,15 @@ pub fn evm_unsafe_try_construct_block_in_q(
failed_transactions,
total_burnt_fees,
total_priority_fees,
block_number,
}) => {
cross_boundary_success(result);
ffi::FinalizeBlockCompletion {
block_hash,
failed_transactions,
total_burnt_fees: WeiAmount(total_burnt_fees).to_satoshi().as_u64(),
total_priority_fees: WeiAmount(total_priority_fees).to_satoshi().as_u64(),
block_number: block_number.as_u64(),
}
}
Err(e) => cross_boundary_error_return(result, e.to_string()),
Expand Down Expand Up @@ -501,6 +503,24 @@ pub fn evm_try_get_block_count(result: &mut ffi::CrossBoundaryResult) -> u64 {
}
}

pub fn evm_try_is_dst20_deployed_or_queued(
result: &mut ffi::CrossBoundaryResult,
queue_id: u64,
name: &str,
symbol: &str,
token_id: &str,
) -> bool {
unsafe {
match SERVICES
.evm
.is_dst20_deployed_or_queued(queue_id, name, symbol, token_id)
{
Ok(is_deployed) => cross_boundary_success_return(result, is_deployed),
Err(e) => cross_boundary_error_return(result, e.to_string()),
}
}
}

pub fn evm_try_create_dst20(
result: &mut ffi::CrossBoundaryResult,
queue_id: u64,
Expand Down
9 changes: 8 additions & 1 deletion lib/ain-rs-exports/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pub mod ffi {
pub failed_transactions: Vec<String>,
pub total_burnt_fees: u64,
pub total_priority_fees: u64,
pub block_number: u64,
}

#[derive(Default)]
Expand Down Expand Up @@ -148,7 +149,6 @@ pub mod ffi {
symbol: &str,
token_id: &str,
);

fn evm_try_bridge_dst20(
result: &mut CrossBoundaryResult,
context: u64,
Expand All @@ -158,5 +158,12 @@ pub mod ffi {
token_id: &str,
out: bool,
);
fn evm_try_is_dst20_deployed_or_queued(
result: &mut CrossBoundaryResult,
queue_id: u64,
name: &str,
symbol: &str,
token_id: &str,
) -> bool;
}
}
4 changes: 4 additions & 0 deletions src/masternodes/errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,10 @@ class DeFiErrors {
return Res::Err("Fixed interval price currency pair must be set first");
}

static Res GovVarErrorCreatingDST20(const std::string &str) {
return Res::Err("Error creating DST20 token: %s", str);
}

static Res GovVarUnsupportedValue() {
return Res::Err("Unsupported value");
}
Expand Down
42 changes: 39 additions & 3 deletions src/masternodes/govvariables/attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <masternodes/mn_checks.h> /// GetAggregatePrice / CustomTxType
#include <validation.h> /// GetNextAccPosition

#include <ain_rs_exports.h>

#include <amount.h> /// GetDecimaleString
#include <core_io.h> /// ValueFromAmount
#include <util/strencodings.h>
Expand Down Expand Up @@ -1704,19 +1706,53 @@ Res ATTRIBUTES::Validate(const CCustomCSView &view) const {
}
}
[[fallthrough]];
case TokenKeys::LoanCollateralEnabled:
case TokenKeys::LoanMintingEnabled: {
case TokenKeys::LoanCollateralEnabled: {
if (view.GetLastHeight() < Params().GetConsensus().FortCanningCrunchHeight) {
return DeFiErrors::GovVarValidateFortCanningCrunch();
}
if (!VerifyToken(view, attrV0->typeId)) {
return DeFiErrors::GovVarValidateToken(attrV0->typeId);
}
CDataStructureV0 intervalPriceKey{
AttributeTypes::Token, attrV0->typeId, TokenKeys::FixedIntervalPriceId};
AttributeTypes::Token, attrV0->typeId, TokenKeys::FixedIntervalPriceId};
if (GetValue(intervalPriceKey, CTokenCurrencyPair{}) == CTokenCurrencyPair{}) {
return DeFiErrors::GovVarValidateCurrencyPair();
}
break;
}
case TokenKeys::LoanMintingEnabled: {
if (view.GetLastHeight() < Params().GetConsensus().FortCanningCrunchHeight) {
return DeFiErrors::GovVarValidateFortCanningCrunch();
}
const auto tokenID = DCT_ID{attrV0->typeId};
const auto token = view.GetToken(tokenID);
if (!token) {
return DeFiErrors::GovVarValidateToken(attrV0->typeId);
}
CDataStructureV0 intervalPriceKey{
AttributeTypes::Token, attrV0->typeId, TokenKeys::FixedIntervalPriceId};
if (GetValue(intervalPriceKey, CTokenCurrencyPair{}) == CTokenCurrencyPair{}) {
return DeFiErrors::GovVarValidateCurrencyPair();
}

const CDataStructureV0 enabledKey{AttributeTypes::Param, ParamIDs::Feature,
DFIPKeys::EVMEnabled};

CrossBoundaryResult result;
if (view.GetLastHeight() >= Params().GetConsensus().NextNetworkUpgradeHeight &&
GetValue(enabledKey, false) &&
evmQueueId &&
!evm_try_is_dst20_deployed_or_queued(result, evmQueueId, token->name, token->symbol,
tokenID.ToString())) {
evm_try_create_dst20(result, evmQueueId, token->creationTx.GetByteArray(),
token->name,
token->symbol,
tokenID.ToString());

if (!result.ok) {
return DeFiErrors::GovVarErrorCreatingDST20(result.reason.c_str());
}
}
break;
}
case TokenKeys::FixedIntervalPriceId:
Expand Down
1 change: 1 addition & 0 deletions src/masternodes/govvariables/attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ class ATTRIBUTES : public GovVariable, public AutoRegistrator<GovVariable, ATTRI
}

uint32_t time{0};
uint64_t evmQueueId{};

// For formatting in export
static const std::map<uint8_t, std::string> &displayVersions();
Expand Down
9 changes: 7 additions & 2 deletions src/masternodes/mn_checks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1853,6 +1853,7 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor {
}

govVar->time = time;
govVar->evmQueueId = evmQueueId;

auto newVar = std::dynamic_pointer_cast<ATTRIBUTES>(var);
assert(newVar);
Expand Down Expand Up @@ -2635,8 +2636,11 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor {
}

CTokenImplementation token;
token.symbol = trim_ws(obj.symbol).substr(0, CToken::MAX_TOKEN_SYMBOL_LENGTH);
token.name = trim_ws(obj.name).substr(0, CToken::MAX_TOKEN_NAME_LENGTH);
auto tokenSymbol = trim_ws(obj.symbol).substr(0, CToken::MAX_TOKEN_SYMBOL_LENGTH);
auto tokenName = trim_ws(obj.name).substr(0, CToken::MAX_TOKEN_NAME_LENGTH);

token.symbol = tokenSymbol;
token.name = tokenName;
token.creationTx = tx.GetHash();
token.creationHeight = height;
token.flags = obj.mintable ? static_cast<uint8_t>(CToken::TokenFlags::Default)
Expand All @@ -2652,6 +2656,7 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor {

auto attributes = mnview.GetAttributes();
attributes->time = time;
attributes->evmQueueId = evmQueueId;

CDataStructureV0 mintEnabled{AttributeTypes::Token, id, TokenKeys::LoanMintingEnabled};
CDataStructureV0 mintInterest{AttributeTypes::Token, id, TokenKeys::LoanMintingInterest};
Expand Down
Loading