Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace custom serialization and asn.1 with Canoto #46

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ type BlockBuilder interface {

type Storage interface {
Height() uint64
Retrieve(seq uint64) (Block, FinalizationCertificate, bool)
Index(block Block, certificate FinalizationCertificate)
Retrieve(seq uint64) (Block, Quorum, bool)
Index(block Block, certificate Quorum)
}

type Communication interface {
Expand Down Expand Up @@ -95,12 +95,15 @@ type BlockDeserializer interface {
DeserializeBlock(bytes []byte) (Block, error)
}

// Signature encodes a signature and the node that signed it, without the message it was signed on.
type Signature struct {
// Signer is the NodeID of the creator of the signature.
Signer NodeID
// Value is the byte representation of the signature.
Value []byte
// QuorumCertificate is equivalent to a collection of signatures from a quorum of nodes,
type QuorumCertificate interface {
// Signers returns who participated in creating this QuorumCertificate.
Signers() []NodeID
// Verify checks whether the nodes participated in creating this QuorumCertificate,
// signed the given message.
Verify(msg []byte) error
// Bytes returns a raw representation of the given QuorumCertificate.
Bytes() []byte
}

// QCDeserializer deserializes QuorumCertificates according to formatting
Expand Down
113 changes: 0 additions & 113 deletions encoding.go
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is now essentially entirely auto-generated.

This file was deleted.

122 changes: 36 additions & 86 deletions encoding_test.go
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this whole file be deleted? It is testing canoto more than this library.

Original file line number Diff line number Diff line change
Expand Up @@ -6,120 +6,70 @@ package simplex
import (
"crypto/rand"
"crypto/sha256"
"simplex/record"
"testing"

"github.com/stretchr/testify/require"
)

func TestBlockRecord(t *testing.T) {
bh := BlockHeader{
ProtocolMetadata: ProtocolMetadata{
Version: 1,
Round: 2,
Seq: 3,
Epoch: 4,
},
}

_, err := rand.Read(bh.Prev[:])
require.NoError(t, err)

_, err = rand.Read(bh.Digest[:])
require.NoError(t, err)

payload := []byte{11, 12, 13, 14, 15, 16}

record := blockRecord(bh, payload)

md2, payload2, err := blockFromRecord(record)
require.NoError(t, err)

require.Equal(t, bh, md2)
require.Equal(t, payload, payload2)
}

func FuzzBlockRecord(f *testing.F) {
f.Fuzz(func(t *testing.T, version uint8, round, seq, epoch uint64, prevPreimage, digestPreimage []byte, payload []byte) {
prev := sha256.Sum256(prevPreimage)
digest := sha256.Sum256(digestPreimage)
bh := BlockHeader{
ProtocolMetadata: ProtocolMetadata{
Version: version,
Round: round,
Seq: seq,
Epoch: epoch,
Prev: prev,
},
Digest: digest,
}

record := blockRecord(bh, payload)

md2, payload2, err := blockFromRecord(record)
require.NoError(t, err)

require.Equal(t, bh, md2)
require.Equal(t, payload, payload2)
})
}
Comment on lines -15 to -65
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also a change unrelated to the Canoto inclusion. The block record previously included the protocol metadata multiple times (because the payload is expected to be able to be parsed and the result is then expected to provide the metadata as well)


func TestNotarizationRecord(t *testing.T) {
sig := make([]byte, 64)
_, err := rand.Read(sig)
require.NoError(t, err)

vote := ToBeSignedVote{
BlockHeader{
ProtocolMetadata: ProtocolMetadata{
Version: 1,
Round: 2,
Seq: 3,
Epoch: 4,
},
vote := BlockHeader{
ProtocolMetadata: ProtocolMetadata{
Round: 2,
Seq: 3,
Epoch: 4,
},
}

_, err = rand.Read(vote.Prev[:])
require.NoError(t, err)

_, err = rand.Read(vote.Prev[:])
_, err = rand.Read(vote.Digest[:])
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an unrelated fix.

require.NoError(t, err)

record := quorumRecord([]byte{1, 2, 3}, vote.Bytes(), record.NotarizationRecordType)
qc, vote2, err := NotarizationFromRecord(record)
require.NoError(t, err)
require.Equal(t, []byte{1, 2, 3}, qc)
require.Equal(t, vote, vote2)
record := Record{
Notarization: &Quorum{
Header: vote,
QC: []byte{1, 2, 3},
},
}
recordBytes := record.MarshalCanoto()

var parsedRecord Record
require.NoError(t, parsedRecord.UnmarshalCanoto(recordBytes))
require.True(t, vote.Equals(&parsedRecord.Notarization.Header))
require.Equal(t, []byte{1, 2, 3}, parsedRecord.Notarization.QC)
}

func FuzzNotarizationRecord(f *testing.F) {
f.Fuzz(func(t *testing.T, version uint8, round uint64, seq uint64, epoch uint64, prevPreimage, digestPreimage []byte, sig []byte, signer1, signer2 []byte) {
f.Fuzz(func(t *testing.T, round uint64, seq uint64, epoch uint64, prevPreimage, digestPreimage []byte, sig []byte, signer1, signer2 []byte) {
prev := sha256.Sum256(prevPreimage)
digest := sha256.Sum256(digestPreimage)

vote := ToBeSignedVote{
BlockHeader{
ProtocolMetadata: ProtocolMetadata{
Version: version,
Round: round,
Seq: seq,
Epoch: epoch,
Prev: prev,
},
Digest: digest,
vote := BlockHeader{
ProtocolMetadata: ProtocolMetadata{
Round: round,
Seq: seq,
Epoch: epoch,
Prev: prev,
},
Digest: digest,
}

var signers []NodeID
for _, signer := range [][]byte{signer1, signer2} {
signers = append(signers, signer)
record := Record{
Notarization: &Quorum{
Header: vote,
QC: []byte{1, 2, 3},
},
}
recordBytes := record.MarshalCanoto()

record := quorumRecord([]byte{1, 2, 3}, vote.Bytes(), record.NotarizationRecordType)
qc, vote2, err := NotarizationFromRecord(record)
require.NoError(t, err)
require.Equal(t, []byte{1, 2, 3}, qc)
require.Equal(t, vote, vote2)
var parsedRecord Record
require.NoError(t, parsedRecord.UnmarshalCanoto(recordBytes))
require.True(t, vote.Equals(&parsedRecord.Notarization.Header))
require.Equal(t, []byte{1, 2, 3}, parsedRecord.Notarization.QC)
})
}
Loading
Loading