Skip to content

Commit

Permalink
Add kroma support (#11179) (#267)
Browse files Browse the repository at this point in the history
  • Loading branch information
simsonraj authored Nov 8, 2023
2 parents 9627023 + bb76149 commit 781ed85
Show file tree
Hide file tree
Showing 14 changed files with 451 additions and 9 deletions.
27 changes: 27 additions & 0 deletions core/chains/evm/config/toml/defaults/Kroma_Mainnet.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
ChainID = '255'
ChainType = 'kroma' # Kroma is based on the Optimism Bedrock architechture
FinalityDepth = 400
FinalityTagEnabled = true
LogPollInterval = '2s'
NoNewHeadsThreshold = '40s'
MinIncomingConfirmations = 1

[GasEstimator]
EIP1559DynamicFees = true
PriceMin = '1 wei'
BumpMin = '100 wei'

[GasEstimator.BlockHistory]
BlockHistorySize = 24

[Transactions]
ResendAfterThreshold = '30s'

[HeadTracker]
HistoryDepth = 400

[NodePool]
SyncThreshold = 10

[OCR]
ContractConfirmations = 1
27 changes: 27 additions & 0 deletions core/chains/evm/config/toml/defaults/Kroma_Sepolia.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
ChainID = '2358'
ChainType = 'kroma' # Kroma is based on the Optimism Bedrock architechture
FinalityDepth = 400
FinalityTagEnabled = true
LogPollInterval = '2s'
NoNewHeadsThreshold = '40s'
MinIncomingConfirmations = 1

[GasEstimator]
EIP1559DynamicFees = true
PriceMin = '1 wei'
BumpMin = '100 wei'

[GasEstimator.BlockHistory]
BlockHistorySize = 24

[Transactions]
ResendAfterThreshold = '30s'

[HeadTracker]
HistoryDepth = 400

[NodePool]
SyncThreshold = 10

[OCR]
ContractConfirmations = 1
14 changes: 14 additions & 0 deletions core/chains/evm/config/toml/defaults/WeMix_Mainnet.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
ChainID = '1111'
ChainType = 'wemix'
FinalityDepth = 1
MinIncomingConfirmations = 1
# WeMix emits a block every 1 second, regardless of transactions
LogPollInterval = '3s'
NoNewHeadsThreshold = '30s'

[OCR]
ContractConfirmations = 1

[GasEstimator]
EIP1559DynamicFees = true
TipCapDefault = '100 gwei'
14 changes: 14 additions & 0 deletions core/chains/evm/config/toml/defaults/WeMix_Testnet.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
ChainID = '1112'
ChainType = 'wemix'
FinalityDepth = 1
MinIncomingConfirmations = 1
# WeMix emits a block every 1 second, regardless of transactions
LogPollInterval = '3s'
NoNewHeadsThreshold = '30s'

[OCR]
ContractConfirmations = 1

[GasEstimator]
EIP1559DynamicFees = true
TipCapDefault = '100 gwei'
6 changes: 6 additions & 0 deletions core/chains/evm/gas/block_history_estimator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1329,6 +1329,12 @@ func TestBlockHistoryEstimator_IsUsable(t *testing.T) {
assert.Equal(t, true, bhe.IsUsable(tx2, block, cfg.ChainType(), geCfg.PriceMin(), logger.TestLogger(t)))
})

t.Run("returns false if transaction is of type 0x16 only on WeMix", func(t *testing.T) {
cfg.ChainTypeF = "wemix"
tx := evmtypes.Transaction{Type: 0x16, GasPrice: assets.NewWeiI(10), GasLimit: 42, Hash: utils.NewHash()}
assert.Equal(t, false, bhe.IsUsable(tx, block, cfg.ChainType(), geCfg.PriceMin(), logger.TestLogger(t)))
})

