-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MultiNode Integration: TOML Configurations (#844)
* MultiNode integration setup * Update MultiNode files * Add MultiNode flag * Remove internal dependency * Fix build * Fix import cycle * tidy * Update client_test.go * lint * Fix duplicate metrics * Add chain multinode flag * Extend client * Add defaults * Address comments * lint * Fix lint overflow issues * Update transaction_sender.go * Fix lint * Validate node config * Update toml.go * Add SendOnly nodes * Use pointers on config * Use test context * Use configured selection mode * Set defaults * lint * Add nil check * Update multinode.go * Add comments * Update multinode.go * Wrap multinode config * Fix imports * Update .golangci.yml * Use MultiNode config
- Loading branch information
1 parent
c8e4c1f
commit 3f52bbc
Showing
3 changed files
with
181 additions
and
65 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,87 +1,206 @@ | ||
package config | ||
|
||
import "time" | ||
import ( | ||
"time" | ||
|
||
"github.com/smartcontractkit/chainlink-common/pkg/config" | ||
|
||
mn "github.com/smartcontractkit/chainlink-solana/pkg/solana/client/multinode" | ||
) | ||
|
||
// MultiNodeConfig is a wrapper to provide required functions while keeping configs Public | ||
type MultiNodeConfig struct { | ||
MultiNode | ||
} | ||
|
||
type MultiNode struct { | ||
// TODO: Determine current config overlap https://smartcontract-it.atlassian.net/browse/BCI-4065 | ||
// Feature flag | ||
multiNodeEnabled bool | ||
Enabled *bool | ||
|
||
// Node Configs | ||
pollFailureThreshold uint32 | ||
pollInterval time.Duration | ||
selectionMode string | ||
syncThreshold uint32 | ||
nodeIsSyncingEnabled bool | ||
finalizedBlockPollInterval time.Duration | ||
enforceRepeatableRead bool | ||
deathDeclarationDelay time.Duration | ||
PollFailureThreshold *uint32 | ||
PollInterval *config.Duration | ||
SelectionMode *string | ||
SyncThreshold *uint32 | ||
NodeIsSyncingEnabled *bool | ||
LeaseDuration *config.Duration | ||
FinalizedBlockPollInterval *config.Duration | ||
EnforceRepeatableRead *bool | ||
DeathDeclarationDelay *config.Duration | ||
|
||
// Chain Configs | ||
nodeNoNewHeadsThreshold time.Duration | ||
noNewFinalizedHeadsThreshold time.Duration | ||
finalityDepth uint32 | ||
finalityTagEnabled bool | ||
finalizedBlockOffset uint32 | ||
NodeNoNewHeadsThreshold *config.Duration | ||
NoNewFinalizedHeadsThreshold *config.Duration | ||
FinalityDepth *uint32 | ||
FinalityTagEnabled *bool | ||
FinalizedBlockOffset *uint32 | ||
} | ||
|
||
func (c *MultiNode) MultiNodeEnabled() bool { | ||
return c.multiNodeEnabled | ||
func (c *MultiNodeConfig) Enabled() bool { | ||
return c.MultiNode.Enabled != nil && *c.MultiNode.Enabled | ||
} | ||
|
||
func (c *MultiNode) PollFailureThreshold() uint32 { | ||
return c.pollFailureThreshold | ||
func (c *MultiNodeConfig) PollFailureThreshold() uint32 { | ||
return *c.MultiNode.PollFailureThreshold | ||
} | ||
|
||
func (c *MultiNode) PollInterval() time.Duration { | ||
return c.pollInterval | ||
func (c *MultiNodeConfig) PollInterval() time.Duration { | ||
return c.MultiNode.PollInterval.Duration() | ||
} | ||
|
||
func (c *MultiNode) SelectionMode() string { | ||
return c.selectionMode | ||
} | ||
func (c *MultiNodeConfig) SelectionMode() string { | ||
return *c.MultiNode.SelectionMode | ||
} | ||
|
||
func (c *MultiNode) SyncThreshold() uint32 { | ||
return c.syncThreshold | ||
func (c *MultiNodeConfig) SyncThreshold() uint32 { | ||
return *c.MultiNode.SyncThreshold | ||
} | ||
|
||
func (c *MultiNode) NodeIsSyncingEnabled() bool { | ||
return c.nodeIsSyncingEnabled | ||
func (c *MultiNodeConfig) NodeIsSyncingEnabled() bool { | ||
return *c.MultiNode.NodeIsSyncingEnabled | ||
} | ||
|
||
func (c *MultiNode) FinalizedBlockPollInterval() time.Duration { | ||
return c.finalizedBlockPollInterval | ||
} | ||
func (c *MultiNodeConfig) LeaseDuration() time.Duration { return c.MultiNode.LeaseDuration.Duration() } | ||
|
||
func (c *MultiNode) EnforceRepeatableRead() bool { | ||
return c.enforceRepeatableRead | ||
func (c *MultiNodeConfig) FinalizedBlockPollInterval() time.Duration { | ||
return c.MultiNode.FinalizedBlockPollInterval.Duration() | ||
} | ||
|
||
func (c *MultiNode) DeathDeclarationDelay() time.Duration { | ||
return c.deathDeclarationDelay | ||
} | ||
func (c *MultiNodeConfig) EnforceRepeatableRead() bool { return *c.MultiNode.EnforceRepeatableRead } | ||
|
||
func (c *MultiNode) NodeNoNewHeadsThreshold() time.Duration { | ||
return c.nodeNoNewHeadsThreshold | ||
func (c *MultiNodeConfig) DeathDeclarationDelay() time.Duration { | ||
return c.MultiNode.DeathDeclarationDelay.Duration() | ||
} | ||
|
||
func (c *MultiNode) NoNewFinalizedHeadsThreshold() time.Duration { | ||
return c.noNewFinalizedHeadsThreshold | ||
func (c *MultiNodeConfig) NodeNoNewHeadsThreshold() time.Duration { | ||
return c.MultiNode.NodeNoNewHeadsThreshold.Duration() | ||
} | ||
|
||
func (c *MultiNode) FinalityDepth() uint32 { | ||
return c.finalityDepth | ||
func (c *MultiNodeConfig) NoNewFinalizedHeadsThreshold() time.Duration { | ||
return c.MultiNode.NoNewFinalizedHeadsThreshold.Duration() | ||
} | ||
|
||
func (c *MultiNode) FinalityTagEnabled() bool { | ||
return c.finalityTagEnabled | ||
} | ||
func (c *MultiNodeConfig) FinalityDepth() uint32 { return *c.MultiNode.FinalityDepth } | ||
|
||
func (c *MultiNode) FinalizedBlockOffset() uint32 { | ||
return c.finalizedBlockOffset | ||
} | ||
func (c *MultiNodeConfig) FinalityTagEnabled() bool { return *c.MultiNode.FinalityTagEnabled } | ||
|
||
func (c *MultiNodeConfig) FinalizedBlockOffset() uint32 { return *c.MultiNode.FinalizedBlockOffset } | ||
|
||
func (c *MultiNodeConfig) SetDefaults() { | ||
// MultiNode is disabled as it's not fully implemented yet: BCFR-122 | ||
if c.MultiNode.Enabled == nil { | ||
c.MultiNode.Enabled = ptr(false) | ||
} | ||
|
||
/* Node Configs */ | ||
// Failure threshold for polling set to 5 to tolerate some polling failures before taking action. | ||
if c.MultiNode.PollFailureThreshold == nil { | ||
c.MultiNode.PollFailureThreshold = ptr(uint32(5)) | ||
} | ||
// Poll interval is set to 10 seconds to ensure timely updates while minimizing resource usage. | ||
if c.MultiNode.PollInterval == nil { | ||
c.MultiNode.PollInterval = config.MustNewDuration(10 * time.Second) | ||
} | ||
// Selection mode defaults to priority level to enable using node priorities | ||
if c.MultiNode.SelectionMode == nil { | ||
c.MultiNode.SelectionMode = ptr(mn.NodeSelectionModePriorityLevel) | ||
} | ||
// The sync threshold is set to 5 to allow for some flexibility in node synchronization before considering it out of sync. | ||
if c.MultiNode.SyncThreshold == nil { | ||
c.MultiNode.SyncThreshold = ptr(uint32(5)) | ||
} | ||
// Lease duration is set to 1 minute by default to allow node locks for a reasonable amount of time. | ||
if c.MultiNode.LeaseDuration == nil { | ||
c.MultiNode.LeaseDuration = config.MustNewDuration(time.Minute) | ||
} | ||
// Node syncing is not relevant for Solana and is disabled by default. | ||
if c.MultiNode.NodeIsSyncingEnabled == nil { | ||
c.MultiNode.NodeIsSyncingEnabled = ptr(false) | ||
} | ||
// The finalized block polling interval is set to 5 seconds to ensure timely updates while minimizing resource usage. | ||
if c.MultiNode.FinalizedBlockPollInterval == nil { | ||
c.MultiNode.FinalizedBlockPollInterval = config.MustNewDuration(5 * time.Second) | ||
} | ||
// Repeatable read guarantee should be enforced by default. | ||
if c.MultiNode.EnforceRepeatableRead == nil { | ||
c.MultiNode.EnforceRepeatableRead = ptr(true) | ||
} | ||
// The delay before declaring a node dead is set to 10 seconds to give nodes time to recover from temporary issues. | ||
if c.MultiNode.DeathDeclarationDelay == nil { | ||
c.MultiNode.DeathDeclarationDelay = config.MustNewDuration(10 * time.Second) | ||
} | ||
|
||
func (c *MultiNode) SetDefaults() { | ||
// TODO: Set defaults for MultiNode config https://smartcontract-it.atlassian.net/browse/BCI-4065 | ||
c.multiNodeEnabled = false | ||
/* Chain Configs */ | ||
// Threshold for no new heads is set to 10 seconds, assuming that heads should update at a reasonable pace. | ||
if c.MultiNode.NodeNoNewHeadsThreshold == nil { | ||
c.MultiNode.NodeNoNewHeadsThreshold = config.MustNewDuration(10 * time.Second) | ||
} | ||
// Similar to heads, finalized heads should be updated within 10 seconds. | ||
if c.MultiNode.NoNewFinalizedHeadsThreshold == nil { | ||
c.MultiNode.NoNewFinalizedHeadsThreshold = config.MustNewDuration(10 * time.Second) | ||
} | ||
// Finality tags are used in Solana and enabled by default. | ||
if c.MultiNode.FinalityTagEnabled == nil { | ||
c.MultiNode.FinalityTagEnabled = ptr(true) | ||
} | ||
// Finality depth will not be used since finality tags are enabled. | ||
if c.MultiNode.FinalityDepth == nil { | ||
c.MultiNode.FinalityDepth = ptr(uint32(0)) | ||
} | ||
// Finalized block offset will not be used since finality tags are enabled. | ||
if c.MultiNode.FinalizedBlockOffset == nil { | ||
c.MultiNode.FinalizedBlockOffset = ptr(uint32(0)) | ||
} | ||
} | ||
|
||
func (c *MultiNodeConfig) SetFrom(f *MultiNodeConfig) { | ||
if f.MultiNode.Enabled != nil { | ||
c.MultiNode.Enabled = f.MultiNode.Enabled | ||
} | ||
|
||
// Node Configs | ||
if f.MultiNode.PollFailureThreshold != nil { | ||
c.MultiNode.PollFailureThreshold = f.MultiNode.PollFailureThreshold | ||
} | ||
if f.MultiNode.PollInterval != nil { | ||
c.MultiNode.PollInterval = f.MultiNode.PollInterval | ||
} | ||
if f.MultiNode.SelectionMode != nil { | ||
c.MultiNode.SelectionMode = f.MultiNode.SelectionMode | ||
} | ||
if f.MultiNode.SyncThreshold != nil { | ||
c.MultiNode.SyncThreshold = f.MultiNode.SyncThreshold | ||
} | ||
if f.MultiNode.NodeIsSyncingEnabled != nil { | ||
c.MultiNode.NodeIsSyncingEnabled = f.MultiNode.NodeIsSyncingEnabled | ||
} | ||
if f.MultiNode.LeaseDuration != nil { | ||
c.MultiNode.LeaseDuration = f.MultiNode.LeaseDuration | ||
} | ||
if f.MultiNode.FinalizedBlockPollInterval != nil { | ||
c.MultiNode.FinalizedBlockPollInterval = f.MultiNode.FinalizedBlockPollInterval | ||
} | ||
if f.MultiNode.EnforceRepeatableRead != nil { | ||
c.MultiNode.EnforceRepeatableRead = f.MultiNode.EnforceRepeatableRead | ||
} | ||
if f.MultiNode.DeathDeclarationDelay != nil { | ||
c.MultiNode.DeathDeclarationDelay = f.MultiNode.DeathDeclarationDelay | ||
} | ||
|
||
// Chain Configs | ||
if f.MultiNode.NodeNoNewHeadsThreshold != nil { | ||
c.MultiNode.NodeNoNewHeadsThreshold = f.MultiNode.NodeNoNewHeadsThreshold | ||
} | ||
if f.MultiNode.NoNewFinalizedHeadsThreshold != nil { | ||
c.MultiNode.NoNewFinalizedHeadsThreshold = f.MultiNode.NoNewFinalizedHeadsThreshold | ||
} | ||
if f.MultiNode.FinalityDepth != nil { | ||
c.MultiNode.FinalityDepth = f.MultiNode.FinalityDepth | ||
} | ||
if f.MultiNode.FinalityTagEnabled != nil { | ||
c.MultiNode.FinalityTagEnabled = f.MultiNode.FinalityTagEnabled | ||
} | ||
if f.MultiNode.FinalizedBlockOffset != nil { | ||
c.MultiNode.FinalizedBlockOffset = f.MultiNode.FinalizedBlockOffset | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters