Skip to content

Commit

Permalink
Merge branch 'master' into feature/limit-connections-per-ip
Browse files Browse the repository at this point in the history
  • Loading branch information
Dentosal authored Jul 29, 2024
2 parents 73b28c0 + 1cfbb05 commit bfc8fc8
Show file tree
Hide file tree
Showing 21 changed files with 677 additions and 86 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- "gas-price-threshold-percent" - the threshold percent for determining if the gas price will be increase or decreased
And the following CLI flags are serving a new purpose
- "min-gas-price" - the minimum gas price that the gas price algorithm will return

### Fixed

#### Breaking
- [2045](https://github.com/FuelLabs/fuel-core/pull/2045): Include withdrawal message only if transaction is executed successfully.
- [2041](https://github.com/FuelLabs/fuel-core/pull/2041): Add code for startup of the gas price algorithm updater so
the gas price db on startup is always in sync with the on chain db

## [Version 0.31.0]

### Added
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

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

108 changes: 107 additions & 1 deletion crates/fuel-core/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ mod tests {
RegId,
},
fuel_crypto::SecretKey,
fuel_merkle::sparse,
fuel_merkle::{
common::empty_sum_sha256,
sparse,
},
fuel_tx::{
consensus_parameters::gas::GasCostsValuesV1,
field::{
Expand Down Expand Up @@ -2528,6 +2531,109 @@ mod tests {
));
}

#[test]
fn withdrawal_message_included_in_header_for_successfully_executed_transaction() {
// Given
let amount_from_random_input = 1000;
let smo_tx = TransactionBuilder::script(
vec![
// The amount to send in coins.
op::movi(0x13, amount_from_random_input),
// Send the message output.
op::smo(0x0, 0x0, 0x0, 0x13),
op::ret(RegId::ONE),
]
.into_iter()
.collect(),
vec![],
)
.add_random_fee_input()
.script_gas_limit(1000000)
.finalize_as_transaction();

let block = PartialFuelBlock {
header: Default::default(),
transactions: vec![smo_tx],
};

// When
let ExecutionResult { block, .. } =
create_executor(Default::default(), Default::default())
.produce_and_commit(block)
.expect("block execution failed unexpectedly");
let result = create_executor(Default::default(), Default::default())
.validate_and_commit(&block)
.expect("block validation failed unexpectedly");

// Then
let Some(Receipt::MessageOut {
sender,
recipient,
amount,
nonce,
data,
..
}) = result.tx_status[0].result.receipts().first().cloned()
else {
panic!("Expected a MessageOut receipt");
};

// Reconstruct merkle message outbox merkle root and see that it matches
let mut mt = fuel_core_types::fuel_merkle::binary::in_memory::MerkleTree::new();
mt.push(
&Message::V1(MessageV1 {
sender,
recipient,
nonce,
amount,
data: data.unwrap_or_default(),
da_height: 1u64.into(),
})
.message_id()
.to_bytes(),
);
assert_eq!(block.header().message_outbox_root.as_ref(), mt.root());
}

#[test]
fn withdrawal_message_not_included_in_header_for_failed_transaction() {
// Given
let amount_from_random_input = 1000;
let smo_tx = TransactionBuilder::script(
vec![
// The amount to send in coins.
op::movi(0x13, amount_from_random_input),
// Send the message output.
op::smo(0x0, 0x0, 0x0, 0x13),
op::rvrt(0x0),
]
.into_iter()
.collect(),
vec![],
)
.add_random_fee_input()
.script_gas_limit(1000000)
.finalize_as_transaction();

let block = PartialFuelBlock {
header: Default::default(),
transactions: vec![smo_tx],
};

// When
let ExecutionResult { block, .. } =
create_executor(Default::default(), Default::default())
.produce_and_commit(block)
.expect("block execution failed unexpectedly");
create_executor(Default::default(), Default::default())
.validate_and_commit(&block)
.expect("block validation failed unexpectedly");

// Then
let empty_root = empty_sum_sha256();
assert_eq!(block.header().message_outbox_root.as_ref(), empty_root)
}

#[test]
fn get_block_height_returns_current_executing_block() {
let mut rng = StdRng::seed_from_u64(1234);
Expand Down
2 changes: 1 addition & 1 deletion crates/fuel-core/src/graphql_api/ports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ pub trait P2pPort: Send + Sync {
#[async_trait::async_trait]
pub trait GasPriceEstimate: Send + Sync {
/// The worst case scenario for gas price at a given horizon
async fn worst_case_gas_price(&self, height: BlockHeight) -> u64;
async fn worst_case_gas_price(&self, height: BlockHeight) -> Option<u64>;
}

/// Trait for getting VM memory.
Expand Down
5 changes: 4 additions & 1 deletion crates/fuel-core/src/schema/gas_price.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,10 @@ impl EstimateGasPriceQuery {
let gas_price_provider = ctx.data_unchecked::<GasPriceProvider>();
let gas_price = gas_price_provider
.worst_case_gas_price(target_block.into())
.await;
.await
.ok_or(async_graphql::Error::new(format!(
"Failed to estimate gas price for block, algorithm not yet set: {target_block:?}"
)))?;

Ok(EstimateGasPrice {
gas_price: gas_price.into(),
Expand Down
19 changes: 14 additions & 5 deletions crates/fuel-core/src/service/adapters/fuel_gas_price_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use fuel_core_producer::block_producer::gas_price::GasPriceProvider as ProducerG
use fuel_core_txpool::ports::GasPriceProvider as TxPoolGasPriceProvider;
use fuel_core_types::{
fuel_types::BlockHeight,
services::txpool::Result as TxPoolResult,
services::txpool::{
Error as TxPoolError,
Result as TxPoolResult,
},
};

pub type Result<T, E = Error> = std::result::Result<T, E>;
Expand Down Expand Up @@ -53,7 +56,7 @@ impl<A> FuelGasPriceProvider<A>
where
A: GasPriceAlgorithm + Send + Sync,
{
async fn next_gas_price(&self) -> u64 {
async fn next_gas_price(&self) -> Option<u64> {
self.algorithm.next_gas_price().await
}
}
Expand All @@ -64,7 +67,9 @@ where
A: GasPriceAlgorithm + Send + Sync,
{
async fn next_gas_price(&self) -> anyhow::Result<u64> {
Ok(self.next_gas_price().await)
self.next_gas_price()
.await
.ok_or(anyhow::anyhow!("No gas price available"))
}
}

Expand All @@ -74,7 +79,11 @@ where
A: GasPriceAlgorithm + Send + Sync,
{
async fn next_gas_price(&self) -> TxPoolResult<u64> {
Ok(self.next_gas_price().await)
self.next_gas_price()
.await
.ok_or(TxPoolError::GasPriceNotFound(
"Gas price not set yet".to_string(),
))
}
}

Expand All @@ -83,7 +92,7 @@ impl<A> GraphqlGasPriceEstimate for FuelGasPriceProvider<A>
where
A: GasPriceAlgorithm + Send + Sync,
{
async fn worst_case_gas_price(&self, height: BlockHeight) -> u64 {
async fn worst_case_gas_price(&self, height: BlockHeight) -> Option<u64> {
self.algorithm.worst_case_gas_price(height).await
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fn build_provider<A>(algorithm: A) -> FuelGasPriceProvider<A>
where
A: Send + Sync,
{
let algorithm = SharedGasPriceAlgo::new(algorithm);
let algorithm = SharedGasPriceAlgo::new_with_algorithm(algorithm);
FuelGasPriceProvider::new(algorithm)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ async fn estimate_gas_price__happy_path() {

// when
let expected_price = algo.worst_case_gas_price(next_height);
let actual_price = gas_price_provider.worst_case_gas_price(next_height).await;
let actual_price = gas_price_provider
.worst_case_gas_price(next_height)
.await
.unwrap();

// then
assert_eq!(expected_price, actual_price);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ async fn gas_price__if_requested_block_height_is_latest_return_gas_price() {

// when
let expected_price = algo.next_gas_price();
let actual_price = gas_price_provider.next_gas_price().await;
let actual_price = gas_price_provider.next_gas_price().await.unwrap();

// then
assert_eq!(expected_price, actual_price);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ async fn gas_price__if_requested_block_height_is_latest_return_gas_price() {

// when
let expected_price = algo.next_gas_price();
let actual_price = gas_price_provider.next_gas_price().await;
let actual_price = gas_price_provider.next_gas_price().await.unwrap();

// then
assert_eq!(expected_price, actual_price);
Expand Down
4 changes: 2 additions & 2 deletions crates/fuel-core/src/service/adapters/graphql_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ impl worker::TxPool for TxPoolAdapter {

#[async_trait::async_trait]
impl GasPriceEstimate for StaticGasPrice {
async fn worst_case_gas_price(&self, _height: BlockHeight) -> u64 {
self.gas_price
async fn worst_case_gas_price(&self, _height: BlockHeight) -> Option<u64> {
Some(self.gas_price)
}
}

Expand Down
37 changes: 21 additions & 16 deletions crates/fuel-core/src/service/sub_services.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![allow(clippy::let_unit_value)]

use super::{
adapters::P2PAdapter,
genesis::create_genesis_block,
Expand Down Expand Up @@ -32,23 +33,31 @@ use crate::{
SubServices,
},
};
#[allow(unused_imports)]
use fuel_core_gas_price_service::fuel_gas_price_updater::{
fuel_core_storage_adapter::FuelL2BlockSource,
Algorithm,
AlgorithmV0,
FuelGasPriceUpdater,
UpdaterMetadata,
V0Metadata,
};
use fuel_core_poa::Trigger;
use fuel_core_services::{
RunnableService,
ServiceRunner,
};
use fuel_core_storage::{
structured_storage::StructuredStorage,
self,
transactional::AtomicView,
};
#[cfg(feature = "relayer")]
use fuel_core_types::blockchain::primitives::DaBlockHeight;
use std::sync::Arc;
use tokio::sync::Mutex;

mod algorithm_updater;

pub type PoAService =
fuel_core_poa::Service<TxPoolAdapter, BlockProducerAdapter, BlockImporterAdapter>;
#[cfg(feature = "p2p")]
Expand Down Expand Up @@ -176,24 +185,20 @@ pub fn init_sub_services(
#[cfg(not(feature = "p2p"))]
let p2p_adapter = P2PAdapter::new();

let updater_metadata = UpdaterMetadata::V0(V0Metadata {
new_exec_price: config.starting_gas_price,
min_exec_gas_price: config.min_gas_price,
exec_gas_price_change_percent: config.gas_price_change_percent,
l2_block_height: last_height.into(),
l2_block_fullness_threshold_percent: config.gas_price_threshold_percent,
});
let genesis_block_height = *genesis_block.header().height();
let settings = consensus_parameters_provider.clone();
let block_stream = importer_adapter.events_shared_result();
let l2_block_source =
FuelL2BlockSource::new(genesis_block_height, settings, block_stream);
let metadata_storage = StructuredStorage::new(database.gas_price().clone());
let update_algo =
FuelGasPriceUpdater::init(updater_metadata, l2_block_source, metadata_storage)?;
let gas_price_service =
fuel_core_gas_price_service::new_service(last_height, update_algo)?;
let next_algo = gas_price_service.shared.clone();

let gas_price_init = algorithm_updater::InitializeTask::new(
config.clone(),
genesis_block_height,
settings,
block_stream,
database.gas_price().clone(),
database.on_chain().clone(),
)?;
let next_algo = gas_price_init.shared_data();
let gas_price_service = ServiceRunner::new(gas_price_init);

let gas_price_provider = FuelGasPriceProvider::new(next_algo);
let txpool = fuel_core_txpool::new_service(
Expand Down
Loading

0 comments on commit bfc8fc8

Please sign in to comment.