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

Add Test_GetChainFeePriceUpdates #15240

Merged
merged 10 commits into from
Nov 15, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ package ccipreader

import (
"context"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Get rid of newline

evmconfig "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/configs/evm"

"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

goimports

"math/big"
"sort"
"testing"
Expand Down Expand Up @@ -47,6 +51,10 @@ const (
chainD = cciptypes.ChainSelector(4)
)

var (
defaultGasPrice = big.NewInt(1e9)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use assets.GWei instead

)

func TestCCIPReader_CommitReportsGTETimestamp(t *testing.T) {
ctx := testutils.Context(t)

Expand Down Expand Up @@ -75,7 +83,7 @@ func TestCCIPReader_CommitReportsGTETimestamp(t *testing.T) {
Name: consts.ContractNameOnRamp,
},
},
})
}, true)

tokenA := common.HexToAddress("123")
const numReports = 5
Expand Down Expand Up @@ -189,7 +197,7 @@ func TestCCIPReader_ExecutedMessageRanges(t *testing.T) {
},
}

s := testSetup(ctx, t, chainD, chainD, nil, cfg, nil)
s := testSetup(ctx, t, chainD, chainD, nil, cfg, nil, true)

_, err := s.contract.EmitExecutionStateChanged(
s.auth,
Expand Down Expand Up @@ -274,7 +282,7 @@ func TestCCIPReader_MsgsBetweenSeqNums(t *testing.T) {
},
}

s := testSetup(ctx, t, chainS1, chainD, nil, cfg, nil)
s := testSetup(ctx, t, chainS1, chainD, nil, cfg, nil, true)

_, err := s.contract.EmitCCIPMessageSent(s.auth, uint64(chainD), ccip_reader_tester.InternalEVM2AnyRampMessage{
Header: ccip_reader_tester.InternalRampMessageHeader{
Expand Down Expand Up @@ -375,7 +383,7 @@ func TestCCIPReader_NextSeqNum(t *testing.T) {
},
}

s := testSetup(ctx, t, chainD, chainD, onChainSeqNums, cfg, nil)
s := testSetup(ctx, t, chainD, chainD, onChainSeqNums, cfg, nil, true)

seqNums, err := s.reader.NextSeqNum(ctx, []cciptypes.ChainSelector{chainS1, chainS2, chainS3})
assert.NoError(t, err)
Expand All @@ -402,7 +410,7 @@ func TestCCIPReader_GetExpectedNextSequenceNumber(t *testing.T) {
},
}

s := testSetup(ctx, t, chainS1, chainD, nil, cfg, nil)
s := testSetup(ctx, t, chainS1, chainD, nil, cfg, nil, true)

_, err := s.contract.SetDestChainSeqNr(s.auth, uint64(chainD), 10)
require.NoError(t, err)
Expand Down Expand Up @@ -452,7 +460,7 @@ func TestCCIPReader_Nonces(t *testing.T) {
},
}

s := testSetup(ctx, t, chainD, chainD, nil, cfg, nil)
s := testSetup(ctx, t, chainD, chainD, nil, cfg, nil, true)

// Add some nonces.
for chain, addrs := range nonces {
Expand All @@ -479,14 +487,86 @@ func TestCCIPReader_Nonces(t *testing.T) {
}
}

func Test_GetChainFeePriceUpdates(t *testing.T) {
ctx := testutils.Context(t)
s := testSetup(ctx, t, chainD, chainD, nil, evmconfig.DestReaderConfig, nil, false)
feeQuoter := deployFeeQuoterWithPrices(t, s.auth, s.sb)
// Bind FeeQuoter directly
err := s.extendedCR.Bind(ctx, []types.BoundContract{
{
Address: feeQuoter.Address().String(),
Name: consts.ContractNameFeeQuoter,
},
})
require.NoError(t, err)

updates := s.reader.GetChainFeePriceUpdate(ctx, []cciptypes.ChainSelector{chainS1})
require.Len(t, updates, 1)
require.Equal(t, defaultGasPrice, updates[chainS1].Value.Int)
}