t.Run("returns false if transaction has base fee higher than the gas price only on Celo", func(t *testing.T) {
cfg.ChainTypeF = "celo"
tx := evmtypes.Transaction{Type: 0x0, GasPrice: assets.NewWeiI(10), GasLimit: 42, Hash: utils.NewHash()}
Expand Down
9 changes: 8 additions & 1 deletion core/chains/evm/gas/chain_specific.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func chainSpecificIsUsable(tx evmtypes.Transaction, baseFee *assets.Wei, chainTy
return false
}
}
if chainType == config.ChainOptimismBedrock {
if chainType == config.ChainOptimismBedrock || chainType == config.ChainKroma {
// This is a special deposit transaction type introduced in Bedrock upgrade.
// This is a system transaction that it will occur at least one time per block.
// We should discard this type before even processing it to avoid flooding the
Expand All @@ -42,5 +42,12 @@ func chainSpecificIsUsable(tx evmtypes.Transaction, baseFee *assets.Wei, chainTy
return false
}
}
if chainType == config.ChainWeMix {
// WeMix specific transaction types that enables fee delegation.
// https://docs.wemix.com/v/en/design/fee-delegation
if tx.Type == 0x16 {
return false
}
}
return true
}
12 changes: 11 additions & 1 deletion core/chains/evm/gas/rollups/l1_gas_price_oracle.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,18 @@ const (
// `function l1BaseFee() external view returns (uint256);`
OPGasOracle_l1BaseFee = "519b4bd3"

// GasOracleAddress is the address of the precompiled contract that exists on Kroma chain.
// This is the case for Kroma.
KromaGasOracleAddress = "0x4200000000000000000000000000000000000005"
// GasOracle_l1BaseFee is the a hex encoded call to:
// `function l1BaseFee() external view returns (uint256);`
KromaGasOracle_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}
var supportedChainTypes = []config.ChainType{config.ChainArbitrum, config.ChainOptimismBedrock, config.ChainKroma}

func IsRollupWithL1Support(chainType config.ChainType) bool {
return slices.Contains(supportedChainTypes, chainType)
Expand All @@ -75,6 +82,9 @@ func NewL1GasPriceOracle(lggr logger.Logger, ethClient ethClient, chainType conf
case config.ChainOptimismBedrock:
address = OPGasOracleAddress
callArgs = OPGasOracle_l1BaseFee
case config.ChainKroma:
address = KromaGasOracleAddress
callArgs = KromaGasOracle_l1BaseFee
default:
panic(fmt.Sprintf("Received unspported chaintype %s", chainType))
}
Expand Down
22 changes: 22 additions & 0 deletions core/chains/evm/gas/rollups/l1_gas_price_oracle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,28 @@ func TestL1GasPriceOracle(t *testing.T) {
assert.Equal(t, assets.NewWei(l1BaseFee), gasPrice)
})

t.Run("Calling GasPrice on started Kroma L1Oracle returns Kroma 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, KromaGasOracleAddress, callMsg.To.String())
assert.Equal(t, KromaGasOracle_l1BaseFee, fmt.Sprintf("%x", callMsg.Data))
assert.Nil(t, blockNumber)
}).Return(common.BigToHash(l1BaseFee).Bytes(), nil)

oracle := NewL1GasPriceOracle(logger.TestLogger(t), ethClient, config.ChainKroma)
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)
})

t.Run("Calling GasPrice on started OPStack L1Oracle returns OPStack l1GasPrice", func(t *testing.T) {
l1BaseFee := big.NewInt(200)

Expand Down
6 changes: 4 additions & 2 deletions core/config/chaintype.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,18 @@ const (
ChainOptimismBedrock ChainType = "optimismBedrock"
ChainXDai ChainType = "xdai"
ChainCelo ChainType = "celo"
ChainWeMix ChainType = "wemix"
ChainKroma ChainType = "kroma"
)

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)}, ", "))

// IsValid returns true if the ChainType value is known or empty.
func (c ChainType) IsValid() bool {
switch c {
case "", ChainArbitrum, ChainMetis, ChainOptimismBedrock, ChainXDai, ChainCelo:
case "", ChainArbitrum, ChainMetis, ChainOptimismBedrock, ChainXDai, ChainCelo, ChainKroma, ChainWeMix:
return true
}
return false
Expand Down
2 changes: 1 addition & 1 deletion core/config/docs/chains-evm.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
# Available types: arbitrum, metis, optimismBedrock, xdai, celo, kroma, wemix
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
Expand Down
4 changes: 2 additions & 2 deletions core/services/chainlink/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1096,7 +1096,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 or omitted
- ChainType: invalid value (Foo): must be one of arbitrum, metis, xdai, optimismBedrock, celo, kroma, wemix 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
Expand All @@ -1105,7 +1105,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 or omitted
- ChainType: invalid value (Arbitrum): must be one of arbitrum, metis, xdai, optimismBedrock, celo, kroma, wemix 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:
Expand Down
2 changes: 1 addition & 1 deletion core/services/ocr/contract_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,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.ChainXDai:
case "", config.ChainArbitrum, config.ChainXDai, config.ChainKroma, config.ChainWeMix:
// continue
}
latestBlockHeight := t.getLatestBlockHeight()
Expand Down
Loading

0 comments on commit 781ed85

Please sign in to comment.