Skip to content

Commit 4486d29

Browse files
committed
refactor: use ledger block on verify block
Signed-off-by: Chris Gianelloni <wolf31o2@blinklabs.io>
1 parent 84c0c51 commit 4486d29

File tree

19 files changed

+916
-341
lines changed

19 files changed

+916
-341
lines changed

cbor/encode.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"bytes"
1919
"errors"
2020
"reflect"
21+
"sort"
2122
"sync"
2223

2324
_cbor "github.com/fxamacker/cbor/v2"
@@ -132,3 +133,54 @@ func (i IndefLengthByteString) MarshalCBOR() ([]byte, error) {
132133
)
133134
return ret, nil
134135
}
136+
137+
type IndefLengthMap map[any]any
138+
139+
func (i IndefLengthMap) MarshalCBOR() ([]byte, error) {
140+
ret := []byte{
141+
// Start indefinite-length map
142+
0xbf,
143+
}
144+
145+
// Collect keys and sort them by their CBOR encoding for deterministic output
146+
type keyValue struct {
147+
key any
148+
keyCbor []byte
149+
value any
150+
}
151+
152+
kvPairs := make([]keyValue, 0, len(i))
153+
for key, value := range i {
154+
keyData, err := Encode(key)
155+
if err != nil {
156+
return nil, err
157+
}
158+
kvPairs = append(kvPairs, keyValue{
159+
key: key,
160+
keyCbor: keyData,
161+
value: value,
162+
})
163+
}
164+
165+
// Sort by CBOR-encoded key for deterministic ordering
166+
sort.Slice(kvPairs, func(a, b int) bool {
167+
return bytes.Compare(kvPairs[a].keyCbor, kvPairs[b].keyCbor) < 0
168+
})
169+
170+
// Encode in sorted order
171+
for _, kv := range kvPairs {
172+
ret = append(ret, kv.keyCbor...)
173+
valueData, err := Encode(kv.value)
174+
if err != nil {
175+
return nil, err
176+
}
177+
ret = append(ret, valueData...)
178+
}
179+
180+
ret = append(
181+
ret,
182+
// End indefinite length map
183+
byte(0xff),
184+
)
185+
return ret, nil
186+
}

connection_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import (
2020
"time"
2121

2222
ouroboros "github.com/blinklabs-io/gouroboros"
23-
"github.com/blinklabs-io/ouroboros-mock"
23+
ouroboros_mock "github.com/blinklabs-io/ouroboros-mock"
2424
"go.uber.org/goleak"
2525
)
2626

ledger/allegra/allegra.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ func (b *AllegraBlock) Utxorpc() (*utxorpc.Block, error) {
136136
return block, nil
137137
}
138138

139+
func (b *AllegraBlock) BlockBodyHash() common.Blake2b256 {
140+
return b.Header().BlockBodyHash()
141+
}
142+
139143
type AllegraBlockHeader struct {
140144
shelley.ShelleyBlockHeader
141145
}

ledger/alonzo/alonzo.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,10 @@ func (b *AlonzoBlock) Utxorpc() (*utxorpc.Block, error) {
189189
return block, nil
190190
}
191191

192+
func (b *AlonzoBlock) BlockBodyHash() common.Blake2b256 {
193+
return b.Header().BlockBodyHash()
194+
}
195+
192196
type AlonzoBlockHeader struct {
193197
shelley.ShelleyBlockHeader
194198
}

ledger/babbage/babbage.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,10 @@ func (b *BabbageBlock) Utxorpc() (*utxorpc.Block, error) {
149149
return block, nil
150150
}
151151

