Skip to content

Commit e2d9edb

Browse files
committed
refactor(ledger): put error at end of return
Signed-off-by: Chris Gianelloni <wolf31o2@blinklabs.io>
1 parent 8312b54 commit e2d9edb

File tree

2 files changed

+68
-29
lines changed

2 files changed

+68
-29
lines changed

ledger/verify_block.go

Lines changed: 67 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import (
2828
)
2929

3030
//nolint:staticcheck
31-
func VerifyBlock(block BlockHexCbor) (error, bool, string, uint64, uint64) {
31+
func VerifyBlock(block BlockHexCbor) (bool, string, uint64, uint64, error) {
3232
headerCborHex := block.HeaderCbor
3333
epochNonceHex := block.Eta0
3434
bodyHex := block.BlockBodyCbor
@@ -37,70 +37,109 @@ func VerifyBlock(block BlockHexCbor) (error, bool, string, uint64, uint64) {
3737
isValid := false
3838
vrfHex := ""
3939

40-
// check is KES valid
40+
// Check if this is a Leios block, which is not supported for verification
41+
if block.Flag < 0 {
42+
return false, "", 0, 0, fmt.Errorf(
43+
"VerifyBlock: invalid block flag %d, must be non-negative",
44+
block.Flag,
45+
)
46+
}
47+
blockType := uint(block.Flag) // #nosec G115
48+
if blockType == BlockTypeLeiosRanking ||
49+
blockType == BlockTypeLeiosEndorser {
50+
return false, "", 0, 0, errors.New(
51+
"VerifyBlock: Leios blocks are not supported for verification",
52+
)
53+
}
54+
55+
// For backward compatibility, try to decode as Babbage header first
56+
// This allows the function to work with different eras that have compatible structures
4157
headerCborByte, headerDecodeError := hex.DecodeString(headerCborHex)
4258
if headerDecodeError != nil {
43-
return fmt.Errorf(
59+
return false, "", 0, 0, fmt.Errorf(
4460
"VerifyBlock: headerCborByte decode error, %v",
4561
headerDecodeError.Error(),
46-
), false, "", 0, 0
62+
)
4763
}
48-
header, headerUnmarshalError := NewBabbageBlockHeaderFromCbor(
49-
headerCborByte,
50-
)
64+
var header BlockHeader
65+
var headerUnmarshalError error
66+
header, headerUnmarshalError = NewBabbageBlockHeaderFromCbor(headerCborByte)
5167
if headerUnmarshalError != nil {
52-
return fmt.Errorf(
53-
"VerifyBlock: header unmarshal error, %v",
54-
headerUnmarshalError.Error(),
55-
), false, "", 0, 0
68+
// If Babbage decoding fails, try the era-specific decoder
69+
header, headerUnmarshalError = NewBlockHeaderFromCbor(
70+
blockType,
71+
headerCborByte,
72+
)
73+
if headerUnmarshalError != nil {
74+
return false, "", 0, 0, fmt.Errorf(
75+
"VerifyBlock: header unmarshal error, %v",
76+
headerUnmarshalError.Error(),
77+
)
78+
}
5679
}
5780
if header == nil {
58-
return errors.New("VerifyBlock: header returned empty"), false, "", 0, 0
81+
return false, "", 0, 0, errors.New("VerifyBlock: header returned empty")
5982
}
60-
isKesValid, errKes := VerifyKes(header, slotPerKesPeriod)
83+
84+
// For verification, we need to work with Babbage-compatible headers
85+
// Try to cast to BabbageBlockHeader
86+
babbageHeader, ok := header.(*BabbageBlockHeader)
87+
if !ok {
88+
// If it's not a Babbage header, check if it's Conway (which embeds Babbage)
89+
if conwayHeader, ok := header.(*ConwayBlockHeader); ok {
90+
babbageHeader = &conwayHeader.BabbageBlockHeader
91+
} else {
92+
return false, "", 0, 0, fmt.Errorf("VerifyBlock: block verification only supported for Babbage-compatible headers, got type: %T", header)
93+
}
94+
}
95+
96+
isKesValid, errKes := VerifyKes(babbageHeader, slotPerKesPeriod)
6197
if errKes != nil {
62-
return fmt.Errorf(
98+
return false, "", 0, 0, fmt.Errorf(
6399
"VerifyBlock: KES invalid, %v",
64100
errKes.Error(),
65-
), false, "", 0, 0
101+
)
66102
}
67103

68104
// check is VRF valid
69105
// Ref: https://github.com/IntersectMBO/ouroboros-consensus/blob/de74882102236fdc4dd25aaa2552e8b3e208448c/ouroboros-consensus-protocol/src/ouroboros-consensus-protocol/Ouroboros/Consensus/Protocol/Praos.hs#L541
70106
epochNonceByte, epochNonceDecodeError := hex.DecodeString(epochNonceHex)
71107
if epochNonceDecodeError != nil {
72-
return fmt.Errorf(
108+
return false, "", 0, 0, fmt.Errorf(
73109
"VerifyBlock: epochNonceByte decode error, %v",
74110
epochNonceDecodeError.Error(),
75-
), false, "", 0, 0
111+
)
76112
}
77-
vrfBytes := header.Body.VrfKey[:]
78-
vrfResult := header.Body.VrfResult
79-
seed := MkInputVrf(int64(header.Body.Slot), epochNonceByte) // #nosec G115
113+
vrfBytes := babbageHeader.Body.VrfKey[:]
114+
vrfResult := babbageHeader.Body.VrfResult
115+
seed := MkInputVrf(
116+
int64(babbageHeader.Body.Slot),
117+
epochNonceByte,
118+
) // #nosec G115
80119
output, errVrf := VrfVerifyAndHash(vrfBytes, vrfResult.Proof, seed)
81120
if errVrf != nil {
82-
return fmt.Errorf(
121+
return false, "", 0, 0, fmt.Errorf(
83122
"VerifyBlock: vrf invalid, %v",
84123
errVrf.Error(),
85-
), false, "", 0, 0
124+
)
86125
}
87126
isVrfValid := bytes.Equal(output, vrfResult.Output)
88127

89128
// check if block data valid
90-
blockBodyHash := header.Body.BlockBodyHash
129+
blockBodyHash := babbageHeader.Body.BlockBodyHash
91130
blockBodyHashHex := hex.EncodeToString(blockBodyHash[:])
92131
isBodyValid, isBodyValidError := VerifyBlockBody(bodyHex, blockBodyHashHex)
93132
if isBodyValidError != nil {
94-
return fmt.Errorf(
133+
return false, "", 0, 0, fmt.Errorf(
95134
"VerifyBlock: VerifyBlockBody error, %v",
96135
isBodyValidError.Error(),
97-
), false, "", 0, 0
136+
)
98137
}
99138
isValid = isKesValid && isVrfValid && isBodyValid
100139
vrfHex = hex.EncodeToString(vrfBytes)
101-
blockNo := header.Body.BlockNumber
102-
slotNo := header.Body.Slot
103-
return nil, isValid, vrfHex, blockNo, slotNo
140+
blockNo := babbageHeader.Body.BlockNumber
141+
slotNo := babbageHeader.Body.Slot
142+
return isValid, vrfHex, blockNo, slotNo, nil
104143
}
105144

106145
func ExtractBlockData(

ledger/verify_block_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func TestVerifyBlockBody(t *testing.T) {
5050

5151
for _, tc := range testCases {
5252
t.Run(tc.name, func(t *testing.T) {
53-
err, isValid, _, _, _ := VerifyBlock(tc.blockHexCbor)
53+
isValid, _, _, _, err := VerifyBlock(tc.blockHexCbor)
5454
if tc.expectedValid != isValid {
5555
t.Errorf("unexpected error: %v", err)
5656
}

0 commit comments

Comments
 (0)