Skip to content

Commit 425fbd9

Browse files
authored
Apply TXM and LogPoller default config values field by field (#302)
1 parent 9054901 commit 425fbd9

File tree

8 files changed

+314
-65
lines changed

8 files changed

+314
-65
lines changed

integration-tests/txm/txm_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
test_utils "github.com/smartcontractkit/chainlink-ton/deployment/utils"
1111

12+
commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config"
1213
"github.com/smartcontractkit/chainlink-common/pkg/logger"
1314
"github.com/smartcontractkit/chainlink-common/pkg/loop"
1415
cldf_ton "github.com/smartcontractkit/chainlink-deployments-framework/chain/ton"
@@ -49,7 +50,7 @@ func TestTxmLocal(t *testing.T) {
4950
require.NotNil(t, keystore)
5051

5152
config := txm.DefaultConfigSet
52-
config.ConfirmPollSecs = 2
53+
config.ConfirmPollInterval = commonconfig.MustNewDuration(2 * time.Second)
5354

5455
runTxmTest(t, logger, config, tonChain, keystore, 5)
5556
}

pkg/config/toml.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import (
99

1010
"github.com/smartcontractkit/chainlink-common/pkg/config"
1111
relaytypes "github.com/smartcontractkit/chainlink-common/pkg/types"
12+
13+
"github.com/smartcontractkit/chainlink-ton/pkg/logpoller"
14+
"github.com/smartcontractkit/chainlink-ton/pkg/txm"
1215
)
1316

1417
type TOMLConfig struct {
@@ -36,25 +39,29 @@ func NewDecodedTOMLConfig(rawConfig string) (*TOMLConfig, error) {
3639
return &TOMLConfig{}, fmt.Errorf("failed to decode config toml: %w:\n\t%s", err, rawConfig)
3740
}
3841

42+
// Apply defaults before validation
43+
cfg.SetDefaults()
44+
3945
if err := cfg.ValidateConfig(); err != nil {
4046
return &TOMLConfig{}, fmt.Errorf("invalid ton config: %w", err)
4147
}
4248

4349
if !cfg.IsEnabled() {
4450
return &TOMLConfig{}, fmt.Errorf("cannot create new chain with ID %s: config is disabled", cfg.ChainID)
4551
}
46-
47-
cfg.SetDefaults()
4852
return &cfg, nil
4953
}
5054

5155
func (c *TOMLConfig) SetDefaults() {
5256
if c.TransactionManager == nil {
53-
c.TransactionManager = DefaultConfigSet.TransactionManager
57+
c.TransactionManager = &txm.Config{}
5458
}
59+
c.TransactionManager.ApplyDefaults()
60+
5561
if c.LogPoller == nil {
56-
c.LogPoller = DefaultConfigSet.LogPoller
62+
c.LogPoller = &logpoller.Config{}
5763
}
64+
c.LogPoller.ApplyDefaults()
5865

5966
// Set network name full defaults
6067
if c.NetworkNameFull == "" {
@@ -90,6 +97,7 @@ func NodeStatus(n *Node, id string) (relaytypes.NodeStatus, error) {
9097
}
9198

9299
func setFromChain(c, f *Chain) {
100+
c.ClientTTL = f.ClientTTL
93101
if f.TransactionManager != nil {
94102
c.TransactionManager = f.TransactionManager
95103
}
@@ -111,6 +119,9 @@ func (c *TOMLConfig) ValidateConfig() (err error) {
111119
}
112120
}
113121

122+
err = errors.Join(err, c.TransactionManager.ValidateConfig())
123+
err = errors.Join(err, c.LogPoller.ValidateConfig())
124+
114125
return
115126
}
116127

pkg/config/toml_test.go

Lines changed: 102 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,18 @@ ChainID = '-3'
2121
NetworkName = 'testnet'
2222

2323
[TransactionManager]
24-
BroadcastChanSize = 200
25-
SendRetryDelay = '5s'
26-
CleanupIntervalMins = 15
24+
BroadcastChanSize = 101
25+
ConfirmPollInterval = '9s'
26+
SendRetryDelay = '8s'
27+
MaxSendRetryAttempts = 7
28+
TxExpiration = '6h'
29+
CleanupInterval = '15m'
2730

2831
[LogPoller]
2932
PollPeriod = '10s'
3033
PageSize = 50
31-
BlockTime = '2500ms'
34+
LogPollerStartingLookback = '1h'
35+
BlockTime = '1200ms'
3236

3337
[[Nodes]]
3438
Name = 'ton-testnet-1'
@@ -44,14 +48,18 @@ URL = 'http://localhost:8081'
4448

4549
// Verify config sections exist and key fields parse correctly
4650
require.NotNil(t, cfg.TransactionManager)
47-
assert.Equal(t, uint(200), cfg.TransactionManager.BroadcastChanSize)
48-
assert.Equal(t, 5*time.Second, cfg.TransactionManager.SendRetryDelay.Duration())
49-
assert.Equal(t, uint(15), cfg.TransactionManager.CleanupIntervalMins)
51+
assert.Equal(t, uint(101), cfg.TransactionManager.BroadcastChanSize)
52+
assert.Equal(t, 9*time.Second, cfg.TransactionManager.ConfirmPollInterval.Duration())
53+
assert.Equal(t, 8*time.Second, cfg.TransactionManager.SendRetryDelay.Duration())
54+
assert.Equal(t, uint(7), cfg.TransactionManager.MaxSendRetryAttempts)
55+
assert.Equal(t, 6*time.Hour, cfg.TransactionManager.TxExpiration.Duration())
56+
assert.Equal(t, 15*time.Minute, cfg.TransactionManager.CleanupInterval.Duration())
5057

5158
require.NotNil(t, cfg.LogPoller)
5259
assert.Equal(t, uint32(50), cfg.LogPoller.PageSize)
5360
assert.Equal(t, 10*time.Second, cfg.LogPoller.PollPeriod.Duration())
54-
assert.Equal(t, 2500*time.Millisecond, cfg.LogPoller.BlockTime.Duration())
61+
assert.Equal(t, 1*time.Hour, cfg.LogPoller.LogPollerStartingLookback.Duration())
62+
assert.Equal(t, 1200*time.Millisecond, cfg.LogPoller.BlockTime.Duration())
5563

5664
require.Len(t, cfg.Nodes, 1)
5765
assert.Equal(t, "ton-testnet-1", *cfg.Nodes[0].Name)
@@ -71,12 +79,23 @@ URL = 'http://localhost:8081'
7179
cfg, err := NewDecodedTOMLConfig(tomlStr)
7280
require.NoError(t, err)
7381

74-
// Missing sections should get full defaults
75-
assert.Equal(t, DefaultConfigSet.TransactionManager, cfg.TransactionManager)
76-
assert.Equal(t, DefaultConfigSet.LogPoller, cfg.LogPoller)
82+
// Missing sections should get full defaults - verify field by field
83+
require.NotNil(t, cfg.TransactionManager)
84+
assert.Equal(t, txm.DefaultConfigSet.BroadcastChanSize, cfg.TransactionManager.BroadcastChanSize)
85+
assert.Equal(t, txm.DefaultConfigSet.ConfirmPollInterval, cfg.TransactionManager.ConfirmPollInterval)
86+
assert.Equal(t, txm.DefaultConfigSet.SendRetryDelay, cfg.TransactionManager.SendRetryDelay)
87+
assert.Equal(t, txm.DefaultConfigSet.MaxSendRetryAttempts, cfg.TransactionManager.MaxSendRetryAttempts)
88+
assert.Equal(t, txm.DefaultConfigSet.TxExpiration, cfg.TransactionManager.TxExpiration)
89+
assert.Equal(t, txm.DefaultConfigSet.CleanupInterval, cfg.TransactionManager.CleanupInterval)
90+
91+
require.NotNil(t, cfg.LogPoller)
92+
assert.Equal(t, logpoller.DefaultConfigSet.PollPeriod, cfg.LogPoller.PollPeriod)
93+
assert.Equal(t, logpoller.DefaultConfigSet.PageSize, cfg.LogPoller.PageSize)
94+
assert.Equal(t, logpoller.DefaultConfigSet.LogPollerStartingLookback, cfg.LogPoller.LogPollerStartingLookback)
95+
assert.Equal(t, logpoller.DefaultConfigSet.BlockTime, cfg.LogPoller.BlockTime)
7796
})
7897

