ceremonyclient/protobufs/global_test.go
Cassandra Heart aac841e6e6
v2.1.0.11 (#477)
* v2.1.0.11

* v2.1.0.11, the later half
2025-11-21 04:41:02 -06:00

1371 lines
39 KiB
Go

package protobufs
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestSeniorityMerge_Serialization(t *testing.T) {
tests := []struct {
name string
merge *SeniorityMerge
}{
{
name: "complete seniority merge",
merge: &SeniorityMerge{
Signature: make([]byte, 114), // Ed448 signature
KeyType: 0,
ProverPublicKey: make([]byte, 57), // Ed448 public key
},
},
{
name: "different key type",
merge: &SeniorityMerge{
Signature: append([]byte{0xFF}, make([]byte, 113)...),
KeyType: 1,
ProverPublicKey: append([]byte{0xAA}, make([]byte, 56)...),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.merge.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
merge2 := &SeniorityMerge{}
err = merge2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.Equal(t, tt.merge.Signature, merge2.Signature)
assert.Equal(t, tt.merge.KeyType, merge2.KeyType)
assert.Equal(t, tt.merge.ProverPublicKey, merge2.ProverPublicKey)
})
}
}
func TestLegacyProverRequest_Serialization(t *testing.T) {
tests := []struct {
name string
req *LegacyProverRequest
}{
{
name: "complete legacy prover request",
req: &LegacyProverRequest{
PublicKeySignaturesEd448: []*Ed448Signature{
{
PublicKey: &Ed448PublicKey{
KeyValue: make([]byte, 57),
},
Signature: make([]byte, 114),
},
{
PublicKey: &Ed448PublicKey{
KeyValue: append([]byte{0xAA}, make([]byte, 56)...),
},
Signature: append([]byte{0xBB}, make([]byte, 113)...),
},
},
},
},
{
name: "empty legacy prover request",
req: &LegacyProverRequest{
PublicKeySignaturesEd448: []*Ed448Signature{},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.req.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
req2 := &LegacyProverRequest{}
err = req2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.Equal(t, len(tt.req.PublicKeySignaturesEd448), len(req2.PublicKeySignaturesEd448))
for i := range tt.req.PublicKeySignaturesEd448 {
assert.Equal(t, tt.req.PublicKeySignaturesEd448[i].PublicKey.KeyValue, req2.PublicKeySignaturesEd448[i].PublicKey.KeyValue)
assert.Equal(t, tt.req.PublicKeySignaturesEd448[i].Signature, req2.PublicKeySignaturesEd448[i].Signature)
}
})
}
}
func TestProverJoin_Serialization(t *testing.T) {
tests := []struct {
name string
join *ProverJoin
}{
{
name: "complete prover join",
join: &ProverJoin{
Filters: [][]byte{make([]byte, 32), append([]byte{0xFF}, make([]byte, 31)...)},
FrameNumber: 12345,
PublicKeySignatureBls48581: &BLS48581SignatureWithProofOfPossession{
Signature: make([]byte, 74), // BLS48-581 signature size
PopSignature: make([]byte, 74), // BLS48-581 PoP size
PublicKey: &BLS48581G2PublicKey{
KeyValue: make([]byte, 585), // BLS48-581 G2 key size
},
},
DelegateAddress: make([]byte, 32),
MergeTargets: []*SeniorityMerge{
{
Signature: make([]byte, 114),
KeyType: 0,
ProverPublicKey: make([]byte, 57),
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.join.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
join2 := &ProverJoin{}
err = join2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.Equal(t, tt.join.Filters, join2.Filters)
assert.Equal(t, tt.join.FrameNumber, join2.FrameNumber)
assert.Equal(t, tt.join.DelegateAddress, join2.DelegateAddress)
assert.Equal(t, len(tt.join.MergeTargets), len(join2.MergeTargets))
if tt.join.PublicKeySignatureBls48581 != nil {
assert.NotNil(t, join2.PublicKeySignatureBls48581)
assert.Equal(t, tt.join.PublicKeySignatureBls48581.Signature, join2.PublicKeySignatureBls48581.Signature)
assert.Equal(t, tt.join.PublicKeySignatureBls48581.PopSignature, join2.PublicKeySignatureBls48581.PopSignature)
if tt.join.PublicKeySignatureBls48581.PublicKey != nil {
assert.NotNil(t, join2.PublicKeySignatureBls48581.PublicKey)
assert.Equal(t, tt.join.PublicKeySignatureBls48581.PublicKey.KeyValue, join2.PublicKeySignatureBls48581.PublicKey.KeyValue)
}
} else {
assert.Nil(t, join2.PublicKeySignatureBls48581)
}
})
}
}
func TestFrameHeader_Serialization(t *testing.T) {
tests := []struct {
name string
header *FrameHeader
}{
{
name: "complete frame header",
header: &FrameHeader{
Address: make([]byte, 64),
FrameNumber: 99999,
Timestamp: 1234567890123,
Difficulty: 1000000,
Output: make([]byte, 516), // VDF output: 258 + 258 bytes
ParentSelector: make([]byte, 32),
RequestsRoot: make([]byte, 74),
StateRoots: [][]byte{
make([]byte, 74),
make([]byte, 74),
make([]byte, 74),
make([]byte, 74),
},
Prover: make([]byte, 32),
FeeMultiplierVote: 500,
PublicKeySignatureBls48581: &BLS48581AggregateSignature{
Signature: make([]byte, 74),
PublicKey: &BLS48581G2PublicKey{
KeyValue: make([]byte, 585),
},
Bitmask: make([]byte, 32),
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.header.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
header2 := &FrameHeader{}
err = header2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.Equal(t, tt.header.Address, header2.Address)
assert.Equal(t, tt.header.FrameNumber, header2.FrameNumber)
assert.Equal(t, tt.header.Timestamp, header2.Timestamp)
assert.Equal(t, tt.header.Difficulty, header2.Difficulty)
assert.Equal(t, tt.header.Output, header2.Output)
assert.Equal(t, tt.header.ParentSelector, header2.ParentSelector)
assert.Equal(t, tt.header.RequestsRoot, header2.RequestsRoot)
assert.Equal(t, tt.header.StateRoots, header2.StateRoots)
assert.Equal(t, tt.header.Prover, header2.Prover)
assert.Equal(t, tt.header.FeeMultiplierVote, header2.FeeMultiplierVote)
if tt.header.PublicKeySignatureBls48581 != nil {
assert.NotNil(t, header2.PublicKeySignatureBls48581)
assert.Equal(t, tt.header.PublicKeySignatureBls48581.Signature, header2.PublicKeySignatureBls48581.Signature)
assert.Equal(t, tt.header.PublicKeySignatureBls48581.Bitmask, header2.PublicKeySignatureBls48581.Bitmask)
if tt.header.PublicKeySignatureBls48581.PublicKey != nil {
assert.NotNil(t, header2.PublicKeySignatureBls48581.PublicKey)
assert.Equal(t, tt.header.PublicKeySignatureBls48581.PublicKey.KeyValue, header2.PublicKeySignatureBls48581.PublicKey.KeyValue)
}
} else {
assert.Nil(t, header2.PublicKeySignatureBls48581)
}
})
}
}
// Note: MessageRequest is a complex union type that requires special handling
// The actual implementation would need to test each specific request type
func TestMessageRequest_Serialization(t *testing.T) {
tests := []struct {
name string
req *MessageRequest
}{
{
name: "message request with join",
req: &MessageRequest{
Request: &MessageRequest_Join{
Join: &ProverJoin{
Filters: [][]byte{make([]byte, 32)},
FrameNumber: 12345,
PublicKeySignatureBls48581: &BLS48581SignatureWithProofOfPossession{
Signature: make([]byte, 74),
PopSignature: make([]byte, 74),
PublicKey: &BLS48581G2PublicKey{
KeyValue: make([]byte, 585),
},
},
DelegateAddress: make([]byte, 32),
MergeTargets: []*SeniorityMerge{},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.req.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
req2 := &MessageRequest{}
err = req2.FromCanonicalBytes(data)
require.NoError(t, err)
// Verify the union type was preserved
assert.NotNil(t, req2.Request)
// Type assertion to verify specific request type
if joinReq, ok := tt.req.Request.(*MessageRequest_Join); ok {
join2, ok2 := req2.Request.(*MessageRequest_Join)
assert.True(t, ok2)
if ok2 {
assert.Equal(t, joinReq.Join.FrameNumber, join2.Join.FrameNumber)
assert.Equal(t, joinReq.Join.Filters, join2.Join.Filters)
}
}
})
}
}
// Simplified tests for the remaining types - many follow similar patterns
func TestProverUpdate_Serialization(t *testing.T) {
tests := []struct {
name string
update *ProverUpdate
}{
{
name: "complete prover update",
update: &ProverUpdate{
DelegateAddress: make([]byte, 32),
PublicKeySignatureBls48581: &BLS48581AddressedSignature{
Signature: make([]byte, 74),
Address: make([]byte, 32),
},
},
},
{
name: "minimal prover update",
update: &ProverUpdate{
DelegateAddress: []byte{},
PublicKeySignatureBls48581: nil,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.update.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
update2 := &ProverUpdate{}
err = update2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.Equal(t, tt.update.DelegateAddress, update2.DelegateAddress)
if tt.update.PublicKeySignatureBls48581 != nil {
assert.NotNil(t, update2.PublicKeySignatureBls48581)
assert.Equal(t, tt.update.PublicKeySignatureBls48581.Signature, update2.PublicKeySignatureBls48581.Signature)
assert.Equal(t, tt.update.PublicKeySignatureBls48581.Address, update2.PublicKeySignatureBls48581.Address)
} else {
assert.Nil(t, update2.PublicKeySignatureBls48581)
}
})
}
}
func TestGlobalAlert_Serialization(t *testing.T) {
tests := []struct {
name string
alert *GlobalAlert
}{
{
name: "complete global alert",
alert: &GlobalAlert{
Message: "Critical alert: Network maintenance scheduled",
Signature: make([]byte, 114), // Ed448 signature size
},
},
{
name: "empty global alert",
alert: &GlobalAlert{
Message: "",
Signature: []byte{},
},
},
{
name: "alert with short message",
alert: &GlobalAlert{
Message: "Alert",
Signature: append([]byte{0xAA}, make([]byte, 113)...),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.alert.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
alert2 := &GlobalAlert{}
err = alert2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.Equal(t, tt.alert.Message, alert2.Message)
assert.Equal(t, tt.alert.Signature, alert2.Signature)
})
}
}
func TestProverLeave_Serialization(t *testing.T) {
tests := []struct {
name string
leave *ProverLeave
}{
{
name: "complete prover leave",
leave: &ProverLeave{
Filters: [][]byte{make([]byte, 32), append([]byte{0xAA}, make([]byte, 31)...)},
FrameNumber: 54321,
PublicKeySignatureBls48581: &BLS48581AddressedSignature{
Signature: make([]byte, 74),
Address: make([]byte, 32),
},
},
},
{
name: "minimal prover leave",
leave: &ProverLeave{
Filters: [][]byte{},
FrameNumber: 0,
PublicKeySignatureBls48581: nil,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.leave.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
leave2 := &ProverLeave{}
err = leave2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.Equal(t, tt.leave.Filters, leave2.Filters)
assert.Equal(t, tt.leave.FrameNumber, leave2.FrameNumber)
if tt.leave.PublicKeySignatureBls48581 != nil {
assert.NotNil(t, leave2.PublicKeySignatureBls48581)
assert.Equal(t, tt.leave.PublicKeySignatureBls48581.Signature, leave2.PublicKeySignatureBls48581.Signature)
assert.Equal(t, tt.leave.PublicKeySignatureBls48581.Address, leave2.PublicKeySignatureBls48581.Address)
} else {
assert.Nil(t, leave2.PublicKeySignatureBls48581)
}
})
}
}
func TestProverPause_Serialization(t *testing.T) {
tests := []struct {
name string
pause *ProverPause
}{
{
name: "complete prover pause",
pause: &ProverPause{
Filter: make([]byte, 32),
FrameNumber: 99999,
PublicKeySignatureBls48581: &BLS48581AddressedSignature{
Signature: make([]byte, 74),
Address: make([]byte, 32),
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.pause.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
pause2 := &ProverPause{}
err = pause2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.Equal(t, tt.pause.Filter, pause2.Filter)
assert.Equal(t, tt.pause.FrameNumber, pause2.FrameNumber)
assert.NotNil(t, pause2.PublicKeySignatureBls48581)
assert.Equal(t, tt.pause.PublicKeySignatureBls48581.Signature, pause2.PublicKeySignatureBls48581.Signature)
})
}
}
func TestProverResume_Serialization(t *testing.T) {
tests := []struct {
name string
resume *ProverResume
}{
{
name: "complete prover resume",
resume: &ProverResume{
Filter: make([]byte, 32),
FrameNumber: 77777,
PublicKeySignatureBls48581: &BLS48581AddressedSignature{
Signature: make([]byte, 74),
Address: make([]byte, 32),
},
},
},
{
name: "minimal prover resume",
resume: &ProverResume{
Filter: []byte{},
FrameNumber: 0,
PublicKeySignatureBls48581: nil,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.resume.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
resume2 := &ProverResume{}
err = resume2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.Equal(t, tt.resume.Filter, resume2.Filter)
assert.Equal(t, tt.resume.FrameNumber, resume2.FrameNumber)
if tt.resume.PublicKeySignatureBls48581 != nil {
assert.NotNil(t, resume2.PublicKeySignatureBls48581)
assert.Equal(t, tt.resume.PublicKeySignatureBls48581.Signature, resume2.PublicKeySignatureBls48581.Signature)
assert.Equal(t, tt.resume.PublicKeySignatureBls48581.Address, resume2.PublicKeySignatureBls48581.Address)
} else {
assert.Nil(t, resume2.PublicKeySignatureBls48581)
}
})
}
}
func TestProverConfirm_Serialization(t *testing.T) {
tests := []struct {
name string
confirm *ProverConfirm
}{
{
name: "complete prover confirm",
confirm: &ProverConfirm{
Filter: make([]byte, 32),
FrameNumber: 33333,
PublicKeySignatureBls48581: &BLS48581AddressedSignature{
Signature: make([]byte, 74),
Address: make([]byte, 32),
},
},
},
{
name: "minimal prover confirm",
confirm: &ProverConfirm{
Filter: []byte{},
FrameNumber: 0,
PublicKeySignatureBls48581: nil,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.confirm.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
confirm2 := &ProverConfirm{}
err = confirm2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.Equal(t, tt.confirm.Filter, confirm2.Filter)
assert.Equal(t, tt.confirm.FrameNumber, confirm2.FrameNumber)
if tt.confirm.PublicKeySignatureBls48581 != nil {
assert.NotNil(t, confirm2.PublicKeySignatureBls48581)
assert.Equal(t, tt.confirm.PublicKeySignatureBls48581.Signature, confirm2.PublicKeySignatureBls48581.Signature)
assert.Equal(t, tt.confirm.PublicKeySignatureBls48581.Address, confirm2.PublicKeySignatureBls48581.Address)
} else {
assert.Nil(t, confirm2.PublicKeySignatureBls48581)
}
})
}
}
func TestProverReject_Serialization(t *testing.T) {
tests := []struct {
name string
reject *ProverReject
}{
{
name: "complete prover reject",
reject: &ProverReject{
Filter: make([]byte, 32),
FrameNumber: 44444,
PublicKeySignatureBls48581: &BLS48581AddressedSignature{
Signature: make([]byte, 74),
Address: make([]byte, 32),
},
},
},
{
name: "minimal prover reject",
reject: &ProverReject{
Filter: []byte{},
FrameNumber: 0,
PublicKeySignatureBls48581: nil,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.reject.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
reject2 := &ProverReject{}
err = reject2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.Equal(t, tt.reject.Filter, reject2.Filter)
assert.Equal(t, tt.reject.FrameNumber, reject2.FrameNumber)
if tt.reject.PublicKeySignatureBls48581 != nil {
assert.NotNil(t, reject2.PublicKeySignatureBls48581)
assert.Equal(t, tt.reject.PublicKeySignatureBls48581.Signature, reject2.PublicKeySignatureBls48581.Signature)
assert.Equal(t, tt.reject.PublicKeySignatureBls48581.Address, reject2.PublicKeySignatureBls48581.Address)
} else {
assert.Nil(t, reject2.PublicKeySignatureBls48581)
}
})
}
}
func TestProverKick_Serialization(t *testing.T) {
tests := []struct {
name string
kick *ProverKick
}{
{
name: "complete prover kick",
kick: &ProverKick{
FrameNumber: 66666,
KickedProverPublicKey: make([]byte, 585), // BLS48-581 public key
ConflictingFrame_1: make([]byte, 32),
ConflictingFrame_2: make([]byte, 32),
Commitment: make([]byte, 32),
Proof: make([]byte, 160),
TraversalProof: &TraversalProof{
Multiproof: &Multiproof{
Multicommitment: make([]byte, 74),
Proof: make([]byte, 74),
},
SubProofs: []*TraversalSubProof{
{
Commits: [][]byte{make([]byte, 32)},
Ys: [][]byte{make([]byte, 48)},
Paths: []*Path{{Indices: []uint64{1, 2}}},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.kick.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
kick2 := &ProverKick{}
err = kick2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.Equal(t, tt.kick.FrameNumber, kick2.FrameNumber)
assert.Equal(t, tt.kick.KickedProverPublicKey, kick2.KickedProverPublicKey)
assert.Equal(t, tt.kick.ConflictingFrame_1, kick2.ConflictingFrame_1)
assert.Equal(t, tt.kick.ConflictingFrame_2, kick2.ConflictingFrame_2)
assert.Equal(t, tt.kick.Commitment, kick2.Commitment)
assert.Equal(t, tt.kick.Proof, kick2.Proof)
if tt.kick.TraversalProof != nil {
assert.NotNil(t, kick2.TraversalProof)
assert.NotNil(t, kick2.TraversalProof.Multiproof)
assert.Equal(t, len(tt.kick.TraversalProof.SubProofs), len(kick2.TraversalProof.SubProofs))
} else {
assert.Nil(t, kick2.TraversalProof)
}
})
}
}
func TestProverLivenessCheck_Serialization(t *testing.T) {
tests := []struct {
name string
check *ProverLivenessCheck
}{
{
name: "complete liveness check",
check: &ProverLivenessCheck{
Filter: make([]byte, 32),
FrameNumber: 88888,
Timestamp: 1234567890123,
CommitmentHash: make([]byte, 32),
PublicKeySignatureBls48581: &BLS48581AddressedSignature{
Signature: make([]byte, 74),
Address: make([]byte, 32),
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.check.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
check2 := &ProverLivenessCheck{}
err = check2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.Equal(t, tt.check.Filter, check2.Filter)
assert.Equal(t, tt.check.FrameNumber, check2.FrameNumber)
assert.Equal(t, tt.check.Timestamp, check2.Timestamp)
assert.Equal(t, tt.check.CommitmentHash, check2.CommitmentHash)
if tt.check.PublicKeySignatureBls48581 != nil {
assert.NotNil(t, check2.PublicKeySignatureBls48581)
assert.Equal(t, tt.check.PublicKeySignatureBls48581.Signature, check2.PublicKeySignatureBls48581.Signature)
assert.Equal(t, tt.check.PublicKeySignatureBls48581.Address, check2.PublicKeySignatureBls48581.Address)
} else {
assert.Nil(t, check2.PublicKeySignatureBls48581)
}
})
}
}
func TestProposalVote_Serialization(t *testing.T) {
tests := []struct {
name string
vote *ProposalVote
}{
{
name: "complete frame vote approve",
vote: &ProposalVote{
FrameNumber: 77777,
Rank: 77777,
Selector: make([]byte, 32),
PublicKeySignatureBls48581: &BLS48581AddressedSignature{
Signature: make([]byte, 74),
Address: make([]byte, 32),
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.vote.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
vote2 := &ProposalVote{}
err = vote2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.Equal(t, tt.vote.FrameNumber, vote2.FrameNumber)
assert.Equal(t, tt.vote.Rank, vote2.Rank)
assert.Equal(t, tt.vote.Selector, vote2.Selector)
assert.NotNil(t, vote2.PublicKeySignatureBls48581)
assert.Equal(t, tt.vote.PublicKeySignatureBls48581.Signature, vote2.PublicKeySignatureBls48581.Signature)
assert.Equal(t, tt.vote.PublicKeySignatureBls48581.Address, vote2.PublicKeySignatureBls48581.Address)
})
}
}
func TestQuorumCertificate_Serialization(t *testing.T) {
tests := []struct {
name string
conf *QuorumCertificate
}{
{
name: "complete confirmation",
conf: &QuorumCertificate{
FrameNumber: 12345,
Rank: 12345,
Selector: make([]byte, 32),
AggregateSignature: &BLS48581AggregateSignature{
Signature: make([]byte, 74),
PublicKey: &BLS48581G2PublicKey{
KeyValue: make([]byte, 585),
},
Bitmask: make([]byte, 32),
},
},
},
{
name: "minimal confirmation",
conf: &QuorumCertificate{
FrameNumber: 0,
Rank: 0,
Selector: []byte{},
AggregateSignature: nil,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.conf.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
conf2 := &QuorumCertificate{}
err = conf2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.Equal(t, tt.conf.FrameNumber, conf2.FrameNumber)
assert.Equal(t, tt.conf.Rank, conf2.Rank)
assert.Equal(t, tt.conf.Selector, conf2.Selector)
if tt.conf.AggregateSignature != nil {
assert.NotNil(t, conf2.AggregateSignature)
assert.Equal(t, tt.conf.AggregateSignature.Signature, conf2.AggregateSignature.Signature)
assert.Equal(t, tt.conf.AggregateSignature.Bitmask, conf2.AggregateSignature.Bitmask)
if tt.conf.AggregateSignature.PublicKey != nil {
assert.NotNil(t, conf2.AggregateSignature.PublicKey)
assert.Equal(t, tt.conf.AggregateSignature.PublicKey.KeyValue, conf2.AggregateSignature.PublicKey.KeyValue)
}
} else {
assert.Nil(t, conf2.AggregateSignature)
}
})
}
}
func TestGlobalFrameHeader_Serialization(t *testing.T) {
tests := []struct {
name string
header *GlobalFrameHeader
}{
{
name: "complete global frame header",
header: &GlobalFrameHeader{
FrameNumber: 54321,
Timestamp: 9876543210123,
Difficulty: 2000000,
Output: make([]byte, 516),
ParentSelector: make([]byte, 32),
GlobalCommitments: [][]byte{
make([]byte, 32),
make([]byte, 32),
make([]byte, 32),
},
ProverTreeCommitment: make([]byte, 32),
PublicKeySignatureBls48581: &BLS48581AggregateSignature{
Signature: make([]byte, 74),
PublicKey: &BLS48581G2PublicKey{
KeyValue: make([]byte, 585),
},
Bitmask: make([]byte, 32),
},
},
},
{
name: "minimal global frame header",
header: &GlobalFrameHeader{
FrameNumber: 0,
Timestamp: 0,
Difficulty: 0,
Output: []byte{},
ParentSelector: []byte{},
GlobalCommitments: [][]byte{},
ProverTreeCommitment: []byte{},
PublicKeySignatureBls48581: nil,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.header.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
header2 := &GlobalFrameHeader{}
err = header2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.Equal(t, tt.header.FrameNumber, header2.FrameNumber)
assert.Equal(t, tt.header.Timestamp, header2.Timestamp)
assert.Equal(t, tt.header.Difficulty, header2.Difficulty)
assert.Equal(t, tt.header.Output, header2.Output)
assert.Equal(t, tt.header.ParentSelector, header2.ParentSelector)
assert.Equal(t, tt.header.GlobalCommitments, header2.GlobalCommitments)
assert.Equal(t, tt.header.ProverTreeCommitment, header2.ProverTreeCommitment)
if tt.header.PublicKeySignatureBls48581 != nil {
assert.NotNil(t, header2.PublicKeySignatureBls48581)
assert.Equal(t, tt.header.PublicKeySignatureBls48581.Signature, header2.PublicKeySignatureBls48581.Signature)
assert.Equal(t, tt.header.PublicKeySignatureBls48581.Bitmask, header2.PublicKeySignatureBls48581.Bitmask)
if tt.header.PublicKeySignatureBls48581.PublicKey != nil {
assert.NotNil(t, header2.PublicKeySignatureBls48581.PublicKey)
assert.Equal(t, tt.header.PublicKeySignatureBls48581.PublicKey.KeyValue, header2.PublicKeySignatureBls48581.PublicKey.KeyValue)
}
} else {
assert.Nil(t, header2.PublicKeySignatureBls48581)
}
})
}
}
func TestGlobalFrame_Serialization(t *testing.T) {
tests := []struct {
name string
frame *GlobalFrame
}{
{
name: "complete global frame",
frame: &GlobalFrame{
Header: &GlobalFrameHeader{
FrameNumber: 11111,
Timestamp: 1111111111111,
Difficulty: 1500000,
Output: make([]byte, 516),
ParentSelector: make([]byte, 32),
GlobalCommitments: [][]byte{
make([]byte, 32),
make([]byte, 32),
},
ProverTreeCommitment: make([]byte, 32),
PublicKeySignatureBls48581: &BLS48581AggregateSignature{
Signature: make([]byte, 74),
PublicKey: &BLS48581G2PublicKey{
KeyValue: make([]byte, 585),
},
Bitmask: make([]byte, 32),
},
},
Requests: []*MessageBundle{
{
Requests: []*MessageRequest{},
Timestamp: 1234567890123,
},
{
Requests: []*MessageRequest{
{
Request: &MessageRequest_Join{
Join: &ProverJoin{
Filters: [][]byte{make([]byte, 32)},
FrameNumber: 12345,
PublicKeySignatureBls48581: &BLS48581SignatureWithProofOfPossession{
Signature: make([]byte, 74),
PopSignature: make([]byte, 74),
PublicKey: &BLS48581G2PublicKey{
KeyValue: make([]byte, 585),
},
},
DelegateAddress: make([]byte, 32),
MergeTargets: []*SeniorityMerge{},
},
},
},
},
Timestamp: 1234567890456,
},
},
},
},
{
name: "minimal global frame",
frame: &GlobalFrame{
Header: nil,
Requests: []*MessageBundle{},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.frame.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
frame2 := &GlobalFrame{}
err = frame2.FromCanonicalBytes(data)
require.NoError(t, err)
if tt.frame.Header != nil {
assert.NotNil(t, frame2.Header)
assert.Equal(t, tt.frame.Header.FrameNumber, frame2.Header.FrameNumber)
assert.Equal(t, tt.frame.Header.Timestamp, frame2.Header.Timestamp)
assert.Equal(t, tt.frame.Header.Difficulty, frame2.Header.Difficulty)
assert.Equal(t, tt.frame.Header.Output, frame2.Header.Output)
assert.Equal(t, tt.frame.Header.ParentSelector, frame2.Header.ParentSelector)
assert.Equal(t, tt.frame.Header.GlobalCommitments, frame2.Header.GlobalCommitments)
assert.Equal(t, tt.frame.Header.ProverTreeCommitment, frame2.Header.ProverTreeCommitment)
} else {
assert.Nil(t, frame2.Header)
}
assert.Equal(t, len(tt.frame.Requests), len(frame2.Requests))
for i := range tt.frame.Requests {
assert.Equal(t, tt.frame.Requests[i].Timestamp, frame2.Requests[i].Timestamp)
assert.Equal(t, len(tt.frame.Requests[i].Requests), len(frame2.Requests[i].Requests))
for j := range tt.frame.Requests[i].Requests {
assert.NotNil(t, frame2.Requests[i].Requests[j].Request)
// Verify the union type was preserved (basic check)
if joinReq, ok := tt.frame.Requests[i].Requests[j].Request.(*MessageRequest_Join); ok {
join2, ok2 := frame2.Requests[i].Requests[j].Request.(*MessageRequest_Join)
assert.True(t, ok2)
if ok2 {
assert.Equal(t, joinReq.Join.FrameNumber, join2.Join.FrameNumber)
assert.Equal(t, joinReq.Join.Filters, join2.Join.Filters)
}
}
}
}
})
}
}
func TestAppShardFrame_Serialization(t *testing.T) {
tests := []struct {
name string
frame *AppShardFrame
}{
{
name: "complete app shard frame",
frame: &AppShardFrame{
Header: &FrameHeader{
Address: make([]byte, 32),
FrameNumber: 67890,
Timestamp: 1234567890123,
Difficulty: 500000,
Output: make([]byte, 516),
ParentSelector: make([]byte, 32),
RequestsRoot: make([]byte, 32),
StateRoots: [][]byte{
make([]byte, 74),
make([]byte, 74),
make([]byte, 74),
make([]byte, 74),
},
Prover: make([]byte, 32),
FeeMultiplierVote: 250,
PublicKeySignatureBls48581: &BLS48581AggregateSignature{
Signature: make([]byte, 74),
PublicKey: &BLS48581G2PublicKey{
KeyValue: make([]byte, 585),
},
Bitmask: make([]byte, 32),
},
},
Requests: []*MessageBundle{
{
Requests: []*MessageRequest{},
Timestamp: 1234567890123,
},
{
Requests: []*MessageRequest{
{
Request: &MessageRequest_Join{
Join: &ProverJoin{
Filters: [][]byte{make([]byte, 32)},
FrameNumber: 67890,
PublicKeySignatureBls48581: &BLS48581SignatureWithProofOfPossession{
Signature: make([]byte, 74),
PopSignature: make([]byte, 74),
PublicKey: &BLS48581G2PublicKey{
KeyValue: make([]byte, 585),
},
},
DelegateAddress: make([]byte, 32),
MergeTargets: []*SeniorityMerge{},
},
},
},
},
Timestamp: 1234567890456,
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.frame.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
frame2 := &AppShardFrame{}
err = frame2.FromCanonicalBytes(data)
require.NoError(t, err)
if tt.frame.Header != nil {
assert.NotNil(t, frame2.Header)
assert.Equal(t, tt.frame.Header.Address, frame2.Header.Address)
assert.Equal(t, tt.frame.Header.FrameNumber, frame2.Header.FrameNumber)
assert.Equal(t, tt.frame.Header.Timestamp, frame2.Header.Timestamp)
assert.Equal(t, tt.frame.Header.Difficulty, frame2.Header.Difficulty)
assert.Equal(t, tt.frame.Header.Output, frame2.Header.Output)
assert.Equal(t, tt.frame.Header.ParentSelector, frame2.Header.ParentSelector)
assert.Equal(t, tt.frame.Header.RequestsRoot, frame2.Header.RequestsRoot)
assert.Equal(t, tt.frame.Header.StateRoots, frame2.Header.StateRoots)
assert.Equal(t, tt.frame.Header.Prover, frame2.Header.Prover)
assert.Equal(t, tt.frame.Header.FeeMultiplierVote, frame2.Header.FeeMultiplierVote)
if tt.frame.Header.PublicKeySignatureBls48581 != nil {
assert.NotNil(t, frame2.Header.PublicKeySignatureBls48581)
assert.Equal(t, tt.frame.Header.PublicKeySignatureBls48581.Signature, frame2.Header.PublicKeySignatureBls48581.Signature)
assert.Equal(t, tt.frame.Header.PublicKeySignatureBls48581.Bitmask, frame2.Header.PublicKeySignatureBls48581.Bitmask)
}
} else {
assert.Nil(t, frame2.Header)
}
assert.Equal(t, len(tt.frame.Requests), len(frame2.Requests))
for i := range tt.frame.Requests {
assert.Equal(t, tt.frame.Requests[i].Timestamp, frame2.Requests[i].Timestamp)
assert.Equal(t, len(tt.frame.Requests[i].Requests), len(frame2.Requests[i].Requests))
for j := range tt.frame.Requests[i].Requests {
assert.NotNil(t, frame2.Requests[i].Requests[j].Request)
}
}
})
}
}
func TestMessageBundle_Serialization(t *testing.T) {
tests := []struct {
name string
bundle *MessageBundle
}{
{
name: "complete message bundle",
bundle: &MessageBundle{
Requests: []*MessageRequest{
{
Request: &MessageRequest_Join{
Join: &ProverJoin{
Filters: [][]byte{make([]byte, 32)},
FrameNumber: 12345,
PublicKeySignatureBls48581: &BLS48581SignatureWithProofOfPossession{
Signature: make([]byte, 74),
PopSignature: make([]byte, 74),
PublicKey: &BLS48581G2PublicKey{
KeyValue: make([]byte, 585),
},
},
DelegateAddress: make([]byte, 32),
MergeTargets: []*SeniorityMerge{},
},
},
},
{
Request: &MessageRequest_Leave{
Leave: &ProverLeave{
Filters: [][]byte{append([]byte{0xFF}, make([]byte, 31)...)},
FrameNumber: 67890,
PublicKeySignatureBls48581: &BLS48581AddressedSignature{
Signature: make([]byte, 74),
Address: make([]byte, 32),
},
},
},
},
},
Timestamp: 1234567890123,
},
},
{
name: "empty message bundle",
bundle: &MessageBundle{
Requests: []*MessageRequest{},
Timestamp: 0,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.bundle.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
bundle2 := &MessageBundle{}
err = bundle2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.Equal(t, tt.bundle.Timestamp, bundle2.Timestamp)
assert.Equal(t, len(tt.bundle.Requests), len(bundle2.Requests))
for i := range tt.bundle.Requests {
assert.NotNil(t, bundle2.Requests[i].Request)
// Verify the union type was preserved (basic check)
if joinReq, ok := tt.bundle.Requests[i].Request.(*MessageRequest_Join); ok {
join2, ok2 := bundle2.Requests[i].Request.(*MessageRequest_Join)
assert.True(t, ok2)
if ok2 {
assert.Equal(t, joinReq.Join.FrameNumber, join2.Join.FrameNumber)
assert.Equal(t, joinReq.Join.Filters, join2.Join.Filters)
}
} else if leaveReq, ok := tt.bundle.Requests[i].Request.(*MessageRequest_Leave); ok {
leave2, ok2 := bundle2.Requests[i].Request.(*MessageRequest_Leave)
assert.True(t, ok2)
if ok2 {
assert.Equal(t, leaveReq.Leave.FrameNumber, leave2.Leave.FrameNumber)
assert.Equal(t, leaveReq.Leave.Filters, leave2.Leave.Filters)
}
}
}
})
}
}
func TestMultiproof_Serialization(t *testing.T) {
tests := []struct {
name string
multiproof *Multiproof
}{
{
name: "complete multiproof",
multiproof: &Multiproof{
Multicommitment: make([]byte, 74),
Proof: make([]byte, 74),
},
},
{
name: "multiproof with different sizes",
multiproof: &Multiproof{
Multicommitment: append([]byte{0xAA}, make([]byte, 73)...),
Proof: append([]byte{0xBB}, make([]byte, 73)...),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.multiproof.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
multiproof2 := &Multiproof{}
err = multiproof2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.Equal(t, tt.multiproof.Multicommitment, multiproof2.Multicommitment)
assert.Equal(t, tt.multiproof.Proof, multiproof2.Proof)
})
}
}
func TestPath_Serialization(t *testing.T) {
tests := []struct {
name string
path *Path
}{
{
name: "complete path",
path: &Path{
Indices: []uint64{1, 2, 3, 4, 5},
},
},
{
name: "single index path",
path: &Path{
Indices: []uint64{42},
},
},
{
name: "empty path",
path: &Path{
Indices: []uint64{},
},
},
{
name: "path with large indices",
path: &Path{
Indices: []uint64{1<<63 - 1, 1<<32 - 1, 0},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.path.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
path2 := &Path{}
err = path2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.Equal(t, tt.path.Indices, path2.Indices)
})
}
}
func TestTraversalSubProof_Serialization(t *testing.T) {
tests := []struct {
name string
subProof *TraversalSubProof
}{
{
name: "complete traversal sub proof",
subProof: &TraversalSubProof{
Commits: [][]byte{
make([]byte, 32),
make([]byte, 32),
},
Ys: [][]byte{
make([]byte, 48),
make([]byte, 48),
},
Paths: []*Path{
{Indices: []uint64{1, 2, 3}},
{Indices: []uint64{4, 5}},
},
},
},
{
name: "minimal traversal sub proof",
subProof: &TraversalSubProof{
Commits: [][]byte{},
Ys: [][]byte{},
Paths: []*Path{},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.subProof.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
subProof2 := &TraversalSubProof{}
err = subProof2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.Equal(t, tt.subProof.Commits, subProof2.Commits)
assert.Equal(t, tt.subProof.Ys, subProof2.Ys)
assert.Equal(t, len(tt.subProof.Paths), len(subProof2.Paths))
for i := range tt.subProof.Paths {
assert.Equal(t, tt.subProof.Paths[i].Indices, subProof2.Paths[i].Indices)
}
})
}
}
func TestTraversalProof_Serialization(t *testing.T) {
tests := []struct {
name string
proof *TraversalProof
}{
{
name: "complete traversal proof",
proof: &TraversalProof{
Multiproof: &Multiproof{
Multicommitment: make([]byte, 74),
Proof: make([]byte, 74),
},
SubProofs: []*TraversalSubProof{
{
Commits: [][]byte{make([]byte, 74)},
Ys: [][]byte{make([]byte, 48)},
Paths: []*Path{{Indices: []uint64{1, 2}}},
},
{
Commits: [][]byte{make([]byte, 74), make([]byte, 74)},
Ys: [][]byte{make([]byte, 48), make([]byte, 48)},
Paths: []*Path{{Indices: []uint64{3, 4, 5}}},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := tt.proof.ToCanonicalBytes()
require.NoError(t, err)
require.NotNil(t, data)
proof2 := &TraversalProof{}
err = proof2.FromCanonicalBytes(data)
require.NoError(t, err)
assert.NotNil(t, proof2.Multiproof)
assert.Equal(t, tt.proof.Multiproof.Multicommitment, proof2.Multiproof.Multicommitment)
assert.Equal(t, tt.proof.Multiproof.Proof, proof2.Multiproof.Proof)
assert.Equal(t, len(tt.proof.SubProofs), len(proof2.SubProofs))
for i := range tt.proof.SubProofs {
assert.Equal(t, tt.proof.SubProofs[i].Commits, proof2.SubProofs[i].Commits)
assert.Equal(t, tt.proof.SubProofs[i].Ys, proof2.SubProofs[i].Ys)
assert.Equal(t, len(tt.proof.SubProofs[i].Paths), len(proof2.SubProofs[i].Paths))
}
})
}
}