Skip to content

Commit 7e1af56

Browse files
authored
feat: exposed era in chainsync input (#373)
* feat: exposed era in chainsync input Signed-off-by: Jenita <[email protected]>
1 parent e5d77a1 commit 7e1af56

File tree

2 files changed

+256
-0
lines changed

2 files changed

+256
-0
lines changed

input/chainsync/block.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type BlockContext struct {
2222
BlockNumber uint64 `json:"blockNumber"`
2323
SlotNumber uint64 `json:"slotNumber"`
2424
NetworkMagic uint32 `json:"networkMagic"`
25+
Era string `json:"era"`
2526
}
2627

2728
type BlockEvent struct {
@@ -38,6 +39,7 @@ func NewBlockContext(block ledger.Block, networkMagic uint32) BlockContext {
3839
BlockNumber: block.BlockNumber(),
3940
SlotNumber: block.SlotNumber(),
4041
NetworkMagic: networkMagic,
42+
Era: block.Era().Name,
4143
}
4244
return ctx
4345
}
@@ -46,6 +48,7 @@ func NewBlockHeaderContext(block ledger.BlockHeader) BlockContext {
4648
ctx := BlockContext{
4749
BlockNumber: block.BlockNumber(),
4850
SlotNumber: block.SlotNumber(),
51+
Era: block.Era().Name,
4952
}
5053
return ctx
5154
}

input/chainsync/block_test.go

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
package chainsync
2+
3+
import (
4+
"testing"
5+
6+
"github.com/blinklabs-io/gouroboros/ledger/common"
7+
"github.com/stretchr/testify/assert"
8+
utxorpc "github.com/utxorpc/go-codegen/utxorpc/v1alpha/cardano"
9+
)
10+
11+
// MockIssuerVkey to implement IssuerVkey interface
12+
type MockIssuerVkey struct{}
13+
14+
func (m MockIssuerVkey) Bytes() []byte {
15+
return []byte{0x01, 0x02, 0x03}
16+
}
17+
18+
func (m MockIssuerVkey) Hash() []byte {
19+
return []byte{0x04, 0x05, 0x06}
20+
}
21+
22+
// MockBlockHeader implements BlockHeader interface
23+
type MockBlockHeader struct {
24+
hash string
25+
prevHash string
26+
blockNumber uint64
27+
slotNumber uint64
28+
issuerVkey common.IssuerVkey
29+
blockBodySize uint64
30+
era common.Era
31+
cborBytes []byte
32+
}
33+
34+
func (m MockBlockHeader) Hash() string {
35+
return m.hash
36+
}
37+
38+
func (m MockBlockHeader) PrevHash() string {
39+
return m.prevHash
40+
}
41+
42+
func (m MockBlockHeader) BlockNumber() uint64 {
43+
return m.blockNumber
44+
}
45+
46+
func (m MockBlockHeader) SlotNumber() uint64 {
47+
return m.slotNumber
48+
}
49+
50+
func (m MockBlockHeader) IssuerVkey() common.IssuerVkey {
51+
return m.issuerVkey
52+
}
53+
54+
func (m MockBlockHeader) BlockBodySize() uint64 {
55+
return m.blockBodySize
56+
}
57+
58+
func (m MockBlockHeader) Era() common.Era {
59+
return m.era
60+
}
61+
62+
func (m MockBlockHeader) Cbor() []byte {
63+
return m.cborBytes
64+
}
65+
66+
// MockBlock implements Block interface
67+
type MockBlock struct {
68+
MockBlockHeader
69+
transactions []common.Transaction
70+
}
71+
72+
func (m MockBlock) Header() common.BlockHeader {
73+
return m.MockBlockHeader
74+
}
75+
76+
func (m MockBlock) Type() int {
77+
return 0
78+
}
79+
80+
func (m MockBlock) Transactions() []common.Transaction {
81+
return m.transactions
82+
}
83+
84+
func (m MockBlock) Utxorpc() *utxorpc.Block {
85+
return nil
86+
}
87+
88+
func (m MockBlock) IsShelley() bool {
89+
return m.era.Name == "Shelley"
90+
}
91+
92+
func (m MockBlock) IsAllegra() bool {
93+
return m.era.Name == "Allegra"
94+
}
95+
96+
func (m MockBlock) IsMary() bool {
97+
return m.era.Name == "Mary"
98+
}
99+
100+
func (m MockBlock) IsAlonzo() bool {
101+
return m.era.Name == "Alonzo"
102+
}
103+
104+
func (m MockBlock) IsBabbage() bool {
105+
return m.era.Name == "Babbage"
106+
}
107+
108+
func (m MockBlock) IsConway() bool {
109+
return m.era.Name == "Conway"
110+
}
111+
112+
func TestNewBlockContext(t *testing.T) {
113+
testCases := []struct {
114+
name string
115+
block MockBlock
116+
networkMagic uint32
117+
expectedEra string
118+
expectedBlock uint64
119+
expectedSlot uint64
120+
}{
121+
{
122+
name: "Shelley Era Block",
123+
block: MockBlock{
124+
MockBlockHeader: MockBlockHeader{
125+
blockNumber: 1000,
126+
slotNumber: 5000,
127+
era: common.Era{
128+
Name: "Shelley",
129+
},
130+
hash: "sample-hash-shelley",
131+
prevHash: "prev-hash-shelley",
132+
blockBodySize: 1024,
133+
cborBytes: []byte{0x01, 0x02, 0x03},
134+
},
135+
transactions: nil,
136+
},
137+
networkMagic: 764824073,
138+
expectedEra: "Shelley",
139+
expectedBlock: 1000,
140+
expectedSlot: 5000,
141+
},
142+
{
143+
name: "Allegra Era Block",
144+
block: MockBlock{
145+
MockBlockHeader: MockBlockHeader{
146+
blockNumber: 2500,
147+
slotNumber: 10000,
148+
era: common.Era{
149+
Name: "Allegra",
150+
},
151+
hash: "another-hash-allegra",
152+
prevHash: "prev-hash-allegra",
153+
blockBodySize: 2048,
154+
cborBytes: []byte{0x04, 0x05, 0x06},
155+
},
156+
transactions: nil,
157+
},
158+
networkMagic: 1097911063,
159+
expectedEra: "Allegra",
160+
expectedBlock: 2500,
161+
expectedSlot: 10000,
162+
},
163+
{
164+
name: "Mary Era Block",
165+
block: MockBlock{
166+
MockBlockHeader: MockBlockHeader{
167+
blockNumber: 5000,
168+
slotNumber: 25000,
169+
era: common.Era{
170+
Name: "Mary",
171+
},
172+
hash: "mary-block-hash",
173+
prevHash: "prev-hash-mary",
174+
blockBodySize: 4096,
175+
cborBytes: []byte{0x07, 0x08, 0x09},
176+
},
177+
transactions: nil,
178+
},
179+
networkMagic: 0,
180+
expectedEra: "Mary",
181+
expectedBlock: 5000,
182+
expectedSlot: 25000,
183+
},
184+
}
185+
186+
for _, tc := range testCases {
187+
t.Run(tc.name, func(t *testing.T) {
188+
blockContext := NewBlockContext(tc.block, tc.networkMagic)
189+
assert.Equal(t, tc.expectedEra, blockContext.Era, "Era should match")
190+
assert.Equal(t, tc.expectedBlock, blockContext.BlockNumber, "Block number should match")
191+
assert.Equal(t, tc.expectedSlot, blockContext.SlotNumber, "Slot number should match")
192+
assert.Equal(t, tc.networkMagic, blockContext.NetworkMagic, "Network magic should match")
193+
})
194+
}
195+
}
196+
197+
func TestNewBlockContextEdgeCases(t *testing.T) {
198+
testCases := []struct {
199+
name string
200+
block MockBlock
201+
networkMagic uint32
202+
expectedEra string
203+
}{
204+
{
205+
name: "Zero Values",
206+
block: MockBlock{
207+
MockBlockHeader: MockBlockHeader{
208+
blockNumber: 0,
209+
slotNumber: 0,
210+
era: common.Era{
211+
Name: "",
212+
},
213+
hash: "",
214+
prevHash: "",
215+
blockBodySize: 0,
216+
cborBytes: []byte{},
217+
},
218+
transactions: nil,
219+
},
220+
networkMagic: 0,
221+
expectedEra: "",
222+
},
223+
{
224+
name: "Very Large Numbers",
225+
block: MockBlock{
226+
MockBlockHeader: MockBlockHeader{
227+
blockNumber: ^uint64(0), // Max uint64 value
228+
slotNumber: ^uint64(0),
229+
era: common.Era{
230+
Name: "Alonzo",
231+
},
232+
hash: "max-block-hash",
233+
prevHash: "max-prev-hash",
234+
blockBodySize: ^uint64(0),
235+
cborBytes: []byte{0x0A, 0x0B, 0x0C},
236+
},
237+
transactions: nil,
238+
},
239+
networkMagic: ^uint32(0), // Max uint32 value
240+
expectedEra: "Alonzo",
241+
},
242+
}
243+
244+
for _, tc := range testCases {
245+
t.Run(tc.name, func(t *testing.T) {
246+
blockContext := NewBlockContext(tc.block, tc.networkMagic)
247+
assert.Equal(t, tc.expectedEra, blockContext.Era, "Era should match")
248+
assert.Equal(t, tc.block.BlockNumber(), blockContext.BlockNumber, "Block number should match")
249+
assert.Equal(t, tc.block.SlotNumber(), blockContext.SlotNumber, "Slot number should match")
250+
assert.Equal(t, tc.networkMagic, blockContext.NetworkMagic, "Network magic should match")
251+
})
252+
}
253+
}

0 commit comments

Comments
 (0)