Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gas estimator + fee boosting integ test #15208

Merged
merged 26 commits into from
Nov 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -963,6 +963,20 @@ runner-test-matrix:
E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2
E2E_JD_VERSION: 0.4.0

- id: smoke/fee_boosting_test.go:*
path: integration-tests/smoke/fee_boosting_test.go
test_env_type: docker
runs_on: ubuntu-latest
triggers:
- PR E2E Core Tests
- Merge Queue E2E Core Tests
- Nightly E2E Tests
test_cmd: cd integration-tests/ && go test smoke/fee_boosting_test.go -timeout 15m -test.parallel=1 -count=1 -json
pyroscope_env: ci-smoke-ccipv1_6-evm-simulated
test_env_vars:
E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2
E2E_JD_VERSION: 0.4.0

# END: CCIPv1.6 tests

# START: CCIP tests
Expand Down
7 changes: 4 additions & 3 deletions core/capabilities/ccip/ccipevm/gas_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ const (
ExecutionStateProcessingOverheadGas = 2_100 + // COLD_SLOAD_COST for first reading the state
20_000 + // SSTORE_SET_GAS for writing from 0 (untouched) to non-zero (in-progress)
100 //# SLOAD_GAS = WARM_STORAGE_READ_COST for rewriting from non-zero (in-progress) to non-zero (success/failure)
// TODO: investigate the write overhead for v1.6
DestGasOverhead = 110_000 + 110_000 + 130_000 // 110K for commit, 110K for RMN, 130K for Exec
0xnogo marked this conversation as resolved.
Show resolved Hide resolved
)

func NewGasEstimateProvider() EstimateProvider {
Expand Down Expand Up @@ -61,8 +63,6 @@ func (gp EstimateProvider) CalculateMessageMaxGas(msg cciptypes.Message) uint64
}

