Skip to content

Commit

Permalink
feat(parachain): Add StatementDistributionMessage varingDataType (#3316)
Browse files Browse the repository at this point in the history
  • Loading branch information
axaysagathiya authored and timwu20 committed Jun 17, 2024
1 parent 8a9ae61 commit 79b0c99
Show file tree
Hide file tree
Showing 6 changed files with 498 additions and 1 deletion.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ require (
golang.org/x/exp v0.0.0-20240213143201-ec583247a57a
golang.org/x/term v0.21.0
google.golang.org/protobuf v1.34.1
gopkg.in/yaml.v3 v3.0.1
)

require (
Expand Down Expand Up @@ -195,7 +196,6 @@ require (
gonum.org/v1/gonum v0.13.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/blake3 v1.2.1 // indirect
)

Expand Down
81 changes: 81 additions & 0 deletions lib/parachain/statement.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package parachain

import (
"fmt"

"github.com/ChainSafe/gossamer/lib/common"
"github.com/ChainSafe/gossamer/pkg/scale"
)

// Statement is a result of candidate validation. It could be either `Valid` or `Seconded`.
type StatementValues interface {
Valid | Seconded
}

type Statement struct {
inner any
}

func setStatement[Value StatementValues](mvdt *Statement, value Value) {
mvdt.inner = value
}

func (mvdt *Statement) SetValue(value any) (err error) {
switch value := value.(type) {
case Valid:
setStatement(mvdt, value)
return

case Seconded:
setStatement(mvdt, value)
return

default:
return fmt.Errorf("unsupported type")
}
}

func (mvdt Statement) IndexValue() (index uint, value any, err error) {
switch mvdt.inner.(type) {
case Valid:
return 2, mvdt.inner, nil

case Seconded:
return 1, mvdt.inner, nil

}
return 0, nil, scale.ErrUnsupportedVaryingDataTypeValue
}

func (mvdt Statement) Value() (value any, err error) {
_, value, err = mvdt.IndexValue()
return
}

func (mvdt Statement) ValueAt(index uint) (value any, err error) {
switch index {
case 2:
return *new(Valid), nil

case 1:
return *new(Seconded), nil

}
return nil, scale.ErrUnknownVaryingDataTypeValue
}

// NewStatement returns a new Statement VaryingDataType
func NewStatement() Statement {
return Statement{}
}

// Seconded represents a statement that a validator seconds a candidate.
type Seconded CommittedCandidateReceipt

// Valid represents a statement that a validator has deemed a candidate valid.
type Valid CandidateHash

// CandidateHash makes it easy to enforce that a hash is a candidate hash on the type level.
type CandidateHash struct {
Value common.Hash `scale:"1"`
}
116 changes: 116 additions & 0 deletions lib/parachain/statement_distribution_message.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package parachain

import (
"fmt"

"github.com/ChainSafe/gossamer/lib/common"
"github.com/ChainSafe/gossamer/pkg/scale"
)

type StatementDistributionMessageValues interface {
SignedFullStatement | SecondedStatementWithLargePayload
}

// StatementDistributionMessage represents network messages used by the statement distribution subsystem
type StatementDistributionMessage struct {
inner any
}

func setStatementDistributionMessage[Value StatementDistributionMessageValues](mvdt *StatementDistributionMessage, value Value) {
mvdt.inner = value
}

func (mvdt *StatementDistributionMessage) SetValue(value any) (err error) {
switch value := value.(type) {
case SignedFullStatement:
setStatementDistributionMessage(mvdt, value)
return

case SecondedStatementWithLargePayload:
setStatementDistributionMessage(mvdt, value)
return

default:
return fmt.Errorf("unsupported type")
}
}

func (mvdt StatementDistributionMessage) IndexValue() (index uint, value any, err error) {
switch mvdt.inner.(type) {
case SignedFullStatement:
return 0, mvdt.inner, nil

case SecondedStatementWithLargePayload:
return 1, mvdt.inner, nil

}
return 0, nil, scale.ErrUnsupportedVaryingDataTypeValue
}

func (mvdt StatementDistributionMessage) Value() (value any, err error) {
_, value, err = mvdt.IndexValue()
return
}

func (mvdt StatementDistributionMessage) ValueAt(index uint) (value any, err error) {
switch index {
case 0:
return *new(SignedFullStatement), nil

case 1:
return *new(SecondedStatementWithLargePayload), nil

}
return nil, scale.ErrUnknownVaryingDataTypeValue
}

// NewStatementDistributionMessage returns a new StatementDistributionMessage VaryingDataType
func NewStatementDistributionMessage() StatementDistributionMessage {
return StatementDistributionMessage{}
}

// SignedFullStatement represents a signed full statement under a given relay-parent.
type SignedFullStatement struct {
Hash common.Hash `scale:"1"`
UncheckedSignedFullStatement UncheckedSignedFullStatement `scale:"2"`
}

// Seconded statement with large payload (e.g. containing a runtime upgrade).
//
// We only gossip the hash in that case, actual payloads can be fetched from sending node
// via request/response.
type SecondedStatementWithLargePayload StatementMetadata

// UncheckedSignedFullStatement is a Variant of `SignedFullStatement` where the signature has not yet been verified.
type UncheckedSignedFullStatement struct {
// The payload is part of the signed data. The rest is the signing context,
// which is known both at signing and at validation.
Payload Statement `scale:"1"`

// The index of the validator signing this statement.
ValidatorIndex ValidatorIndex `scale:"2"`

// The signature by the validator of the signed payload.
Signature ValidatorSignature `scale:"3"`
}

// StatementMetadata represents the data that makes a statement unique.
type StatementMetadata struct {
// Relay parent this statement is relevant under.
RelayParent common.Hash `scale:"1"`

// Hash of the candidate that got validated.
CandidateHash CandidateHash `scale:"2"`

// Validator that attested the validity.
SignedBy ValidatorIndex `scale:"3"`

// Signature of seconding validator.
Signature ValidatorSignature `scale:"4"`
}

// ValidatorSignature represents the signature with which parachain validators sign blocks.
type ValidatorSignature Signature

// Signature represents a cryptographic signature.
type Signature [64]byte
Loading

0 comments on commit 79b0c99

Please sign in to comment.