Skip to content

Commit

Permalink
daPriceEstimator rework
Browse files Browse the repository at this point in the history
  • Loading branch information
valerii-kabisov-cll committed Jun 28, 2024
1 parent e135d77 commit 00b3f89
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 35 deletions.
13 changes: 12 additions & 1 deletion core/services/ocr2/plugins/ccip/ccipcommit/initializers.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,17 @@ func jobSpecToCommitPluginConfig(ctx context.Context, orm cciporm.ORM, lggr logg
if err != nil {
return nil, nil, nil, nil, errors.Wrap(err, "failed onramp reader")
}
offRampReader, err := factory.NewOffRampReader(commitLggr, versionFinder, params.pluginConfig.OffRamp, params.destChain.Client(), params.destChain.LogPoller(), params.destChain.GasEstimator(), params.destChain.Config().EVM().GasEstimator().PriceMax().ToInt(), true)

offRampReader, err := factory.NewOffRampReader(
commitLggr,
versionFinder,
params.pluginConfig.OffRamp,
params.destChain.Client(),
params.destChain.LogPoller(),
params.destChain.GasEstimator(),
params.destChain.Config().EVM().GasEstimator().PriceMax().ToInt(),
true,
)
if err != nil {
return nil, nil, nil, nil, errors.Wrap(err, "failed offramp reader")
}
Expand Down Expand Up @@ -297,6 +307,7 @@ type jobSpecParams struct {
pluginConfig ccipconfig.CommitPluginJobSpecConfig
commitStoreAddress cciptypes.Address
commitStoreStaticCfg commit_store.CommitStoreStaticConfig
daGasPriceEstimator cciptypes.GasPriceEstimator
sourceChain legacyevm.Chain
destChain legacyevm.Chain
}
Expand Down
69 changes: 65 additions & 4 deletions core/services/ocr2/plugins/ccip/ccipexec/initializers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices"
"math/big"
"net/url"
"strconv"
"strings"
"time"

"github.com/Masterminds/semver/v3"
Expand Down Expand Up @@ -45,6 +51,10 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/promwrapper"
)

const (
ConfigSetEventName = "ConfigSet"
)

