Skip to content

Commit 7f527d2

Browse files
authored
Add unmarshal to types (#528)
* Add unmarshal to types
1 parent 4b95cda commit 7f527d2

File tree

12 files changed

+433
-55
lines changed

12 files changed

+433
-55
lines changed

internal/block/assurance.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package block
22

33
import (
4+
"io"
5+
46
"github.com/eigerco/strawberry/internal/constants"
57
"github.com/eigerco/strawberry/internal/crypto"
8+
"github.com/eigerco/strawberry/pkg/serialization/codec/jam"
69
)
710

811
const AvailBitfieldBytes = (constants.TotalNumberOfCores + 7) / 8 // (cores-count + 7) / 8
@@ -23,6 +26,23 @@ type Assurance struct {
2326
Signature crypto.Ed25519Signature // Ed25519 signature (s ∈ V̄)
2427
}
2528

29+
// UnmarshalJAM implements the JAM codec Unmarshaler interface.
30+
func (a *Assurance) UnmarshalJAM(r io.Reader) error {
31+
if _, err := io.ReadFull(r, a.Anchor[:]); err != nil {
32+
return err
33+
}
34+
if _, err := io.ReadFull(r, a.Bitfield[:]); err != nil {
35+
return err
36+
}
37+
buf := make([]byte, 2)
38+
if _, err := io.ReadFull(r, buf); err != nil {
39+
return err
40+
}
41+
a.ValidatorIndex = jam.DecodeUint16(buf)
42+
_, err := io.ReadFull(r, a.Signature[:])
43+
return err
44+
}
45+
2646
type AssurancesExtrinsic []Assurance
2747

2848
// IsForCore checks if the validator has assured availability for a specific core.

internal/block/dispute.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package block
22

33
import (
4+
"io"
5+
46
"github.com/eigerco/strawberry/internal/constants"
57
"github.com/eigerco/strawberry/internal/crypto"
68
"github.com/eigerco/strawberry/internal/crypto/ed25519"
79
"github.com/eigerco/strawberry/internal/jamtime"
10+
"github.com/eigerco/strawberry/pkg/serialization/codec/jam"
811
)
912

1013
// DisputeExtrinsic represents the structured input for submitting disputes.
@@ -37,13 +40,44 @@ type Verdict struct {
3740
Judgements [constants.ValidatorsSuperMajority]Judgement // ⟦{{⊺,⊥}, NV, V̄}⟧⌊2/3V⌋+1
3841
}
3942

43+
// UnmarshalJAM implements the JAM codec Unmarshaler interface.
44+
func (v *Verdict) UnmarshalJAM(r io.Reader) error {
45+
if _, err := io.ReadFull(r, v.ReportHash[:]); err != nil {
46+
return err
47+
}
48+
buf := make([]byte, 4)
49+
if _, err := io.ReadFull(r, buf); err != nil {
50+
return err
51+
}
52+
v.EpochIndex = jamtime.Epoch(jam.DecodeUint32(buf))
53+
for i := range v.Judgements {
54+
if err := v.Judgements[i].UnmarshalJAM(r); err != nil {
55+
return err
56+
}
57+
}
58+
return nil
59+
}
60+
4061
// Culprit represents misbehaving guarantor who guaranteed an invalid work-report
4162
type Culprit struct {
4263
ReportHash crypto.Hash // H, hash of the work report
4364
ValidatorEd25519PublicKey ed25519.PublicKey // H̄
4465
Signature crypto.Ed25519Signature // V̄
4566
}
4667

68+
// UnmarshalJAM implements the JAM codec Unmarshaler interface.
69+
func (c *Culprit) UnmarshalJAM(r io.Reader) error {
70+
if _, err := io.ReadFull(r, c.ReportHash[:]); err != nil {
71+
return err
72+
}
73+
c.ValidatorEd25519PublicKey = make([]byte, crypto.Ed25519PublicSize)
74+
if _, err := io.ReadFull(r, c.ValidatorEd25519PublicKey); err != nil {
75+
return err
76+
}
77+
_, err := io.ReadFull(r, c.Signature[:])
78+
return err
79+
}
80+
4781
// Fault is an Auditor who made incorrect judgment
4882
type Fault struct {
4983
ReportHash crypto.Hash // H, hash of the work report
@@ -52,17 +86,60 @@ type Fault struct {
5286
Signature crypto.Ed25519Signature // V̄
5387
}
5488

89+
// UnmarshalJAM implements the JAM codec Unmarshaler interface.
90+
func (f *Fault) UnmarshalJAM(r io.Reader) error {
91+
if _, err := io.ReadFull(r, f.ReportHash[:]); err != nil {
92+
return err
93+
}
94+
b := make([]byte, 1)
95+
if _, err := io.ReadFull(r, b); err != nil {
96+
return err
97+
}
98+
f.IsValid = b[0] != 0
99+
f.ValidatorEd25519PublicKey = make([]byte, crypto.Ed25519PublicSize)
100+
if _, err := io.ReadFull(r, f.ValidatorEd25519PublicKey); err != nil {
101+
return err
102+
}
103+
_, err := io.ReadFull(r, f.Signature[:])
104+
return err
105+
}
106+
55107
// Judgement is a statement from an auditor that declares whether a given work-report is valid or invalid
56108
type Judgement struct {
57109
IsValid bool // {⊺,⊥}
58110
ValidatorIndex uint16 // NV
59111
Signature crypto.Ed25519Signature // V̄
60112
}
61113

114+
// UnmarshalJAM implements the JAM codec Unmarshaler interface.
115+
func (j *Judgement) UnmarshalJAM(r io.Reader) error {
116+
buf := make([]byte, 3)
117+
if _, err := io.ReadFull(r, buf); err != nil {
118+
return err
119+
}
120+
j.IsValid = buf[0] != 0
121+
j.ValidatorIndex = jam.DecodeUint16(buf[1:3])
122+
_, err := io.ReadFull(r, j.Signature[:])
123+
return err
124+
}
125+
62126
// VerdictSummary V is a sequence of (report_hash, vote_count) pairs
63127
// where vote_count must be exactly one of: 0, ⌊V/3⌋, or ⌊2V/3⌋+1
64128
// V ∈ ⟦⟨H, {0, ⌊1/3V⌋, ⌊2/3V⌋ + 1}⟩⟧ (eq. 10.11 v0.7.0)
65129
type VerdictSummary struct {
66130
ReportHash crypto.Hash // H
67131
VoteCount uint16 // Must be 0, V/3, or 2V/3+1
68132
}
133+
134+
// UnmarshalJAM implements the JAM codec Unmarshaler interface.
135+
func (vs *VerdictSummary) UnmarshalJAM(r io.Reader) error {
136+
if _, err := io.ReadFull(r, vs.ReportHash[:]); err != nil {
137+
return err
138+
}
139+
buf := make([]byte, 2)
140+
if _, err := io.ReadFull(r, buf); err != nil {
141+
return err
142+
}
143+
vs.VoteCount = jam.DecodeUint16(buf)
144+
return nil
145+
}

internal/block/guarantee.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package block
22

33
import (
44
"fmt"
5+
"io"
56

67
"github.com/eigerco/strawberry/internal/constants"
78
"github.com/eigerco/strawberry/internal/crypto"
@@ -30,6 +31,17 @@ type CredentialSignature struct {
3031
Signature crypto.Ed25519Signature // The Ed25519 signature
3132
}
3233

34+
// UnmarshalJAM implements the JAM codec Unmarshaler interface.
35+
func (cs *CredentialSignature) UnmarshalJAM(r io.Reader) error {
36+
buf := make([]byte, 2)
37+
if _, err := io.ReadFull(r, buf); err != nil {
38+
return err
39+
}
40+
cs.ValidatorIndex = jam.DecodeUint16(buf)
41+
_, err := io.ReadFull(r, cs.Signature[:])
42+
return err
43+
}
44+
3345
// WorkReport represents a work report in the JAM state
3446
// R ≡ {s ∈ Y, c ∈ C, c ∈ NC, a ∈ H, t ∈ B, l ∈ ⟦H → H⟧, d ∈ ⟦D⟧1:I, g ∈ NG} (eq. 11.2 v 0.7.0)
3547
// E(rs, rc, rc, ra, rg , ↕rt, ↕rl, ↕rd)
@@ -53,6 +65,30 @@ type AvailabilitySpecification struct {
5365
SegmentCount uint16 // Segment count (n)
5466
}
5567

68+
// UnmarshalJAM implements the JAM codec Unmarshaler interface.
69+
func (as *AvailabilitySpecification) UnmarshalJAM(r io.Reader) error {
70+
if _, err := io.ReadFull(r, as.WorkPackageHash[:]); err != nil {
71+
return err
72+
}
73+
buf := make([]byte, 4)
74+
if _, err := io.ReadFull(r, buf); err != nil {
75+
return err
76+
}
77+
as.AuditableWorkBundleLength = jam.DecodeUint32(buf)
78+
if _, err := io.ReadFull(r, as.ErasureRoot[:]); err != nil {
79+
return err
80+
}
81+
if _, err := io.ReadFull(r, as.SegmentRoot[:]); err != nil {
82+
return err
83+
}
84+
buf2 := make([]byte, 2)
85+
if _, err := io.ReadFull(r, buf2); err != nil {
86+
return err
87+
}
88+
as.SegmentCount = jam.DecodeUint16(buf2)
89+
return nil
90+
}
91+
5692
// RefinementContext describes the context of the chain at the point that the report's corresponding work-package was evaluated.
5793
//
5894
// C ≡ {a ∈ H, s ∈ H, b ∈ H, l ∈ H, t ∈ NT, p ∈ {[H]}} (eq. 11.4 v 0.7.0)
@@ -69,12 +105,37 @@ type RefinementContextAnchor struct {
69105
PosteriorBeefyRoot crypto.Hash // Posterior beefy root (b)
70106
}
71107

108+
// UnmarshalJAM implements the JAM codec Unmarshaler interface.
109+
func (rca *RefinementContextAnchor) UnmarshalJAM(r io.Reader) error {
110+
if _, err := io.ReadFull(r, rca.HeaderHash[:]); err != nil {
111+
return err
112+
}
113+
if _, err := io.ReadFull(r, rca.PosteriorStateRoot[:]); err != nil {
114+
return err
115+
}
116+
_, err := io.ReadFull(r, rca.PosteriorBeefyRoot[:])
117+
return err
118+
}
119+
72120
// l ∈ H, t ∈ N_T
73121
type RefinementContextLookupAnchor struct {
74122
HeaderHash crypto.Hash // HeaderHash of the anchor (l)
75123
Timeslot jamtime.Timeslot // Timeslot (t)
76124
}
77125

126+
// UnmarshalJAM implements the JAM codec Unmarshaler interface.
127+
func (rcla *RefinementContextLookupAnchor) UnmarshalJAM(r io.Reader) error {
128+
if _, err := io.ReadFull(r, rcla.HeaderHash[:]); err != nil {
129+
return err
130+
}
131+
buf := make([]byte, 4)
132+
if _, err := io.ReadFull(r, buf); err != nil {
133+
return err
134+
}
135+
rcla.Timeslot = jamtime.Timeslot(jam.DecodeUint32(buf))
136+
return nil
137+
}
138+
78139
// GuarantorAssignments represents the mapping of validators to cores and their keys
79140
// M ∈ {⟦NC⟧V, ⟦H̄⟧V} (eq. 11.18 v 0.7.0)
80141
type GuarantorAssignments struct {

internal/block/header.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package block
22

33
import (
44
"fmt"
5+
"io"
56

67
"github.com/eigerco/strawberry/internal/crypto/ed25519"
78

@@ -30,6 +31,16 @@ type ValidatorKeys struct {
3031
Ed25519 ed25519.PublicKey
3132
}
3233

34+
// UnmarshalJAM implements the JAM codec Unmarshaler interface.
35+
func (vk *ValidatorKeys) UnmarshalJAM(r io.Reader) error {
36+
if _, err := io.ReadFull(r, vk.Bandersnatch[:]); err != nil {
37+
return err
38+
}
39+
vk.Ed25519 = make([]byte, crypto.Ed25519PublicSize)
40+
_, err := io.ReadFull(r, vk.Ed25519)
41+
return err
42+
}
43+
3344
// EpochMarker consists of epoch randomness and a sequence of
3445
// Bandersnatch keys defining the Bandersnatch validator keys (kb) beginning in the next epoch.
3546
type EpochMarker struct {
@@ -38,8 +49,34 @@ type EpochMarker struct {
3849
Keys [constants.NumberOfValidators]ValidatorKeys
3950
}
4051

52+
// UnmarshalJAM implements the JAM codec Unmarshaler interface.
53+
func (em *EpochMarker) UnmarshalJAM(r io.Reader) error {
54+
if _, err := io.ReadFull(r, em.Entropy[:]); err != nil {
55+
return err
56+
}
57+
if _, err := io.ReadFull(r, em.TicketsEntropy[:]); err != nil {
58+
return err
59+
}
60+
for i := range em.Keys {
61+
if err := em.Keys[i].UnmarshalJAM(r); err != nil {
62+
return err
63+
}
64+
}
65+
return nil
66+
}
67+
4168
type WinningTicketMarker [constants.TimeslotsPerEpoch]Ticket
4269

70+
// UnmarshalJAM implements the JAM codec Unmarshaler interface.
71+
func (wtm *WinningTicketMarker) UnmarshalJAM(r io.Reader) error {
72+
for i := range wtm {
73+
if err := wtm[i].UnmarshalJAM(r); err != nil {
74+
return err
75+
}
76+
}
77+
return nil
78+
}
79+
4380
// Hash returns the hash of the header
4481
func (h Header) Hash() (crypto.Hash, error) {
4582
jamBytes, err := jam.Marshal(h)

internal/block/ticket.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package block
22

3-
import "github.com/eigerco/strawberry/internal/crypto"
3+
import (
4+
"io"
5+
6+
"github.com/eigerco/strawberry/internal/crypto"
7+
)
48

59
const (
610
TicketProofSize = 784 // Size of F̄[]γz⟨XT ⌢ η′2 r⟩
@@ -12,6 +16,19 @@ type Ticket struct {
1216
EntryIndex uint8 // r ∈ Nn (0, 1)
1317
}
1418

19+
// UnmarshalJAM implements the JAM codec Unmarshaler interface.
20+
func (t *Ticket) UnmarshalJAM(r io.Reader) error {
21+
if _, err := io.ReadFull(r, t.Identifier[:]); err != nil {
22+
return err
23+
}
24+
b := make([]byte, 1)
25+
if _, err := io.ReadFull(r, b); err != nil {
26+
return err
27+
}
28+
t.EntryIndex = b[0]
29+
return nil
30+
}
31+
1532
func (t Ticket) TicketOrKeyType() {}
1633

1734
// TicketProof represents a proof of a valid ticket
@@ -20,6 +37,17 @@ type TicketProof struct {
2037
Proof [TicketProofSize]byte // RingVRF proof
2138
}
2239

40+
// UnmarshalJAM implements the JAM codec Unmarshaler interface.
41+
func (tp *TicketProof) UnmarshalJAM(r io.Reader) error {
42+
b := make([]byte, 1)
43+
if _, err := io.ReadFull(r, b); err != nil {
44+
return err
45+
}
46+
tp.EntryIndex = b[0]
47+
_, err := io.ReadFull(r, tp.Proof[:])
48+
return err
49+
}
50+
2351
// TicketExtrinsic represents the E_T extrinsic
2452
type TicketExtrinsic struct {
2553
TicketProofs []TicketProof

internal/crypto/hash.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,22 @@ package crypto
22

33
import (
44
"encoding/hex"
5-
"golang.org/x/crypto/blake2b"
6-
"golang.org/x/crypto/sha3"
5+
"io"
76
"log"
87
"strings"
8+
9+
"golang.org/x/crypto/blake2b"
10+
"golang.org/x/crypto/sha3"
911
)
1012

1113
type Hash [HashSize]byte
1214

15+
// UnmarshalJAM implements the JAM codec Unmarshaler interface.
16+
func (h *Hash) UnmarshalJAM(r io.Reader) error {
17+
_, err := io.ReadFull(r, h[:])
18+
return err
19+
}
20+
1321
func HashData(data []byte) Hash {
1422
hash := blake2b.Sum256(data)
1523
return hash

0 commit comments

Comments
 (0)