// CalculateMessageMaxGasWithError computes the maximum gas overhead for a message.
// TODO: Add destGasOverhead, see:
// https://github.com/smartcontractkit/chainlink/blob/23452266132228234312947660374fb393e96f1a/contracts/src/v0.8/ccip/FeeQuoter.sol#L97
func (gp EstimateProvider) CalculateMessageMaxGasWithError(msg cciptypes.Message) (uint64, error) {
numTokens := len(msg.TokenAmounts)
var data []byte = msg.Data
Expand Down Expand Up @@ -98,7 +98,8 @@ func (gp EstimateProvider) CalculateMessageMaxGasWithError(msg cciptypes.Message
adminRegistryOverhead = TokenAdminRegistryWarmupCost
}

return messageGasLimit.Uint64() +
return DestGasOverhead +
messageGasLimit.Uint64() +
messageCallDataGas +
ExecutionStateProcessingOverheadGas +
SupportsInterfaceCheck +
Expand Down
18 changes: 9 additions & 9 deletions core/capabilities/ccip/ccipevm/gas_helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@ func Test_calculateMessageMaxGas(t *testing.T) {
{
name: "base",
args: args{dataLen: 5, numTokens: 2, extraArgs: makeExtraArgsV1(200_000), tokenGasOverhead: 10},
want: 1_022_284,
want: 1_372_284,
},
{
name: "large",
args: args{dataLen: 1000, numTokens: 1000, extraArgs: makeExtraArgsV1(200_000), tokenGasOverhead: 1},
want: 346_678_520,
want: 347_028_520,
},
{
name: "overheadGas test 1",
args: args{dataLen: 0, numTokens: 0, extraArgs: makeExtraArgsV1(200_000), tokenGasOverhead: 100},
want: 319_920,
want: 669_920,
},
{
name: "overheadGas test 2",
Expand All @@ -46,7 +46,7 @@ func Test_calculateMessageMaxGas(t *testing.T) {
extraArgs: makeExtraArgsV1(200_000),
tokenGasOverhead: 2,
},
want: 675_950,
want: 1_025_950,
},
{
name: "allowOOO set to true makes no difference to final gas estimate",
Expand All @@ -56,7 +56,7 @@ func Test_calculateMessageMaxGas(t *testing.T) {
extraArgs: makeExtraArgsV2(200_000, true),
tokenGasOverhead: 100,
},
want: 1_022_464,
want: 1_372_464,
},
{
name: "allowOOO set to false makes no difference to final gas estimate",
Expand All @@ -66,7 +66,7 @@ func Test_calculateMessageMaxGas(t *testing.T) {
extraArgs: makeExtraArgsV2(200_000, false),
tokenGasOverhead: 100,
},
want: 1_022_464,
want: 1_372_464,
},
}

Expand Down Expand Up @@ -104,7 +104,7 @@ func TestCalculateMaxGas(t *testing.T) {
numberOfTokens: 0,
extraArgs: makeExtraArgsV1(200_000),
tokenGasOverhead: 10,
want: 322_992,
want: 672_992,
},
{
name: "maxGasOverheadGas 2",
Expand All @@ -113,7 +113,7 @@ func TestCalculateMaxGas(t *testing.T) {
numberOfTokens: 1,
extraArgs: makeExtraArgsV1(200_000),
tokenGasOverhead: 10,
want: 678_518,
want: 1_028_518,
},
{
name: "v2 extra args",
Expand All @@ -122,7 +122,7 @@ func TestCalculateMaxGas(t *testing.T) {
numberOfTokens: 1,
extraArgs: makeExtraArgsV2(200_000, true),
tokenGasOverhead: 10,
want: 678_518,
want: 1_028_518,
},
}

Expand Down
2 changes: 1 addition & 1 deletion core/scripts/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ require (
github.com/shirou/gopsutil/v3 v3.24.3 // indirect
github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 // indirect
github.com/smartcontractkit/chain-selectors v1.0.29 // indirect
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241112095015-3e85d9f1898b // indirect
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241115103032-ec39846b3436 // indirect
github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241017133723-5277829bd53f // indirect
github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241018134907-a00ba3729b5e // indirect
github.com/smartcontractkit/chainlink-feeds v0.1.1 // indirect
Expand Down
4 changes: 2 additions & 2 deletions core/scripts/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1092,8 +1092,8 @@ github.com/smartcontractkit/chain-selectors v1.0.29 h1:aZ9+OoUSMn4nqnissHtDvDoKR
github.com/smartcontractkit/chain-selectors v1.0.29/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8=
github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU=
github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241112095015-3e85d9f1898b h1:4kmZtaQ4fXwduHnw9xk5VmiIOW4nHg/Mx6iidlZJt5o=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241112095015-3e85d9f1898b/go.mod h1:4adKaHNaxFsRvV/lYfqtbsWyyvIPUMLR0FdOJN/ljis=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241115103032-ec39846b3436 h1:n3wy96cqxsaJGoCDbFulFPHind6Etq0tiWZcwAnTs3Q=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241115103032-ec39846b3436/go.mod h1:4adKaHNaxFsRvV/lYfqtbsWyyvIPUMLR0FdOJN/ljis=
github.com/smartcontractkit/chainlink-common v0.3.1-0.20241114134822-aadff98ef068 h1:2llRW4Tn9W/EZp2XvXclQ9IjeTBwwxVPrrqaerX+vCE=
github.com/smartcontractkit/chainlink-common v0.3.1-0.20241114134822-aadff98ef068/go.mod h1:ny87uTW6hLjCTLiBqBRNFEhETSXhHWevYlPclT5lSco=
github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241017133723-5277829bd53f h1:BwrIaQIx5Iy6eT+DfLhFfK2XqjxRm74mVdlX8gbu4dw=
Expand Down
35 changes: 23 additions & 12 deletions deployment/ccip/add_lane.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,31 @@ import (
"github.com/ethereum/go-ethereum/common"

"github.com/smartcontractkit/chainlink/deployment"
"github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ccipevm"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp"

"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router"
)

var (
InitialLinkPrice = deployment.E18Mult(20)
InitialWethPrice = deployment.E18Mult(4000)
InitialGasPrice = big.NewInt(2e12)
)
type InitialPrices struct {
LinkPrice *big.Int // USD to the power of 18 (e18) per LINK
WethPrice *big.Int // USD to the power of 18 (e18) per WETH
GasPrice *big.Int // uint224 packed gas price in USD (112 for exec // 112 for da)
}

var DefaultInitialPrices = InitialPrices{
LinkPrice: deployment.E18Mult(20),
WethPrice: deployment.E18Mult(4000),
GasPrice: ToPackedFee(big.NewInt(8e14), big.NewInt(0)),
}

func AddLaneWithDefaultPrices(e deployment.Environment, state CCIPOnChainState, from, to uint64) error {
return AddLane(e, state, from, to, DefaultInitialPrices)
}

func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64) error {
func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64, initialPrices InitialPrices) error {
// TODO: Batch
tx, err := state.Chains[from].Router.ApplyRampUpdates(e.Chains[from].DeployerKey, []router.RouterOnRamp{
{
Expand All @@ -47,17 +58,17 @@ func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64)
TokenPriceUpdates: []fee_quoter.InternalTokenPriceUpdate{
{
SourceToken: state.Chains[from].LinkToken.Address(),
UsdPerToken: InitialLinkPrice,
UsdPerToken: initialPrices.LinkPrice,
},
{
SourceToken: state.Chains[from].Weth9.Address(),
UsdPerToken: InitialWethPrice,
UsdPerToken: initialPrices.WethPrice,
},
},
GasPriceUpdates: []fee_quoter.InternalGasPriceUpdate{
{
DestChainSelector: to,
UsdPerUnitGas: InitialGasPrice,
UsdPerUnitGas: initialPrices.GasPrice,
},
}})
if _, err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil {
Expand Down Expand Up @@ -112,15 +123,15 @@ func DefaultFeeQuoterDestChainConfig() fee_quoter.FeeQuoterDestChainConfig {
MaxNumberOfTokensPerMsg: 10,
MaxDataBytes: 256,
MaxPerMsgGasLimit: 3_000_000,
DestGasOverhead: 50_000,
DestGasOverhead: ccipevm.DestGasOverhead,
DefaultTokenFeeUSDCents: 1,
DestGasPerPayloadByte: 10,
DestGasPerPayloadByte: ccipevm.CalldataGasPerByte,
DestDataAvailabilityOverheadGas: 100,
DestGasPerDataAvailabilityByte: 100,
DestDataAvailabilityMultiplierBps: 1,
DefaultTokenDestGasOverhead: 125_000,
DefaultTxGasLimit: 200_000,
GasMultiplierWeiPerEth: 1,
GasMultiplierWeiPerEth: 11e17, // Gas multiplier in wei per eth is scaled by 1e18, so 11e17 is 1.1 = 110%
NetworkFeeUSDCents: 1,
ChainFamilySelector: [4]byte(evmFamilySelector),
}
Expand Down
4 changes: 2 additions & 2 deletions deployment/ccip/add_lane_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func TestAddLane(t *testing.T) {
require.NoError(t, err)

// Add one lane from chain1 to chain 2 and send traffic.
require.NoError(t, AddLane(e.Env, state, chain1, chain2))
require.NoError(t, AddLaneWithDefaultPrices(e.Env, state, chain1, chain2))

ReplayLogs(t, e.Env.Offchain, replayBlocks)
time.Sleep(30 * time.Second)
Expand Down Expand Up @@ -110,7 +110,7 @@ func TestAddLane(t *testing.T) {
require.Equal(t, uint64(1), msgSentEvent1.SequenceNumber)

// Add another lane
require.NoError(t, AddLane(e.Env, state, chain2, chain1))
require.NoError(t, AddLaneWithDefaultPrices(e.Env, state, chain2, chain1))

// Send traffic on the second lane and it should succeed
latesthdr, err = e.Env.Chains[chain1].Client.HeaderByNumber(testcontext.Get(t), nil)
Expand Down
2 changes: 1 addition & 1 deletion deployment/ccip/changeset/active_candidate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func TestActiveCandidate(t *testing.T) {

lggr := logger.TestLogger(t)
ctx := ccdeploy.Context(t)
tenv := ccdeploy.NewMemoryEnvironment(t, lggr, 3, 5)
tenv := ccdeploy.NewMemoryEnvironment(t, lggr, 3, 5, ccdeploy.MockLinkPrice, ccdeploy.MockWethPrice)
e := tenv.Env

state, err := ccdeploy.LoadOnchainState(tenv.Env)
Expand Down
2 changes: 1 addition & 1 deletion deployment/ccip/changeset/add_chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func TestAddChainInbound(t *testing.T) {
for _, source := range initialDeploy {
for _, dest := range initialDeploy {
if source != dest {
require.NoError(t, ccipdeployment.AddLane(e.Env, state, source, dest))
require.NoError(t, ccipdeployment.AddLaneWithDefaultPrices(e.Env, state, source, dest))
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions deployment/ccip/changeset/initial_deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
func TestInitialDeploy(t *testing.T) {
lggr := logger.TestLogger(t)
ctx := ccdeploy.Context(t)
tenv := ccdeploy.NewMemoryEnvironment(t, lggr, 3, 4)
tenv := ccdeploy.NewMemoryEnvironment(t, lggr, 3, 4, ccdeploy.MockLinkPrice, ccdeploy.MockWethPrice)
e := tenv.Env

state, err := ccdeploy.LoadOnchainState(tenv.Env)
Expand Down Expand Up @@ -93,7 +93,8 @@ func TestInitialDeploy(t *testing.T) {
ccdeploy.ConfirmCommitForAllWithExpectedSeqNums(t, e, state, expectedSeqNum, startBlocks)

// Confirm token and gas prices are updated
ccdeploy.ConfirmTokenPriceUpdatedForAll(t, e, state, startBlocks)
ccdeploy.ConfirmTokenPriceUpdatedForAll(t, e, state, startBlocks,
ccdeploy.DefaultInitialPrices.LinkPrice, ccdeploy.DefaultInitialPrices.WethPrice)
// TODO: Fix gas prices?
//ccdeploy.ConfirmGasPriceUpdatedForAll(t, e, state, startBlocks)
//
Expand Down
2 changes: 1 addition & 1 deletion deployment/ccip/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func TestDeployCCIPContracts(t *testing.T) {
})
// Deploy all the CCIP contracts.
homeChainSel, feedChainSel := allocateCCIPChainSelectors(e.Chains)
_ = DeployTestContracts(t, lggr, e.ExistingAddresses, homeChainSel, feedChainSel, e.Chains)
_ = DeployTestContracts(t, lggr, e.ExistingAddresses, homeChainSel, feedChainSel, e.Chains, MockLinkPrice, MockWethPrice)

nodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain)
require.NoError(t, err)
Expand Down
11 changes: 8 additions & 3 deletions deployment/ccip/test_assertions.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func ConfirmGasPriceUpdatedForAll(
e deployment.Environment,
state CCIPOnChainState,
startBlocks map[uint64]*uint64,
gasPrice *big.Int,
) {
var wg errgroup.Group
for src, srcChain := range e.Chains {
Expand All @@ -46,6 +47,7 @@ func ConfirmGasPriceUpdatedForAll(
dstChain,
state.Chains[srcChain.Selector].FeeQuoter,
*startBlock,
gasPrice,
)
})
}
Expand All @@ -58,6 +60,7 @@ func ConfirmGasPriceUpdated(
dest deployment.Chain,
srcFeeQuoter *fee_quoter.FeeQuoter,
startBlock uint64,
gasPrice *big.Int,
) error {
it, err := srcFeeQuoter.FilterUsdPerUnitGasUpdated(&bind.FilterOpts{
Context: context.Background(),
Expand All @@ -67,7 +70,7 @@ func ConfirmGasPriceUpdated(
require.NoError(t, err)
require.Truef(t, it.Next(), "No gas price update event found on chain %d, fee quoter %s",
dest.Selector, srcFeeQuoter.Address().String())
require.NotEqualf(t, InitialGasPrice, it.Event.Value, "Gas price not updated on chain %d, fee quoter %s",
require.NotEqualf(t, gasPrice, it.Event.Value, "Gas price not updated on chain %d, fee quoter %s",
dest.Selector, srcFeeQuoter.Address().String())
return nil
}
Expand All @@ -77,6 +80,8 @@ func ConfirmTokenPriceUpdatedForAll(
e deployment.Environment,
state CCIPOnChainState,
startBlocks map[uint64]*uint64,
linkPrice *big.Int,
wethPrice *big.Int,
) {
var wg errgroup.Group
for _, chain := range e.Chains {
Expand All @@ -89,8 +94,8 @@ func ConfirmTokenPriceUpdatedForAll(
linkAddress := state.Chains[chain.Selector].LinkToken.Address()
wethAddress := state.Chains[chain.Selector].Weth9.Address()
tokenToPrice := make(map[common.Address]*big.Int)
tokenToPrice[linkAddress] = InitialLinkPrice
tokenToPrice[wethAddress] = InitialWethPrice
tokenToPrice[linkAddress] = linkPrice
tokenToPrice[wethAddress] = wethPrice
return ConfirmTokenPriceUpdated(
t,
chain,
Expand Down
Loading
Loading