Skip to content

Commit

Permalink
nofee wireup
Browse files Browse the repository at this point in the history
  • Loading branch information
EdHastingsCasperAssociation committed Mar 15, 2024
1 parent 8c72a76 commit 67ad52e
Show file tree
Hide file tree
Showing 36 changed files with 914 additions and 679 deletions.
2 changes: 1 addition & 1 deletion execution_engine/src/engine_state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ impl ExecutionEngineV1 {
FeeHandling::PayToProposer => {
FeesPurseHandling::ToProposer(proposer.to_account_hash())
}
FeeHandling::None => FeesPurseHandling::None(payment_purse_uref),
FeeHandling::NoFee => FeesPurseHandling::None(payment_purse_uref),
FeeHandling::Accumulate => FeesPurseHandling::Accumulate,
FeeHandling::Burn => FeesPurseHandling::Burn,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ fn test_burning_fees(
let total_supply_after = builder.total_supply(None, protocol_version);

match fee_handling {
FeeHandling::PayToProposer | FeeHandling::Accumulate | FeeHandling::None => {
FeeHandling::PayToProposer | FeeHandling::Accumulate | FeeHandling::NoFee => {
assert_eq!(total_supply_before, total_supply_after);
}
FeeHandling::Burn => {
Expand Down
11 changes: 6 additions & 5 deletions node/src/components/block_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use crate::{
EffectBuilder, EffectExt, Effects, Responder,
},
fatal,
types::{BlockWithMetadata, NodeId, TransactionExt, ValidatorMatrix},
types::{BlockWithMetadata, NodeId, TransactionFootprint, ValidatorMatrix},
NodeRng,
};
pub use config::Config;
Expand Down Expand Up @@ -553,11 +553,12 @@ impl BlockValidator {
.flat_map(|state| state.try_mark_invalid(&transaction_hash));
return respond(false, responders);
}
let transaction_footprint = match item.footprint(&self.chainspec) {
Some(footprint) => footprint,
None => {
let transaction_footprint = match TransactionFootprint::new(&self.chainspec, &item)
{
Ok(footprint) => footprint,
Err(invalid_transaction_error) => {
warn!(
%transaction_hash,
%transaction_hash, ?invalid_transaction_error,
"could not convert transaction",
);
// Hard failure - change state to Invalid.
Expand Down
9 changes: 4 additions & 5 deletions node/src/components/block_validator/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ mod tests {
};

use super::{super::tests::*, *};
use crate::{types::TransactionExt, utils::Loadable};
use crate::utils::Loadable;

struct Fixture<'a> {
rng: &'a mut TestRng,
Expand All @@ -574,8 +574,7 @@ mod tests {
.map(|transaction| {
(
transaction.hash(),
transaction
.footprint(&self.chainspec)
TransactionFootprint::new(&self.chainspec, transaction)
.expect("must create footprint"),
)
})
Expand Down Expand Up @@ -1197,7 +1196,7 @@ mod tests {
Transaction::V1(v1) => TransactionHash::V1(*v1.hash()),
};
let chainspec = Chainspec::default();
let footprint = transaction.footprint(&chainspec).unwrap();
let footprint = TransactionFootprint::new(&chainspec, &transaction).unwrap();

// Ensure trying to add it doesn't change the state.
let responders = state.try_add_transaction_footprint(&transaction_hash, &footprint);
Expand Down Expand Up @@ -1257,7 +1256,7 @@ mod tests {
// The invalid transaction should cause the state to go to `Invalid` and the responders to
// be returned.
let chainspec = Chainspec::default();
let footprint = invalid_transaction.footprint(&chainspec).unwrap();
let footprint = TransactionFootprint::new(&chainspec, &invalid_transaction).unwrap();
let responders = state.try_add_transaction_footprint(&transaction_hash, &footprint);
assert_eq!(responders.len(), 1);
assert!(matches!(state, BlockValidationState::Invalid(_)));
Expand Down
134 changes: 98 additions & 36 deletions node/src/components/contract_runtime/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ use casper_execution_engine::engine_state::{
use casper_storage::{
block_store::types::ApprovalsHashes,
data_access_layer::{
AuctionMethod, BiddingRequest, BiddingResult, BlockRewardsRequest, BlockRewardsResult,
DataAccessLayer, EraValidatorsRequest, EraValidatorsResult, EvictItem, FeeRequest,
FeeResult, FlushRequest, PruneRequest, PruneResult, StepRequest, StepResult,
TransferRequest, TransferResult,
AuctionMethod, BalanceHoldRequest, BiddingRequest, BiddingResult, BlockRewardsRequest,
BlockRewardsResult, DataAccessLayer, EraValidatorsRequest, EraValidatorsResult, EvictItem,
FeeRequest, FeeResult, FlushRequest, InsufficientBalanceHandling, PruneRequest,
PruneResult, StepRequest, StepResult, TransferRequest, TransferResult,
},
global_state::{
error::Error as GlobalStateError,
Expand All @@ -30,8 +30,9 @@ use casper_types::{
bytesrepr::{self, ToBytes, U32_SERIALIZED_LENGTH},
contract_messages::Messages,
execution::{Effects, ExecutionResult, ExecutionResultV2, TransformKindV2, TransformV2},
ApprovalsHash, BlockV2, CLValue, Chainspec, ChecksumRegistry, DeployHash, Digest, EraEndV2,
EraId, Key, ProtocolVersion, PublicKey, Transaction, U512,
system::mint::BalanceHoldAddrTag,
ApprovalsHash, BlockTime, BlockV2, CLValue, Chainspec, ChecksumRegistry, DeployHash, Digest,
EraEndV2, EraId, FeeHandling, GasLimited, Key, ProtocolVersion, PublicKey, Transaction, U512,
};

use crate::{
Expand Down Expand Up @@ -96,42 +97,103 @@ pub fn execute_finalized_block(
let scratch_state = data_access_layer.get_scratch_global_state();
let mut effects = Effects::new();

let system_costs = chainspec.system_costs_config;
let insufficient_balance_handling = InsufficientBalanceHandling::HoldRemaining;
let gas_price = Some(1); // < --TODO: this is where Karan's calculated gas price needs to be used

for transaction in executable_block.transactions {
let transaction_hash = transaction.hash();
let runtime_args = transaction.session_args().clone();
let entry_point = transaction.entry_point();

// NOTE: this is the actual adjusted cost (gas limit * gas price)
// NOT the allowed computation limit (gas limit)
let cost = match transaction.gas_limit(&system_costs, gas_price) {
Ok(gas) => gas.value(),
Err(ite) => {
execution_artifacts.push(ExecutionArtifact::new(
transaction_hash,
transaction.header(),
ExecutionResult::V2(ExecutionResultV2::Failure {
effects: Effects::new(),
cost: U512::zero(),
transfers: vec![],
error_message: format!("{:?}", ite),
}),
Messages::default(),
));
debug!(%ite, "invalid transaction");
continue;
}
};

// handle payment per the chainspec determined fee setting
// match chainspec.core_config.fee_handling {
// FeeHandling::None => {
// // this is the "fee elimination" model...a BalanceHold for the
// // amount is placed on the paying purse(s).
// let hold_amount = transaction.gas_limit();
// let hold_purse = get_purse_from_transaction_initiator();
// let hold_req = BalanceHoldRequest::new(hold_purse, hold_amount);
// match scratch_state.hold(hold_req) {
// BalanceHoldRequest::RootNotFound => {}
// BalanceHoldRequest::Failure(tce) => {}
// BalanceHoldRequest::Success{ effects } => {}
// }
// }
// FeeHandling::PayToProposer => {
// // this is the current mainnet mechanism...pay up front
// // finalize at the end
// }
// FeeHandling::Accumulate => {
// // this is a variation on PayToProposer that was added for
// // for some private networks...the fees are all accumulated
// // and distributed to administrative accounts as part of fee
// // distribution. So, we just send the payment to the accumulator
// // purse and move on.
// }
// FeeHandling::Burn => {
// // this is a new variation that is not currently supported.
// // this is for future use...but it is very simple...the
// // fees are simply burned, lowering total supply.
// }
// }
match chainspec.core_config.fee_handling {
FeeHandling::NoFee => {
// this is the "fee elimination" model...a BalanceHold for the full cost is placed
// on the initiator's purse.
let hold_amount = cost;
let hold_result = scratch_state.balance_hold(BalanceHoldRequest::new(
state_root_hash,
protocol_version,
transaction.initiator_addr().into(),
BalanceHoldAddrTag::Gas,
hold_amount,
BlockTime::new(block_time),
chainspec.core_config.balance_hold_interval,
insufficient_balance_handling,
));
if hold_result.is_root_not_found() {
return Err(BlockExecutionError::RootNotFound(state_root_hash));
}
let execution_result = {
let hold_cost = U512::zero(); // we don't charge for the hold itself.
let hold_effects = hold_result.effects();
if hold_result.is_fully_covered() {
ExecutionResultV2::Success {
effects: hold_effects,
transfers: vec![],
cost: hold_cost,
}
} else {
let error_message = hold_result.error_message();
debug!(%error_message);
ExecutionResultV2::Failure {
effects: hold_effects,
transfers: vec![],
error_message,
cost: hold_cost,
}
}
};
execution_artifacts.push(ExecutionArtifact::new(
transaction_hash,
transaction.header(),
ExecutionResult::V2(execution_result),
Messages::default(),
));
if !hold_result.is_fully_covered() {
continue;
}
}
FeeHandling::PayToProposer => {
// this is the current mainnet mechanism...pay up front
// finalize at the end
// we have the proposer of this block...just deposit to them
}
FeeHandling::Accumulate => {
// this is a variation on PayToProposer that was added for
// for some private networks...the fees are all accumulated
// and distributed to administrative accounts as part of fee
// distribution. So, we just send the payment to the accumulator
// purse and move on.
}
FeeHandling::Burn => {
// this is a new variation that is not currently supported.
// this is for future use...but it is very simple...the
// fees are simply burned, lowering total supply.
}
}

if transaction.is_native_mint() {
// native transfers are routed to the data provider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{collections::HashMap, time::Duration};
use async_trait::async_trait;
use futures::FutureExt;

use casper_types::{Transaction, TransactionConfigFailure, TransactionId};
use casper_types::{InvalidTransaction, Transaction, TransactionId};

use crate::{
components::fetcher::{
Expand All @@ -16,7 +16,7 @@ use crate::{

impl FetchItem for Transaction {
type Id = TransactionId;
type ValidationError = TransactionConfigFailure;
type ValidationError = InvalidTransaction;
type ValidationMetadata = EmptyValidationMetadata;

const TAG: Tag = Tag::Transaction;
Expand Down
20 changes: 12 additions & 8 deletions node/src/components/transaction_acceptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ impl TransactionAcceptor {
self.acceptor_config.timestamp_leeway,
event_metadata.verification_start_timestamp,
)
.map_err(Error::from),
.map_err(|err| Error::InvalidTransaction(err.into())),
Transaction::V1(txn) => txn
.is_config_compliant(
&self.chain_name,
Expand All @@ -139,7 +139,7 @@ impl TransactionAcceptor {
self.acceptor_config.timestamp_leeway,
event_metadata.verification_start_timestamp,
)
.map_err(Error::from),
.map_err(|err| Error::InvalidTransaction(err.into())),
};

if let Err(error) = is_config_compliant {
Expand Down Expand Up @@ -696,8 +696,12 @@ impl TransactionAcceptor {
event_metadata: Box<EventMetadata>,
) -> Effects<Event> {
let is_valid = match &event_metadata.transaction {
Transaction::Deploy(deploy) => deploy.is_valid().map_err(Error::from),
Transaction::V1(txn) => txn.verify().map_err(Error::from),
Transaction::Deploy(deploy) => deploy
.is_valid()
.map_err(|err| Error::InvalidTransaction(err.into())),
Transaction::V1(txn) => txn
.verify()
.map_err(|err| Error::InvalidTransaction(err.into())),
};
if let Err(error) = is_valid {
return self.reject_transaction(effect_builder, *event_metadata, error);
Expand Down Expand Up @@ -832,6 +836,10 @@ impl TransactionAcceptor {
impl<REv: ReactorEventT> Component<REv> for TransactionAcceptor {
type Event = Event;

fn name(&self) -> &str {
COMPONENT_NAME
}

fn handle_event(
&mut self,
effect_builder: EffectBuilder<REv>,
Expand Down Expand Up @@ -913,10 +921,6 @@ impl<REv: ReactorEventT> Component<REv> for TransactionAcceptor {
} => self.handle_stored_finalized_approvals(effect_builder, event_metadata, is_new),
}
}

fn name(&self) -> &str {
COMPONENT_NAME
}
}

// `allow` can be removed once https://github.com/casper-network/casper-node/issues/3063 is fixed.
Expand Down
17 changes: 6 additions & 11 deletions node/src/components/transaction_acceptor/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use serde::Serialize;
use thiserror::Error;

use casper_types::{
binary_port, AddressableEntityHash, BlockHash, BlockHeader, DeployConfigFailure, Digest,
EntityVersion, InitiatorAddr, PackageHash, Timestamp, TransactionV1ConfigFailure,
binary_port, AddressableEntityHash, BlockHash, BlockHeader, Digest, EntityVersion,
InitiatorAddr, InvalidTransaction, PackageHash, Timestamp,
};

// `allow` can be removed once https://github.com/casper-network/casper-node/issues/3063 is fixed.
Expand All @@ -15,13 +15,9 @@ pub(crate) enum Error {
#[error("block chain has no blocks")]
EmptyBlockchain,

/// The deploy has an invalid configuration.
#[error("invalid deploy: {0}")]
InvalidDeployConfiguration(#[from] DeployConfigFailure),

/// The v1 transaction has an invalid configuration.
#[error("invalid v1 transaction: {0}")]
InvalidV1Configuration(#[from] TransactionV1ConfigFailure),
/// The deploy has an invalid transaction.
#[error("invalid transaction: {0}")]
InvalidTransaction(#[from] InvalidTransaction),

/// The transaction is invalid due to missing or otherwise invalid parameters.
#[error(
Expand Down Expand Up @@ -72,8 +68,7 @@ impl From<Error> for binary_port::ErrorCode {
fn from(err: Error) -> Self {
match err {
Error::EmptyBlockchain
| Error::InvalidDeployConfiguration(_)
| Error::InvalidV1Configuration(_)
| Error::InvalidTransaction(_)
| Error::Parameters { .. }
| Error::Expired { .. }
| Error::ExpectedDeploy
Expand Down
Loading

0 comments on commit 67ad52e

Please sign in to comment.