Skip to content

Commit

Permalink
Updated block sealing (#233)
Browse files Browse the repository at this point in the history
* Updated block sealing

- Overhaul existing block seal code.
- Add some initial community test cases to verify our signatures.
- Add type safety with a simulated union type for ticket or key.
- Add type safety for the TicketBodies or EpochKeys enum/union.
- Some renaming for clarity.

* Add more tests

- Move community tests to integration tests since they use the tiny
  vector constants.
- Add all remaining community test vectors.

* Addressing review comments
  • Loading branch information
greywolve authored Jan 21, 2025
1 parent 64909d6 commit 78505ff
Show file tree
Hide file tree
Showing 21 changed files with 540 additions and 228 deletions.
2 changes: 2 additions & 0 deletions internal/block/ticket.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ type Ticket struct {
EntryIndex uint8 // r ∈ Nn (0, 1)
}

func (t Ticket) TicketOrKeyType() {}

// TicketProof represents a proof of a valid ticket
type TicketProof struct {
EntryIndex uint8 // r ∈ Nn (0, 1)
Expand Down
8 changes: 8 additions & 0 deletions internal/crypto/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,21 @@ type Ed25519Signature [Ed25519SignatureSize]byte
type BlsKey [BLSSize]byte
type BandersnatchSeedKey [BandersnatchSize]byte
type BandersnatchPrivateKey [BandersnatchSize]byte

type BandersnatchPublicKey [BandersnatchSize]byte

func (b BandersnatchPublicKey) TicketOrKeyType() {}

type BandersnatchSignature [96]byte
type BandersnatchOutputHash [32]byte
type RingVrfSignature [VrfProofSize]byte
type MetadataKey [MetadataSize]byte
type RingCommitment [BandersnatchRingSize]byte

type EpochKeys [jamtime.TimeslotsPerEpoch]BandersnatchPublicKey

func (e EpochKeys) TicketsOrKeysType() {}

type ValidatorKey struct {
Bandersnatch BandersnatchPublicKey
Ed25519 ed25519.PublicKey
Expand Down
45 changes: 28 additions & 17 deletions internal/safrole/safrole.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package safrole

import (
"fmt"

"github.com/eigerco/strawberry/pkg/serialization/codec/jam"

"github.com/eigerco/strawberry/internal/block"
Expand All @@ -11,48 +12,58 @@ import (

type TicketsBodies [jamtime.TimeslotsPerEpoch]block.Ticket

// TicketsOrKeys is enum
type TicketsOrKeys struct {
inner any
func (t TicketsBodies) TicketsOrKeysType() {}

// TicketAccumulator is enum/union that represents ya. It should contain either
// TicketBodies which is an array of tickets, or in the fallback case
// crypto.EpochKeys, an array of bandersnatch public keys.
type TicketAccumulator struct {
inner TicketsOrKeys
}

// TicketsOrKeys represents the union of either TicketBodies or
// crypto.EpochKeys.
type TicketsOrKeys interface {
TicketsOrKeysType()
}

type TicketsOrKeysValues interface {
crypto.EpochKeys | TicketsBodies
func (ta *TicketAccumulator) Set(value TicketsOrKeys) {
ta.inner = value
}

func setTicketsOrKeys[Value TicketsOrKeysValues](tok *TicketsOrKeys, value Value) {
tok.inner = value
func (ta *TicketAccumulator) Get() TicketsOrKeys {
return ta.inner
}

func (tok *TicketsOrKeys) SetValue(value any) error {
func (ta *TicketAccumulator) SetValue(value any) error {
switch value := value.(type) {
case crypto.EpochKeys:
setTicketsOrKeys(tok, value)
ta.inner = value
return nil
case TicketsBodies:
setTicketsOrKeys(tok, value)
ta.inner = value
return nil
default:
return fmt.Errorf(jam.ErrUnsupportedType, value)
}
}

func (tok TicketsOrKeys) IndexValue() (uint, any, error) {
switch tok.inner.(type) {
func (ta TicketAccumulator) IndexValue() (uint, any, error) {
switch ta.inner.(type) {
case crypto.EpochKeys:
return 1, tok.inner, nil
return 1, ta.inner, nil
case TicketsBodies:
return 0, tok.inner, nil
return 0, ta.inner, nil
}
return 0, nil, jam.ErrUnsupportedEnumTypeValue
}

func (tok TicketsOrKeys) Value() (value any, err error) {
_, value, err = tok.IndexValue()
func (ta TicketAccumulator) Value() (value any, err error) {
_, value, err = ta.IndexValue()
return
}

func (tok TicketsOrKeys) ValueAt(index uint) (any, error) {
func (ta TicketAccumulator) ValueAt(index uint) (any, error) {
switch index {
case 1:
return crypto.EpochKeys{}, nil
Expand Down
2 changes: 1 addition & 1 deletion internal/safrole/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
type State struct {
NextValidators ValidatorsData // (γk) Validator keys for the following epoch.
TicketAccumulator []block.Ticket // (γa) Sealing-key contest ticket accumulator.
SealingKeySeries TicketsOrKeys // (γs) Sealing-key series of the current epoch.
SealingKeySeries TicketAccumulator // (γs) Sealing-key series of the current epoch.
RingCommitment crypto.RingCommitment // (γz) Bandersnatch ring commitment.
}

Expand Down
Loading

0 comments on commit 78505ff

Please sign in to comment.