Skip to content

Commit

Permalink
gas estimator + fee boosting integ test (#15208)
Browse files Browse the repository at this point in the history
* initial test

* gomodtidy

* merge and fix

* price updates

* adding price in integ-test helpers

* commong bump

* messageMaxGas update

* remodelling of fee boosting test

* gomodtidy

* fixing

* fixes

* reset gomod

* update cl-ccip

* smoke test

* change timeout

* skip

* reset go.mod

* addressing comments

* go mod cl-ccip

* adding comments

* update after last rebase
  • Loading branch information
0xnogo authored Nov 17, 2024
1 parent c686783 commit 6f95b09
Show file tree
Hide file tree
Showing 25 changed files with 296 additions and 66 deletions.
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
)

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

0 comments on commit 6f95b09

Please sign in to comment.