From 5e9f38164daba1f209d63c0e01f09fa83d49d0f3 Mon Sep 17 00:00:00 2001
From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com>
Date: Wed, 18 Sep 2024 01:03:15 +0200
Subject: [PATCH] evm: use `Header` AT in `ConfigureEvmEnv` (#10968)
---
Cargo.lock | 2 ++
.../engine/invalid-block-hooks/src/witness.rs | 8 +++--
crates/engine/util/src/reorg.rs | 4 +--
crates/ethereum/evm/src/execute.rs | 14 ++++-----
crates/ethereum/evm/src/lib.rs | 22 +++++++++++++-
crates/ethereum/node/Cargo.toml | 1 +
crates/ethereum/node/src/node.rs | 3 +-
crates/ethereum/payload/src/lib.rs | 6 ++--
crates/evm/src/lib.rs | 30 ++++---------------
crates/evm/src/provider.rs | 10 +++----
crates/evm/src/system_calls/eip2935.rs | 7 +++--
crates/evm/src/system_calls/mod.rs | 14 ++++-----
crates/node/api/Cargo.toml | 1 +
crates/node/api/src/node.rs | 3 +-
crates/node/builder/src/components/builder.rs | 3 +-
crates/node/builder/src/components/execute.rs | 5 ++--
crates/node/builder/src/components/mod.rs | 7 +++--
crates/optimism/evm/src/execute.rs | 14 ++++-----
crates/optimism/evm/src/lib.rs | 24 +++++++++++++--
crates/optimism/node/src/node.rs | 3 +-
crates/optimism/payload/src/builder.rs | 6 ++--
crates/optimism/rpc/src/eth/call.rs | 7 +++--
crates/optimism/rpc/src/eth/mod.rs | 3 +-
crates/optimism/rpc/src/eth/pending_block.rs | 4 +--
crates/rpc/rpc-builder/Cargo.toml | 2 +-
crates/rpc/rpc-builder/src/eth.rs | 3 +-
crates/rpc/rpc-builder/src/lib.rs | 16 ++++++----
crates/rpc/rpc-eth-api/src/helpers/call.rs | 4 +--
.../rpc-eth-api/src/helpers/pending_block.rs | 2 +-
crates/rpc/rpc-eth-api/src/helpers/trace.rs | 3 +-
crates/rpc/rpc-eth-types/src/cache/mod.rs | 12 ++++----
crates/rpc/rpc/src/eth/helpers/call.rs | 5 ++--
.../rpc/rpc/src/eth/helpers/pending_block.rs | 5 ++--
crates/rpc/rpc/src/eth/helpers/trace.rs | 5 ++--
.../src/providers/blockchain_provider.rs | 8 ++---
.../provider/src/providers/database/mod.rs | 8 ++---
.../src/providers/database/provider.rs | 8 ++---
crates/storage/provider/src/providers/mod.rs | 8 ++---
.../storage/provider/src/test_utils/mock.rs | 8 ++---
.../storage/provider/src/test_utils/noop.rs | 8 ++---
examples/custom-evm/src/main.rs | 24 +++++++++++++--
examples/stateful-precompile/src/main.rs | 24 +++++++++++++--
42 files changed, 220 insertions(+), 134 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index ab4e47533920..09de394ebc50 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -7631,6 +7631,7 @@ dependencies = [
"reth-node-types",
"reth-payload-builder",
"reth-payload-primitives",
+ "reth-primitives",
"reth-provider",
"reth-rpc-eth-api",
"reth-tasks",
@@ -7782,6 +7783,7 @@ dependencies = [
"reth-node-builder",
"reth-node-core",
"reth-payload-builder",
+ "reth-primitives",
"reth-provider",
"reth-rpc",
"reth-tasks",
diff --git a/crates/engine/invalid-block-hooks/src/witness.rs b/crates/engine/invalid-block-hooks/src/witness.rs
index eb703fb3336a..343dc6bb314e 100644
--- a/crates/engine/invalid-block-hooks/src/witness.rs
+++ b/crates/engine/invalid-block-hooks/src/witness.rs
@@ -9,7 +9,9 @@ use reth_evm::{
system_calls::{apply_beacon_root_contract_call, apply_blockhashes_contract_call},
ConfigureEvm,
};
-use reth_primitives::{keccak256, Receipt, SealedBlockWithSenders, SealedHeader, B256, U256};
+use reth_primitives::{
+ keccak256, Header, Receipt, SealedBlockWithSenders, SealedHeader, B256, U256,
+};
use reth_provider::{BlockExecutionOutput, ChainSpecProvider, StateProviderFactory};
use reth_revm::{
database::StateProviderDatabase,
@@ -50,7 +52,7 @@ impl
InvalidBlockWitnessHook
{
impl
InvalidBlockWitnessHook
where
P: StateProviderFactory + ChainSpecProvider + Send + Sync + 'static,
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
{
fn on_invalid_block(
&self,
@@ -236,7 +238,7 @@ where
impl InvalidBlockHook for InvalidBlockWitnessHook
where
P: StateProviderFactory + ChainSpecProvider + Send + Sync + 'static,
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
{
fn on_invalid_block(
&self,
diff --git a/crates/engine/util/src/reorg.rs b/crates/engine/util/src/reorg.rs
index 0459ff341ad1..622e01847521 100644
--- a/crates/engine/util/src/reorg.rs
+++ b/crates/engine/util/src/reorg.rs
@@ -105,7 +105,7 @@ where
S: Stream- >,
Engine: EngineTypes,
Provider: BlockReader + StateProviderFactory,
- Evm: ConfigureEvm,
+ Evm: ConfigureEvm,
{
type Item = S::Item;
@@ -237,7 +237,7 @@ fn create_reorg_head(
) -> RethResult<(ExecutionPayload, Option)>
where
Provider: BlockReader + StateProviderFactory,
- Evm: ConfigureEvm,
+ Evm: ConfigureEvm,
{
let chain_spec = payload_validator.chain_spec();
diff --git a/crates/ethereum/evm/src/execute.rs b/crates/ethereum/evm/src/execute.rs
index f173c6cca454..096b44d0e828 100644
--- a/crates/ethereum/evm/src/execute.rs
+++ b/crates/ethereum/evm/src/execute.rs
@@ -67,7 +67,7 @@ impl EthExecutorProvider {
impl EthExecutorProvider
where
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
{
fn eth_executor(&self, db: DB) -> EthBlockExecutor
where
@@ -83,7 +83,7 @@ where
impl BlockExecutorProvider for EthExecutorProvider
where
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
{
type Executor + Display>> =
EthBlockExecutor;
@@ -126,7 +126,7 @@ struct EthEvmExecutor {
impl EthEvmExecutor
where
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
{
/// Executes the transactions in the block and returns the receipts of the transactions in the
/// block, the total gas used and the list of EIP-7685 [requests](Request).
@@ -267,7 +267,7 @@ impl EthBlockExecutor {
impl EthBlockExecutor
where
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
DB: Database + Display>,
{
/// Configures a new evm configuration and block environment for the given block.
@@ -356,7 +356,7 @@ where
impl Executor for EthBlockExecutor
where
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
DB: Database + Display>,
{
type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>;
@@ -391,7 +391,7 @@ pub struct BlockAccessListExecutor {
impl Executor for BlockAccessListExecutor
where
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
DB: Database + Display>,
{
type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>;
@@ -485,7 +485,7 @@ impl EthBatchExecutor {
impl BatchExecutor for EthBatchExecutor
where
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
DB: Database + Display>,
{
type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>;
diff --git a/crates/ethereum/evm/src/lib.rs b/crates/ethereum/evm/src/lib.rs
index 80d96c80cc7e..2894b66e7dd0 100644
--- a/crates/ethereum/evm/src/lib.rs
+++ b/crates/ethereum/evm/src/lib.rs
@@ -122,9 +122,29 @@ impl ConfigureEvmEnv for EthEvmConfig {
cfg_env.handler_cfg.spec_id = spec_id;
}
+ fn fill_block_env(&self, block_env: &mut BlockEnv, header: &Self::Header, after_merge: bool) {
+ block_env.number = U256::from(header.number);
+ block_env.coinbase = header.beneficiary;
+ block_env.timestamp = U256::from(header.timestamp);
+ if after_merge {
+ block_env.prevrandao = Some(header.mix_hash);
+ block_env.difficulty = U256::ZERO;
+ } else {
+ block_env.difficulty = header.difficulty;
+ block_env.prevrandao = None;
+ }
+ block_env.basefee = U256::from(header.base_fee_per_gas.unwrap_or_default());
+ block_env.gas_limit = U256::from(header.gas_limit);
+
+ // EIP-4844 excess blob gas of this block, introduced in Cancun
+ if let Some(excess_blob_gas) = header.excess_blob_gas {
+ block_env.set_blob_excess_gas_and_price(excess_blob_gas);
+ }
+ }
+
fn next_cfg_and_block_env(
&self,
- parent: &Header,
+ parent: &Self::Header,
attributes: NextBlockEnvAttributes,
) -> (CfgEnvWithHandlerCfg, BlockEnv) {
// configure evm env based on parent block
diff --git a/crates/ethereum/node/Cargo.toml b/crates/ethereum/node/Cargo.toml
index e7a5e702956e..145a966833cf 100644
--- a/crates/ethereum/node/Cargo.toml
+++ b/crates/ethereum/node/Cargo.toml
@@ -28,6 +28,7 @@ reth-beacon-consensus.workspace = true
reth-rpc.workspace = true
reth-node-api.workspace = true
reth-chainspec.workspace = true
+reth-primitives.workspace = true
# misc
eyre.workspace = true
diff --git a/crates/ethereum/node/src/node.rs b/crates/ethereum/node/src/node.rs
index 939f3db1e56e..050f9b9bc181 100644
--- a/crates/ethereum/node/src/node.rs
+++ b/crates/ethereum/node/src/node.rs
@@ -21,6 +21,7 @@ use reth_node_builder::{
BuilderContext, Node, PayloadBuilderConfig, PayloadTypes,
};
use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService};
+use reth_primitives::Header;
use reth_provider::CanonStateSubscriptions;
use reth_rpc::EthApi;
use reth_tracing::tracing::{debug, info};
@@ -217,7 +218,7 @@ impl EthereumPayloadBuilder {
where
Types: NodeTypesWithEngine,
Node: FullNodeTypes,
- Evm: ConfigureEvm,
+ Evm: ConfigureEvm,
Pool: TransactionPool + Unpin + 'static,
Types::Engine: PayloadTypes<
BuiltPayload = EthBuiltPayload,
diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs
index cde5d52d299b..9cd7981ff367 100644
--- a/crates/ethereum/payload/src/lib.rs
+++ b/crates/ethereum/payload/src/lib.rs
@@ -67,7 +67,7 @@ impl EthereumPayloadBuilder {
impl EthereumPayloadBuilder
where
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
{
/// Returns the configured [`CfgEnvWithHandlerCfg`] and [`BlockEnv`] for the targeted payload
/// (that has the `parent` as its parent).
@@ -88,7 +88,7 @@ where
// Default implementation of [PayloadBuilder] for unit type
impl PayloadBuilder for EthereumPayloadBuilder
where
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
Client: StateProviderFactory,
Pool: TransactionPool,
{
@@ -137,7 +137,7 @@ pub fn default_ethereum_payload(
initialized_block_env: BlockEnv,
) -> Result, PayloadBuilderError>
where
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
Client: StateProviderFactory,
Pool: TransactionPool,
{
diff --git a/crates/evm/src/lib.rs b/crates/evm/src/lib.rs
index f767d254f2c6..14a8ff21bf03 100644
--- a/crates/evm/src/lib.rs
+++ b/crates/evm/src/lib.rs
@@ -14,9 +14,7 @@ extern crate alloc;
use core::ops::Deref;
use crate::builder::RethEvmBuilder;
-use reth_primitives::{
- Address, Header, TransactionSigned, TransactionSignedEcRecovered, B256, U256,
-};
+use reth_primitives::{Address, TransactionSigned, TransactionSignedEcRecovered, B256, U256};
use revm::{Database, Evm, GetInspector};
use revm_primitives::{
BlockEnv, Bytes, CfgEnvWithHandlerCfg, Env, EnvWithHandlerCfg, SpecId, TxEnv,
@@ -139,30 +137,12 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static {
fn fill_cfg_env(
&self,
cfg_env: &mut CfgEnvWithHandlerCfg,
- header: &Header,
+ header: &Self::Header,
total_difficulty: U256,
);
/// Fill [`BlockEnv`] field according to the chain spec and given header
- fn fill_block_env(&self, block_env: &mut BlockEnv, header: &Header, after_merge: bool) {
- block_env.number = U256::from(header.number);
- block_env.coinbase = header.beneficiary;
- block_env.timestamp = U256::from(header.timestamp);
- if after_merge {
- block_env.prevrandao = Some(header.mix_hash);
- block_env.difficulty = U256::ZERO;
- } else {
- block_env.difficulty = header.difficulty;
- block_env.prevrandao = None;
- }
- block_env.basefee = U256::from(header.base_fee_per_gas.unwrap_or_default());
- block_env.gas_limit = U256::from(header.gas_limit);
-
- // EIP-4844 excess blob gas of this block, introduced in Cancun
- if let Some(excess_blob_gas) = header.excess_blob_gas {
- block_env.set_blob_excess_gas_and_price(excess_blob_gas);
- }
- }
+ fn fill_block_env(&self, block_env: &mut BlockEnv, header: &Self::Header, after_merge: bool);
/// Convenience function to call both [`fill_cfg_env`](ConfigureEvmEnv::fill_cfg_env) and
/// [`ConfigureEvmEnv::fill_block_env`].
@@ -172,7 +152,7 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static {
&self,
cfg: &mut CfgEnvWithHandlerCfg,
block_env: &mut BlockEnv,
- header: &Header,
+ header: &Self::Header,
total_difficulty: U256,
) {
self.fill_cfg_env(cfg, header, total_difficulty);
@@ -187,7 +167,7 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static {
/// the CL, such as the timestamp, suggested fee recipient, and randomness value.
fn next_cfg_and_block_env(
&self,
- parent: &Header,
+ parent: &Self::Header,
attributes: NextBlockEnvAttributes,
) -> (CfgEnvWithHandlerCfg, BlockEnv);
}
diff --git a/crates/evm/src/provider.rs b/crates/evm/src/provider.rs
index b847a0665a35..fc3d4ff94f79 100644
--- a/crates/evm/src/provider.rs
+++ b/crates/evm/src/provider.rs
@@ -22,7 +22,7 @@ pub trait EvmEnvProvider: Send + Sync {
evm_config: EvmConfig,
) -> ProviderResult<()>
where
- EvmConfig: ConfigureEvmEnv;
+ EvmConfig: ConfigureEvmEnv;
/// Fills the default [`CfgEnvWithHandlerCfg`] and [BlockEnv] fields with values specific to the
/// given [Header].
@@ -32,7 +32,7 @@ pub trait EvmEnvProvider: Send + Sync {
evm_config: EvmConfig,
) -> ProviderResult<(CfgEnvWithHandlerCfg, BlockEnv)>
where
- EvmConfig: ConfigureEvmEnv,
+ EvmConfig: ConfigureEvmEnv,
{
let mut cfg = CfgEnvWithHandlerCfg::new_with_spec_id(CfgEnv::default(), SpecId::LATEST);
let mut block_env = BlockEnv::default();
@@ -50,7 +50,7 @@ pub trait EvmEnvProvider: Send + Sync {
evm_config: EvmConfig,
) -> ProviderResult<()>
where
- EvmConfig: ConfigureEvmEnv;
+ EvmConfig: ConfigureEvmEnv;
/// Fills the [`CfgEnvWithHandlerCfg`] fields with values specific to the given
/// [BlockHashOrNumber].
@@ -61,7 +61,7 @@ pub trait EvmEnvProvider: Send + Sync {
evm_config: EvmConfig,
) -> ProviderResult<()>
where
- EvmConfig: ConfigureEvmEnv;
+ EvmConfig: ConfigureEvmEnv;
/// Fills the [`CfgEnvWithHandlerCfg`] fields with values specific to the given [Header].
fn fill_cfg_env_with_header(
@@ -71,5 +71,5 @@ pub trait EvmEnvProvider: Send + Sync {
evm_config: EvmConfig,
) -> ProviderResult<()>
where
- EvmConfig: ConfigureEvmEnv;
+ EvmConfig: ConfigureEvmEnv;
}
diff --git a/crates/evm/src/system_calls/eip2935.rs b/crates/evm/src/system_calls/eip2935.rs
index 0ed123e8a879..d32a58966653 100644
--- a/crates/evm/src/system_calls/eip2935.rs
+++ b/crates/evm/src/system_calls/eip2935.rs
@@ -7,6 +7,7 @@ use crate::ConfigureEvm;
use core::fmt::Display;
use reth_chainspec::{ChainSpec, EthereumHardforks};
use reth_execution_errors::{BlockExecutionError, BlockValidationError};
+use reth_primitives::Header;
use revm::{interpreter::Host, Database, DatabaseCommit, Evm};
use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ResultAndState, B256};
@@ -28,7 +29,7 @@ pub fn pre_block_blockhashes_contract_call(
where
DB: Database + DatabaseCommit,
DB::Error: Display,
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
{
// Apply the pre-block EIP-2935 contract call
let mut evm_pre_block = Evm::builder()
@@ -74,7 +75,7 @@ pub fn transact_blockhashes_contract_call(
where
DB: Database + DatabaseCommit,
DB::Error: core::fmt::Display,
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
{
if !chain_spec.is_prague_active_at_timestamp(block_timestamp) {
return Ok(None)
@@ -133,7 +134,7 @@ pub fn apply_blockhashes_contract_call(
where
DB: Database + DatabaseCommit,
DB::Error: core::fmt::Display,
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
{
if let Some(res) = transact_blockhashes_contract_call(
evm_config,
diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs
index 24af2098c87d..21073d869da3 100644
--- a/crates/evm/src/system_calls/mod.rs
+++ b/crates/evm/src/system_calls/mod.rs
@@ -11,7 +11,7 @@ use alloy_eips::{
};
use reth_chainspec::{ChainSpec, EthereumHardforks};
use reth_execution_errors::{BlockExecutionError, BlockValidationError};
-use reth_primitives::{Buf, Request};
+use reth_primitives::{Buf, Header, Request};
use revm::{interpreter::Host, Database, DatabaseCommit, Evm};
use revm_primitives::{
Address, BlockEnv, Bytes, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ExecutionResult, FixedBytes,
@@ -39,7 +39,7 @@ pub fn pre_block_beacon_root_contract_call(
where
DB: Database + DatabaseCommit,
DB::Error: Display,
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
{
// apply pre-block EIP-4788 contract call
let mut evm_pre_block = Evm::builder()
@@ -81,7 +81,7 @@ pub fn apply_beacon_root_contract_call(
where
DB: Database + DatabaseCommit,
DB::Error: core::fmt::Display,
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
{
if !chain_spec.is_cancun_active_at_timestamp(block_timestamp) {
return Ok(())
@@ -152,7 +152,7 @@ pub fn post_block_withdrawal_requests_contract_call(
where
DB: Database + DatabaseCommit,
DB::Error: Display,
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
{
// apply post-block EIP-7002 contract call
let mut evm_post_block = Evm::builder()
@@ -180,7 +180,7 @@ pub fn apply_withdrawal_requests_contract_call(
where
DB: Database + DatabaseCommit,
DB::Error: core::fmt::Display,
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
{
// get previous env
let previous_env = Box::new(evm.context.env().clone());
@@ -282,7 +282,7 @@ pub fn post_block_consolidation_requests_contract_call(
where
DB: Database + DatabaseCommit,
DB::Error: Display,
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
{
// apply post-block EIP-7251 contract call
let mut evm_post_block = Evm::builder()
@@ -310,7 +310,7 @@ pub fn apply_consolidation_requests_contract_call(
where
DB: Database + DatabaseCommit,
DB::Error: core::fmt::Display,
- EvmConfig: ConfigureEvm,
+ EvmConfig: ConfigureEvm,
{
// get previous env
let previous_env = Box::new(evm.context.env().clone());
diff --git a/crates/node/api/Cargo.toml b/crates/node/api/Cargo.toml
index 82e863d5a98b..e7685acc84fd 100644
--- a/crates/node/api/Cargo.toml
+++ b/crates/node/api/Cargo.toml
@@ -22,3 +22,4 @@ reth-tasks.workspace = true
reth-rpc-eth-api.workspace = true
reth-network-api.workspace = true
reth-node-types.workspace = true
+reth-primitives.workspace = true
diff --git a/crates/node/api/src/node.rs b/crates/node/api/src/node.rs
index bc59c134a022..ce6b16c8ffcd 100644
--- a/crates/node/api/src/node.rs
+++ b/crates/node/api/src/node.rs
@@ -6,6 +6,7 @@ use reth_evm::execute::BlockExecutorProvider;
use reth_network_api::FullNetwork;
use reth_node_types::{NodeTypesWithDB, NodeTypesWithEngine};
use reth_payload_builder::PayloadBuilderHandle;
+use reth_primitives::Header;
use reth_provider::FullProvider;
use reth_rpc_eth_api::EthApiTypes;
use reth_tasks::TaskExecutor;
@@ -48,7 +49,7 @@ pub trait FullNodeComponents: FullNodeTypes + Clone + 'static {
type Pool: TransactionPool + Unpin;
/// The node's EVM configuration, defining settings for the Ethereum Virtual Machine.
- type Evm: ConfigureEvm;
+ type Evm: ConfigureEvm;
/// The type that knows how to execute blocks.
type Executor: BlockExecutorProvider;
diff --git a/crates/node/builder/src/components/builder.rs b/crates/node/builder/src/components/builder.rs
index 650ab24abc13..ef9f303a740a 100644
--- a/crates/node/builder/src/components/builder.rs
+++ b/crates/node/builder/src/components/builder.rs
@@ -4,6 +4,7 @@ use std::{future::Future, marker::PhantomData};
use reth_consensus::Consensus;
use reth_evm::execute::BlockExecutorProvider;
+use reth_primitives::Header;
use reth_transaction_pool::TransactionPool;
use crate::{
@@ -371,7 +372,7 @@ where
F: FnOnce(&BuilderContext) -> Fut + Send,
Fut: Future