79-
t.Run("partial configs get zero values", func(t *testing.T) {
98+
t.Run("partial configs get field-by-field defaults", func(t *testing.T) {
8099
tomlStr := `
81100
Enabled = true
82101
ChainID = '-3'
@@ -100,11 +119,16 @@ URL = 'http://localhost:8081'
100119
assert.Equal(t, uint(300), cfg.TransactionManager.BroadcastChanSize)
101120
assert.Equal(t, uint32(200), cfg.LogPoller.PageSize)
102121

103-
// Missing fields get zero values (Aptos behavior)
104-
assert.Equal(t, uint(0), cfg.TransactionManager.ConfirmPollSecs)
105-
assert.Equal(t, uint(0), cfg.TransactionManager.CleanupIntervalMins)
106-
assert.Nil(t, cfg.TransactionManager.SendRetryDelay)
107-
assert.False(t, cfg.TransactionManager.StickyNodeContextEnabled)
122+
// Missing fields get defaults applied (field-by-field)
123+
assert.Equal(t, txm.DefaultConfigSet.ConfirmPollInterval, cfg.TransactionManager.ConfirmPollInterval)
124+
assert.Equal(t, txm.DefaultConfigSet.SendRetryDelay, cfg.TransactionManager.SendRetryDelay)
125+
assert.Equal(t, txm.DefaultConfigSet.MaxSendRetryAttempts, cfg.TransactionManager.MaxSendRetryAttempts)
126+
assert.Equal(t, txm.DefaultConfigSet.TxExpiration, cfg.TransactionManager.TxExpiration)
127+
assert.Equal(t, txm.DefaultConfigSet.CleanupInterval, cfg.TransactionManager.CleanupInterval)
128+
129+
assert.Equal(t, logpoller.DefaultConfigSet.PollPeriod, cfg.LogPoller.PollPeriod)
130+
assert.Equal(t, logpoller.DefaultConfigSet.LogPollerStartingLookback, cfg.LogPoller.LogPollerStartingLookback)
131+
assert.Equal(t, logpoller.DefaultConfigSet.BlockTime, cfg.LogPoller.BlockTime)
108132
})
109133

110134
t.Run("validation errors", func(t *testing.T) {
@@ -123,31 +147,67 @@ URL = 'http://localhost:8081'
123147
}
124148

125149
func TestTOMLConfig_SetDefaults(t *testing.T) {
126-
// Test nil configs get defaults
127-
cfg := &TOMLConfig{NetworkName: "testnet"}
128-
cfg.SetDefaults()
129-
130-
assert.Equal(t, DefaultConfigSet.TransactionManager, cfg.TransactionManager)
131-
assert.Equal(t, DefaultConfigSet.LogPoller, cfg.LogPoller)
132-
assert.Equal(t, "ton-testnet", cfg.NetworkNameFull)
133-
134-
// Test existing configs preserved
135-
customTxm := &txm.Config{BroadcastChanSize: 999}
136-
customLP := &logpoller.Config{PageSize: 777}
137-
138-
cfg2 := &TOMLConfig{
139-
NetworkName: "mainnet",
140-
NetworkNameFull: "custom-name",
141-
Chain: Chain{
142-
TransactionManager: customTxm,
143-
LogPoller: customLP,
144-
},
145-
}
146-
cfg2.SetDefaults()
147-
148-
assert.Equal(t, customTxm, cfg2.TransactionManager)
149-
assert.Equal(t, customLP, cfg2.LogPoller)
150-
assert.Equal(t, "custom-name", cfg2.NetworkNameFull)
150+
t.Run("nil configs get full defaults", func(t *testing.T) {
151+
cfg := &TOMLConfig{NetworkName: "testnet"}
152+
cfg.SetDefaults()
153+
154+
// Verify all TransactionManager fields got defaults
155+
require.NotNil(t, cfg.TransactionManager)
156+
assert.Equal(t, txm.DefaultConfigSet.BroadcastChanSize, cfg.TransactionManager.BroadcastChanSize)
157+
assert.Equal(t, txm.DefaultConfigSet.ConfirmPollInterval, cfg.TransactionManager.ConfirmPollInterval)
158+
assert.Equal(t, txm.DefaultConfigSet.SendRetryDelay, cfg.TransactionManager.SendRetryDelay)
159+
assert.Equal(t, txm.DefaultConfigSet.MaxSendRetryAttempts, cfg.TransactionManager.MaxSendRetryAttempts)
160+
assert.Equal(t, txm.DefaultConfigSet.TxExpiration, cfg.TransactionManager.TxExpiration)
161+
assert.Equal(t, txm.DefaultConfigSet.CleanupInterval, cfg.TransactionManager.CleanupInterval)
162+
163+
// Verify all LogPoller fields got defaults
164+
require.NotNil(t, cfg.LogPoller)
165+
assert.Equal(t, logpoller.DefaultConfigSet.PollPeriod, cfg.LogPoller.PollPeriod)
166+
assert.Equal(t, logpoller.DefaultConfigSet.PageSize, cfg.LogPoller.PageSize)
167+
assert.Equal(t, logpoller.DefaultConfigSet.LogPollerStartingLookback, cfg.LogPoller.LogPollerStartingLookback)
168+
assert.Equal(t, logpoller.DefaultConfigSet.BlockTime, cfg.LogPoller.BlockTime)
169+
170+
assert.Equal(t, "ton-testnet", cfg.NetworkNameFull)
171+
})
172+
173+
t.Run("partial configs get field-by-field defaults applied", func(t *testing.T) {
174+
// Create configs with only some fields set
175+
customTxm := &txm.Config{
176+
BroadcastChanSize: 999,
177+
SendRetryDelay: config.MustNewDuration(10 * time.Second),
178+
}
179+
customLP := &logpoller.Config{
180+
PageSize: 777,
181+
BlockTime: config.MustNewDuration(3 * time.Second),
182+
}
183+
184+
cfg := &TOMLConfig{
185+
NetworkName: "mainnet",
186+
NetworkNameFull: "custom-name",
187+
Chain: Chain{
188+
TransactionManager: customTxm,
189+
LogPoller: customLP,
190+
},
191+
}
192+
cfg.SetDefaults()
193+
194+
// Verify custom values are preserved
195+
assert.Equal(t, uint(999), cfg.TransactionManager.BroadcastChanSize)
196+
assert.Equal(t, 10*time.Second, cfg.TransactionManager.SendRetryDelay.Duration())
197+
assert.Equal(t, uint32(777), cfg.LogPoller.PageSize)
198+
assert.Equal(t, 3*time.Second, cfg.LogPoller.BlockTime.Duration())
199+
200+
// Verify missing fields got defaults
201+
assert.Equal(t, txm.DefaultConfigSet.ConfirmPollInterval, cfg.TransactionManager.ConfirmPollInterval)
202+
assert.Equal(t, txm.DefaultConfigSet.MaxSendRetryAttempts, cfg.TransactionManager.MaxSendRetryAttempts)
203+
assert.Equal(t, txm.DefaultConfigSet.TxExpiration, cfg.TransactionManager.TxExpiration)
204+
assert.Equal(t, txm.DefaultConfigSet.CleanupInterval, cfg.TransactionManager.CleanupInterval)
205+
206+
assert.Equal(t, logpoller.DefaultConfigSet.PollPeriod, cfg.LogPoller.PollPeriod)
207+
assert.Equal(t, logpoller.DefaultConfigSet.LogPollerStartingLookback, cfg.LogPoller.LogPollerStartingLookback)
208+
209+
assert.Equal(t, "custom-name", cfg.NetworkNameFull)
210+
})
151211
}
152212

153213
func TestSetFromChain(t *testing.T) {

pkg/logpoller/config.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import (
66
"github.com/smartcontractkit/chainlink-common/pkg/config"
77
)
88

9+
// Config holds the configuration for the log poller.
10+
// NOTE: when adding new fields, please update ApplyDefaults, DefaultConfigSet, and ValidateConfig accordingly.
11+
// Also check toml_test.go TestNewDecodedTOMLConfig() to ensure new fields are tested there.
912
type Config struct {
1013
PollPeriod *config.Duration
1114
PageSize uint32
@@ -19,3 +22,22 @@ var DefaultConfigSet = Config{
1922
LogPollerStartingLookback: config.MustNewDuration(24 * time.Hour), // Look back 24 hours on startup
2023
BlockTime: config.MustNewDuration(2500 * time.Millisecond), // TON block time is approximately 2.5 seconds (2500ms)
2124
}
25+
26+
func (c *Config) ApplyDefaults() {
27+
if c.PollPeriod == nil {
28+
c.PollPeriod = DefaultConfigSet.PollPeriod
29+
}
30+
if c.PageSize == 0 {
31+
c.PageSize = DefaultConfigSet.PageSize
32+
}
33+
if c.LogPollerStartingLookback == nil {
34+
c.LogPollerStartingLookback = DefaultConfigSet.LogPollerStartingLookback
35+
}
36+
if c.BlockTime == nil {
37+
c.BlockTime = DefaultConfigSet.BlockTime
38+
}
39+
}
40+
41+
func (c *Config) ValidateConfig() (err error) {
42+
return nil
43+
}

pkg/logpoller/config_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package logpoller
2+
3+
import (
4+
"testing"
5+
"time"
6+
7+
"github.com/stretchr/testify/assert"
8+
9+
"github.com/smartcontractkit/chainlink-common/pkg/config"
10+
)
11+
12+
func TestConfig_ApplyDefaults(t *testing.T) {
13+
t.Run("applies all defaults to empty config", func(t *testing.T) {
14+
cfg := &Config{}
15+
cfg.ApplyDefaults()
16+
17+
assert.Equal(t, DefaultConfigSet.PollPeriod, cfg.PollPeriod)
18+
assert.Equal(t, DefaultConfigSet.PageSize, cfg.PageSize)
19+
assert.Equal(t, DefaultConfigSet.LogPollerStartingLookback, cfg.LogPollerStartingLookback)
20+
assert.Equal(t, DefaultConfigSet.BlockTime, cfg.BlockTime)
21+
})
22+
23+
t.Run("preserves custom values and applies defaults to missing fields", func(t *testing.T) {
24+
customPageSize := uint32(250)
25+
customBlockTime := config.MustNewDuration(13 * time.Second)
26+
27+
cfg := &Config{
28+
PageSize: customPageSize,
29+
BlockTime: customBlockTime,
30+
}
31+
cfg.ApplyDefaults()
32+
33+
// Custom values
34+
assert.Equal(t, customPageSize, cfg.PageSize)
35+
assert.Equal(t, customBlockTime, cfg.BlockTime)
36+
37+
// Defaults
38+
assert.Equal(t, DefaultConfigSet.PollPeriod, cfg.PollPeriod)
39+
assert.Equal(t, DefaultConfigSet.LogPollerStartingLookback, cfg.LogPollerStartingLookback)
40+
})
41+
42+
t.Run("all fields set - nothing should change", func(t *testing.T) {
43+
customConfig := Config{
44+
PollPeriod: config.MustNewDuration(1 * time.Second),
45+
PageSize: 50,
46+
LogPollerStartingLookback: config.MustNewDuration(48 * time.Hour),
47+
BlockTime: config.MustNewDuration(1 * time.Second),
48+
}
49+
50+
original := customConfig
51+
customConfig.ApplyDefaults()
52+
53+
assert.Equal(t, original.PollPeriod, customConfig.PollPeriod)
54+
assert.Equal(t, original.PageSize, customConfig.PageSize)
55+
assert.Equal(t, original.LogPollerStartingLookback, customConfig.LogPollerStartingLookback)
56+
assert.Equal(t, original.BlockTime, customConfig.BlockTime)
57+
})
58+
}

0 commit comments

Comments
 (0)