Skip to content

Commit

Permalink
fix linter issues
Browse files Browse the repository at this point in the history
  • Loading branch information
jmank88 committed Sep 30, 2024
1 parent 8fa9a67 commit b3171d0
Show file tree
Hide file tree
Showing 14 changed files with 35 additions and 391 deletions.
4 changes: 2 additions & 2 deletions common/client/multi_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package client

import (
"context"
"errors"
"fmt"
"math"
"math/big"
Expand Down Expand Up @@ -687,9 +688,8 @@ func aggregateTxResults(resultsByCode sendTxErrors) (txResult error, err error)
// We assume that primary node would never report false positive txResult for a transaction.
// Thus, if such case occurs it's probably due to misconfiguration or a bug and requires manual intervention.
if hasSevereErrors {
const errMsg = "found contradictions in nodes replies on SendTransaction: got success and severe error"
// return success, since at least 1 node has accepted our broadcasted Tx, and thus it can now be included onchain
return successResults[0], fmt.Errorf(errMsg)
return successResults[0], errors.New("found contradictions in nodes replies on SendTransaction: got success and severe error")
}

// other errors are temporary - we are safe to return success
Expand Down
16 changes: 12 additions & 4 deletions common/headtracker/head_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,10 +434,10 @@ func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) backfill(ctx context.Context, hea
}

if head.BlockHash() != latestFinalizedHead.BlockHash() {
const errMsg = "expected finalized block to be present in canonical chain"
ht.log.With("finalized_block_number", latestFinalizedHead.BlockNumber(), "finalized_hash", latestFinalizedHead.BlockHash(),
"canonical_chain_block_number", head.BlockNumber(), "canonical_chain_hash", head.BlockHash()).Criticalf(errMsg)
return fmt.Errorf(errMsg)
ht.log.Criticalw("Finalized block missing from conical chain",
"finalized_block_number", latestFinalizedHead.BlockNumber(), "finalized_hash", latestFinalizedHead.BlockHash(),
"canonical_chain_block_number", head.BlockNumber(), "canonical_chain_hash", head.BlockHash())
return FinalizedMissingError[BLOCK_HASH]{latestFinalizedHead.BlockHash(), head.BlockHash()}
}

l = l.With("latest_finalized_block_hash", latestFinalizedHead.BlockHash(),
Expand All @@ -454,6 +454,14 @@ func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) backfill(ctx context.Context, hea
return
}

type FinalizedMissingError[BLOCK_HASH types.Hashable] struct {
Finalized, Canonical BLOCK_HASH
}

func (e FinalizedMissingError[BLOCK_HASH]) Error() string {
return fmt.Sprintf("finalized block %s missing from canonical chain %s", e.Finalized, e.Canonical)
}

func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) fetchAndSaveHead(ctx context.Context, n int64, hash BLOCK_HASH) (HTH, error) {
ht.log.Debugw("Fetching head", "blockHeight", n, "blockHash", hash)
head, err := ht.client.HeadByHash(ctx, hash)
Expand Down
12 changes: 6 additions & 6 deletions core/capabilities/targets/write_target_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,11 @@ func TestWriteTarget(t *testing.T) {
})

