Skip to content

Commit

Permalink
enrich debug w/ mixins[SLT-330] (#3263)
Browse files Browse the repository at this point in the history
* enrich debug [SLT-330]

[goreleaser]

* fix lint issues

[goreleaser]

---------

Co-authored-by: Trajan0x <trajan0x@users.noreply.github.com>
  • Loading branch information
trajan0x and trajan0x authored Oct 10, 2024
1 parent 4bb6360 commit 59f2fb3
Show file tree
Hide file tree
Showing 13 changed files with 322 additions and 235 deletions.
44 changes: 0 additions & 44 deletions ethergo/submitter/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,13 @@ import (
"github.com/synapsecns/sanguine/ethergo/signer/signer"
"github.com/synapsecns/sanguine/ethergo/submitter/config"
"github.com/synapsecns/sanguine/ethergo/submitter/db"
"go.opentelemetry.io/otel/attribute"
)

// CopyTransactOpts exports copyTransactOpts for testing.
func CopyTransactOpts(opts *bind.TransactOpts) *bind.TransactOpts {
return copyTransactOpts(opts)
}

// NullFieldAttribute is a constant used to test the null field attribute.
// it exports the underlying constant for testing.
const NullFieldAttribute = nullFieldAttribute

func AddressPtrToString(address *common.Address) string {
return addressPtrToString(address)
}

// BigPtrToString converts a big.Int pointer to a string.
func BigPtrToString(num *big.Int) string {
return bigPtrToString(num)
}

// TxToAttributes exports txToAttributes for testing.
func TxToAttributes(transaction *types.Transaction, UUID string) []attribute.KeyValue {
return txToAttributes(transaction, UUID)
}

// SortTxes exports sortTxesByChainID for testing.
func SortTxes(txs []db.TX, maxPerChain int) map[uint64][]db.TX {
return sortTxesByChainID(txs, maxPerChain)
Expand All @@ -48,31 +29,6 @@ func GroupTxesByNonce(txs []db.TX) map[uint64][]db.TX {
return groupTxesByNonce(txs)
}

const (
// HashAttr exports hashAttr for testing.
HashAttr = hashAttr
// FromAttr exports fromAttr for testing.
FromAttr = fromAttr
// ToAttr exports toAttr for testing.
ToAttr = toAttr
// DataAttr exports dataAttr for testing.
DataAttr = dataAttr
// ValueAttr exports valueAttr for testing.
ValueAttr = valueAttr
// NonceAttr exports nonceAttr for testing.
NonceAttr = nonceAttr
// GasLimitAttr exports gasLimitAttr for testing.
GasLimitAttr = gasLimitAttr
// ChainIDAttr exports chainIDAttr for testing.
ChainIDAttr = chainIDAttr
// GasPriceAttr exports gasPriceAttr for testing.
GasPriceAttr = gasPriceAttr
// GasFeeCapAttr exports gasFeeCapAttr for testing.
GasFeeCapAttr = gasFeeCapAttr
// GasTipCapAttr exports gasTipCapAttr for testing.
GasTipCapAttr = gasTipCapAttr
)

// NewTestTransactionSubmitter wraps TestTransactionSubmitter in a TransactionSubmitter interface.
func NewTestTransactionSubmitter(metrics metrics.Handler, signer signer.Signer, fetcher ClientFetcher, db db.Service, config *config.Config) TestTransactionSubmitter {
txSubmitter := NewTransactionSubmitter(metrics, signer, fetcher, db, config)
Expand Down
34 changes: 17 additions & 17 deletions ethergo/submitter/submitter.go
Original file line number Diff line number Diff line change
Expand Up @@ -463,9 +463,9 @@ func (t *txSubmitterImpl) setGasPrice(ctx context.Context, client client.EVM,
span.SetAttributes(
attribute.Int(metrics.ChainID, chainID),
attribute.Bool("use_dynamic", useDynamic),
attribute.String("gas_price", bigPtrToString(transactor.GasPrice)),
attribute.String("gas_fee_cap", bigPtrToString(transactor.GasFeeCap)),
attribute.String("gas_tip_cap", bigPtrToString(transactor.GasTipCap)),
attribute.String("gas_price", util.BigPtrToString(transactor.GasPrice)),
attribute.String("gas_fee_cap", util.BigPtrToString(transactor.GasFeeCap)),
attribute.String("gas_tip_cap", util.BigPtrToString(transactor.GasTipCap)),
)
metrics.EndSpanWithErr(span, err)
}()
Expand Down Expand Up @@ -501,9 +501,9 @@ func (t *txSubmitterImpl) bumpGasFromPrevTx(ctx context.Context, transactor *bin

defer func() {
span.SetAttributes(
attribute.String("gas_price", bigPtrToString(transactor.GasPrice)),
attribute.String("gas_fee_cap", bigPtrToString(transactor.GasFeeCap)),
attribute.String("gas_tip_cap", bigPtrToString(transactor.GasTipCap)),
attribute.String("gas_price", util.BigPtrToString(transactor.GasPrice)),
attribute.String("gas_fee_cap", util.BigPtrToString(transactor.GasFeeCap)),
attribute.String("gas_tip_cap", util.BigPtrToString(transactor.GasTipCap)),
)
metrics.EndSpan(span)
}()
Expand Down Expand Up @@ -537,9 +537,9 @@ func (t *txSubmitterImpl) applyGasFloor(ctx context.Context, transactor *bind.Tr

defer func() {
span.SetAttributes(
attribute.String("gas_price", bigPtrToString(transactor.GasPrice)),
attribute.String("gas_fee_cap", bigPtrToString(transactor.GasFeeCap)),
attribute.String("gas_tip_cap", bigPtrToString(transactor.GasTipCap)),
attribute.String("gas_price", util.BigPtrToString(transactor.GasPrice)),
attribute.String("gas_fee_cap", util.BigPtrToString(transactor.GasFeeCap)),
attribute.String("gas_tip_cap", util.BigPtrToString(transactor.GasTipCap)),
)
metrics.EndSpan(span)
}()
Expand Down Expand Up @@ -578,10 +578,10 @@ func (t *txSubmitterImpl) applyGasFromOracle(ctx context.Context, transactor *bi
}
transactor.GasTipCap = maxOfBig(transactor.GasTipCap, suggestedGasTipCap)
span.SetAttributes(
attribute.String("suggested_gas_fee_cap", bigPtrToString(suggestedGasFeeCap)),
attribute.String("suggested_gas_tip_cap", bigPtrToString(suggestedGasTipCap)),
attribute.String("gas_fee_cap", bigPtrToString(transactor.GasFeeCap)),
attribute.String("gas_tip_cap", bigPtrToString(transactor.GasTipCap)),
attribute.String("suggested_gas_fee_cap", util.BigPtrToString(suggestedGasFeeCap)),
attribute.String("suggested_gas_tip_cap", util.BigPtrToString(suggestedGasTipCap)),
attribute.String("gas_fee_cap", util.BigPtrToString(transactor.GasFeeCap)),
attribute.String("gas_tip_cap", util.BigPtrToString(transactor.GasTipCap)),
)
} else {
suggestedGasPrice, err := client.SuggestGasPrice(ctx)
Expand All @@ -590,8 +590,8 @@ func (t *txSubmitterImpl) applyGasFromOracle(ctx context.Context, transactor *bi
}
transactor.GasPrice = maxOfBig(transactor.GasPrice, suggestedGasPrice)
span.SetAttributes(
attribute.String("suggested_gas_price", bigPtrToString(suggestedGasPrice)),
attribute.String("gas_price", bigPtrToString(transactor.GasPrice)),
attribute.String("suggested_gas_price", util.BigPtrToString(suggestedGasPrice)),
attribute.String("gas_price", util.BigPtrToString(transactor.GasPrice)),
)
}
return nil
Expand All @@ -605,7 +605,7 @@ func (t *txSubmitterImpl) applyGasCeil(ctx context.Context, transactor *bind.Tra
maxPrice := t.config.GetMaxGasPrice(chainID)

defer func() {
span.SetAttributes(attribute.String("max_price", bigPtrToString(maxPrice)))
span.SetAttributes(attribute.String("max_price", util.BigPtrToString(maxPrice)))
metrics.EndSpanWithErr(span, err)
}()

Expand Down Expand Up @@ -661,7 +661,7 @@ func (t *txSubmitterImpl) getGasBlock(ctx context.Context, chainClient client.EV
if ok {
span.AddEvent("could not get gas block; using cached value", trace.WithAttributes(
attribute.String("error", err.Error()),
attribute.String("blockNumber", bigPtrToString(gasBlock.Number)),
attribute.String("blockNumber", util.BigPtrToString(gasBlock.Number)),
))
} else {
return nil, fmt.Errorf("could not get gas block: %w", err)
Expand Down
76 changes: 7 additions & 69 deletions ethergo/submitter/util.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
package submitter

import (
"fmt"
"github.com/ethereum/go-ethereum/core/types"
"github.com/synapsecns/sanguine/ethergo/util"
"go.opentelemetry.io/otel/attribute"
"math/big"
"sort"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/synapsecns/sanguine/core"
"github.com/synapsecns/sanguine/ethergo/chain/gas"
"github.com/synapsecns/sanguine/ethergo/submitter/db"
"github.com/synapsecns/sanguine/ethergo/util"
"go.opentelemetry.io/otel/attribute"
)

// copyTransactOpts creates a deep copy of the given TransactOpts struct
Expand All @@ -33,74 +31,14 @@ func copyTransactOpts(opts *bind.TransactOpts) *bind.TransactOpts {
return copyOpts
}

const (
uuidAttr = "tx.UUID"
hashAttr = "tx.Hash"
fromAttr = "tx.From"
toAttr = "tx.To"
dataAttr = "tx.Data"
valueAttr = "tx.Value"
nonceAttr = "tx.Nonce"
gasLimitAttr = "tx.GasLimit"
chainIDAttr = "tx.ChainID"
gasPriceAttr = "tx.GasPrice"
gasFeeCapAttr = "tx.GasFeeCap"
gasTipCapAttr = "tx.GasTipCap"
)

// txToAttributes converts a transaction to a slice of attribute.KeyValue.
func txToAttributes(transaction *types.Transaction, uuid string) []attribute.KeyValue {
var from string
call, err := util.TxToCall(transaction)
if err != nil {
from = fmt.Sprintf("could not be detected: %v", err)
} else {
from = call.From.Hex()
}
var attributes = []attribute.KeyValue{
attribute.String(uuidAttr, uuid),
attribute.String(hashAttr, transaction.Hash().Hex()),
attribute.String(fromAttr, from),
attribute.String(toAttr, addressPtrToString(transaction.To())),
attribute.String(dataAttr, fmt.Sprintf("%x", transaction.Data())),
attribute.String(valueAttr, bigPtrToString(transaction.Value())),
// TODO: this could be downcast to int64, but it's unclear how we should handle overflows.
// since this is only for tracing, we can probably ignore it for now.
attribute.Int64(nonceAttr, int64(transaction.Nonce())),
attribute.Int64(gasLimitAttr, int64(transaction.Gas())),
attribute.String(chainIDAttr, bigPtrToString(transaction.ChainId())),
}

if transaction.Type() == types.LegacyTxType && transaction.GasPrice() != nil {
attributes = append(attributes, attribute.String(gasPriceAttr, bigPtrToString(transaction.GasPrice())))
}

if transaction.Type() == types.DynamicFeeTxType && transaction.GasFeeCap() != nil {
attributes = append(attributes, attribute.String(gasFeeCapAttr, bigPtrToString(transaction.GasFeeCap())))
}

if transaction.Type() == types.DynamicFeeTxType && transaction.GasTipCap() != nil {
attributes = append(attributes, attribute.String(gasTipCapAttr, bigPtrToString(transaction.GasTipCap())))
}
func txToAttributes(transaction *types.Transaction, uuid string) (attributes []attribute.KeyValue) {
attributes = util.TxToAttributes(transaction)
attributes = append(attributes, attribute.String(uuidAttr, uuid))

return attributes
}

const nullFieldAttribute = "null"

func addressPtrToString(address *common.Address) string {
if address == nil {
return nullFieldAttribute
}
return address.Hex()
}

func bigPtrToString(num *big.Int) string {
if num == nil {
return nullFieldAttribute
}
return num.String()
}
const uuidAttr = "tx.UUID"

// sortTxesByChainID sorts a slice of transactions by nonce.
func sortTxesByChainID(txs []db.TX, maxPerChain int) map[uint64][]db.TX {
Expand Down
100 changes: 0 additions & 100 deletions ethergo/submitter/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,13 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/google/go-cmp/cmp"
"github.com/google/uuid"
"github.com/synapsecns/sanguine/core"
"github.com/synapsecns/sanguine/core/testsuite"
"github.com/synapsecns/sanguine/ethergo/backends/simulated"
"github.com/synapsecns/sanguine/ethergo/mocks"
"github.com/synapsecns/sanguine/ethergo/submitter"
"github.com/synapsecns/sanguine/ethergo/submitter/db"
"github.com/synapsecns/sanguine/ethergo/util"
"go.opentelemetry.io/otel/attribute"
"gotest.tools/assert"
)

Expand Down Expand Up @@ -106,95 +104,6 @@ func assertBigIntsCopiedEqual(tb testing.TB, original *big.Int, newVal *big.Int,
}
}

func TestAddressPtrToString(t *testing.T) {
// Test case 1: Address is nil
var address *common.Address
assert.Equal(t, submitter.AddressPtrToString(address), submitter.NullFieldAttribute)

// Test case 2: Address is not nil
address = core.PtrTo[common.Address](common.HexToAddress("0x1234567890123456789012345678901234567890"))
assert.Equal(t, submitter.AddressPtrToString(address), "0x1234567890123456789012345678901234567890")
}

func TestBigPtrToString(t *testing.T) {
// Test case: num is nil
var num *big.Int
expected := submitter.NullFieldAttribute
result := submitter.BigPtrToString(num)
if result != expected {
t.Errorf("bigPtrToString(nil) = %q; want %q", result, expected)
}

// Test case: num is an integer
num = big.NewInt(123)
expected = "123"
result = submitter.BigPtrToString(num)
if result != expected {
t.Errorf("bigPtrToString(123) = %q; want %q", result, expected)
}
}

func (s *SubmitterSuite) TestTxToAttributesNullFields() {
s.checkEmptyTx(types.NewTx(&types.DynamicFeeTx{}))
s.checkEmptyTx(types.NewTx(&types.LegacyTx{}))
}

func (s *SubmitterSuite) checkEmptyTx(rawTx *types.Transaction) {
tx := makeAttrMap(rawTx, uuid.New().String())

s.Require().Equal(tx[submitter.HashAttr].AsString(), rawTx.Hash().Hex())
s.Require().Equal(tx[submitter.NonceAttr].AsInt64(), int64(0))
s.Require().Equal(tx[submitter.GasLimitAttr].AsInt64(), int64(0))
s.Require().Equal(tx[submitter.ToAttr].AsString(), submitter.NullFieldAttribute)
s.Require().Equal(tx[submitter.ValueAttr].AsString(), "0")
s.Require().Equal(tx[submitter.DataAttr].AsString(), "")

if rawTx.Type() == types.DynamicFeeTxType {
s.Require().Equal(tx[submitter.GasTipCapAttr].AsString(), "0")
s.Require().Equal(tx[submitter.GasFeeCapAttr].AsString(), "0")
}
if rawTx.Type() == types.LegacyTxType {
s.Require().Equal(tx[submitter.GasPriceAttr].AsString(), "0")
}
}

func (s *SubmitterSuite) TestTxToAttributesLegacyTX() {
mockTX := mocks.GetMockTxes(s.GetTestContext(), s.T(), 1, types.LegacyTxType)[0]
mapAttr := makeAttrMap(mockTX, uuid.New().String())

s.Require().Equal(mapAttr[submitter.HashAttr].AsString(), mockTX.Hash().String())
s.Require().Equal(mapAttr[submitter.NonceAttr].AsInt64(), int64(mockTX.Nonce()))
s.Require().Equal(mapAttr[submitter.GasLimitAttr].AsInt64(), int64(mockTX.Gas()))
s.Require().Equal(mapAttr[submitter.ToAttr].AsString(), mockTX.To().String())
s.Require().Equal(mapAttr[submitter.ValueAttr].AsString(), mockTX.Value().String())
s.Require().Equal(mapAttr[submitter.DataAttr].AsString(), "")

s.Require().Equal(mapAttr[submitter.GasPriceAttr].AsString(), mockTX.GasPrice().String())
_, hasFeeCap := mapAttr[submitter.GasFeeCapAttr]
_, hasTipCap := mapAttr[submitter.GasTipCapAttr]
s.Require().False(hasFeeCap)
s.Require().False(hasTipCap)
s.Require().NotNil(mapAttr[submitter.FromAttr])
}

func (s *SubmitterSuite) TestTxToAttributesDynamicTX() {
mockTX := mocks.GetMockTxes(s.GetTestContext(), s.T(), 1, types.DynamicFeeTxType)[0]
mapAttr := makeAttrMap(mockTX, uuid.New().String())

s.Require().Equal(mapAttr[submitter.HashAttr].AsString(), mockTX.Hash().String())
s.Require().Equal(mapAttr[submitter.NonceAttr].AsInt64(), int64(mockTX.Nonce()))
s.Require().Equal(mapAttr[submitter.GasLimitAttr].AsInt64(), int64(mockTX.Gas()))
s.Require().Equal(mapAttr[submitter.ToAttr].AsString(), mockTX.To().String())
s.Require().Equal(mapAttr[submitter.ValueAttr].AsString(), mockTX.Value().String())
s.Require().Equal(mapAttr[submitter.DataAttr].AsString(), "")

s.Require().Equal(mapAttr[submitter.GasFeeCapAttr].AsString(), mockTX.GasFeeCap().String())
s.Require().Equal(mapAttr[submitter.GasTipCapAttr].AsString(), mockTX.GasTipCap().String())
_, hasGasPrice := mapAttr[submitter.GasPriceAttr]
s.Require().False(hasGasPrice)
s.Require().NotNil(mapAttr[submitter.FromAttr])
}

func (s *SubmitterSuite) TestSortTxes() {
expected := make(map[uint64][]*types.Transaction)
var allTxes []db.TX
Expand Down Expand Up @@ -289,15 +198,6 @@ func (s *SubmitterSuite) TestGroupTxesByNonce() {
}
}

func makeAttrMap(tx *types.Transaction, UUID string) map[string]attribute.Value {
mapAttr := make(map[string]attribute.Value)
attr := submitter.TxToAttributes(tx, UUID)
for _, a := range attr {
mapAttr[string(a.Key)] = a.Value
}
return mapAttr
}

// Test for the outersection function.
func TestOutersection(t *testing.T) {
set := []*big.Int{
Expand Down
Loading

0 comments on commit 59f2fb3

Please sign in to comment.