Skip to content

Commit

Permalink
chore: improvement zero gas transaction performance
Browse files Browse the repository at this point in the history
  • Loading branch information
GabrielMartinezRodriguez committed Nov 20, 2023
1 parent a4d6194 commit 63c2c06
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 56 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions client/authorship/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ prometheus-endpoint = { workspace = true }
sc-block-builder = { workspace = true }
sc-client-api = { workspace = true }
sc-proposer-metrics = { workspace = true }
fp-rpc = { workspace = true }
sc-telemetry = { workspace = true }
sc-transaction-pool-api = { workspace = true }
sp-api = { workspace = true }
Expand Down
86 changes: 44 additions & 42 deletions client/authorship/src/authorship.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ use sc_proposer_metrics::{EndProposingReason, MetricsLink as PrometheusMetrics};
use sp_core::crypto::KeyTypeId;
use sp_keystore::{Keystore, KeystorePtr};
use stbl_primitives_fee_compatible_api::CompatibleFeeApi;
use fp_rpc::EthereumRuntimeRPCApi;
use sp_runtime::Saturating;



/// Default block size limit in bytes used by [`Proposer`].
///
Expand Down Expand Up @@ -259,6 +263,7 @@ where
+ 'static,
C::Api: ApiExt<Block, StateBackend = backend::StateBackendFor<B, Block>>
+ BlockBuilderApi<Block>
+ fp_rpc::EthereumRuntimeRPCApi<Block>
+ stbl_primitives_fee_compatible_api::CompatibleFeeApi<Block, AccountId>
+ stbl_primitives_zero_gas_transactions_api::ZeroGasTransactionApi<Block>,
PR: ProofRecording,
Expand Down Expand Up @@ -305,6 +310,7 @@ where
+ 'static,
C::Api: ApiExt<Block, StateBackend = backend::StateBackendFor<B, Block>>
+ BlockBuilderApi<Block>
+ fp_rpc::EthereumRuntimeRPCApi<Block>
+ stbl_primitives_fee_compatible_api::CompatibleFeeApi<Block, AccountId>
+ stbl_primitives_zero_gas_transactions_api::ZeroGasTransactionApi<Block>,
PR: ProofRecording,
Expand Down Expand Up @@ -367,6 +373,7 @@ where
+ 'static,
C::Api: ApiExt<Block, StateBackend = backend::StateBackendFor<B, Block>>
+ BlockBuilderApi<Block>
+ fp_rpc::EthereumRuntimeRPCApi<Block>
+ stbl_primitives_fee_compatible_api::CompatibleFeeApi<Block, AccountId>
+ stbl_primitives_zero_gas_transactions_api::ZeroGasTransactionApi<Block>,
PR: ProofRecording,
Expand Down Expand Up @@ -437,7 +444,6 @@ where
let http_client = reqwest::Client::new();
let mut request = Box::pin(http_client.post(zero_gas_tx_pool).send().fuse());
let mut timeout = Box::pin(futures_timer::Delay::new(std::time::Duration::from_millis(500)).fuse());


let result_response_raw_zero = select! {
res = request => {
Expand Down Expand Up @@ -475,18 +481,48 @@ where
} else {
None
};



// If we pull successfully from the zero gas transaction pool, we will try to push them to the block

if let Some(raw_zero_gas_transactions) = raw_zero_gas_transactions_option {

let reason = if let Some(raw_zero_gas_transactions) = raw_zero_gas_transactions_option {
let mut pending_raw_zero_gas_transactions = raw_zero_gas_transactions.transactions.into_iter();


let chain_id = self
.client
.runtime_api()
.chain_id(self.parent_hash).expect("Could not get chain id");

let current_block = self.parent_number.saturated_into::<u32>().saturating_add(1);

let message: Vec<u8> = b"I consent to validate to execute zero gas transactions in block "
.iter()
.chain(current_block.to_string().as_bytes().iter())
.chain(b" on chain ")
.chain(chain_id.to_string().as_bytes().iter())
.cloned()
.collect();

let keys = Keystore::ecdsa_public_keys(
&*self.keystore,
KeyTypeId::try_from("aura").unwrap_or_default(),
);
let public = keys[0].clone().into();

let eip191_message = stbl_tools::eth::build_eip191_message_hash(message.clone());

let signed_hash = Keystore::ecdsa_sign_prehashed(
&*self.keystore,
KeyTypeId::try_from("aura").unwrap_or_default(),
&public,
&eip191_message.as_fixed_bytes(),
).expect("Could not sign the Ethereum transaction hash").expect("Could not sign the Ethereum transaction hash");

loop {
let pending_hex_string_tx = if let Some(tx) = pending_raw_zero_gas_transactions.next() {
tx
} else {
debug!("No more transactions in the zero gas transaction pool");
break EndProposingReason::NoMoreTransactions;
};

Expand All @@ -498,7 +534,7 @@ where
);
break EndProposingReason::HitDeadline;
}

let pending_raw_tx = if let Ok(pending_raw_tx) = hex::decode(pending_hex_string_tx) {
pending_raw_tx
}
Expand All @@ -507,38 +543,6 @@ where
};

let ethereum_transaction: ethereum::TransactionV2 = ethereum::EnvelopedDecodable::decode(&pending_raw_tx).unwrap();


let keys = Keystore::ecdsa_public_keys(
&*self.keystore,
KeyTypeId::try_from("aura").unwrap_or_default(),
);


let public = keys[0].clone().into();
let hash = ethereum_transaction.hash();
let hash_string = hex::encode(hash.as_bytes());


let mut message: Vec<u8> = Vec::new();
message.extend_from_slice(b"I consent to validate the transaction for free: 0x");
message.extend_from_slice(hash_string.as_bytes());

let eip191_message = stbl_tools::eth::build_eip191_message_hash(message.clone());

let signed_hash_option = Keystore::ecdsa_sign_prehashed(
&*self.keystore,
KeyTypeId::try_from("aura").unwrap_or_default(),
&public,
&eip191_message.as_fixed_bytes(),
).expect("Could not sign the Ethereum transaction hash");

let signed_hash = if let Some(signed_hash) = signed_hash_option {
signed_hash
}
else {
continue;
};

let pending_tx = if let Ok(pending_tx) = self
.client
Expand All @@ -549,9 +553,7 @@ where
else {
continue;
};




let block_size =
block_builder.estimate_block_size(self.include_proof_in_block_size_estimation);

Expand Down Expand Up @@ -605,7 +607,7 @@ where
}
}
};
}
};