var (
// tokenDataWorkerTimeout defines 1) The timeout while waiting for a bg call to the token data 3P provider.
// 2) When a client requests token data and does not specify a timeout this value is used as a default.
Expand Down Expand Up @@ -100,7 +110,7 @@ func NewExecutionServices(ctx context.Context, lggr logger.Logger, jb job.Job, c
// See comment in UnregisterCommitPluginLpFilters
// It MUST mirror the filters registered in NewExecutionServices.
func UnregisterExecPluginLpFilters(ctx context.Context, lggr logger.Logger, jb job.Job, chainSet legacyevm.LegacyChainContainer) error {
params, err := extractJobSpecParams(lggr, jb, chainSet, false)
params, err := extractJobSpecParams(ctx, lggr, jb, chainSet, false)
if err != nil {
return err
}
Expand Down Expand Up @@ -180,7 +190,7 @@ func initTokenDataProviders(lggr logger.Logger, jobID string, pluginConfig ccipc
}

func jobSpecToExecPluginConfig(ctx context.Context, lggr logger.Logger, jb job.Job, chainSet legacyevm.LegacyChainContainer) (*ExecutionPluginStaticConfig, *ccipcommon.BackfillArgs, *cache.ObservedChainHealthcheck, *tokendata.BackgroundWorker, error) {
params, err := extractJobSpecParams(lggr, jb, chainSet, true)
params, err := extractJobSpecParams(ctx, lggr, jb, chainSet, true)
if err != nil {
return nil, nil, nil, nil, err
}
Expand Down Expand Up @@ -307,6 +317,48 @@ func jobSpecToExecPluginConfig(ctx context.Context, lggr logger.Logger, jb job.J
tokenDataWorkerTimeout,
2*tokenDataWorkerTimeout,
)

// TODO: evm_2_evm_onramp_1_2_0 version specific, need fetch updates in the version agnostic way
onRampABI, err := abi.JSON(strings.NewReader(evm_2_evm_onramp_1_2_0.EVM2EVMOnRampABI))
if err != nil {
return nil, nil, nil, nil, fmt.Errorf("get onRampABI: %w", err)
}

onRampAddress, err := ccipcalc.GenericAddrToEvm(params.offRampConfig.OnRamp)
onRampConfigCache := cache.NewLogpollerEventsBased[cciptypes.OnRampDynamicConfig](
params.sourceChain.LogPoller(),
[]common.Hash{
abihelpers.MustGetEventID(ConfigSetEventName, onRampABI),
},
onRampAddress,
)

dynamicConfigFetcher := func(_ context.Context) (cciptypes.OnRampDynamicConfig, error) {
if onRampReader == nil {
return cciptypes.OnRampDynamicConfig{}, fmt.Errorf("onramp not initialized")
}
dynamicConfig, err := onRampReader.GetDynamicConfig(ctx)
if err != nil {
return cciptypes.OnRampDynamicConfig{}, fmt.Errorf("get dynamic config v1.2: %w", err)
}
return cciptypes.OnRampDynamicConfig{
DestDataAvailabilityOverheadGas: dynamicConfig.DestDataAvailabilityOverheadGas,
DestGasPerDataAvailabilityByte: dynamicConfig.DestGasPerDataAvailabilityByte,
DestDataAvailabilityMultiplierBps: dynamicConfig.DestDataAvailabilityMultiplierBps,
}, nil
}

gasPriceEstimator := prices.NewDAGasPriceEstimator(
params.destChain.GasEstimator(),
params.destChain.Config().EVM().GasEstimator().PriceMax().ToInt(),
0,
0,
dynamicConfigFetcher,
onRampConfigCache,
)

offRampReader.SetDAGasEstimator(ctx, gasPriceEstimator)

return &ExecutionPluginStaticConfig{
lggr: execLggr,
onRampReader: onRampReader,
Expand Down Expand Up @@ -340,7 +392,7 @@ type jobSpecParams struct {
destChain legacyevm.Chain
}

func extractJobSpecParams(lggr logger.Logger, jb job.Job, chainSet legacyevm.LegacyChainContainer, registerFilters bool) (*jobSpecParams, error) {
func extractJobSpecParams(ctx context.Context, lggr logger.Logger, jb job.Job, chainSet legacyevm.LegacyChainContainer, registerFilters bool) (*jobSpecParams, error) {
if jb.OCR2OracleSpec == nil {
return nil, errors.New("spec is nil")
}
Expand All @@ -358,7 +410,16 @@ func extractJobSpecParams(lggr logger.Logger, jb job.Job, chainSet legacyevm.Leg

versionFinder := factory.NewEvmVersionFinder()
offRampAddress := ccipcalc.HexToAddress(spec.ContractID)
offRampReader, err := factory.NewOffRampReader(lggr, versionFinder, offRampAddress, destChain.Client(), destChain.LogPoller(), destChain.GasEstimator(), destChain.Config().EVM().GasEstimator().PriceMax().ToInt(), registerFilters)
offRampReader, err := factory.NewOffRampReader(
lggr,
versionFinder,
offRampAddress,
destChain.Client(),
destChain.LogPoller(),
destChain.GasEstimator(),
destChain.Config().EVM().GasEstimator().PriceMax().ToInt(),
registerFilters,
)
if err != nil {
return nil, errors.Wrap(err, "create offRampReader")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,17 @@ func CloseOffRampReader(lggr logger.Logger, versionFinder VersionFinder, addr cc
return err
}

func initOrCloseOffRampReader(lggr logger.Logger, versionFinder VersionFinder, addr cciptypes.Address, destClient client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator, destMaxGasPrice *big.Int, closeReader bool, registerFilters bool) (ccipdata.OffRampReader, error) {
func initOrCloseOffRampReader(
lggr logger.Logger,
versionFinder VersionFinder,
addr cciptypes.Address,
destClient client.Client,
lp logpoller.LogPoller,
estimator gas.EvmFeeEstimator,
destMaxGasPrice *big.Int,
closeReader bool,
registerFilters bool,
) (ccipdata.OffRampReader, error) {
contractType, version, err := versionFinder.TypeAndVersion(addr, destClient)
if err != nil {
return nil, errors.Wrapf(err, "unable to read type and version")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ccipdata

import (
"context"
cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip"
)

Expand All @@ -11,4 +12,5 @@ const (
//go:generate mockery --quiet --name OffRampReader --filename offramp_reader_mock.go --case=underscore
type OffRampReader interface {
cciptypes.OffRampReader
SetDAGasEstimator(context.Context, cciptypes.GasPriceEstimator)
}
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,11 @@ type OffRamp struct {

// Dynamic config
// configMu guards all the dynamic config fields.
configMu sync.RWMutex
gasPriceEstimator prices.GasPriceEstimatorExec
offchainConfig cciptypes.ExecOffchainConfig
onchainConfig cciptypes.ExecOnchainConfig
configMu sync.RWMutex
gasPriceEstimator prices.GasPriceEstimatorExec
offchainConfig cciptypes.ExecOffchainConfig
onchainConfig cciptypes.ExecOnchainConfig
daGasPriceEstimator cciptypes.GasPriceEstimator // TODO: specify minimum interface
}

func (o *OffRamp) GetStaticConfig(ctx context.Context) (cciptypes.OffRampStaticConfig, error) {
Expand All @@ -180,6 +181,12 @@ func (o *OffRamp) GetStaticConfig(ctx context.Context) (cciptypes.OffRampStaticC
}, nil
}

func (o *OffRamp) SetDAGasEstimator(_ context.Context, gpe cciptypes.GasPriceEstimator) {
o.configMu.RLock()
defer o.configMu.RUnlock()
o.daGasPriceEstimator = gpe
}

func (o *OffRamp) GetExecutionState(ctx context.Context, sequenceNumber uint64) (uint8, error) {
return o.offRampV100.GetExecutionState(&bind.CallOpts{Context: ctx}, sequenceNumber)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,16 @@ func (c *CommitStore) ChangeConfig(_ context.Context, onchainConfig []byte, offc
return "", fmt.Errorf("this CommitStore sourceMaxGasPrice is nil. SetSourceMaxGasPrice should be called before ChangeConfig")
}

// TODO: move out to the initializer
c.gasPriceEstimator = prices.NewDAGasPriceEstimator(
*c.estimator,
c.sourceMaxGasPrice,
int64(offchainConfigParsed.ExecGasPriceDeviationPPB),
int64(offchainConfigParsed.DAGasPriceDeviationPPB),
func(ctx context.Context) (cciptypes.OnRampDynamicConfig, error) {
return cciptypes.OnRampDynamicConfig{}, nil
},
nil,
)
c.offchainConfig = ccipdata.NewCommitOffchainConfig(
offchainConfigParsed.ExecGasPriceDeviationPPB,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_0_0"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices"
)

var (
Expand Down Expand Up @@ -121,7 +120,8 @@ func (c JSONExecOffchainConfig) Validate() error {
// OffRamp In 1.2 we have a different estimator impl
type OffRamp struct {
*v1_0_0.OffRamp
offRampV120 evm_2_evm_offramp_1_2_0.EVM2EVMOffRampInterface
offRampV120 evm_2_evm_offramp_1_2_0.EVM2EVMOffRampInterface
daGasPriceEstimator cciptypes.GasPriceEstimator // TODO: specify minimum interface
}

func (o *OffRamp) CurrentRateLimiterState(ctx context.Context) (cciptypes.TokenBucketRateLimit, error) {
Expand All @@ -146,6 +146,10 @@ func (o *OffRamp) GetRouter(ctx context.Context) (cciptypes.Address, error) {
return ccipcalc.EvmAddrToGeneric(dynamicConfig.Router), nil
}

func (o *OffRamp) SetDAGasEstimator(ctx context.Context, gpe cciptypes.GasPriceEstimator) {
o.daGasPriceEstimator = gpe
}

func (o *OffRamp) ChangeConfig(ctx context.Context, onchainConfigBytes []byte, offchainConfigBytes []byte) (cciptypes.Address, cciptypes.Address, error) {
// Same as the v1.0.0 method, except for the ExecOnchainConfig type.
onchainConfigParsed, err := abihelpers.DecodeAbiStruct[ExecOnchainConfig](onchainConfigBytes)
Expand Down Expand Up @@ -177,9 +181,12 @@ func (o *OffRamp) ChangeConfig(ctx context.Context, onchainConfigBytes []byte, o
PermissionLessExecutionThresholdSeconds: time.Second * time.Duration(onchainConfigParsed.PermissionLessExecutionThresholdSeconds),
Router: cciptypes.Address(onchainConfigParsed.Router.String()),
}
priceEstimator := prices.NewDAGasPriceEstimator(o.Estimator, o.DestMaxGasPrice, 0, 0)

o.UpdateDynamicConfig(onchainConfig, offchainConfig, priceEstimator)
//TODO: for reference, remove it
//priceEstimator := prices.NewDAGasPriceEstimator(o.Estimator, o.DestMaxGasPrice, 0, 0)
//_ = priceEstimator

o.UpdateDynamicConfig(onchainConfig, offchainConfig, o.daGasPriceEstimator)

o.Logger.Infow("Starting exec plugin",
"offchainConfig", onchainConfigParsed,
Expand Down Expand Up @@ -317,7 +324,14 @@ func (o *OffRamp) DecodeExecutionReport(ctx context.Context, report []byte) (cci
return DecodeExecReport(ctx, o.ExecutionReportArgs, report)
}

func NewOffRamp(lggr logger.Logger, addr common.Address, ec client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator, destMaxGasPrice *big.Int) (*OffRamp, error) {
func NewOffRamp(
lggr logger.Logger,
addr common.Address,
ec client.Client,
lp logpoller.LogPoller,
estimator gas.EvmFeeEstimator,
destMaxGasPrice *big.Int,
) (*OffRamp, error) {
v100, err := v1_0_0.NewOffRamp(lggr, addr, ec, lp, estimator, destMaxGasPrice)
if err != nil {
return nil, err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices"
)

var (
Expand Down Expand Up @@ -78,6 +77,7 @@ type OffRamp struct {
*v1_2_0.OffRamp
offRampV150 evm_2_evm_offramp.EVM2EVMOffRampInterface
cachedRateLimitTokens cache.AutoSync[cciptypes.OffRampTokens]
daGasPriceEstimator cciptypes.GasPriceEstimator // TODO: specify minimum interface
}

// GetTokens Returns no data as the offRamps no longer have this information.
Expand All @@ -92,6 +92,10 @@ func (o *OffRamp) GetTokens(ctx context.Context) (cciptypes.OffRampTokens, error
}, nil
}

func (o *OffRamp) SetDAGasEstimator(ctx context.Context, gpe cciptypes.GasPriceEstimator) {
o.daGasPriceEstimator = gpe
}

func (o *OffRamp) GetSourceAndDestRateLimitTokens(ctx context.Context) (sourceTokens []cciptypes.Address, destTokens []cciptypes.Address, err error) {
cachedTokens, err := o.cachedRateLimitTokens.Get(ctx, func(ctx context.Context) (cciptypes.OffRampTokens, error) {
tokens, err2 := o.offRampV150.GetAllRateLimitTokens(&bind.CallOpts{Context: ctx})
Expand Down Expand Up @@ -162,9 +166,8 @@ func (o *OffRamp) ChangeConfig(ctx context.Context, onchainConfigBytes []byte, o
PermissionLessExecutionThresholdSeconds: time.Second * time.Duration(onchainConfigParsed.PermissionLessExecutionThresholdSeconds),
Router: cciptypes.Address(onchainConfigParsed.Router.String()),
}
priceEstimator := prices.NewDAGasPriceEstimator(o.Estimator, o.DestMaxGasPrice, 0, 0)

o.UpdateDynamicConfig(onchainConfig, offchainConfig, priceEstimator)
o.UpdateDynamicConfig(onchainConfig, offchainConfig, o.daGasPriceEstimator)

o.Logger.Infow("Starting exec plugin",
"offchainConfig", onchainConfigParsed,
Expand All @@ -173,7 +176,14 @@ func (o *OffRamp) ChangeConfig(ctx context.Context, onchainConfigBytes []byte, o
cciptypes.Address(destWrappedNative.String()), nil
}

func NewOffRamp(lggr logger.Logger, addr common.Address, ec client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator, destMaxGasPrice *big.Int) (*OffRamp, error) {
func NewOffRamp(
lggr logger.Logger,
addr common.Address,
ec client.Client,
lp logpoller.LogPoller,
estimator gas.EvmFeeEstimator,
destMaxGasPrice *big.Int,
) (*OffRamp, error) {
v120, err := v1_2_0.NewOffRamp(lggr, addr, ec, lp, estimator, destMaxGasPrice)
if err != nil {
return nil, err
Expand Down
Loading

0 comments on commit 00b3f89

Please sign in to comment.