func deployFeeQuoterWithPrices(t *testing.T, auth *bind.TransactOpts, sb *simulated.Backend) *fee_quoter.FeeQuoter {
linkAddress := utils.RandomAddress()
wethAddress := utils.RandomAddress()
address, _, _, err := fee_quoter.DeployFeeQuoter(
auth,
sb.Client(),
fee_quoter.FeeQuoterStaticConfig{
MaxFeeJuelsPerMsg: big.NewInt(0).Mul(big.NewInt(2e2), big.NewInt(1e18)),
LinkToken: linkAddress,
TokenPriceStalenessThreshold: uint32(24 * 60 * 60),
},
[]common.Address{auth.From},
[]common.Address{wethAddress, linkAddress},
[]fee_quoter.FeeQuoterTokenPriceFeedUpdate{},
[]fee_quoter.FeeQuoterTokenTransferFeeConfigArgs{},
[]fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthArgs{
{
PremiumMultiplierWeiPerEth: 9e17, // 0.9 ETH
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this means 90% and not 0.9ETH cc @0xnogo

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i.e a 10% discount

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@makramkd I think you are referring to the gasMultiplierWeiPerEth. But here it's the PremiumMultiplierWeiPerEth

Copy link
Collaborator

@0xnogo 0xnogo Nov 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this one is set to pay 10% if you are paying with Link token. I think it needs to have 1e18 unit, so what we have here is correct:

    // Calculate number of fee tokens to charge.
    // Total USD fee is in 36 decimals, feeTokenPrice is in 18 decimals USD for 1e18 smallest token denominations.
    // Result of the division is the number of smallest token denominations.
    return ((premiumFee * s_premiumMultiplierWeiPerEth[message.feeToken]) + executionCost + dataAvailabilityCost)
      / feeTokenPrice;

executionCost + dataAvailabilityCost => e36
premium (e18) * s_premiumMultiplierWeiPerEth[message.feeToken] (e18) => e36

Token: linkAddress,
},
{
PremiumMultiplierWeiPerEth: 1e18,
Token: wethAddress,
},
},
[]fee_quoter.FeeQuoterDestChainConfigArgs{},
)

require.NoError(t, err)
sb.Commit()

feeQuoter, err := fee_quoter.NewFeeQuoter(address, sb.Client())
require.NoError(t, err)

_, err = feeQuoter.UpdatePrices(
auth, fee_quoter.InternalPriceUpdates{
GasPriceUpdates: []fee_quoter.InternalGasPriceUpdate{
{
DestChainSelector: uint64(chainS1),
UsdPerUnitGas: defaultGasPrice,
},
}},
)
require.NoError(t, err)
sb.Commit()

gas, err := feeQuoter.GetDestinationChainGasPrice(&bind.CallOpts{}, uint64(chainS1))
require.NoError(t, err)
require.Equal(t, defaultGasPrice, gas.Value)

return feeQuoter
}

func testSetup(
ctx context.Context,
t *testing.T,
readerChain,
destChain cciptypes.ChainSelector,
onChainSeqNums map[cciptypes.ChainSelector]cciptypes.SeqNum,
cfg evmtypes.ChainReaderConfig,
otherBindings map[cciptypes.ChainSelector][]types.BoundContract,
toMockBindings map[cciptypes.ChainSelector][]types.BoundContract,
bindTester bool,
) *testSetupData {
const chainID = 1337

Expand All @@ -497,12 +577,12 @@ func testSetup(
blnc, ok := big.NewInt(0).SetString("999999999999999999999999999999999999", 10)
assert.True(t, ok)
alloc := map[common.Address]ethtypes.Account{crypto.PubkeyToAddress(privateKey.PublicKey): {Balance: blnc}}
simulatedBackend := simulated.NewBackend(alloc, simulated.WithBlockGasLimit(0))
simulatedBackend := simulated.NewBackend(alloc, simulated.WithBlockGasLimit(8000000))
// Create a transactor

auth, err := bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(chainID))
assert.NoError(t, err)
auth.GasLimit = uint64(0)
auth.GasLimit = uint64(6000000)

// Deploy the contract
address, _, _, err := ccip_reader_tester.DeployCCIPReaderTester(auth, simulatedBackend.Client())
Expand Down Expand Up @@ -547,21 +627,24 @@ func testSetup(
}

contractNames := maps.Keys(cfg.Contracts)
assert.Len(t, contractNames, 1, "test setup assumes there is only one contract")

cr, err := evm.NewChainReaderService(ctx, lggr, lp, headTracker, cl, cfg)
require.NoError(t, err)

extendedCr := contractreader.NewExtendedContractReader(cr)
err = extendedCr.Bind(ctx, []types.BoundContract{
{
Address: address.String(),
Name: contractNames[0],
},
})
require.NoError(t, err)

if bindTester {
err = extendedCr.Bind(ctx, []types.BoundContract{
{
Address: address.String(),
Name: contractNames[0],
},
})
require.NoError(t, err)
}

var otherCrs = make(map[cciptypes.ChainSelector]contractreader.Extended)
for chain, bindings := range otherBindings {
for chain, bindings := range toMockBindings {
m := readermocks.NewMockContractReaderFacade(t)
m.EXPECT().Bind(ctx, bindings).Return(nil)
ecr := contractreader.NewExtendedContractReader(m)
Expand Down Expand Up @@ -594,6 +677,7 @@ func testSetup(
lp: lp,
cl: cl,
reader: reader,
extendedCR: extendedCr,
}
}

Expand All @@ -605,4 +689,5 @@ type testSetupData struct {
lp logpoller.LogPoller
cl client.Client
reader ccipreaderpkg.CCIPReader
extendedCR contractreader.Extended
}
Loading