From eabf3f0aca169df73e93170cf473ad57917f97ac Mon Sep 17 00:00:00 2001 From: Silas Lenihan Date: Mon, 20 Oct 2025 09:11:52 -0400 Subject: [PATCH 1/2] Created SafeTagEnabled for multinode config --- multinode/config/config.go | 6 ++++++ multinode/mocks/config.go | 5 +++++ multinode/node.go | 1 + 3 files changed, 12 insertions(+) diff --git a/multinode/config/config.go b/multinode/config/config.go index 4d7d8ca..5fc2723 100644 --- a/multinode/config/config.go +++ b/multinode/config/config.go @@ -33,6 +33,7 @@ type MultiNode struct { NoNewFinalizedHeadsThreshold *config.Duration FinalityDepth *uint32 FinalityTagEnabled *bool + SafeTagEnabled *bool FinalizedBlockOffset *uint32 } @@ -92,6 +93,8 @@ func (c *MultiNodeConfig) FinalityDepth() uint32 { return *c.MultiNode.FinalityD func (c *MultiNodeConfig) FinalityTagEnabled() bool { return *c.MultiNode.FinalityTagEnabled } +func (c *MultiNodeConfig) SafeTagEnabled() bool { return *c.MultiNode.SafeTagEnabled } + func (c *MultiNodeConfig) FinalizedBlockOffset() uint32 { return *c.MultiNode.FinalizedBlockOffset } func (c *MultiNodeConfig) SetFrom(f *MultiNodeConfig) { @@ -147,6 +150,9 @@ func (c *MultiNodeConfig) SetFrom(f *MultiNodeConfig) { if f.MultiNode.FinalityTagEnabled != nil { c.MultiNode.FinalityTagEnabled = f.MultiNode.FinalityTagEnabled } + if f.MultiNode.SafeTagEnabled != nil { + c.MultiNode.SafeTagEnabled = f.MultiNode.SafeTagEnabled + } if f.MultiNode.FinalizedBlockOffset != nil { c.MultiNode.FinalizedBlockOffset = f.MultiNode.FinalizedBlockOffset } diff --git a/multinode/mocks/config.go b/multinode/mocks/config.go index 95b57cc..7f5b181 100644 --- a/multinode/mocks/config.go +++ b/multinode/mocks/config.go @@ -4,6 +4,7 @@ import "time" type ChainConfig struct { IsFinalityTagEnabled bool + IsSafeTagEnabled bool FinalityDepthVal uint32 NoNewHeadsThresholdVal time.Duration FinalizedBlockOffsetVal uint32 @@ -22,6 +23,10 @@ func (t ChainConfig) FinalityTagEnabled() bool { return t.IsFinalityTagEnabled } +func (t ChainConfig) SafeTagEnabled() bool { + return t.IsSafeTagEnabled +} + func (t ChainConfig) FinalizedBlockOffset() uint32 { return t.FinalizedBlockOffsetVal } diff --git a/multinode/node.go b/multinode/node.go index 6729459..1adb709 100644 --- a/multinode/node.go +++ b/multinode/node.go @@ -34,6 +34,7 @@ type ChainConfig interface { NoNewFinalizedHeadsThreshold() time.Duration FinalityDepth() uint32 FinalityTagEnabled() bool + SafeTagEnabled() bool FinalizedBlockOffset() uint32 } From 98417134056c8fb449b85708cd6ee4c6badfd982 Mon Sep 17 00:00:00 2001 From: Silas Lenihan Date: Mon, 20 Oct 2025 14:03:26 -0400 Subject: [PATCH 2/2] moved safe tag calculation to tracker --- chains/heads/tracker.go | 17 ++++++++++++++--- multinode/config/config.go | 6 ------ multinode/mocks/config.go | 5 ----- multinode/node.go | 1 - 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/chains/heads/tracker.go b/chains/heads/tracker.go index ebe0311..7e9955d 100644 --- a/chains/heads/tracker.go +++ b/chains/heads/tracker.go @@ -51,6 +51,7 @@ type ChainConfig interface { FinalityDepth() uint32 SafeDepth() uint32 FinalityTagEnabled() bool + SafeTagSupported() bool FinalizedBlockOffset() uint32 } @@ -402,9 +403,19 @@ func (t *tracker[HTH, S, ID, BHASH]) backfillLoop(ctx context.Context) { func (t *tracker[HTH, S, ID, BHASH]) LatestSafeBlock(ctx context.Context) (safe HTH, err error) { if t.config.FinalityTagEnabled() { - latestSafe, err2 := t.client.LatestSafeBlock(ctx) - if err2 != nil { - return latestSafe, fmt.Errorf("failed to get latest finalized block: %w", err2) + var latestSafe HTH + if t.config.SafeTagSupported() { + latestSafe, err = t.client.LatestSafeBlock(ctx) + if err != nil { + return latestSafe, fmt.Errorf("failed to get latest finalized block: %w", err) + } + } else { + // return latest finalized block if safe tag is not enabled + _, finalized, err2 := t.LatestAndFinalizedBlock(ctx) + if err2 != nil { + return finalized, fmt.Errorf("failed to get latest finalized block: %w", err2) + } + latestSafe = finalized } if !latestSafe.IsValid() { diff --git a/multinode/config/config.go b/multinode/config/config.go index 5fc2723..4d7d8ca 100644 --- a/multinode/config/config.go +++ b/multinode/config/config.go @@ -33,7 +33,6 @@ type MultiNode struct { NoNewFinalizedHeadsThreshold *config.Duration FinalityDepth *uint32 FinalityTagEnabled *bool - SafeTagEnabled *bool FinalizedBlockOffset *uint32 } @@ -93,8 +92,6 @@ func (c *MultiNodeConfig) FinalityDepth() uint32 { return *c.MultiNode.FinalityD func (c *MultiNodeConfig) FinalityTagEnabled() bool { return *c.MultiNode.FinalityTagEnabled } -func (c *MultiNodeConfig) SafeTagEnabled() bool { return *c.MultiNode.SafeTagEnabled } - func (c *MultiNodeConfig) FinalizedBlockOffset() uint32 { return *c.MultiNode.FinalizedBlockOffset } func (c *MultiNodeConfig) SetFrom(f *MultiNodeConfig) { @@ -150,9 +147,6 @@ func (c *MultiNodeConfig) SetFrom(f *MultiNodeConfig) { if f.MultiNode.FinalityTagEnabled != nil { c.MultiNode.FinalityTagEnabled = f.MultiNode.FinalityTagEnabled } - if f.MultiNode.SafeTagEnabled != nil { - c.MultiNode.SafeTagEnabled = f.MultiNode.SafeTagEnabled - } if f.MultiNode.FinalizedBlockOffset != nil { c.MultiNode.FinalizedBlockOffset = f.MultiNode.FinalizedBlockOffset } diff --git a/multinode/mocks/config.go b/multinode/mocks/config.go index 7f5b181..95b57cc 100644 --- a/multinode/mocks/config.go +++ b/multinode/mocks/config.go @@ -4,7 +4,6 @@ import "time" type ChainConfig struct { IsFinalityTagEnabled bool - IsSafeTagEnabled bool FinalityDepthVal uint32 NoNewHeadsThresholdVal time.Duration FinalizedBlockOffsetVal uint32 @@ -23,10 +22,6 @@ func (t ChainConfig) FinalityTagEnabled() bool { return t.IsFinalityTagEnabled } -func (t ChainConfig) SafeTagEnabled() bool { - return t.IsSafeTagEnabled -} - func (t ChainConfig) FinalizedBlockOffset() uint32 { return t.FinalizedBlockOffsetVal } diff --git a/multinode/node.go b/multinode/node.go index 1adb709..6729459 100644 --- a/multinode/node.go +++ b/multinode/node.go @@ -34,7 +34,6 @@ type ChainConfig interface { NoNewFinalizedHeadsThreshold() time.Duration FinalityDepth() uint32 FinalityTagEnabled() bool - SafeTagEnabled() bool FinalizedBlockOffset() uint32 }