t.Run("passes gas limit set on config to the chain writer", func(t *testing.T) {
configGasLimit, err := values.NewMap(map[string]any{
configGasLimit, err2 := values.NewMap(map[string]any{
"Address": forwarderAddr,
"GasLimit": 500000,
})
require.NoError(t, err)
require.NoError(t, err2)
req := capabilities.CapabilityRequest{
Metadata: validMetadata,
Config: configGasLimit,
Expand All @@ -134,16 +134,16 @@ func TestWriteTarget(t *testing.T) {
meta := types.TxMeta{WorkflowExecutionID: &req.Metadata.WorkflowExecutionID, GasLimit: big.NewInt(500000)}
cw.On("SubmitTransaction", mock.Anything, "forwarder", "report", mock.Anything, mock.Anything, forwarderAddr, &meta, mock.Anything).Return(types.ErrSettingTransactionGasLimitNotSupported)

_, err2 := writeTarget.Execute(ctx, req)
_, err2 = writeTarget.Execute(ctx, req)
require.Error(t, err2)
})

t.Run("retries without gas limit when ChainWriter's SubmitTransaction returns error due to gas limit not supported", func(t *testing.T) {
configGasLimit, err := values.NewMap(map[string]any{
configGasLimit, err2 := values.NewMap(map[string]any{
"Address": forwarderAddr,
"GasLimit": 500000,
})
require.NoError(t, err)
require.NoError(t, err2)
req := capabilities.CapabilityRequest{
Metadata: validMetadata,
Config: configGasLimit,
Expand All @@ -165,7 +165,7 @@ func TestWriteTarget(t *testing.T) {
Inputs: validInputs,
}

_, err2 := writeTarget.Execute(ctx, req)
_, err2 = writeTarget.Execute(ctx, req)
require.Error(t, err2)
})

Expand Down
6 changes: 3 additions & 3 deletions core/chains/evm/gas/block_history_estimator.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,9 +340,9 @@ func (b *BlockHistoryEstimator) haltBumping(attempts []EvmPriorAttempt) error {
}
// Return error to prevent bumping if gas price is nil or if EIP1559 is enabled and tip cap is nil
if maxGasPrice == nil || (b.eConfig.EIP1559DynamicFees() && maxTipCap == nil) {
errorMsg := fmt.Sprintf("%d percentile price is not set. This is likely because there aren't any valid transactions to estimate from. Preventing bumping until valid price is available to compare", percentile)
b.logger.Debugf(errorMsg)
return errors.New(errorMsg)
err := fmt.Errorf("%d percentile price is not set. This is likely because there aren't any valid transactions to estimate from. Preventing bumping until valid price is available to compare", percentile)
b.logger.Debugw("Bumping halted", "err", err)
return err
}
// Get the latest CheckInclusionBlocks from block history for fee cap check below
blockHistory := b.getBlocks()
Expand Down
57 changes: 3 additions & 54 deletions core/chains/evm/gas/rollups/arbitrum_l1_oracle.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,11 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"

gethtypes "github.com/ethereum/go-ethereum/core/types"

"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink-common/pkg/services"

"github.com/smartcontractkit/chainlink/v2/common/client"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/chaintype"
)

type ArbL1GasOracle interface {
Expand All @@ -35,7 +31,6 @@ type arbitrumL1Oracle struct {
client l1OracleClient
pollPeriod time.Duration
logger logger.SugaredLogger
chainType chaintype.ChainType

l1GasPriceAddress string
gasPriceMethod string
Expand Down Expand Up @@ -93,7 +88,6 @@ func NewArbitrumL1GasOracle(lggr logger.Logger, ethClient l1OracleClient) (*arbi
client: ethClient,
pollPeriod: PollPeriod,
logger: logger.Sugared(logger.Named(lggr, "L1GasOracle(arbitrum)")),
chainType: chaintype.ChainArbitrum,

l1GasPriceAddress: l1GasPriceAddress,
gasPriceMethod: gasPriceMethod,
Expand All @@ -112,10 +106,6 @@ func (o *arbitrumL1Oracle) Name() string {
return o.logger.Name()
}

func (o *arbitrumL1Oracle) ChainType(_ context.Context) chaintype.ChainType {
return o.chainType
}

func (o *arbitrumL1Oracle) Start(ctx context.Context) error {
return o.StartOnce(o.Name(), func() error {
go o.run()
Expand Down Expand Up @@ -184,24 +174,18 @@ func (o *arbitrumL1Oracle) fetchL1GasPrice(ctx context.Context) (price *big.Int,
precompile := common.HexToAddress(o.l1GasPriceAddress)
callData, err = o.l1GasPriceMethodAbi.Pack(o.gasPriceMethod)
if err != nil {
errMsg := "failed to pack calldata for arbitrum L1 gas price method"
o.logger.Errorf(errMsg)
return nil, fmt.Errorf("%s: %w", errMsg, err)
return nil, fmt.Errorf("failed to pack calldata for arbitrum L1 gas price method: %w", err)
}
b, err = o.client.CallContract(ctx, ethereum.CallMsg{
To: &precompile,
Data: callData,
}, nil)
if err != nil {
errMsg := "gas oracle contract call failed"
o.logger.Errorf(errMsg)
return nil, fmt.Errorf("%s: %w", errMsg, err)
return nil, fmt.Errorf("gas oracle contract call failed: %w", err)
}

if len(b) != 32 { // returns uint256;
errMsg := fmt.Sprintf("return data length (%d) different than expected (%d)", len(b), 32)
o.logger.Criticalf(errMsg)
return nil, fmt.Errorf(errMsg)
return nil, fmt.Errorf("return data length (%d) different than expected (%d)", len(b), 32)
}
price = new(big.Int).SetBytes(b)
return price, nil
Expand Down Expand Up @@ -229,41 +213,6 @@ func (o *arbitrumL1Oracle) GasPrice(_ context.Context) (l1GasPrice *assets.Wei,
return
}

// Gets the L1 gas cost for the provided transaction at the specified block num
// If block num is not provided, the value on the latest block num is used
func (o *arbitrumL1Oracle) GetGasCost(ctx context.Context, tx *gethtypes.Transaction, blockNum *big.Int) (*assets.Wei, error) {
ctx, cancel := context.WithTimeout(ctx, client.QueryTimeout)
defer cancel()
var callData, b []byte
var err error

if callData, err = o.l1GasCostMethodAbi.Pack(o.gasCostMethod, tx.To(), false, tx.Data()); err != nil {
return nil, fmt.Errorf("failed to pack calldata for %s L1 gas cost estimation method: %w", o.chainType, err)
}

precompile := common.HexToAddress(o.l1GasCostAddress)
b, err = o.client.CallContract(ctx, ethereum.CallMsg{
To: &precompile,
Data: callData,
}, blockNum)
if err != nil {
errorMsg := fmt.Sprintf("gas oracle contract call failed: %v", err)
o.logger.Errorf(errorMsg)
return nil, fmt.Errorf(errorMsg)
}

var l1GasCost *big.Int

if len(b) != 8+2*32 { // returns (uint64 gasEstimateForL1, uint256 baseFee, uint256 l1BaseFeeEstimate);
errorMsg := fmt.Sprintf("return data length (%d) different than expected (%d)", len(b), 8+2*32)
o.logger.Critical(errorMsg)
return nil, fmt.Errorf(errorMsg)
}
l1GasCost = new(big.Int).SetBytes(b[:8])

return assets.NewWei(l1GasCost), nil
}

// callGetPricesInArbGas calls ArbGasInfo.getPricesInArbGas() on the precompile contract ArbGasInfoAddress.
//
// @return (per L2 tx, per L1 calldata unit, per storage allocation)
Expand Down
3 changes: 0 additions & 3 deletions core/chains/evm/gas/rollups/l1_oracle.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"time"

"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rpc"

"github.com/smartcontractkit/chainlink-common/pkg/services"
Expand All @@ -25,8 +24,6 @@ type L1Oracle interface {
services.Service

GasPrice(ctx context.Context) (*assets.Wei, error)
GetGasCost(ctx context.Context, tx *types.Transaction, blockNum *big.Int) (*assets.Wei, error)
ChainType(ctx context.Context) chaintype.ChainType
}

type l1OracleClient interface {
Expand Down
128 changes: 0 additions & 128 deletions core/chains/evm/gas/rollups/l1_oracle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
Expand All @@ -21,7 +20,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/chaintype"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups/mocks"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils"
)

func TestL1Oracle(t *testing.T) {
Expand Down Expand Up @@ -195,129 +193,3 @@ func TestL1Oracle_GasPrice(t *testing.T) {
assert.Equal(t, assets.NewWei(new(big.Int).Mul(gasPriceL2, gasPerPubByteL2)), gasPrice)
})
}

func TestL1Oracle_GetGasCost(t *testing.T) {
t.Parallel()

t.Run("Calling GetGasCost on started Arbitrum L1Oracle returns Arbitrum getL1Fee", func(t *testing.T) {
l1GasCost := big.NewInt(100)
baseFee := utils.Uint256ToBytes32(big.NewInt(1000))
l1BaseFeeEstimate := utils.Uint256ToBytes32(big.NewInt(500))
blockNum := big.NewInt(1000)
toAddress := utils.RandomAddress()
callData := []byte{1, 2, 3, 4, 5, 6, 7}
l1GasCostMethodAbi, err := abi.JSON(strings.NewReader(GasEstimateL1ComponentAbiString))
require.NoError(t, err)

tx := types.NewTx(&types.LegacyTx{
Nonce: 42,
To: &toAddress,
Data: callData,
})
result := common.LeftPadBytes(l1GasCost.Bytes(), 8)
result = append(result, baseFee...)
result = append(result, l1BaseFeeEstimate...)

ethClient := mocks.NewL1OracleClient(t)
ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
callMsg := args.Get(1).(ethereum.CallMsg)
blockNumber := args.Get(2).(*big.Int)
var payload []byte
payload, err = l1GasCostMethodAbi.Pack("gasEstimateL1Component", toAddress, false, callData)
require.NoError(t, err)
require.Equal(t, payload, callMsg.Data)
require.Equal(t, blockNum, blockNumber)
}).Return(result, nil)

oracle, err := NewL1GasOracle(logger.Test(t), ethClient, chaintype.ChainArbitrum)
require.NoError(t, err)

gasCost, err := oracle.GetGasCost(tests.Context(t), tx, blockNum)
require.NoError(t, err)
require.Equal(t, assets.NewWei(l1GasCost), gasCost)
})

t.Run("Calling GetGasCost on started Kroma L1Oracle returns error", func(t *testing.T) {
blockNum := big.NewInt(1000)
tx := types.NewTx(&types.LegacyTx{})

ethClient := mocks.NewL1OracleClient(t)
oracle, err := NewL1GasOracle(logger.Test(t), ethClient, chaintype.ChainKroma)
require.NoError(t, err)

_, err = oracle.GetGasCost(tests.Context(t), tx, blockNum)
require.Error(t, err, "L1 gas cost not supported for this chain: kroma")
})

t.Run("Calling GetGasCost on started OPStack L1Oracle returns OPStack getL1Fee", func(t *testing.T) {
l1GasCost := big.NewInt(100)
blockNum := big.NewInt(1000)
toAddress := utils.RandomAddress()
callData := []byte{1, 2, 3}
l1GasCostMethodAbi, err := abi.JSON(strings.NewReader(GetL1FeeAbiString))
require.NoError(t, err)

tx := types.NewTx(&types.LegacyTx{
Nonce: 42,
To: &toAddress,
Data: callData,
})

encodedTx, err := tx.MarshalBinary()
require.NoError(t, err)

ethClient := mocks.NewL1OracleClient(t)
ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
callMsg := args.Get(1).(ethereum.CallMsg)
blockNumber := args.Get(2).(*big.Int)
var payload []byte
payload, err = l1GasCostMethodAbi.Pack("getL1Fee", encodedTx)
require.NoError(t, err)
require.Equal(t, payload, callMsg.Data)
require.Equal(t, blockNum, blockNumber)
}).Return(common.BigToHash(l1GasCost).Bytes(), nil)

oracle, err := NewL1GasOracle(logger.Test(t), ethClient, chaintype.ChainOptimismBedrock)
require.NoError(t, err)

gasCost, err := oracle.GetGasCost(tests.Context(t), tx, blockNum)
require.NoError(t, err)
require.Equal(t, assets.NewWei(l1GasCost), gasCost)
})

t.Run("Calling GetGasCost on started Scroll L1Oracle returns Scroll getL1Fee", func(t *testing.T) {
l1GasCost := big.NewInt(100)
blockNum := big.NewInt(1000)
toAddress := utils.RandomAddress()
callData := []byte{1, 2, 3}
l1GasCostMethodAbi, err := abi.JSON(strings.NewReader(GetL1FeeAbiString))
require.NoError(t, err)

tx := types.NewTx(&types.LegacyTx{
Nonce: 42,
To: &toAddress,
Data: callData,
})

encodedTx, err := tx.MarshalBinary()
require.NoError(t, err)

ethClient := mocks.NewL1OracleClient(t)
ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
callMsg := args.Get(1).(ethereum.CallMsg)
blockNumber := args.Get(2).(*big.Int)
var payload []byte
payload, err = l1GasCostMethodAbi.Pack("getL1Fee", encodedTx)
require.NoError(t, err)
require.Equal(t, payload, callMsg.Data)
require.Equal(t, blockNum, blockNumber)
}).Return(common.BigToHash(l1GasCost).Bytes(), nil)

oracle, err := NewL1GasOracle(logger.Test(t), ethClient, chaintype.ChainScroll)
require.NoError(t, err)

gasCost, err := oracle.GetGasCost(tests.Context(t), tx, blockNum)
require.NoError(t, err)
require.Equal(t, assets.NewWei(l1GasCost), gasCost)
})
}
Loading

0 comments on commit b3171d0

Please sign in to comment.