152+
func (b *BabbageBlock) BlockBodyHash() common.Blake2b256 {
153+
return b.Header().BlockBodyHash()
154+
}
155+
152156
type BabbageBlockHeader struct {
153157
cbor.StructAsArray
154158
cbor.DecodeStoreCbor
@@ -228,6 +232,10 @@ func (h *BabbageBlockHeader) Era() common.Era {
228232
return EraBabbage
229233
}
230234

235+
func (h *BabbageBlockHeader) BlockBodyHash() common.Blake2b256 {
236+
return h.Body.BlockBodyHash
237+
}
238+
231239
type BabbageTransactionPparamUpdate struct {
232240
cbor.StructAsArray
233241
ProtocolParamUpdates map[common.Blake2b224]BabbageProtocolParameterUpdate

ledger/byron/byron.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,17 @@ func (h *ByronMainBlockHeader) Era() common.Era {
136136
return EraByron
137137
}
138138

139+
func (h *ByronMainBlockHeader) BlockBodyHash() common.Blake2b256 {
140+
// BodyProof is guaranteed to be common.Blake2b256 for valid Byron blocks
141+
// as per the Cardano Byron era specification
142+
if bodyProof, ok := h.BodyProof.(common.Blake2b256); ok {
143+
return bodyProof
144+
}
145+
panic(
146+
"invariant violation: ByronMainBlockHeader.BodyProof is not common.Blake2b256",
147+
)
148+
}
149+
139150
type ByronTransaction struct {
140151
cbor.StructAsArray
141152
cbor.DecodeStoreCbor
@@ -731,6 +742,17 @@ func (h *ByronEpochBoundaryBlockHeader) Era() common.Era {
731742
return EraByron
732743
}
733744

745+
func (h *ByronEpochBoundaryBlockHeader) BlockBodyHash() common.Blake2b256 {
746+
// BodyProof is guaranteed to be common.Blake2b256 for valid Byron blocks
747+
// as per the Cardano Byron era specification
748+
if bodyProof, ok := h.BodyProof.(common.Blake2b256); ok {
749+
return bodyProof
750+
}
751+
panic(
752+
"invariant violation: ByronEpochBoundaryBlockHeader.BodyProof is not common.Blake2b256",
753+
)
754+
}
755+
734756
type ByronMainBlock struct {
735757
cbor.StructAsArray
736758
cbor.DecodeStoreCbor
@@ -798,6 +820,10 @@ func (b *ByronMainBlock) Utxorpc() (*utxorpc.Block, error) {
798820
return &utxorpc.Block{}, nil
799821
}
800822

823+
func (b *ByronMainBlock) BlockBodyHash() common.Blake2b256 {
824+
return b.Header().BlockBodyHash()
825+
}
826+
801827
type ByronEpochBoundaryBlock struct {
802828
cbor.StructAsArray
803829
cbor.DecodeStoreCbor
@@ -863,6 +889,10 @@ func (b *ByronEpochBoundaryBlock) Utxorpc() (*utxorpc.Block, error) {
863889
return &utxorpc.Block{}, nil
864890
}
865891

892+
func (b *ByronEpochBoundaryBlock) BlockBodyHash() common.Blake2b256 {
893+
return b.Header().BlockBodyHash()
894+
}
895+
866896
func NewByronEpochBoundaryBlockFromCbor(
867897
data []byte,
868898
) (*ByronEpochBoundaryBlock, error) {

ledger/common/block.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ type BlockHeader interface {
1919
BlockBodySize() uint64
2020
Era() Era
2121
Cbor() []byte
22+
BlockBodyHash() Blake2b256
2223
}

ledger/common/rewards.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,10 @@ func calculatePoolShare(
394394
stakeRatio := float64(poolStake) / float64(snapshot.TotalActiveStake)
395395

396396
// Calculate saturation (capped at 1.0)
397-
saturation := math.Min(stakeRatio/0.05, 1.0) // TODO: consider wiring a param or helper for consistency with CalculatePoolSaturation
397+
saturation := math.Min(
398+
stakeRatio/0.05,
399+
1.0,
400+
) // TODO: consider wiring a param or helper for consistency with CalculatePoolSaturation
398401

399402
// Calculate pool reward share using leader stake influence formula
400403
// R_pool = (stake_ratio * performance * (1 - margin)) / (1 + a0 * saturation)

ledger/conway/conway.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,10 @@ func (b *ConwayBlock) Utxorpc() (*utxorpc.Block, error) {
149149
return block, nil
150150
}
151151

152+
func (b *ConwayBlock) BlockBodyHash() common.Blake2b256 {
153+
return b.Header().BlockBodyHash()
154+
}
155+
152156
type ConwayBlockHeader struct {
153157
babbage.BabbageBlockHeader
154158
}

ledger/leios/leios.go

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,27 @@ type LeiosBlockHeaderBody struct {
6060
CertifiedEb *bool
6161
}
6262

63+
type LeiosEndorserBlockBody struct {
64+
cbor.StructAsArray
65+
Transactions []common.Transaction
66+
TxReferences map[common.Blake2b256]uint16
67+
}
68+
69+
func (b *LeiosEndorserBlockBody) BlockBodyHash() common.Blake2b256 {
70+
// Compute hash of the block body content
71+
bodyCbor, err := cbor.Encode(b)
72+
if err != nil {
73+
// Return zero hash on encoding error
74+
return common.Blake2b256{}
75+
}
76+
return common.Blake2b256Hash(bodyCbor)
77+
}
78+
6379
type LeiosEndorserBlock struct {
6480
cbor.DecodeStoreCbor
6581
cbor.StructAsArray
66-
hash *common.Blake2b256
67-
transactions []common.Transaction
68-
TxReferences map[common.Blake2b256]uint16
82+
hash *common.Blake2b256
83+
Body *LeiosEndorserBlockBody
6984
}
7085

7186
func (h *LeiosBlockHeader) UnmarshalCBOR(cborData []byte) error {
@@ -111,6 +126,10 @@ func (h *LeiosBlockHeader) Era() common.Era {
111126
return EraLeios
112127
}
113128

129+
func (h *LeiosBlockHeader) BlockBodyHash() common.Blake2b256 {
130+
return h.Body.BlockBodyHash
131+
}
132+
114133
func (LeiosEndorserBlock) Type() int {
115134
return BlockTypeLeiosEndorser
116135
}
@@ -154,14 +173,24 @@ func (b *LeiosEndorserBlock) PrevHash() common.Blake2b256 {
154173
}
155174

156175
func (b *LeiosEndorserBlock) Transactions() []common.Transaction {
157-
return b.transactions
176+
if b.Body == nil {
177+
return nil
178+
}
179+
return b.Body.Transactions
158180
}
159181

160182
func (b *LeiosEndorserBlock) Utxorpc() (*utxorpc.Block, error) {
161183
// TODO: figure out how this fits into UTxO RPC
162184
return &utxorpc.Block{}, nil
163185
}
164186

187+
func (b *LeiosEndorserBlock) BlockBodyHash() common.Blake2b256 {
188+
if b.Body == nil {
189+
return common.Blake2b256{}
190+
}
191+
return b.Body.BlockBodyHash()
192+
}
193+
165194
type LeiosRankingBlock struct {
166195
conway.ConwayBlock
167196
BlockHeader *LeiosBlockHeader `cbor:"0,keyasint"`
@@ -248,6 +277,10 @@ func (b *LeiosRankingBlock) Utxorpc() (*utxorpc.Block, error) {
248277
return block, nil
249278
}
250279

280+
func (b *LeiosRankingBlock) BlockBodyHash() common.Blake2b256 {
281+
return b.Header().BlockBodyHash()
282+
}
283+
251284
func NewLeiosEndorserBlockFromCbor(data []byte) (*LeiosEndorserBlock, error) {
252285
var leiosEndorserBlock LeiosEndorserBlock
253286
if _, err := cbor.Decode(data, &leiosEndorserBlock); err != nil {

0 commit comments

Comments
 (0)