let mut unqueue_invalid = Vec::new();
let mut t1 = self.transaction_pool.ready_at(self.parent_number).fuse();
Expand Down
30 changes: 16 additions & 14 deletions pallets/zero-gas-transactions/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub mod pallet {
use sp_core::U256;
use sp_std::vec;
use sp_std::vec::Vec;
use parity_scale_codec::alloc::string::ToString;

pub use fp_rpc::TransactionStatus;

Expand All @@ -36,7 +37,7 @@ pub mod pallet {
pub type SponsorNonce<T: Config> = StorageMap<_, Blake2_128Concat, H160, u64, ValueQuery>;

#[pallet::config]
pub trait Config: frame_system::Config + pallet_evm::Config + pallet_ethereum::Config {
pub trait Config: frame_system::Config<BlockNumber = u32> + pallet_evm::Config + pallet_ethereum::Config {
type RuntimeCall: Parameter + GetDispatchInfo;
type UserFeeTokenController: UserFeeTokenController;
}
Expand Down Expand Up @@ -64,7 +65,6 @@ pub mod pallet {
let current_block_validator = <pallet_evm::Pallet<T>>::find_author();

Self::ensure_zero_gas_transaction(
transaction.clone(),
current_block_validator,
validator_signature.clone(),
)
Expand Down Expand Up @@ -118,7 +118,6 @@ pub mod pallet {
let current_block_validator = <pallet_evm::Pallet<T>>::find_author();

Self::ensure_zero_gas_transaction(
transaction.clone(),
current_block_validator,
validator_signature,
)
Expand Down Expand Up @@ -196,12 +195,14 @@ pub mod pallet {
}

fn ensure_zero_gas_transaction(
transaction: pallet_ethereum::Transaction,
expected_validator: H160,
validator_signature: Vec<u8>,
) -> Result<(), ()> {
let chain_id = T::ChainId::get();
let block_number = <frame_system::Pallet<T>>::block_number();

let zero_gas_trx_internal_message: Vec<u8> =
Self::get_zero_gas_transaction_signing_message(transaction.clone());
Self::get_zero_gas_transaction_signing_message(block_number, chain_id);

let eip191_message =
stbl_tools::eth::build_eip191_message_hash(zero_gas_trx_internal_message);
Expand All @@ -216,16 +217,16 @@ pub mod pallet {
}

pub fn get_zero_gas_transaction_signing_message(
trx: pallet_ethereum::Transaction,
block_number: u32,
chain_id: u64,
) -> Vec<u8> {
let mut message: Vec<u8> = Vec::new();

let trx_hash = trx.hash();
let trx_bytes_hash = trx_hash.as_bytes();
let trx_hash_string = hex::encode(trx_bytes_hash);

message.extend_from_slice(b"I consent to validate the transaction for free: 0x");
message.extend_from_slice(trx_hash_string.as_bytes());
let mut message: Vec<u8> = b"I consent to validate to execute zero gas transactions in block "
.iter()
.chain(block_number.to_string().as_bytes().iter())
.chain(b" on chain ")
.chain(chain_id.to_string().as_bytes().iter())
.cloned()
.collect();

return message;
}
Expand All @@ -245,5 +246,6 @@ pub mod pallet {

return Some(H160::from_slice(&result[12..32]));
}

}
}

0 comments on commit 63c2c06

Please sign in to comment.