diff --git a/src/rpc/methods/eth.rs b/src/rpc/methods/eth.rs index 18908282a310..560573915e60 100644 --- a/src/rpc/methods/eth.rs +++ b/src/rpc/methods/eth.rs @@ -835,6 +835,23 @@ impl RpcMethod<0> for EthAccounts { } pub enum EthBaseFee {} + +impl EthBaseFee { + fn get_base_fee(ctx: &Ctx, ts: &Tipset) -> anyhow::Result { + let heights = &ctx.chain_config().height_infos; + let smoke_height = heights + .get(&Height::Smoke) + .context("Missing Smoke height")? + .epoch; + let firehorse_height = heights + .get(&Height::FireHorse) + .context("Missing FireHorse height")? + .epoch; + compute_base_fee(ctx.db(), ts, smoke_height, firehorse_height) + .context("failed to compute base fee for eth_baseFee") + } +} + impl RpcMethod<0> for EthBaseFee { const NAME: &'static str = "Filecoin.EthBaseFee"; const NAME_ALIAS: Option<&'static str> = Some("eth_baseFee"); @@ -852,18 +869,36 @@ impl RpcMethod<0> for EthBaseFee { (): Self::Params, _: &http::Extensions, ) -> Result { - let ts = ctx.chain_store().heaviest_tipset(); - let heights = &ctx.chain_config().height_infos; - let smoke_height = heights - .get(&Height::Smoke) - .context("Missing Smoke height")? - .epoch; - let firehorse_height = heights - .get(&Height::FireHorse) - .context("Missing FireHorse height")? - .epoch; - let base_fee = compute_base_fee(ctx.db(), &ts, smoke_height, firehorse_height) - .context("failed to compute base fee for eth_baseFee")?; + let base_fee = Self::get_base_fee(&ctx, &ctx.chain_store().heaviest_tipset())?; + Ok(EthBigInt(base_fee.atto().clone())) + } +} + +pub enum BaseFeeByHeight {} +impl RpcMethod<1> for BaseFeeByHeight { + const NAME: &'static str = "Forest.BaseFeeByHeight"; + const NAME_ALIAS: Option<&'static str> = None; + const PARAM_NAMES: [&'static str; 1] = ["height"]; + const API_PATHS: BitFlags = ApiPaths::all_with_v2(); + const PERMISSION: Permission = Permission::Read; + const DESCRIPTION: Option<&'static str> = Some( + "Returns the calculated upcoming base fee of the tipset at the given height in attoFIL", + ); + + type Params = (ChainEpoch,); + type Ok = EthBigInt; + + async fn handle( + ctx: Ctx, + (height,): Self::Params, + _: &http::Extensions, + ) -> Result { + let ts = ctx.chain_index().load_required_tipset_by_height( + height, + ctx.chain_store().heaviest_tipset(), + ResolveNullTipset::TakeOlder, + )?; + let base_fee = EthBaseFee::get_base_fee(&ctx, &ts)?; Ok(EthBigInt(base_fee.atto().clone())) } } diff --git a/src/rpc/mod.rs b/src/rpc/mod.rs index f5af90855161..6fc9622d6fd3 100644 --- a/src/rpc/mod.rs +++ b/src/rpc/mod.rs @@ -107,6 +107,7 @@ macro_rules! for_each_rpc_method { $callback!($crate::rpc::eth::EthAddressToFilecoinAddress); $callback!($crate::rpc::eth::FilecoinAddressToEthAddress); $callback!($crate::rpc::eth::EthBaseFee); + $callback!($crate::rpc::eth::BaseFeeByHeight); $callback!($crate::rpc::eth::EthBlockNumber); $callback!($crate::rpc::eth::EthCall); $callback!($crate::rpc::eth::EthChainId); diff --git a/src/rpc/snapshots/forest__rpc__tests__rpc__v0.snap b/src/rpc/snapshots/forest__rpc__tests__rpc__v0.snap index 60c3fff8cfe3..a90a4333e64c 100644 --- a/src/rpc/snapshots/forest__rpc__tests__rpc__v0.snap +++ b/src/rpc/snapshots/forest__rpc__tests__rpc__v0.snap @@ -543,6 +543,20 @@ methods: schema: $ref: "#/components/schemas/EthBigInt" paramStructure: by-position + - name: Forest.BaseFeeByHeight + description: Returns the calculated upcoming base fee of the tipset at the given height in attoFIL + params: + - name: height + required: true + schema: + type: integer + format: int64 + result: + name: Forest.BaseFeeByHeight.Result + required: true + schema: + $ref: "#/components/schemas/EthBigInt" + paramStructure: by-position - name: Filecoin.EthBlockNumber params: [] result: diff --git a/src/rpc/snapshots/forest__rpc__tests__rpc__v1.snap b/src/rpc/snapshots/forest__rpc__tests__rpc__v1.snap index 13c2fa4e7690..b14040e79980 100644 --- a/src/rpc/snapshots/forest__rpc__tests__rpc__v1.snap +++ b/src/rpc/snapshots/forest__rpc__tests__rpc__v1.snap @@ -539,6 +539,20 @@ methods: schema: $ref: "#/components/schemas/EthBigInt" paramStructure: by-position + - name: Forest.BaseFeeByHeight + description: Returns the calculated upcoming base fee of the tipset at the given height in attoFIL + params: + - name: height + required: true + schema: + type: integer + format: int64 + result: + name: Forest.BaseFeeByHeight.Result + required: true + schema: + $ref: "#/components/schemas/EthBigInt" + paramStructure: by-position - name: Filecoin.EthBlockNumber params: [] result: diff --git a/src/rpc/snapshots/forest__rpc__tests__rpc__v2.snap b/src/rpc/snapshots/forest__rpc__tests__rpc__v2.snap index 6dc93c979ba8..60338ee21632 100644 --- a/src/rpc/snapshots/forest__rpc__tests__rpc__v2.snap +++ b/src/rpc/snapshots/forest__rpc__tests__rpc__v2.snap @@ -143,6 +143,20 @@ methods: schema: $ref: "#/components/schemas/EthBigInt" paramStructure: by-position + - name: Forest.BaseFeeByHeight + description: Returns the calculated upcoming base fee of the tipset at the given height in attoFIL + params: + - name: height + required: true + schema: + type: integer + format: int64 + result: + name: Forest.BaseFeeByHeight.Result + required: true + schema: + $ref: "#/components/schemas/EthBigInt" + paramStructure: by-position - name: Filecoin.EthBlockNumber params: [] result: diff --git a/src/tool/subcommands/api_cmd/test_snapshots_ignored.txt b/src/tool/subcommands/api_cmd/test_snapshots_ignored.txt index d2181d5ccc37..22e40cd88d57 100644 --- a/src/tool/subcommands/api_cmd/test_snapshots_ignored.txt +++ b/src/tool/subcommands/api_cmd/test_snapshots_ignored.txt @@ -77,6 +77,7 @@ Filecoin.WalletSetDefault Filecoin.WalletSign Filecoin.WalletSignMessage Filecoin.Web3ClientVersion +Forest.BaseFeeByHeight Forest.ChainExport Forest.ChainExportCancel Forest.ChainExportDiff