From 39847bb007ebb92bd3153d4ea5962ab061ed148d Mon Sep 17 00:00:00 2001 From: Sishir Giri Date: Wed, 17 Jan 2024 17:30:22 -0800 Subject: [PATCH] [Fix] Add Scroll chainType and L1GasOracle (#11790) * added scroll l1 oracle gas * nit * updated docs * nit * linter * amits comment --- common/config/chaintype.go | 5 +++-- .../config/toml/defaults/Scroll_Mainnet.toml | 1 + .../config/toml/defaults/Scroll_Sepolia.toml | 1 + .../evm/gas/rollups/l1_gas_price_oracle.go | 12 +++++++++- .../gas/rollups/l1_gas_price_oracle_test.go | 22 +++++++++++++++++++ core/config/docs/chains-evm.toml | 2 +- core/services/chainlink/config_test.go | 4 ++-- core/services/ocr/contract_tracker.go | 2 +- docs/CONFIG.md | 4 +++- 9 files changed, 45 insertions(+), 8 deletions(-) diff --git a/common/config/chaintype.go b/common/config/chaintype.go index 21fb8cd297d..9ef4864b86e 100644 --- a/common/config/chaintype.go +++ b/common/config/chaintype.go @@ -18,16 +18,17 @@ const ( ChainWeMix ChainType = "wemix" ChainKroma ChainType = "kroma" ChainZkSync ChainType = "zksync" + ChainScroll ChainType = "scroll" ) var ErrInvalidChainType = fmt.Errorf("must be one of %s or omitted", strings.Join([]string{ string(ChainArbitrum), string(ChainMetis), string(ChainXDai), string(ChainOptimismBedrock), string(ChainCelo), - string(ChainKroma), string(ChainWeMix), string(ChainZkSync)}, ", ")) + string(ChainKroma), string(ChainWeMix), string(ChainZkSync), string(ChainScroll)}, ", ")) // IsValid returns true if the ChainType value is known or empty. func (c ChainType) IsValid() bool { switch c { - case "", ChainArbitrum, ChainMetis, ChainOptimismBedrock, ChainXDai, ChainCelo, ChainKroma, ChainWeMix, ChainZkSync: + case "", ChainArbitrum, ChainMetis, ChainOptimismBedrock, ChainXDai, ChainCelo, ChainKroma, ChainWeMix, ChainZkSync, ChainScroll: return true } return false diff --git a/core/chains/evm/config/toml/defaults/Scroll_Mainnet.toml b/core/chains/evm/config/toml/defaults/Scroll_Mainnet.toml index 56ed84c7f38..e087b86fe3e 100644 --- a/core/chains/evm/config/toml/defaults/Scroll_Mainnet.toml +++ b/core/chains/evm/config/toml/defaults/Scroll_Mainnet.toml @@ -1,5 +1,6 @@ ChainID = '534352' FinalityDepth = 1 +ChainType = 'scroll' LogPollInterval = '3s' MinIncomingConfirmations = 1 # Scroll only emits blocks when a new tx is received, so this method of liveness detection is not useful diff --git a/core/chains/evm/config/toml/defaults/Scroll_Sepolia.toml b/core/chains/evm/config/toml/defaults/Scroll_Sepolia.toml index af17c4d485e..9db7a8ebed5 100644 --- a/core/chains/evm/config/toml/defaults/Scroll_Sepolia.toml +++ b/core/chains/evm/config/toml/defaults/Scroll_Sepolia.toml @@ -1,5 +1,6 @@ ChainID = '534351' FinalityDepth = 1 +ChainType = 'scroll' LogPollInterval = '3s' MinIncomingConfirmations = 1 # Scroll only emits blocks when a new tx is received, so this method of liveness detection is not useful diff --git a/core/chains/evm/gas/rollups/l1_gas_price_oracle.go b/core/chains/evm/gas/rollups/l1_gas_price_oracle.go index 8df817f7864..a006ea89923 100644 --- a/core/chains/evm/gas/rollups/l1_gas_price_oracle.go +++ b/core/chains/evm/gas/rollups/l1_gas_price_oracle.go @@ -65,11 +65,18 @@ const ( // `function l1BaseFee() external view returns (uint256);` KromaGasOracle_l1BaseFee = "519b4bd3" + // GasOracleAddress is the address of the precompiled contract that exists on scroll chain. + // This is the case for Scroll. + ScrollGasOracleAddress = "0x5300000000000000000000000000000000000002" + // GasOracle_l1BaseFee is the a hex encoded call to: + // `function l1BaseFee() external view returns (uint256);` + ScrollGasOracle_l1BaseFee = "519b4bd3" + // Interval at which to poll for L1BaseFee. A good starting point is the L1 block time. PollPeriod = 12 * time.Second ) -var supportedChainTypes = []config.ChainType{config.ChainArbitrum, config.ChainOptimismBedrock, config.ChainKroma} +var supportedChainTypes = []config.ChainType{config.ChainArbitrum, config.ChainOptimismBedrock, config.ChainKroma, config.ChainScroll} func IsRollupWithL1Support(chainType config.ChainType) bool { return slices.Contains(supportedChainTypes, chainType) @@ -87,6 +94,9 @@ func NewL1GasPriceOracle(lggr logger.Logger, ethClient ethClient, chainType conf case config.ChainKroma: address = KromaGasOracleAddress callArgs = KromaGasOracle_l1BaseFee + case config.ChainScroll: + address = ScrollGasOracleAddress + callArgs = ScrollGasOracle_l1BaseFee default: panic(fmt.Sprintf("Received unspported chaintype %s", chainType)) } diff --git a/core/chains/evm/gas/rollups/l1_gas_price_oracle_test.go b/core/chains/evm/gas/rollups/l1_gas_price_oracle_test.go index 1a1d1ffdeee..188376bf832 100644 --- a/core/chains/evm/gas/rollups/l1_gas_price_oracle_test.go +++ b/core/chains/evm/gas/rollups/l1_gas_price_oracle_test.go @@ -100,4 +100,26 @@ func TestL1GasPriceOracle(t *testing.T) { assert.Equal(t, assets.NewWei(l1BaseFee), gasPrice) }) + + t.Run("Calling GasPrice on started Scroll L1Oracle returns Scroll l1GasPrice", func(t *testing.T) { + l1BaseFee := big.NewInt(200) + + ethClient := mocks.NewETHClient(t) + ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) { + callMsg := args.Get(1).(ethereum.CallMsg) + blockNumber := args.Get(2).(*big.Int) + assert.Equal(t, ScrollGasOracleAddress, callMsg.To.String()) + assert.Equal(t, ScrollGasOracle_l1BaseFee, fmt.Sprintf("%x", callMsg.Data)) + assert.Nil(t, blockNumber) + }).Return(common.BigToHash(l1BaseFee).Bytes(), nil) + + oracle := NewL1GasPriceOracle(logger.Test(t), ethClient, config.ChainScroll) + require.NoError(t, oracle.Start(testutils.Context(t))) + t.Cleanup(func() { assert.NoError(t, oracle.Close()) }) + + gasPrice, err := oracle.GasPrice(testutils.Context(t)) + require.NoError(t, err) + + assert.Equal(t, assets.NewWei(l1BaseFee), gasPrice) + }) } diff --git a/core/config/docs/chains-evm.toml b/core/config/docs/chains-evm.toml index 711889b3fa5..53f5cb68529 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -14,7 +14,7 @@ BlockBackfillDepth = 10 # Default # BlockBackfillSkip enables skipping of very long backfills. BlockBackfillSkip = false # Default # ChainType is automatically detected from chain ID. Set this to force a certain chain type regardless of chain ID. -# Available types: arbitrum, metis, optimismBedrock, xdai, celo, kroma, wemix, zksync +# Available types: arbitrum, metis, optimismBedrock, xdai, celo, kroma, wemix, zksync, scroll ChainType = 'arbitrum' # Example # FinalityDepth is the number of blocks after which an ethereum transaction is considered "final". Note that the default is automatically set based on chain ID so it should not be necessary to change this under normal operation. # BlocksConsideredFinal determines how deeply we look back to ensure that transactions are confirmed onto the longest chain diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index a7ac1e86d84..7e4be202702 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -1196,7 +1196,7 @@ func TestConfig_Validate(t *testing.T) { - 1: 6 errors: - ChainType: invalid value (Foo): must not be set with this chain id - Nodes: missing: must have at least one node - - ChainType: invalid value (Foo): must be one of arbitrum, metis, xdai, optimismBedrock, celo, kroma, wemix, zksync or omitted + - ChainType: invalid value (Foo): must be one of arbitrum, metis, xdai, optimismBedrock, celo, kroma, wemix, zksync, scroll or omitted - HeadTracker.HistoryDepth: invalid value (30): must be equal to or greater than FinalityDepth - GasEstimator: 2 errors: - FeeCapDefault: invalid value (101 wei): must be equal to PriceMax (99 wei) since you are using FixedPrice estimation with gas bumping disabled in EIP1559 mode - PriceMax will be used as the FeeCap for transactions instead of FeeCapDefault @@ -1205,7 +1205,7 @@ func TestConfig_Validate(t *testing.T) { - 2: 5 errors: - ChainType: invalid value (Arbitrum): only "optimismBedrock" can be used with this chain id - Nodes: missing: must have at least one node - - ChainType: invalid value (Arbitrum): must be one of arbitrum, metis, xdai, optimismBedrock, celo, kroma, wemix, zksync or omitted + - ChainType: invalid value (Arbitrum): must be one of arbitrum, metis, xdai, optimismBedrock, celo, kroma, wemix, zksync, scroll or omitted - FinalityDepth: invalid value (0): must be greater than or equal to 1 - MinIncomingConfirmations: invalid value (0): must be greater than or equal to 1 - 3.Nodes: 5 errors: diff --git a/core/services/ocr/contract_tracker.go b/core/services/ocr/contract_tracker.go index 1287e52e9b5..9eabf93a834 100644 --- a/core/services/ocr/contract_tracker.go +++ b/core/services/ocr/contract_tracker.go @@ -402,7 +402,7 @@ func (t *OCRContractTracker) LatestBlockHeight(ctx context.Context) (blockheight // care about the block height; we have no way of getting the L1 block // height anyway return 0, nil - case "", config.ChainArbitrum, config.ChainCelo, config.ChainOptimismBedrock, config.ChainXDai, config.ChainKroma, config.ChainWeMix, config.ChainZkSync: + case "", config.ChainArbitrum, config.ChainCelo, config.ChainOptimismBedrock, config.ChainXDai, config.ChainKroma, config.ChainWeMix, config.ChainZkSync, config.ChainScroll: // continue } latestBlockHeight := t.getLatestBlockHeight() diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 421b0ea9dad..3ae4afa3bcf 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -5014,6 +5014,7 @@ GasLimit = 14500000 AutoCreateKey = true BlockBackfillDepth = 10 BlockBackfillSkip = false +ChainType = 'scroll' FinalityDepth = 1 FinalityTagEnabled = false LogBackfillBatchSize = 1000 @@ -5094,6 +5095,7 @@ GasLimit = 5300000 AutoCreateKey = true BlockBackfillDepth = 10 BlockBackfillSkip = false +ChainType = 'scroll' FinalityDepth = 1 FinalityTagEnabled = false LogBackfillBatchSize = 1000 @@ -5448,7 +5450,7 @@ BlockBackfillSkip enables skipping of very long backfills. ChainType = 'arbitrum' # Example ``` ChainType is automatically detected from chain ID. Set this to force a certain chain type regardless of chain ID. -Available types: arbitrum, metis, optimismBedrock, xdai, celo, kroma, wemix, zksync +Available types: arbitrum, metis, optimismBedrock, xdai, celo, kroma, wemix, zksync, scroll ### FinalityDepth ```toml