Skip to content

Commit

Permalink
Update DA oracle config struct members to pointers (#15008)
Browse files Browse the repository at this point in the history
* Update DA oracle config struct members to pointers

* Update tests and remake config docs

* suggestions and fix docs_test

* fix config test

(cherry picked from commit b585654)
  • Loading branch information
ogtownsend committed Oct 30, 2024
1 parent 571c154 commit 6951f9e
Show file tree
Hide file tree
Showing 13 changed files with 99 additions and 61 deletions.
5 changes: 5 additions & 0 deletions .changeset/green-crabs-joke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": patch
---

#bugfix Update DA oracle config struct members to pointers
11 changes: 9 additions & 2 deletions core/capabilities/ccip/ocrimpls/contract_transmitter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -600,15 +600,22 @@ type TestDAOracleConfig struct {
evmconfig.DAOracle
}

func (d *TestDAOracleConfig) OracleType() toml.DAOracleType { return toml.DAOracleOPStack }
func (d *TestDAOracleConfig) OracleType() *toml.DAOracleType {
oracleType := toml.DAOracleOPStack
return &oracleType
}

func (d *TestDAOracleConfig) OracleAddress() *types.EIP55Address {
a, err := types.NewEIP55Address("0x420000000000000000000000000000000000000F")
if err != nil {
panic(err)
}
return &a
}
func (d *TestDAOracleConfig) CustomGasPriceCalldata() string { return "" }

func (d *TestDAOracleConfig) CustomGasPriceCalldata() *string {
return nil
}

func (g *TestGasEstimatorConfig) BlockHistory() evmconfig.BlockHistory {
return &TestBlockHistoryConfig{}
Expand Down
6 changes: 3 additions & 3 deletions core/chains/evm/config/chain_scoped_gas_estimator.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ type daOracleConfig struct {
c toml.DAOracle
}

func (d *daOracleConfig) OracleType() toml.DAOracleType {
func (d *daOracleConfig) OracleType() *toml.DAOracleType {
return d.c.OracleType
}

Expand All @@ -137,9 +137,9 @@ func (d *daOracleConfig) OracleAddress() *types.EIP55Address {
}

// CustomGasPriceCalldata returns the calldata for a custom gas price API.
func (d *daOracleConfig) CustomGasPriceCalldata() string {
func (d *daOracleConfig) CustomGasPriceCalldata() *string {
// TODO: CCIP-3710 update once custom calldata oracle is added
return ""
return nil
}

type limitJobTypeConfig struct {
Expand Down
4 changes: 2 additions & 2 deletions core/chains/evm/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,9 @@ type BlockHistory interface {
}

type DAOracle interface {
OracleType() toml.DAOracleType
OracleType() *toml.DAOracleType
OracleAddress() *types.EIP55Address
CustomGasPriceCalldata() string
CustomGasPriceCalldata() *string
}

type FeeHistory interface {
Expand Down
23 changes: 19 additions & 4 deletions core/chains/evm/config/toml/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -759,9 +759,9 @@ func (u *FeeHistoryEstimator) setFrom(f *FeeHistoryEstimator) {
}

type DAOracle struct {
OracleType DAOracleType
OracleType *DAOracleType
OracleAddress *types.EIP55Address
CustomGasPriceCalldata string
CustomGasPriceCalldata *string
}

type DAOracleType string
Expand All @@ -772,6 +772,17 @@ const (
DAOracleZKSync = DAOracleType("zksync")
)

func (o *DAOracle) ValidateConfig() (err error) {
if o.OracleType != nil {
if *o.OracleType == DAOracleOPStack {
if o.OracleAddress == nil {
err = multierr.Append(err, commonconfig.ErrMissing{Name: "OracleAddress", Msg: "required for 'opstack' oracle types"})
}
}
}
return
}

func (o DAOracleType) IsValid() bool {
switch o {
case "", DAOracleOPStack, DAOracleArbitrum, DAOracleZKSync:
Expand All @@ -781,11 +792,15 @@ func (o DAOracleType) IsValid() bool {
}

func (d *DAOracle) setFrom(f *DAOracle) {
d.OracleType = f.OracleType
if v := f.OracleType; v != nil {
d.OracleType = v
}
if v := f.OracleAddress; v != nil {
d.OracleAddress = v
}
d.CustomGasPriceCalldata = f.CustomGasPriceCalldata
if v := f.CustomGasPriceCalldata; v != nil {
d.CustomGasPriceCalldata = v
}
}

type KeySpecificConfig []KeySpecific
Expand Down
1 change: 1 addition & 0 deletions core/chains/evm/gas/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ func NewEstimator(lggr logger.Logger, ethClient feeEstimatorClient, chaintype ch
"priceMax", geCfg.PriceMax(),
"priceMin", geCfg.PriceMin(),
"estimateLimit", geCfg.EstimateLimit(),
"daOracleType", geCfg.DAOracle().OracleType(),
"daOracleAddress", geCfg.DAOracle().OracleAddress(),
)
df := geCfg.EIP1559DynamicFees()
Expand Down
8 changes: 4 additions & 4 deletions core/chains/evm/gas/rollups/da_oracle_test_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ type TestDAOracle struct {
toml.DAOracle
}

func (d *TestDAOracle) OracleType() toml.DAOracleType {
func (d *TestDAOracle) OracleType() *toml.DAOracleType {
return d.DAOracle.OracleType
}

func (d *TestDAOracle) OracleAddress() *types.EIP55Address {
return d.DAOracle.OracleAddress
}

func (d *TestDAOracle) CustomGasPriceCalldata() string {
func (d *TestDAOracle) CustomGasPriceCalldata() *string {
return d.DAOracle.CustomGasPriceCalldata
}

Expand All @@ -31,9 +31,9 @@ func CreateTestDAOracle(t *testing.T, oracleType toml.DAOracleType, oracleAddres

return &TestDAOracle{
DAOracle: toml.DAOracle{
OracleType: oracleType,
OracleType: &oracleType,
OracleAddress: &oracleAddr,
CustomGasPriceCalldata: customGasPriceCalldata,
CustomGasPriceCalldata: &customGasPriceCalldata,
},
}
}
8 changes: 7 additions & 1 deletion core/chains/evm/gas/rollups/l1_oracle.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package rollups

import (
"context"
"errors"
"fmt"
"math/big"
"slices"
Expand Down Expand Up @@ -56,7 +57,12 @@ func NewL1GasOracle(lggr logger.Logger, ethClient l1OracleClient, chainType chai
var l1Oracle L1Oracle
var err error
if daOracle != nil {
switch daOracle.OracleType() {
oracleType := daOracle.OracleType()
if oracleType == nil {
return nil, errors.New("required field OracleType is nil in non-nil DAOracle config")
}

switch *oracleType {
case toml.DAOracleOPStack:
l1Oracle, err = NewOpStackL1GasOracle(lggr, ethClient, chainType, daOracle)
case toml.DAOracleArbitrum:
Expand Down
54 changes: 35 additions & 19 deletions core/chains/evm/gas/rollups/op_l1_oracle.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package rollups

import (
"context"
"errors"
"fmt"
"math/big"
"strings"
Expand All @@ -21,6 +22,7 @@ import (
evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
evmconfig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/chaintype"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml"
)

// Reads L2-specific precompiles and caches the l1GasPrice set by the L2.
Expand All @@ -30,12 +32,12 @@ type optimismL1Oracle struct {
pollPeriod time.Duration
logger logger.SugaredLogger

daOracleConfig evmconfig.DAOracle
l1GasPriceMu sync.RWMutex
l1GasPrice priceEntry
isEcotone bool
isFjord bool
upgradeCheckTs time.Time
daOracleAddress common.Address
l1GasPriceMu sync.RWMutex
l1GasPrice priceEntry
isEcotone bool
isFjord bool
upgradeCheckTs time.Time

chInitialised chan struct{}
chStop services.StopChan
Expand Down Expand Up @@ -88,6 +90,20 @@ const (
)

func NewOpStackL1GasOracle(lggr logger.Logger, ethClient l1OracleClient, chainType chaintype.ChainType, daOracle evmconfig.DAOracle) (*optimismL1Oracle, error) {
if daOracle.OracleType() == nil {
return nil, errors.New("OracleType is required but was nil")
}
if *daOracle.OracleType() != toml.DAOracleOPStack {
return nil, fmt.Errorf("expected %s oracle type, got %s", toml.DAOracleOPStack, *daOracle.OracleType())
}
if daOracle.CustomGasPriceCalldata() != nil && *daOracle.CustomGasPriceCalldata() != "" {
lggr.Warnf("CustomGasPriceCalldata is set but will be ignored for OPStack DA oracle")
}
if daOracle.OracleAddress() == nil || *daOracle.OracleAddress() == "" {
return nil, errors.New("OracleAddress is required but was nil or empty")
}
oracleAddress := *daOracle.OracleAddress()

getL1FeeMethodAbi, err := abi.JSON(strings.NewReader(GetL1FeeAbiString))
if err != nil {
return nil, fmt.Errorf("failed to parse L1 gas cost method ABI for chain: %s", chainType)
Expand Down Expand Up @@ -141,10 +157,10 @@ func NewOpStackL1GasOracle(lggr logger.Logger, ethClient l1OracleClient, chainTy
pollPeriod: PollPeriod,
logger: logger.Sugared(logger.Named(lggr, fmt.Sprintf("L1GasOracle(%s)", chainType))),

daOracleConfig: daOracle,
isEcotone: false,
isFjord: false,
upgradeCheckTs: time.Time{},
daOracleAddress: oracleAddress.Address(),
isEcotone: false,
isFjord: false,
upgradeCheckTs: time.Time{},

chInitialised: make(chan struct{}),
chStop: make(chan struct{}),
Expand Down Expand Up @@ -276,14 +292,15 @@ func (o *optimismL1Oracle) checkForUpgrade(ctx context.Context) error {
if time.Since(o.upgradeCheckTs) < upgradePollingPeriod {
return nil
}

o.upgradeCheckTs = time.Now()
rpcBatchCalls := []rpc.BatchElem{
{
Method: "eth_call",
Args: []any{
map[string]interface{}{
"from": common.Address{},
"to": o.daOracleConfig.OracleAddress().String(),
"to": o.daOracleAddress.String(),
"data": hexutil.Bytes(o.isFjordCalldata),
},
"latest",
Expand All @@ -295,7 +312,7 @@ func (o *optimismL1Oracle) checkForUpgrade(ctx context.Context) error {
Args: []any{
map[string]interface{}{
"from": common.Address{},
"to": o.daOracleConfig.OracleAddress().String(),
"to": o.daOracleAddress.String(),
"data": hexutil.Bytes(o.isEcotoneCalldata),
},
"latest",
Expand Down Expand Up @@ -336,9 +353,8 @@ func (o *optimismL1Oracle) checkForUpgrade(ctx context.Context) error {
}

func (o *optimismL1Oracle) getV1GasPrice(ctx context.Context) (*big.Int, error) {
l1OracleAddress := o.daOracleConfig.OracleAddress().Address()
b, err := o.client.CallContract(ctx, ethereum.CallMsg{
To: &l1OracleAddress,
To: &o.daOracleAddress,
Data: o.l1BaseFeeCalldata,
}, nil)
if err != nil {
Expand All @@ -360,7 +376,7 @@ func (o *optimismL1Oracle) getEcotoneFjordGasPrice(ctx context.Context) (*big.In
Args: []any{
map[string]interface{}{
"from": common.Address{},
"to": o.daOracleConfig.OracleAddress().String(),
"to": o.daOracleAddress.String(),
"data": hexutil.Bytes(o.l1BaseFeeCalldata),
},
"latest",
Expand All @@ -372,7 +388,7 @@ func (o *optimismL1Oracle) getEcotoneFjordGasPrice(ctx context.Context) (*big.In
Args: []any{
map[string]interface{}{
"from": common.Address{},
"to": o.daOracleConfig.OracleAddress().String(),
"to": o.daOracleAddress.String(),
"data": hexutil.Bytes(o.baseFeeScalarCalldata),
},
"latest",
Expand All @@ -384,7 +400,7 @@ func (o *optimismL1Oracle) getEcotoneFjordGasPrice(ctx context.Context) (*big.In
Args: []any{
map[string]interface{}{
"from": common.Address{},
"to": o.daOracleConfig.OracleAddress().String(),
"to": o.daOracleAddress.String(),
"data": hexutil.Bytes(o.blobBaseFeeCalldata),
},
"latest",
Expand All @@ -396,7 +412,7 @@ func (o *optimismL1Oracle) getEcotoneFjordGasPrice(ctx context.Context) (*big.In
Args: []any{
map[string]interface{}{
"from": common.Address{},
"to": o.daOracleConfig.OracleAddress().String(),
"to": o.daOracleAddress.String(),
"data": hexutil.Bytes(o.blobBaseFeeScalarCalldata),
},
"latest",
Expand All @@ -408,7 +424,7 @@ func (o *optimismL1Oracle) getEcotoneFjordGasPrice(ctx context.Context) (*big.In
Args: []any{
map[string]interface{}{
"from": common.Address{},
"to": o.daOracleConfig.OracleAddress().String(),
"to": o.daOracleAddress.String(),
"data": hexutil.Bytes(o.decimalsCalldata),
},
"latest",
Expand Down
7 changes: 5 additions & 2 deletions core/chains/evm/txmgr/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,18 @@ type TestDAOracleConfig struct {
evmconfig.DAOracle
}

func (d *TestDAOracleConfig) OracleType() toml.DAOracleType { return toml.DAOracleOPStack }
func (d *TestDAOracleConfig) OracleType() *toml.DAOracleType {
oracleType := toml.DAOracleOPStack
return &oracleType
}
func (d *TestDAOracleConfig) OracleAddress() *types.EIP55Address {
a, err := types.NewEIP55Address("0x420000000000000000000000000000000000000F")
if err != nil {
panic(err)
}
return &a
}
func (d *TestDAOracleConfig) CustomGasPriceCalldata() string { return "" }
func (d *TestDAOracleConfig) CustomGasPriceCalldata() *string { return nil }

func (g *TestGasEstimatorConfig) BlockHistory() evmconfig.BlockHistory {
return &TestBlockHistoryConfig{}
Expand Down
4 changes: 2 additions & 2 deletions core/config/docs/docs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ func TestDoc(t *testing.T) {
docDefaults.Transactions.AutoPurge.Threshold = nil
docDefaults.Transactions.AutoPurge.MinAttempts = nil

// GasEstimator.DAOracle.OracleAddress is only set if DA oracle config is used
docDefaults.GasEstimator.DAOracle.OracleAddress = nil
// Fallback DA oracle is not set
docDefaults.GasEstimator.DAOracle = evmcfg.DAOracle{}

assertTOML(t, fallbackDefaults, docDefaults)
})
Expand Down
7 changes: 7 additions & 0 deletions core/services/chainlink/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1398,9 +1398,16 @@ func TestConfig_full(t *testing.T) {
if got.EVM[c].Transactions.AutoPurge.DetectionApiUrl == nil {
got.EVM[c].Transactions.AutoPurge.DetectionApiUrl = new(commoncfg.URL)
}
if got.EVM[c].GasEstimator.DAOracle.OracleType == nil {
oracleType := evmcfg.DAOracleOPStack
got.EVM[c].GasEstimator.DAOracle.OracleType = &oracleType
}
if got.EVM[c].GasEstimator.DAOracle.OracleAddress == nil {
got.EVM[c].GasEstimator.DAOracle.OracleAddress = new(types.EIP55Address)
}
if got.EVM[c].GasEstimator.DAOracle.CustomGasPriceCalldata == nil {
got.EVM[c].GasEstimator.DAOracle.CustomGasPriceCalldata = new(string)
}
}

cfgtest.AssertFieldsNotNil(t, got)
Expand Down
Loading

0 comments on commit 6951f9e

Please sign in to comment.