Skip to content

feat: exposed era in chainsync input #373

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 4, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions input/chainsync/chainsync.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ type ChainSyncStatus struct {
TipSlotNumber uint64
TipBlockHash string
TipReached bool
Era string
}

type StatusUpdateFunc func(ChainSyncStatus)
Expand Down Expand Up @@ -420,6 +421,9 @@ func (c *ChainSync) updateStatus(
tipSlotNumber uint64,
tipBlockHash string,
) {
// Determine the era based on slot number
era := c.getEra(slotNumber)

// Update cursor cache
blockHashBytes, _ := hex.DecodeString(blockHash)
c.cursorCache = append(
Expand All @@ -444,6 +448,7 @@ func (c *ChainSync) updateStatus(
c.status.BlockHash = blockHash
c.status.TipSlotNumber = tipSlotNumber
c.status.TipBlockHash = tipBlockHash
c.status.Era = era
if c.statusUpdateFunc != nil {
c.statusUpdateFunc(*(c.status))
}
Expand Down Expand Up @@ -544,3 +549,22 @@ func resolveTransactionInputs(
}
return resolvedInputs, nil
}

func (c *ChainSync) getEra(slotNumber uint64) string {
switch {
case slotNumber < 4492800: // example boundary
return "Byron"
case slotNumber < 15984000:
return "Shelley"
case slotNumber < 34560000:
return "Allegra"
case slotNumber < 38880000:
return "Mary"
case slotNumber < 43200000:
return "Alonzo"
case slotNumber < 50400000:
return "Babbage"
default:
return "Conway" // future era
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These values are only valid for one particular network (presumably mainnet). We should either make sure they are only consulted for that one network, or that we provide values for additional well-known networks (such as preview and preprod)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have made the changes to use the Era name from block, could you please review.

76 changes: 76 additions & 0 deletions input/chainsync/chainsync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,79 @@ func TestHandleRollBackward(t *testing.T) {
assert.Equal(t, uint64(67890), c.status.TipSlotNumber)
assert.Equal(t, "060708090a", c.status.TipBlockHash)
}

func TestUpdateStatusWithEra(t *testing.T) {
chainSync := &ChainSync{
status: &ChainSyncStatus{},
}

testCases := []struct {
slotNumber uint64
expectedEra string
expectedTip bool
}{
{0, "Byron", false}, // lower boundary case
{4492799, "Byron", false}, // edge of Byron
{4492800, "Shelley", false}, // start of Shelley
{15983999, "Shelley", false}, // edge of Shelley
{15984000, "Allegra", false}, // start of Allegra
{34559999, "Allegra", false}, // edge of Allegra
{34560000, "Mary", false}, // start of Mary
{38879999, "Mary", false}, // edge of Mary
{38880000, "Alonzo", false}, // start of Alonzo
{43199999, "Alonzo", false}, // edge of Alonzo
{43200000, "Babbage", false}, // start of Babbage
{50399999, "Babbage", false}, // edge of Babbage
{50400000, "Conway", false}, // start of Conway
{99999999, "Conway", false}, // future slot case
}

for _, tc := range testCases {
blockHash := "abcdef1234567890"
blockHashBytes, _ := hex.DecodeString(blockHash)

chainSync.updateStatus(tc.slotNumber, 100, blockHash, 60000000, "hash")
assert.Equal(t, tc.expectedEra, chainSync.status.Era, "Unexpected era for slot %d", tc.slotNumber)
assert.Equal(t, tc.slotNumber, chainSync.status.SlotNumber)
assert.Equal(t, blockHash, chainSync.status.BlockHash)
assert.Contains(t, chainSync.cursorCache, ocommon.Point{Slot: tc.slotNumber, Hash: blockHashBytes})
}

// Additional edge case: Testing tipReached logic
chainSync.bulkRangeEnd.Slot = 50000000 // example bulk range end
chainSync.updateStatus(60000001, 101, "abcd1234", 60000001, "hash")
assert.True(t, chainSync.status.TipReached, "TipReached should be true when slotNumber >= tipSlotNumber")
}

func TestGetEra(t *testing.T) {
c := &ChainSync{}

tests := []struct {
slotNumber uint64
expected string
}{
{0, "Byron"}, // start of Byron
{4492799, "Byron"}, // end of Byron
{4492800, "Shelley"}, // start of Shelley
{15983999, "Shelley"}, // end of Shelley
{15984000, "Allegra"}, // start of Allegra
{34559999, "Allegra"}, // end of Allegra
{34560000, "Mary"}, // start of Mary
{38879999, "Mary"}, // end of Mary
{38880000, "Alonzo"}, // start of Alonzo
{43199999, "Alonzo"}, // end of Alonzo
{43200000, "Babbage"}, // start of Babbage
{50399999, "Babbage"}, // end of Babbage
{50400000, "Conway"}, // start of Conway
{9999999999, "Conway"}, // far future but still Conway
}

for _, tt := range tests {
t.Run(tt.expected, func(t *testing.T) {
result := c.getEra(tt.slotNumber)
if result != tt.expected {
t.Errorf("getEra(%d) = %s; want %s", tt.slotNumber, result, tt.expected)
}
})
}
}