From f12afc9044dc8788a093b589b738faec20ecee28 Mon Sep 17 00:00:00 2001 From: Daniel Wasserman Date: Wed, 24 Jul 2024 09:38:10 -0500 Subject: [PATCH 1/7] Feat: allow pointers for null val in config --- services/rfq/relayer/relconfig/config.go | 2 +- services/rfq/relayer/relconfig/config_test.go | 17 +++++----- services/rfq/relayer/relconfig/getters.go | 33 ++++++++++++++----- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/services/rfq/relayer/relconfig/config.go b/services/rfq/relayer/relconfig/config.go index 5d69fbd38f..b7b34552ba 100644 --- a/services/rfq/relayer/relconfig/config.go +++ b/services/rfq/relayer/relconfig/config.go @@ -90,7 +90,7 @@ type ChainConfig struct { // MinGasToken is minimum amount of gas that should be leftover after bridging a gas token. MinGasToken string `yaml:"min_gas_token"` // QuotePct is the percent of balance to quote. - QuotePct float64 `yaml:"quote_pct"` + QuotePct *float64 `yaml:"quote_pct"` // QuoteWidthBps is the number of basis points to deduct from the dest amount. // Note that this parameter is applied on a chain level and must be positive. QuoteWidthBps float64 `yaml:"quote_width_bps"` diff --git a/services/rfq/relayer/relconfig/config_test.go b/services/rfq/relayer/relconfig/config_test.go index 2d64aec9e1..ecf0ce4d13 100644 --- a/services/rfq/relayer/relconfig/config_test.go +++ b/services/rfq/relayer/relconfig/config_test.go @@ -1,10 +1,11 @@ package relconfig_test import ( - "github.com/stretchr/testify/assert" "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/synapsecns/sanguine/services/rfq/relayer/relconfig" @@ -30,7 +31,7 @@ func TestChainGetters(t *testing.T) { L1FeeOriginGasEstimate: 30000, L1FeeDestGasEstimate: 40000, MinGasToken: "1000", - QuotePct: 50, + QuotePct: relconfig.NewFloat64Pointer(0), QuoteWidthBps: 10, QuoteFixedFeeMultiplier: 1.1, }, @@ -48,7 +49,7 @@ func TestChainGetters(t *testing.T) { L1FeeOriginGasEstimate: 30001, L1FeeDestGasEstimate: 40001, MinGasToken: "1001", - QuotePct: 51, + QuotePct: relconfig.NewFloat64Pointer(51), QuoteWidthBps: 11, QuoteFixedFeeMultiplier: 1.2, }, @@ -68,7 +69,7 @@ func TestChainGetters(t *testing.T) { L1FeeOriginGasEstimate: 30000, L1FeeDestGasEstimate: 40000, MinGasToken: "1000", - QuotePct: 50, + QuotePct: relconfig.NewFloat64Pointer(50), QuoteWidthBps: 10, QuoteFixedFeeMultiplier: 1.1, Tokens: map[string]relconfig.TokenConfig{ @@ -253,15 +254,15 @@ func TestChainGetters(t *testing.T) { t.Run("GetQuotePct", func(t *testing.T) { defaultVal, err := cfg.GetQuotePct(badChainID) assert.NoError(t, err) - assert.Equal(t, defaultVal, relconfig.DefaultChainConfig.QuotePct) + assert.Equal(t, defaultVal, 100.) baseVal, err := cfgWithBase.GetQuotePct(badChainID) assert.NoError(t, err) - assert.Equal(t, baseVal, cfgWithBase.BaseChainConfig.QuotePct) + assert.Equal(t, baseVal, 51.) chainVal, err := cfgWithBase.GetQuotePct(chainID) assert.NoError(t, err) - assert.Equal(t, chainVal, cfgWithBase.Chains[chainID].QuotePct) + assert.Equal(t, chainVal, 0.) }) t.Run("GetQuoteWidthBps", func(t *testing.T) { @@ -319,7 +320,7 @@ func TestGetQuoteOffset(t *testing.T) { L1FeeOriginGasEstimate: 30000, L1FeeDestGasEstimate: 40000, MinGasToken: "1000", - QuotePct: 50, + QuotePct: relconfig.NewFloat64Pointer(50), QuoteWidthBps: 10, QuoteFixedFeeMultiplier: 1.1, Tokens: map[string]relconfig.TokenConfig{ diff --git a/services/rfq/relayer/relconfig/getters.go b/services/rfq/relayer/relconfig/getters.go index 3bca0f98ce..578fa741e6 100644 --- a/services/rfq/relayer/relconfig/getters.go +++ b/services/rfq/relayer/relconfig/getters.go @@ -17,12 +17,17 @@ var DefaultChainConfig = ChainConfig{ OriginGasEstimate: 160000, DestGasEstimate: 100000, MinGasToken: "100000000000000000", // 1 ETH - QuotePct: 100, + QuotePct: NewFloat64Pointer(100), QuoteWidthBps: 0, QuoteFixedFeeMultiplier: 1, RelayFixedFeeMultiplier: 1, } +// NewFloat64Pointer returns a pointer to a float64. +func NewFloat64Pointer(val float64) *float64 { + return &val +} + // getChainConfigValue gets the value of a field from ChainConfig. // It returns the value from Chains[chainID] if non-zero, // else from BaseChainConfig if non-zero, @@ -34,8 +39,8 @@ func (c Config) getChainConfigValue(chainID int, fieldName string) (interface{}, if err != nil { return nil, err } - if isNonZero(value) { - return value, nil + if !isNilOrZero(value) { + return derefPointer(value), nil } } @@ -43,15 +48,15 @@ func (c Config) getChainConfigValue(chainID int, fieldName string) (interface{}, if err != nil { return nil, err } - if isNonZero(baseValue) { - return baseValue, nil + if !isNilOrZero(baseValue) { + return derefPointer(baseValue), nil } defaultValue, err := getFieldValue(DefaultChainConfig, fieldName) if err != nil { return nil, err } - return defaultValue, nil + return derefPointer(defaultValue), nil } func getFieldValue(obj interface{}, fieldName string) (interface{}, error) { @@ -85,8 +90,20 @@ func isChainConfigField(fieldName string) bool { return ok } -func isNonZero(value interface{}) bool { - return reflect.ValueOf(value).Interface() != reflect.Zero(reflect.TypeOf(value)).Interface() +func derefPointer(value interface{}) interface{} { + val := reflect.ValueOf(value) + if val.Kind() == reflect.Ptr && !val.IsNil() { + return val.Elem().Interface() + } + return value +} + +func isNilOrZero(value interface{}) bool { + val := reflect.ValueOf(value) + if val.Kind() == reflect.Ptr { + return val.IsNil() + } + return reflect.DeepEqual(value, reflect.Zero(val.Type()).Interface()) } // GetRFQAddress returns the RFQ address for the given chainID. From cc7e0121085b0ecc1f4c3563bbbcfeafafd78c59 Mon Sep 17 00:00:00 2001 From: Daniel Wasserman Date: Wed, 24 Jul 2024 09:42:26 -0500 Subject: [PATCH 2/7] Feat: make other fields ptrs (those with nonzero defaults) --- services/rfq/relayer/relconfig/config.go | 4 ++-- services/rfq/relayer/relconfig/config_test.go | 14 +++++++------- services/rfq/relayer/relconfig/getters.go | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/services/rfq/relayer/relconfig/config.go b/services/rfq/relayer/relconfig/config.go index b7b34552ba..36614772d0 100644 --- a/services/rfq/relayer/relconfig/config.go +++ b/services/rfq/relayer/relconfig/config.go @@ -95,9 +95,9 @@ type ChainConfig struct { // Note that this parameter is applied on a chain level and must be positive. QuoteWidthBps float64 `yaml:"quote_width_bps"` // QuoteFixedFeeMultiplier is the multiplier for the fixed fee, applied when generating quotes. - QuoteFixedFeeMultiplier float64 `yaml:"quote_fixed_fee_multiplier"` + QuoteFixedFeeMultiplier *float64 `yaml:"quote_fixed_fee_multiplier"` // RelayFixedFeeMultiplier is the multiplier for the fixed fee, applied when relaying. - RelayFixedFeeMultiplier float64 `yaml:"relay_fixed_fee_multiplier"` + RelayFixedFeeMultiplier *float64 `yaml:"relay_fixed_fee_multiplier"` // CCTP start block is the block at which the chain listener will listen for CCTP events. CCTPStartBlock uint64 `yaml:"cctp_start_block"` } diff --git a/services/rfq/relayer/relconfig/config_test.go b/services/rfq/relayer/relconfig/config_test.go index ecf0ce4d13..4fab53e556 100644 --- a/services/rfq/relayer/relconfig/config_test.go +++ b/services/rfq/relayer/relconfig/config_test.go @@ -33,7 +33,7 @@ func TestChainGetters(t *testing.T) { MinGasToken: "1000", QuotePct: relconfig.NewFloat64Pointer(0), QuoteWidthBps: 10, - QuoteFixedFeeMultiplier: 1.1, + QuoteFixedFeeMultiplier: relconfig.NewFloat64Pointer(1.1), }, }, BaseChainConfig: relconfig.ChainConfig{ @@ -51,7 +51,7 @@ func TestChainGetters(t *testing.T) { MinGasToken: "1001", QuotePct: relconfig.NewFloat64Pointer(51), QuoteWidthBps: 11, - QuoteFixedFeeMultiplier: 1.2, + QuoteFixedFeeMultiplier: relconfig.NewFloat64Pointer(1.2), }, } cfg := relconfig.Config{ @@ -71,7 +71,7 @@ func TestChainGetters(t *testing.T) { MinGasToken: "1000", QuotePct: relconfig.NewFloat64Pointer(50), QuoteWidthBps: 10, - QuoteFixedFeeMultiplier: 1.1, + QuoteFixedFeeMultiplier: relconfig.NewFloat64Pointer(1.1), Tokens: map[string]relconfig.TokenConfig{ "USDC": { Address: usdcAddr, @@ -282,15 +282,15 @@ func TestChainGetters(t *testing.T) { t.Run("GetQuoteFixedFeeMultiplier", func(t *testing.T) { defaultVal, err := cfg.GetQuoteFixedFeeMultiplier(badChainID) assert.NoError(t, err) - assert.Equal(t, defaultVal, relconfig.DefaultChainConfig.QuoteFixedFeeMultiplier) + assert.Equal(t, defaultVal, *relconfig.DefaultChainConfig.QuoteFixedFeeMultiplier) baseVal, err := cfgWithBase.GetQuoteFixedFeeMultiplier(badChainID) assert.NoError(t, err) - assert.Equal(t, baseVal, cfgWithBase.BaseChainConfig.QuoteFixedFeeMultiplier) + assert.Equal(t, baseVal, *cfgWithBase.BaseChainConfig.QuoteFixedFeeMultiplier) chainVal, err := cfgWithBase.GetQuoteFixedFeeMultiplier(chainID) assert.NoError(t, err) - assert.Equal(t, chainVal, cfgWithBase.Chains[chainID].QuoteFixedFeeMultiplier) + assert.Equal(t, chainVal, *cfgWithBase.Chains[chainID].QuoteFixedFeeMultiplier) }) t.Run("GetMaxRebalanceAmount", func(t *testing.T) { @@ -322,7 +322,7 @@ func TestGetQuoteOffset(t *testing.T) { MinGasToken: "1000", QuotePct: relconfig.NewFloat64Pointer(50), QuoteWidthBps: 10, - QuoteFixedFeeMultiplier: 1.1, + QuoteFixedFeeMultiplier: relconfig.NewFloat64Pointer(1.1), Tokens: map[string]relconfig.TokenConfig{ "USDC": { Address: usdcAddr, diff --git a/services/rfq/relayer/relconfig/getters.go b/services/rfq/relayer/relconfig/getters.go index 578fa741e6..818dd7fa85 100644 --- a/services/rfq/relayer/relconfig/getters.go +++ b/services/rfq/relayer/relconfig/getters.go @@ -19,8 +19,8 @@ var DefaultChainConfig = ChainConfig{ MinGasToken: "100000000000000000", // 1 ETH QuotePct: NewFloat64Pointer(100), QuoteWidthBps: 0, - QuoteFixedFeeMultiplier: 1, - RelayFixedFeeMultiplier: 1, + QuoteFixedFeeMultiplier: NewFloat64Pointer(1), + RelayFixedFeeMultiplier: NewFloat64Pointer(1), } // NewFloat64Pointer returns a pointer to a float64. @@ -344,7 +344,7 @@ func (c Config) GetQuoteFixedFeeMultiplier(chainID int) (value float64, err erro return value, fmt.Errorf("failed to cast QuoteFixedFeeMultiplier to int") } if value <= 0 { - value = DefaultChainConfig.QuoteFixedFeeMultiplier + value = *DefaultChainConfig.QuoteFixedFeeMultiplier } return value, nil } From 429dfafa6e2fa361248bd48e5ecb8f56e71e168f Mon Sep 17 00:00:00 2001 From: Daniel Wasserman Date: Wed, 24 Jul 2024 09:43:06 -0500 Subject: [PATCH 3/7] Replace: NewFloat64Pointer -> NewFloatPtr --- services/rfq/relayer/relconfig/config_test.go | 16 ++++++++-------- services/rfq/relayer/relconfig/getters.go | 10 +++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/services/rfq/relayer/relconfig/config_test.go b/services/rfq/relayer/relconfig/config_test.go index 4fab53e556..bac0016c52 100644 --- a/services/rfq/relayer/relconfig/config_test.go +++ b/services/rfq/relayer/relconfig/config_test.go @@ -31,9 +31,9 @@ func TestChainGetters(t *testing.T) { L1FeeOriginGasEstimate: 30000, L1FeeDestGasEstimate: 40000, MinGasToken: "1000", - QuotePct: relconfig.NewFloat64Pointer(0), + QuotePct: relconfig.NewFloatPtr(0), QuoteWidthBps: 10, - QuoteFixedFeeMultiplier: relconfig.NewFloat64Pointer(1.1), + QuoteFixedFeeMultiplier: relconfig.NewFloatPtr(1.1), }, }, BaseChainConfig: relconfig.ChainConfig{ @@ -49,9 +49,9 @@ func TestChainGetters(t *testing.T) { L1FeeOriginGasEstimate: 30001, L1FeeDestGasEstimate: 40001, MinGasToken: "1001", - QuotePct: relconfig.NewFloat64Pointer(51), + QuotePct: relconfig.NewFloatPtr(51), QuoteWidthBps: 11, - QuoteFixedFeeMultiplier: relconfig.NewFloat64Pointer(1.2), + QuoteFixedFeeMultiplier: relconfig.NewFloatPtr(1.2), }, } cfg := relconfig.Config{ @@ -69,9 +69,9 @@ func TestChainGetters(t *testing.T) { L1FeeOriginGasEstimate: 30000, L1FeeDestGasEstimate: 40000, MinGasToken: "1000", - QuotePct: relconfig.NewFloat64Pointer(50), + QuotePct: relconfig.NewFloatPtr(50), QuoteWidthBps: 10, - QuoteFixedFeeMultiplier: relconfig.NewFloat64Pointer(1.1), + QuoteFixedFeeMultiplier: relconfig.NewFloatPtr(1.1), Tokens: map[string]relconfig.TokenConfig{ "USDC": { Address: usdcAddr, @@ -320,9 +320,9 @@ func TestGetQuoteOffset(t *testing.T) { L1FeeOriginGasEstimate: 30000, L1FeeDestGasEstimate: 40000, MinGasToken: "1000", - QuotePct: relconfig.NewFloat64Pointer(50), + QuotePct: relconfig.NewFloatPtr(50), QuoteWidthBps: 10, - QuoteFixedFeeMultiplier: relconfig.NewFloat64Pointer(1.1), + QuoteFixedFeeMultiplier: relconfig.NewFloatPtr(1.1), Tokens: map[string]relconfig.TokenConfig{ "USDC": { Address: usdcAddr, diff --git a/services/rfq/relayer/relconfig/getters.go b/services/rfq/relayer/relconfig/getters.go index 818dd7fa85..053e04c19e 100644 --- a/services/rfq/relayer/relconfig/getters.go +++ b/services/rfq/relayer/relconfig/getters.go @@ -17,14 +17,14 @@ var DefaultChainConfig = ChainConfig{ OriginGasEstimate: 160000, DestGasEstimate: 100000, MinGasToken: "100000000000000000", // 1 ETH - QuotePct: NewFloat64Pointer(100), + QuotePct: NewFloatPtr(100), QuoteWidthBps: 0, - QuoteFixedFeeMultiplier: NewFloat64Pointer(1), - RelayFixedFeeMultiplier: NewFloat64Pointer(1), + QuoteFixedFeeMultiplier: NewFloatPtr(1), + RelayFixedFeeMultiplier: NewFloatPtr(1), } -// NewFloat64Pointer returns a pointer to a float64. -func NewFloat64Pointer(val float64) *float64 { +// NewFloatPtr returns a pointer to a float64. +func NewFloatPtr(val float64) *float64 { return &val } From aa87eab5d92be4445ca4783c5808dfe2884592ff Mon Sep 17 00:00:00 2001 From: Daniel Wasserman Date: Wed, 24 Jul 2024 09:43:20 -0500 Subject: [PATCH 4/7] [goreleaser] From 367bd6f6b8665c9c5f6eef9bf4174fe6891d8fe6 Mon Sep 17 00:00:00 2001 From: Daniel Wasserman Date: Wed, 24 Jul 2024 09:55:33 -0500 Subject: [PATCH 5/7] Fix: tests --- services/rfq/relayer/pricer/fee_pricer_test.go | 9 +++++---- services/rfq/relayer/quoter/quoter_test.go | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/services/rfq/relayer/pricer/fee_pricer_test.go b/services/rfq/relayer/pricer/fee_pricer_test.go index f316622a54..6b6174c7c3 100644 --- a/services/rfq/relayer/pricer/fee_pricer_test.go +++ b/services/rfq/relayer/pricer/fee_pricer_test.go @@ -11,6 +11,7 @@ import ( fetcherMocks "github.com/synapsecns/sanguine/ethergo/submitter/mocks" "github.com/synapsecns/sanguine/services/rfq/relayer/pricer" priceMocks "github.com/synapsecns/sanguine/services/rfq/relayer/pricer/mocks" + "github.com/synapsecns/sanguine/services/rfq/relayer/relconfig" ) var defaultPrices = map[string]float64{"ETH": 2000., "USDC": 1., "MATIC": 0.5} @@ -261,8 +262,8 @@ func (s *PricerSuite) TestGetGasPrice() { func (s *PricerSuite) TestGetTotalFeeWithMultiplier() { // Override the fixed fee multiplier to greater than 1. - s.config.BaseChainConfig.QuoteFixedFeeMultiplier = 2 - s.config.BaseChainConfig.RelayFixedFeeMultiplier = 4 + s.config.BaseChainConfig.QuoteFixedFeeMultiplier = relconfig.NewFloatPtr(2) + s.config.BaseChainConfig.RelayFixedFeeMultiplier = relconfig.NewFloatPtr(4) // Build a new FeePricer with a mocked client for fetching gas price. clientFetcher := new(fetcherMocks.ClientFetcher) @@ -295,7 +296,7 @@ func (s *PricerSuite) TestGetTotalFeeWithMultiplier() { s.Equal(expectedFee, fee) // Override the fixed fee multiplier to less than 1; should default to 1. - s.config.BaseChainConfig.QuoteFixedFeeMultiplier = -1 + s.config.BaseChainConfig.QuoteFixedFeeMultiplier = relconfig.NewFloatPtr(-1) // Build a new FeePricer with a mocked client for fetching gas price. clientOrigin.On(testsuite.GetFunctionName(clientOrigin.SuggestGasPrice), mock.Anything).Once().Return(headerOrigin, nil) @@ -314,7 +315,7 @@ func (s *PricerSuite) TestGetTotalFeeWithMultiplier() { s.Equal(expectedFee, fee) // Reset the fixed fee multiplier to zero; should default to 1 - s.config.BaseChainConfig.QuoteFixedFeeMultiplier = 0 + s.config.BaseChainConfig.QuoteFixedFeeMultiplier = relconfig.NewFloatPtr(0) // Build a new FeePricer with a mocked client for fetching gas price. clientOrigin.On(testsuite.GetFunctionName(clientOrigin.SuggestGasPrice), mock.Anything).Once().Return(headerOrigin, nil) diff --git a/services/rfq/relayer/quoter/quoter_test.go b/services/rfq/relayer/quoter/quoter_test.go index 507b981e0d..44510fabe8 100644 --- a/services/rfq/relayer/quoter/quoter_test.go +++ b/services/rfq/relayer/quoter/quoter_test.go @@ -165,7 +165,7 @@ func (s *QuoterSuite) TestGetOriginAmount() { balance := big.NewInt(1000_000_000) // 1000 USDC setQuoteParams := func(quotePct, quoteOffset float64, minQuoteAmount string) { - s.config.BaseChainConfig.QuotePct = quotePct + s.config.BaseChainConfig.QuotePct = "ePct destTokenCfg := s.config.Chains[dest].Tokens["USDC"] destTokenCfg.MinQuoteAmount = minQuoteAmount originTokenCfg := s.config.Chains[origin].Tokens["USDC"] From 756fcc34d9c04ce1cada911a148a8329218cbd64 Mon Sep 17 00:00:00 2001 From: Daniel Wasserman Date: Wed, 24 Jul 2024 09:55:34 -0500 Subject: [PATCH 6/7] [goreleaser] From e178edb95c0be2f911094a2ba0916520ad027044 Mon Sep 17 00:00:00 2001 From: Trajan0x Date: Sun, 28 Jul 2024 17:26:52 +0200 Subject: [PATCH 7/7] core ptr --- services/rfq/relayer/relconfig/getters.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/rfq/relayer/relconfig/getters.go b/services/rfq/relayer/relconfig/getters.go index 053e04c19e..60e3ab3ac7 100644 --- a/services/rfq/relayer/relconfig/getters.go +++ b/services/rfq/relayer/relconfig/getters.go @@ -2,6 +2,7 @@ package relconfig import ( "fmt" + "github.com/synapsecns/sanguine/core" "math/big" "reflect" "time" @@ -25,7 +26,7 @@ var DefaultChainConfig = ChainConfig{ // NewFloatPtr returns a pointer to a float64. func NewFloatPtr(val float64) *float64 { - return &val + return core.PtrTo(val) } // getChainConfigValue gets the value of a field from ChainConfig.