From daec34b6a7bd3d0788885df5ded1abf15eccdd28 Mon Sep 17 00:00:00 2001 From: Ethan Reesor Date: Mon, 15 Apr 2024 17:17:30 -0500 Subject: [PATCH] Restore simulator recordings [#3593] --- pkg/url/txid.go | 14 +- test/harness/simulator.go | 10 +- test/simulator/consensus.go | 4 +- test/simulator/consensus/app.go | 12 + test/simulator/consensus/dispatcher.go | 2 +- test/simulator/consensus/enums.yml | 22 + test/simulator/consensus/enums_gen.go | 134 ++ test/simulator/consensus/messages.go | 51 + test/simulator/consensus/messages.yml | 144 ++ test/simulator/consensus/node.go | 9 +- test/simulator/consensus/state_block.go | 63 +- test/simulator/consensus/state_node.go | 35 +- test/simulator/consensus/state_submit.go | 14 +- test/simulator/consensus/types.go | 130 +- test/simulator/consensus/types_gen.go | 2686 ++++++++++++++++++++++ test/simulator/consensus/unions_gen.go | 201 ++ test/simulator/recorder.go | 87 +- test/simulator/recorder_enums.yml | 4 +- test/simulator/recorder_enums_gen.go | 11 +- test/simulator/recorder_types.yml | 7 + test/simulator/recorder_types_gen.go | 144 ++ tools/cmd/gen-types/go.go | 2 +- tools/cmd/gen-types/templates.go | 22 +- tools/internal/typegen/types.go | 4 +- 24 files changed, 3542 insertions(+), 270 deletions(-) create mode 100644 test/simulator/consensus/enums.yml create mode 100644 test/simulator/consensus/enums_gen.go create mode 100644 test/simulator/consensus/messages.go create mode 100644 test/simulator/consensus/messages.yml create mode 100644 test/simulator/consensus/types_gen.go create mode 100644 test/simulator/consensus/unions_gen.go diff --git a/pkg/url/txid.go b/pkg/url/txid.go index 34c7dd7e2..108109915 100644 --- a/pkg/url/txid.go +++ b/pkg/url/txid.go @@ -10,6 +10,7 @@ import ( "bytes" "encoding/hex" "encoding/json" + "sync/atomic" ) // TxID is a transaction identifier. @@ -18,7 +19,7 @@ type TxID struct { hash [32]byte memoize struct { - str string + str atomic.Pointer[string] } } @@ -98,12 +99,9 @@ func (x *TxID) Compare(y *TxID) int { // String reassembles the transaction ID into a valid URL string. See // net/url.URL.String(). func (x *TxID) String() string { - if x.memoize.str != "" { - return x.memoize.str - } - - x.memoize.str = x.url.format(x.hash[:], true) - return x.memoize.str + return getOrMakeAtomic(&x.memoize.str, func() string { + return x.url.format(x.hash[:], true) + }) } // RawString reassembles the URL into a valid URL string without encoding any @@ -135,6 +133,6 @@ func (x *TxID) UnmarshalJSON(data []byte) error { return err } - *x = *v + *x = *v //nolint:govet return nil } diff --git a/test/harness/simulator.go b/test/harness/simulator.go index 7582ddb39..5b07b60f2 100644 --- a/test/harness/simulator.go +++ b/test/harness/simulator.go @@ -12,6 +12,7 @@ import ( "io" "os" "path/filepath" + "strings" "testing" "time" @@ -43,6 +44,7 @@ func NewSim(tb testing.TB, opts ...simulator.Option) *Sim { func Recordings(tb testing.TB) simulator.RecordingFunc { onFail := os.Getenv("RECORD_FAILURE") + always := strings.EqualFold(os.Getenv("RECORD_ALWAYS"), "yes") if onFail == "" { return nil } @@ -60,12 +62,16 @@ func Recordings(tb testing.TB) simulator.RecordingFunc { return nil, err } tb.Cleanup(func() { - if !tb.Failed() { + if !always && !tb.Failed() { assert.NoError(tb, f.Close()) return } if !didAnnounce { - tb.Logf("Failure recordings for %s are prefixed with %x", tb.Name(), prefix) + msg := "Failure recordings" + if !tb.Failed() { + msg = "Recordings" + } + tb.Logf("%s for %s are prefixed with %x", msg, tb.Name(), prefix) didAnnounce = true } dst := filepath.Join(onFail, fmt.Sprintf("%x-%s-%d.record", prefix, partition, node)) diff --git a/test/simulator/consensus.go b/test/simulator/consensus.go index 1c58fb6a2..39722a2d4 100644 --- a/test/simulator/consensus.go +++ b/test/simulator/consensus.go @@ -33,8 +33,8 @@ func (p *Partition) Submit(envelope *messaging.Envelope, pretend bool) ([]*proto return st, nil } - var resp consensus.Capture[*consensus.SubmissionResponse] - err = p.sim.hub.With(&resp).Send(&consensus.Submission{ + var resp consensus.Capture[*consensus.EnvelopeSubmitted] + err = p.sim.hub.With(&resp).Send(&consensus.SubmitEnvelope{ Network: p.ID, Envelope: envelope, Pretend: pretend, diff --git a/test/simulator/consensus/app.go b/test/simulator/consensus/app.go index 4d32826d2..be9e641ec 100644 --- a/test/simulator/consensus/app.go +++ b/test/simulator/consensus/app.go @@ -75,10 +75,15 @@ type ExecutorApp struct { Executor execute.Executor Restore RestoreFunc EventBus *events.Bus + Record Recorder } type RestoreFunc func(ioutil.SectionReader) error +func (a *ExecutorApp) SetRecorder(rec Recorder) { + a.Record = rec +} + func (a *ExecutorApp) Info(*InfoRequest) (*InfoResponse, error) { last, hash, err := a.Executor.LastBlock() if err != nil { @@ -191,6 +196,13 @@ func (a *ExecutorApp) Commit(req *CommitRequest) (*CommitResponse, error) { return nil, errors.UnknownError.Wrap(err) } + if a.Record != nil { + err = a.Record.DidCommitBlock(s) + if err != nil { + return nil, errors.UnknownError.Wrap(err) + } + } + return &CommitResponse{ Hash: hash, }, nil diff --git a/test/simulator/consensus/dispatcher.go b/test/simulator/consensus/dispatcher.go index 9317ed9fb..86a1b3fa0 100644 --- a/test/simulator/consensus/dispatcher.go +++ b/test/simulator/consensus/dispatcher.go @@ -34,7 +34,7 @@ func (d *Dispatcher) Submit(ctx context.Context, dest *url.URL, envelope *messag d.mu.Lock() defer d.mu.Unlock() - d.queue = append(d.queue, &Submission{ + d.queue = append(d.queue, &SubmitEnvelope{ Network: partition, Envelope: envelope, }) diff --git a/test/simulator/consensus/enums.yml b/test/simulator/consensus/enums.yml new file mode 100644 index 000000000..76a7d6b31 --- /dev/null +++ b/test/simulator/consensus/enums.yml @@ -0,0 +1,22 @@ +messageType: + StartBlock: + value: 0x10 + ProposeLeader: + value: 0x11 + ProposeBlock: + value: 0x12 + AcceptBlockProposal: + value: 0x13 + FinalizedBlock: + value: 0x14 + CommittedBlock: + value: 0x15 + ExecutedBlock: + value: 0x16 + + SubmitEnvelope: + value: 0x20 + AcceptedSubmission: + value: 0x21 + EnvelopeSubmitted: + value: 0x22 diff --git a/test/simulator/consensus/enums_gen.go b/test/simulator/consensus/enums_gen.go new file mode 100644 index 000000000..a2d99c60a --- /dev/null +++ b/test/simulator/consensus/enums_gen.go @@ -0,0 +1,134 @@ +// Copyright 2024 The Accumulate Authors +// +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file or at +// https://opensource.org/licenses/MIT. + +package consensus + +// GENERATED BY go run ./tools/cmd/gen-enum. DO NOT EDIT. + +import ( + "encoding/json" + "fmt" + "strings" +) + +// messageTypeStartBlock . +const messageTypeStartBlock messageType = 16 + +// messageTypeProposeLeader . +const messageTypeProposeLeader messageType = 17 + +// messageTypeProposeBlock . +const messageTypeProposeBlock messageType = 18 + +// messageTypeAcceptBlockProposal . +const messageTypeAcceptBlockProposal messageType = 19 + +// messageTypeFinalizedBlock . +const messageTypeFinalizedBlock messageType = 20 + +// messageTypeCommittedBlock . +const messageTypeCommittedBlock messageType = 21 + +// messageTypeExecutedBlock . +const messageTypeExecutedBlock messageType = 22 + +// messageTypeSubmitEnvelope . +const messageTypeSubmitEnvelope messageType = 32 + +// messageTypeAcceptedSubmission . +const messageTypeAcceptedSubmission messageType = 33 + +// messageTypeEnvelopeSubmitted . +const messageTypeEnvelopeSubmitted messageType = 34 + +// GetEnumValue returns the value of the message Type +func (v messageType) GetEnumValue() uint64 { return uint64(v) } + +// SetEnumValue sets the value. SetEnumValue returns false if the value is invalid. +func (v *messageType) SetEnumValue(id uint64) bool { + u := messageType(id) + switch u { + case messageTypeStartBlock, messageTypeProposeLeader, messageTypeProposeBlock, messageTypeAcceptBlockProposal, messageTypeFinalizedBlock, messageTypeCommittedBlock, messageTypeExecutedBlock, messageTypeSubmitEnvelope, messageTypeAcceptedSubmission, messageTypeEnvelopeSubmitted: + *v = u + return true + } + return false +} + +// String returns the name of the message Type. +func (v messageType) String() string { + switch v { + case messageTypeStartBlock: + return "startBlock" + case messageTypeProposeLeader: + return "proposeLeader" + case messageTypeProposeBlock: + return "proposeBlock" + case messageTypeAcceptBlockProposal: + return "acceptBlockProposal" + case messageTypeFinalizedBlock: + return "finalizedBlock" + case messageTypeCommittedBlock: + return "committedBlock" + case messageTypeExecutedBlock: + return "executedBlock" + case messageTypeSubmitEnvelope: + return "submitEnvelope" + case messageTypeAcceptedSubmission: + return "acceptedSubmission" + case messageTypeEnvelopeSubmitted: + return "envelopeSubmitted" + } + return fmt.Sprintf("messageType:%d", v) +} + +// messageTypeByName returns the named message Type. +func messageTypeByName(name string) (messageType, bool) { + switch strings.ToLower(name) { + case "startblock": + return messageTypeStartBlock, true + case "proposeleader": + return messageTypeProposeLeader, true + case "proposeblock": + return messageTypeProposeBlock, true + case "acceptblockproposal": + return messageTypeAcceptBlockProposal, true + case "finalizedblock": + return messageTypeFinalizedBlock, true + case "committedblock": + return messageTypeCommittedBlock, true + case "executedblock": + return messageTypeExecutedBlock, true + case "submitenvelope": + return messageTypeSubmitEnvelope, true + case "acceptedsubmission": + return messageTypeAcceptedSubmission, true + case "envelopesubmitted": + return messageTypeEnvelopeSubmitted, true + } + return 0, false +} + +// MarshalJSON marshals the message Type to JSON as a string. +func (v messageType) MarshalJSON() ([]byte, error) { + return json.Marshal(v.String()) +} + +// UnmarshalJSON unmarshals the message Type from JSON as a string. +func (v *messageType) UnmarshalJSON(data []byte) error { + var s string + err := json.Unmarshal(data, &s) + if err != nil { + return err + } + + var ok bool + *v, ok = messageTypeByName(s) + if !ok || strings.ContainsRune(v.String(), ':') { + return fmt.Errorf("invalid message Type %q", s) + } + return nil +} diff --git a/test/simulator/consensus/messages.go b/test/simulator/consensus/messages.go new file mode 100644 index 000000000..2af716ce8 --- /dev/null +++ b/test/simulator/consensus/messages.go @@ -0,0 +1,51 @@ +// Copyright 2024 The Accumulate Authors +// +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file or at +// https://opensource.org/licenses/MIT. +package consensus + +import "gitlab.com/accumulatenetwork/accumulate/pkg/types/encoding" + +//go:generate go run gitlab.com/accumulatenetwork/accumulate/tools/cmd/gen-enum --package consensus --out enums_gen.go enums.yml +//go:generate go run gitlab.com/accumulatenetwork/accumulate/tools/cmd/gen-types --package consensus messages.yml +//go:generate go run gitlab.com/accumulatenetwork/accumulate/tools/cmd/gen-types --package consensus --language go-union --out unions_gen.go messages.yml + +type messageType int + +// A Message is a message sent between modules. +type Message interface { + encoding.UnionValue + isMsg() + Type() messageType +} + +// A NetworkMessage is a message that is specific to a network. +type NetworkMessage interface { + Message + PartitionID() string +} + +// nodeMessages are passed between nodes. +type NodeMessage interface { + NetworkMessage + SenderID() [32]byte +} + +func (*baseNodeMessage) isMsg() {} +func (*SubmitEnvelope) isMsg() {} +func (*EnvelopeSubmitted) isMsg() {} +func (*StartBlock) isMsg() {} +func (*ExecutedBlock) isMsg() {} + +func (m *baseNodeMessage) PartitionID() string { return m.Network } +func (s *SubmitEnvelope) PartitionID() string { return s.Network } + +func (m *baseNodeMessage) SenderID() [32]byte { return m.PubKeyHash } + +var _ NodeMessage = (*proposeLeader)(nil) +var _ NodeMessage = (*proposeBlock)(nil) +var _ NodeMessage = (*acceptBlockProposal)(nil) +var _ NodeMessage = (*finalizedBlock)(nil) +var _ NodeMessage = (*committedBlock)(nil) +var _ NetworkMessage = (*SubmitEnvelope)(nil) diff --git a/test/simulator/consensus/messages.yml b/test/simulator/consensus/messages.yml new file mode 100644 index 000000000..cbc01fc05 --- /dev/null +++ b/test/simulator/consensus/messages.yml @@ -0,0 +1,144 @@ +StartBlock: + union: { type: message, private-enum: true } + fields: ~ + +proposeLeader: + union: { type: message, private-enum: true } + fields: + - type: baseNodeMessage + marshal-as: reference + - type: LeaderProposal + marshal-as: reference + +proposeBlock: + union: { type: message, private-enum: true } + fields: + - type: baseNodeMessage + marshal-as: reference + - type: BlockProposal + marshal-as: reference + +acceptBlockProposal: + union: { type: message, private-enum: true } + fields: + - type: baseNodeMessage + marshal-as: reference + - name: p + type: proposeBlock + marshal-as: reference + +finalizedBlock: + union: { type: message, private-enum: true } + fields: + - type: baseNodeMessage + marshal-as: reference + - name: results + type: BlockResults + marshal-as: reference + +committedBlock: + union: { type: message, private-enum: true } + fields: + - type: baseNodeMessage + marshal-as: reference + - name: results + type: CommitResult + marshal-as: reference + +ExecutedBlock: + union: { type: message, private-enum: true } + fields: + - name: Network + type: string + - name: Node + type: hash + +SubmitEnvelope: + union: { type: message, private-enum: true } + fields: + - name: Network + type: string + - name: Envelope + type: messaging.Envelope + pointer: true + marshal-as: reference + - name: Pretend + type: bool + +acceptedSubmission: + union: { type: message, private-enum: true } + fields: + - type: baseNodeMessage + marshal-as: reference + - name: result + type: EnvelopeSubmitted + marshal-as: reference + - name: env + type: messaging.Envelope + pointer: true + marshal-as: reference + +EnvelopeSubmitted: + union: { type: message, private-enum: true } + fields: + - name: Results + type: protocol.TransactionStatus + pointer: true + repeatable: true + marshal-as: reference + +# Types + +baseNodeMessage: + fields: + - name: PubKeyHash + type: hash + - name: Network + type: string + +LeaderProposal: + fields: + - name: Leader + type: hash + +BlockProposal: + fields: + - type: LeaderProposal + marshal-as: reference + - name: Index + type: uint + - name: Time + type: time + - name: Envelopes + type: messaging.Envelope + pointer: true + repeatable: true + marshal-as: reference + +BlockResults: + fields: + - name: MessageResults + type: protocol.TransactionStatus + pointer: true + repeatable: true + marshal-as: reference + - name: ValidatorUpdates + type: ValidatorUpdate + pointer: true + repeatable: true + marshal-as: reference + +ValidatorUpdate: + fields: + - name: Type + type: protocol.SignatureType + marshal-as: enum + - name: PublicKey + type: bytes + - name: Power + type: int + +CommitResult: + fields: + - name: Hash + type: hash diff --git a/test/simulator/consensus/node.go b/test/simulator/consensus/node.go index 22d28b3f1..f997091fe 100644 --- a/test/simulator/consensus/node.go +++ b/test/simulator/consensus/node.go @@ -14,7 +14,6 @@ import ( "sync" "time" - "gitlab.com/accumulatenetwork/accumulate/exp/ioutil" "gitlab.com/accumulatenetwork/accumulate/internal/core/execute" "gitlab.com/accumulatenetwork/accumulate/internal/logging" sortutil "gitlab.com/accumulatenetwork/accumulate/internal/util/sort" @@ -64,11 +63,6 @@ func (v *validator) cmpKey(k []byte) int { return bytes.Compare(v.PubKey, k) } type ExecuteHookFunc = func(*Node, execute.BlockParams, []*messaging.Envelope) (_ []*messaging.Envelope, keepHook bool) -type Recorder interface { - DidInit(snapshot ioutil.SectionReader) error - DidExecuteBlock(state execute.BlockState, submissions []*messaging.Envelope) error -} - type StatusRequest struct{} type StatusResponse struct { @@ -95,6 +89,9 @@ func (n *Node) SetRecorder(rec Recorder) { n.mu.Lock() defer n.mu.Unlock() n.record = rec + if app, ok := n.app.(interface{ SetRecorder(Recorder) }); ok { + app.SetRecorder(rec) + } } func (n *Node) SetExecuteHook(hook ExecuteHookFunc) { diff --git a/test/simulator/consensus/state_block.go b/test/simulator/consensus/state_block.go index 71c2b53ef..8e4bb78dd 100644 --- a/test/simulator/consensus/state_block.go +++ b/test/simulator/consensus/state_block.go @@ -29,11 +29,6 @@ func (n *Node) proposeLeader() (blockState, []Message, error) { return s, out, err } -type proposeLeader struct { - baseNodeMessage - LeaderProposal -} - // didProposeLeader is the state of the node after a leader has been proposed. type didProposeLeader struct { *Node @@ -52,7 +47,7 @@ func (n *didProposeLeader) execute(msg Message) (blockState, []Message, error) { switch msg := msg.(type) { case *proposeLeader: // Verify the proposal matches - if msg.LeaderProposal != n.p.LeaderProposal { + if !msg.LeaderProposal.Equal(&n.p.LeaderProposal) { slog.ErrorContext(n.context, "Conflicting leader proposal", "mine", logging.AsHex(n.p.Leader).Slice(0, 4), "theirs", logging.AsHex(msg.Leader).Slice(0, 4)) @@ -64,7 +59,7 @@ func (n *didProposeLeader) execute(msg Message) (blockState, []Message, error) { } // Add the vote - n.votes.add(msg.senderID()) + n.votes.add(msg.SenderID()) case *proposeBlock: // Verify the threshold has been reached @@ -73,7 +68,7 @@ func (n *didProposeLeader) execute(msg Message) (blockState, []Message, error) { } // And the block proposal came from the leader - if h := msg.senderID(); h != n.p.Leader { + if h := msg.SenderID(); h != n.p.Leader { return n, nil, errors.Conflict.WithFormat("got block proposal from wrong leader: want %x, got %x", n.p.Leader[:4], h[:4]) } @@ -133,18 +128,8 @@ func (n *Node) acceptBlockProposal(p *proposeBlock) (blockState, []Message, erro m.Node = n m.p = *p m.votes = n.newVotes() - m.votes.add(p.senderID()) - return m, []Message{&acceptBlockProposal{n.newMsg(), *p}}, nil -} - -type proposeBlock struct { - baseNodeMessage - BlockProposal -} - -type acceptBlockProposal struct { - baseNodeMessage - p proposeBlock + m.votes.add(p.SenderID()) + return m, []Message{&acceptBlockProposal{baseNodeMessage: n.newMsg(), p: *p}}, nil } // didProposeBlock is the state of the node after a block has been proposed. @@ -156,7 +141,7 @@ type didProposeBlock struct { func (m *proposeBlock) equal(n *proposeBlock) bool { // The proposals are equal and were proposed by the same node - return m.senderID() == n.senderID() && + return m.SenderID() == n.SenderID() && m.BlockProposal.Equal(&n.BlockProposal) } @@ -174,7 +159,7 @@ func (n *didProposeBlock) execute(msg Message) (blockState, []Message, error) { } } - n.votes.add(msg.senderID()) + n.votes.add(msg.SenderID()) } if !n.votes.reachedThreshold() { @@ -232,17 +217,18 @@ func (n *Node) finalizeBlock(p *BlockProposal) (blockState, []Message, error) { if !n.IgnoreDeliverResults { m.b.results.MessageResults = res.Results } - m.b.results.ValidatorUpdates = res.Updates + for _, up := range res.Updates { + m.b.results.ValidatorUpdates = append(m.b.results.ValidatorUpdates, &ValidatorUpdate{ + Type: up.Type, + PublicKey: up.PublicKey, + Power: up.Power, + }) + } m.votes = n.newVotes() m.blockState = res.Block return m, []Message{&m.b}, nil } -type finalizedBlock struct { - baseNodeMessage - results BlockResults -} - // didFinalizeBlock is the state of a node after the block has been 'finalized' // (executed). type didFinalizeBlock struct { @@ -266,7 +252,7 @@ func (n *didFinalizeBlock) execute(msg Message) (blockState, []Message, error) { } } - n.votes.add(msg.senderID()) + n.votes.add(msg.SenderID()) } if !n.votes.reachedThreshold() { @@ -280,7 +266,15 @@ func (n *didFinalizeBlock) execute(msg Message) (blockState, []Message, error) { func (n *Node) commitBlock(results *BlockResults, state any) (blockState, []Message, error) { // Apply validator updates - n.applyValUp(results.ValidatorUpdates) + var updates []*execute.ValidatorUpdate + for _, up := range results.ValidatorUpdates { + updates = append(updates, &execute.ValidatorUpdate{ + Type: up.Type, + PublicKey: up.PublicKey, + Power: up.Power, + }) + } + n.applyValUp(updates) // Commit the block hash, err := n.commit(state) @@ -298,11 +292,6 @@ func (n *Node) commitBlock(results *BlockResults, state any) (blockState, []Mess return m, []Message{&m.b}, nil } -type committedBlock struct { - baseNodeMessage - results CommitResult -} - // didCommitBlock is the state of the node after a block has been committed. type didCommitBlock struct { *Node @@ -315,7 +304,7 @@ type didCommitBlock struct { func (n *didCommitBlock) execute(msg Message) (blockState, []Message, error) { switch msg := msg.(type) { case *committedBlock: - if !n.IgnoreCommitResults && n.b.results != msg.results { + if !n.IgnoreCommitResults && !n.b.results.Equal(&msg.results) { return n, nil, &ConsensusError[CommitResult]{ Message: "conflicting commit results", Mine: n.b.results, @@ -323,7 +312,7 @@ func (n *didCommitBlock) execute(msg Message) (blockState, []Message, error) { } } - n.votes.add(msg.senderID()) + n.votes.add(msg.SenderID()) } if !n.votes.reachedThreshold() { diff --git a/test/simulator/consensus/state_node.go b/test/simulator/consensus/state_node.go index 726368f7f..10e3ae115 100644 --- a/test/simulator/consensus/state_node.go +++ b/test/simulator/consensus/state_node.go @@ -14,22 +14,29 @@ import ( func (n *Node) Receive(messages ...Message) ([]Message, error) { var allOut []Message + if n.record != nil { + err := n.record.DidReceiveMessages(messages) + if err != nil { + return nil, err + } + } + // Process each message for _, msg := range messages { // Ignore messages from ourself - if msg, ok := msg.(nodeMessage); ok && - msg.senderID() == n.self.PubKeyHash { + if msg, ok := msg.(NodeMessage); ok && + msg.SenderID() == n.self.PubKeyHash { continue } // Ignore messages for other networks - if msg, ok := msg.(networkMessage); ok && - msg.network() != n.network { + if msg, ok := msg.(NetworkMessage); ok && + msg.PartitionID() != n.network { continue } switch msg := msg.(type) { - case *Submission: + case *SubmitEnvelope: if n.submitState[msg.Envelope] != nil { continue } @@ -90,26 +97,10 @@ func (n *Node) Receive(messages ...Message) ([]Message, error) { return allOut, nil } -// nodeMessages are passed between nodes. -type nodeMessage interface { - Message - senderID() [32]byte -} - -type baseNodeMessage struct { - sender *Node -} - -var _ networkMessage = (*baseNodeMessage)(nil) - func (n *Node) newMsg() baseNodeMessage { - return baseNodeMessage{n} + return baseNodeMessage{PubKeyHash: n.self.PubKeyHash, Network: n.network} } -func (_ *baseNodeMessage) isMsg() {} -func (m *baseNodeMessage) senderID() [32]byte { return m.sender.self.PubKeyHash } -func (m *baseNodeMessage) network() string { return m.sender.network } - // Make lint shut up func init() { if false { diff --git a/test/simulator/consensus/state_submit.go b/test/simulator/consensus/state_submit.go index 7b384303c..c18967194 100644 --- a/test/simulator/consensus/state_submit.go +++ b/test/simulator/consensus/state_submit.go @@ -19,7 +19,7 @@ type submitMessage interface { envelope() *messaging.Envelope } -func (n *Node) processSubmission(sub *Submission) (submitState, []Message, error) { +func (n *Node) processSubmission(sub *SubmitEnvelope) (submitState, []Message, error) { result, err := n.check(context.Background(), sub.Envelope) if err != nil { return nil, nil, err @@ -27,7 +27,7 @@ func (n *Node) processSubmission(sub *Submission) (submitState, []Message, error if sub.Pretend { return nil, []Message{ - &SubmissionResponse{ + &EnvelopeSubmitted{ Results: result, }, }, nil @@ -45,12 +45,6 @@ func (n *Node) processSubmission(sub *Submission) (submitState, []Message, error return s, out, err } -type acceptedSubmission struct { - baseNodeMessage - result SubmissionResponse - env *messaging.Envelope -} - type didAcceptSubmission struct { *Node s acceptedSubmission @@ -64,7 +58,7 @@ func (n *didAcceptSubmission) execute(msg Message) (submitState, []Message, erro case *acceptedSubmission: // Verify the result matches if !msg.result.Equal(&n.s.result) { - return n, nil, &ConsensusError[SubmissionResponse]{ + return n, nil, &ConsensusError[EnvelopeSubmitted]{ Message: "conflicting leader proposal", Mine: n.s.result, Theirs: msg.result, @@ -72,7 +66,7 @@ func (n *didAcceptSubmission) execute(msg Message) (submitState, []Message, erro } // Add the vote - n.votes.add(msg.senderID()) + n.votes.add(msg.SenderID()) } if !n.votes.reachedThreshold() { diff --git a/test/simulator/consensus/types.go b/test/simulator/consensus/types.go index 1467d419c..4bb180113 100644 --- a/test/simulator/consensus/types.go +++ b/test/simulator/consensus/types.go @@ -7,11 +7,8 @@ package consensus import ( - "time" - + "gitlab.com/accumulatenetwork/accumulate/exp/ioutil" "gitlab.com/accumulatenetwork/accumulate/internal/core/execute" - "gitlab.com/accumulatenetwork/accumulate/pkg/types/messaging" - "gitlab.com/accumulatenetwork/accumulate/protocol" ) // A Module is a component of a consensus network. @@ -21,17 +18,6 @@ type Module interface { Receive(...Message) ([]Message, error) } -// A Message is a message sent between modules. -type Message interface { - isMsg() -} - -// A networkMessage is a message that is specific to a network. -type networkMessage interface { - Message - network() string -} - // A Hub distributes messages to modules. type Hub interface { Register(module Module) @@ -39,116 +25,10 @@ type Hub interface { With(modules ...Module) Hub } -type Response interface { - Message - isResponse() -} - -type Submission struct { - Network string - Envelope *messaging.Envelope - Pretend bool -} - -var _ networkMessage = (*Submission)(nil) - -func (_ *Submission) isMsg() {} -func (s *Submission) network() string { return s.Network } - -type SubmissionResponse struct { - Results []*protocol.TransactionStatus -} - -var _ Response = (*SubmissionResponse)(nil) - -func (*SubmissionResponse) isMsg() {} -func (*SubmissionResponse) isResponse() {} - -func (s *SubmissionResponse) Equal(r *SubmissionResponse) bool { - if len(s.Results) != len(r.Results) { - return false - } - - for i := range s.Results { - if !s.Results[i].Equal(r.Results[i]) { - return false - } - } - - return true -} - -// StartBlock starts a block. -type StartBlock struct{} - -var _ Message = (*StartBlock)(nil) - -func (*StartBlock) isMsg() {} - -type ExecutedBlock struct { - Network string - Node [32]byte -} - -var _ Response = (*ExecutedBlock)(nil) - -func (*ExecutedBlock) isMsg() {} -func (*ExecutedBlock) isResponse() {} - -type LeaderProposal struct { - Leader [32]byte -} - -type BlockProposal struct { - LeaderProposal - Index uint64 - Time time.Time - Envelopes []*messaging.Envelope -} - -func (b *BlockProposal) Equal(c *BlockProposal) bool { - if b.Index != c.Index || - !b.Time.Equal(c.Time) || - len(b.Envelopes) != len(c.Envelopes) { - return false - } - - for i := range b.Envelopes { - if !b.Envelopes[i].Equal(c.Envelopes[i]) { - return false - } - } - return true -} - -type BlockResults struct { - MessageResults []*protocol.TransactionStatus - ValidatorUpdates []*execute.ValidatorUpdate -} - -func (b *BlockResults) Equal(c *BlockResults) bool { - if len(b.MessageResults) != len(c.MessageResults) || - len(b.ValidatorUpdates) != len(c.ValidatorUpdates) { - return false - } - - for i := range b.MessageResults { - if !b.MessageResults[i].Equal(c.MessageResults[i]) { - return false - } - } - - for i := range b.ValidatorUpdates { - if !b.ValidatorUpdates[i].Equal(c.ValidatorUpdates[i]) { - return false - } - } - - return true -} - -type CommitResult struct { - Hash [32]byte +type Recorder interface { + DidInit(snapshot ioutil.SectionReader) error + DidReceiveMessages([]Message) error + DidCommitBlock(state execute.BlockState) error } // A ConsensusError is produced when nodes produce conflicting results. diff --git a/test/simulator/consensus/types_gen.go b/test/simulator/consensus/types_gen.go new file mode 100644 index 000000000..e5c83de48 --- /dev/null +++ b/test/simulator/consensus/types_gen.go @@ -0,0 +1,2686 @@ +// Copyright 2022 The Accumulate Authors +// +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file or at +// https://opensource.org/licenses/MIT. + +package consensus + +// GENERATED BY go run ./tools/cmd/gen-types. DO NOT EDIT. + +//lint:file-ignore S1001,S1002,S1008,SA4013 generated code + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io" + "strings" + "time" + + "gitlab.com/accumulatenetwork/accumulate/pkg/types/encoding" + "gitlab.com/accumulatenetwork/accumulate/pkg/types/messaging" + "gitlab.com/accumulatenetwork/accumulate/protocol" +) + +type BlockProposal struct { + fieldsSet []bool + LeaderProposal + Index uint64 `json:"index,omitempty" form:"index" query:"index" validate:"required"` + Time time.Time `json:"time,omitempty" form:"time" query:"time" validate:"required"` + Envelopes []*messaging.Envelope `json:"envelopes,omitempty" form:"envelopes" query:"envelopes" validate:"required"` + extraData []byte +} + +type BlockResults struct { + fieldsSet []bool + MessageResults []*protocol.TransactionStatus `json:"messageResults,omitempty" form:"messageResults" query:"messageResults" validate:"required"` + ValidatorUpdates []*ValidatorUpdate `json:"validatorUpdates,omitempty" form:"validatorUpdates" query:"validatorUpdates" validate:"required"` + extraData []byte +} + +type CommitResult struct { + fieldsSet []bool + Hash [32]byte `json:"hash,omitempty" form:"hash" query:"hash" validate:"required"` + extraData []byte +} + +type EnvelopeSubmitted struct { + fieldsSet []bool + Results []*protocol.TransactionStatus `json:"results,omitempty" form:"results" query:"results" validate:"required"` + extraData []byte +} + +type ExecutedBlock struct { + fieldsSet []bool + Network string `json:"network,omitempty" form:"network" query:"network" validate:"required"` + Node [32]byte `json:"node,omitempty" form:"node" query:"node" validate:"required"` + extraData []byte +} + +type LeaderProposal struct { + fieldsSet []bool + Leader [32]byte `json:"leader,omitempty" form:"leader" query:"leader" validate:"required"` + extraData []byte +} + +type StartBlock struct { + fieldsSet []bool + extraData []byte +} + +type SubmitEnvelope struct { + fieldsSet []bool + Network string `json:"network,omitempty" form:"network" query:"network" validate:"required"` + Envelope *messaging.Envelope `json:"envelope,omitempty" form:"envelope" query:"envelope" validate:"required"` + Pretend bool `json:"pretend,omitempty" form:"pretend" query:"pretend" validate:"required"` + extraData []byte +} + +type ValidatorUpdate struct { + fieldsSet []bool + Type protocol.SignatureType `json:"type,omitempty" form:"type" query:"type" validate:"required"` + PublicKey []byte `json:"publicKey,omitempty" form:"publicKey" query:"publicKey" validate:"required"` + Power int64 `json:"power,omitempty" form:"power" query:"power" validate:"required"` + extraData []byte +} + +type acceptBlockProposal struct { + fieldsSet []bool + baseNodeMessage + p proposeBlock `json:"p,omitempty" form:"p" query:"p" validate:"required"` + extraData []byte +} + +type acceptedSubmission struct { + fieldsSet []bool + baseNodeMessage + result EnvelopeSubmitted `json:"result,omitempty" form:"result" query:"result" validate:"required"` + env *messaging.Envelope `json:"env,omitempty" form:"env" query:"env" validate:"required"` + extraData []byte +} + +type baseNodeMessage struct { + fieldsSet []bool + PubKeyHash [32]byte `json:"pubKeyHash,omitempty" form:"pubKeyHash" query:"pubKeyHash" validate:"required"` + Network string `json:"network,omitempty" form:"network" query:"network" validate:"required"` + extraData []byte +} + +type committedBlock struct { + fieldsSet []bool + baseNodeMessage + results CommitResult `json:"results,omitempty" form:"results" query:"results" validate:"required"` + extraData []byte +} + +type finalizedBlock struct { + fieldsSet []bool + baseNodeMessage + results BlockResults `json:"results,omitempty" form:"results" query:"results" validate:"required"` + extraData []byte +} + +type proposeBlock struct { + fieldsSet []bool + baseNodeMessage + BlockProposal + extraData []byte +} + +type proposeLeader struct { + fieldsSet []bool + baseNodeMessage + LeaderProposal + extraData []byte +} + +func (*EnvelopeSubmitted) Type() messageType { return messageTypeEnvelopeSubmitted } + +func (*ExecutedBlock) Type() messageType { return messageTypeExecutedBlock } + +func (*StartBlock) Type() messageType { return messageTypeStartBlock } + +func (*SubmitEnvelope) Type() messageType { return messageTypeSubmitEnvelope } + +func (*acceptBlockProposal) Type() messageType { return messageTypeAcceptBlockProposal } + +func (*acceptedSubmission) Type() messageType { return messageTypeAcceptedSubmission } + +func (*committedBlock) Type() messageType { return messageTypeCommittedBlock } + +func (*finalizedBlock) Type() messageType { return messageTypeFinalizedBlock } + +func (*proposeBlock) Type() messageType { return messageTypeProposeBlock } + +func (*proposeLeader) Type() messageType { return messageTypeProposeLeader } + +func (v *BlockProposal) Copy() *BlockProposal { + u := new(BlockProposal) + + u.LeaderProposal = *v.LeaderProposal.Copy() + u.Index = v.Index + u.Time = v.Time + u.Envelopes = make([]*messaging.Envelope, len(v.Envelopes)) + for i, v := range v.Envelopes { + v := v + if v != nil { + u.Envelopes[i] = (v).Copy() + } + } + if len(v.extraData) > 0 { + u.extraData = make([]byte, len(v.extraData)) + copy(u.extraData, v.extraData) + } + + return u +} + +func (v *BlockProposal) CopyAsInterface() interface{} { return v.Copy() } + +func (v *BlockResults) Copy() *BlockResults { + u := new(BlockResults) + + u.MessageResults = make([]*protocol.TransactionStatus, len(v.MessageResults)) + for i, v := range v.MessageResults { + v := v + if v != nil { + u.MessageResults[i] = (v).Copy() + } + } + u.ValidatorUpdates = make([]*ValidatorUpdate, len(v.ValidatorUpdates)) + for i, v := range v.ValidatorUpdates { + v := v + if v != nil { + u.ValidatorUpdates[i] = (v).Copy() + } + } + if len(v.extraData) > 0 { + u.extraData = make([]byte, len(v.extraData)) + copy(u.extraData, v.extraData) + } + + return u +} + +func (v *BlockResults) CopyAsInterface() interface{} { return v.Copy() } + +func (v *CommitResult) Copy() *CommitResult { + u := new(CommitResult) + + u.Hash = v.Hash + if len(v.extraData) > 0 { + u.extraData = make([]byte, len(v.extraData)) + copy(u.extraData, v.extraData) + } + + return u +} + +func (v *CommitResult) CopyAsInterface() interface{} { return v.Copy() } + +func (v *EnvelopeSubmitted) Copy() *EnvelopeSubmitted { + u := new(EnvelopeSubmitted) + + u.Results = make([]*protocol.TransactionStatus, len(v.Results)) + for i, v := range v.Results { + v := v + if v != nil { + u.Results[i] = (v).Copy() + } + } + if len(v.extraData) > 0 { + u.extraData = make([]byte, len(v.extraData)) + copy(u.extraData, v.extraData) + } + + return u +} + +func (v *EnvelopeSubmitted) CopyAsInterface() interface{} { return v.Copy() } + +func (v *ExecutedBlock) Copy() *ExecutedBlock { + u := new(ExecutedBlock) + + u.Network = v.Network + u.Node = v.Node + if len(v.extraData) > 0 { + u.extraData = make([]byte, len(v.extraData)) + copy(u.extraData, v.extraData) + } + + return u +} + +func (v *ExecutedBlock) CopyAsInterface() interface{} { return v.Copy() } + +func (v *LeaderProposal) Copy() *LeaderProposal { + u := new(LeaderProposal) + + u.Leader = v.Leader + if len(v.extraData) > 0 { + u.extraData = make([]byte, len(v.extraData)) + copy(u.extraData, v.extraData) + } + + return u +} + +func (v *LeaderProposal) CopyAsInterface() interface{} { return v.Copy() } + +func (v *StartBlock) Copy() *StartBlock { + u := new(StartBlock) + + if len(v.extraData) > 0 { + u.extraData = make([]byte, len(v.extraData)) + copy(u.extraData, v.extraData) + } + + return u +} + +func (v *StartBlock) CopyAsInterface() interface{} { return v.Copy() } + +func (v *SubmitEnvelope) Copy() *SubmitEnvelope { + u := new(SubmitEnvelope) + + u.Network = v.Network + if v.Envelope != nil { + u.Envelope = (v.Envelope).Copy() + } + u.Pretend = v.Pretend + if len(v.extraData) > 0 { + u.extraData = make([]byte, len(v.extraData)) + copy(u.extraData, v.extraData) + } + + return u +} + +func (v *SubmitEnvelope) CopyAsInterface() interface{} { return v.Copy() } + +func (v *ValidatorUpdate) Copy() *ValidatorUpdate { + u := new(ValidatorUpdate) + + u.Type = v.Type + u.PublicKey = encoding.BytesCopy(v.PublicKey) + u.Power = v.Power + if len(v.extraData) > 0 { + u.extraData = make([]byte, len(v.extraData)) + copy(u.extraData, v.extraData) + } + + return u +} + +func (v *ValidatorUpdate) CopyAsInterface() interface{} { return v.Copy() } + +func (v *acceptBlockProposal) Copy() *acceptBlockProposal { + u := new(acceptBlockProposal) + + u.baseNodeMessage = *v.baseNodeMessage.Copy() + u.p = *(&v.p).Copy() + if len(v.extraData) > 0 { + u.extraData = make([]byte, len(v.extraData)) + copy(u.extraData, v.extraData) + } + + return u +} + +func (v *acceptBlockProposal) CopyAsInterface() interface{} { return v.Copy() } + +func (v *acceptedSubmission) Copy() *acceptedSubmission { + u := new(acceptedSubmission) + + u.baseNodeMessage = *v.baseNodeMessage.Copy() + u.result = *(&v.result).Copy() + if v.env != nil { + u.env = (v.env).Copy() + } + if len(v.extraData) > 0 { + u.extraData = make([]byte, len(v.extraData)) + copy(u.extraData, v.extraData) + } + + return u +} + +func (v *acceptedSubmission) CopyAsInterface() interface{} { return v.Copy() } + +func (v *baseNodeMessage) Copy() *baseNodeMessage { + u := new(baseNodeMessage) + + u.PubKeyHash = v.PubKeyHash + u.Network = v.Network + if len(v.extraData) > 0 { + u.extraData = make([]byte, len(v.extraData)) + copy(u.extraData, v.extraData) + } + + return u +} + +func (v *baseNodeMessage) CopyAsInterface() interface{} { return v.Copy() } + +func (v *committedBlock) Copy() *committedBlock { + u := new(committedBlock) + + u.baseNodeMessage = *v.baseNodeMessage.Copy() + u.results = *(&v.results).Copy() + if len(v.extraData) > 0 { + u.extraData = make([]byte, len(v.extraData)) + copy(u.extraData, v.extraData) + } + + return u +} + +func (v *committedBlock) CopyAsInterface() interface{} { return v.Copy() } + +func (v *finalizedBlock) Copy() *finalizedBlock { + u := new(finalizedBlock) + + u.baseNodeMessage = *v.baseNodeMessage.Copy() + u.results = *(&v.results).Copy() + if len(v.extraData) > 0 { + u.extraData = make([]byte, len(v.extraData)) + copy(u.extraData, v.extraData) + } + + return u +} + +func (v *finalizedBlock) CopyAsInterface() interface{} { return v.Copy() } + +func (v *proposeBlock) Copy() *proposeBlock { + u := new(proposeBlock) + + u.baseNodeMessage = *v.baseNodeMessage.Copy() + u.BlockProposal = *v.BlockProposal.Copy() + if len(v.extraData) > 0 { + u.extraData = make([]byte, len(v.extraData)) + copy(u.extraData, v.extraData) + } + + return u +} + +func (v *proposeBlock) CopyAsInterface() interface{} { return v.Copy() } + +func (v *proposeLeader) Copy() *proposeLeader { + u := new(proposeLeader) + + u.baseNodeMessage = *v.baseNodeMessage.Copy() + u.LeaderProposal = *v.LeaderProposal.Copy() + if len(v.extraData) > 0 { + u.extraData = make([]byte, len(v.extraData)) + copy(u.extraData, v.extraData) + } + + return u +} + +func (v *proposeLeader) CopyAsInterface() interface{} { return v.Copy() } + +func (v *BlockProposal) Equal(u *BlockProposal) bool { + if !v.LeaderProposal.Equal(&u.LeaderProposal) { + return false + } + if !(v.Index == u.Index) { + return false + } + if !((v.Time).Equal(u.Time)) { + return false + } + if len(v.Envelopes) != len(u.Envelopes) { + return false + } + for i := range v.Envelopes { + if !((v.Envelopes[i]).Equal(u.Envelopes[i])) { + return false + } + } + + return true +} + +func (v *BlockResults) Equal(u *BlockResults) bool { + if len(v.MessageResults) != len(u.MessageResults) { + return false + } + for i := range v.MessageResults { + if !((v.MessageResults[i]).Equal(u.MessageResults[i])) { + return false + } + } + if len(v.ValidatorUpdates) != len(u.ValidatorUpdates) { + return false + } + for i := range v.ValidatorUpdates { + if !((v.ValidatorUpdates[i]).Equal(u.ValidatorUpdates[i])) { + return false + } + } + + return true +} + +func (v *CommitResult) Equal(u *CommitResult) bool { + if !(v.Hash == u.Hash) { + return false + } + + return true +} + +func (v *EnvelopeSubmitted) Equal(u *EnvelopeSubmitted) bool { + if len(v.Results) != len(u.Results) { + return false + } + for i := range v.Results { + if !((v.Results[i]).Equal(u.Results[i])) { + return false + } + } + + return true +} + +func (v *ExecutedBlock) Equal(u *ExecutedBlock) bool { + if !(v.Network == u.Network) { + return false + } + if !(v.Node == u.Node) { + return false + } + + return true +} + +func (v *LeaderProposal) Equal(u *LeaderProposal) bool { + if !(v.Leader == u.Leader) { + return false + } + + return true +} + +func (v *StartBlock) Equal(u *StartBlock) bool { + + return true +} + +func (v *SubmitEnvelope) Equal(u *SubmitEnvelope) bool { + if !(v.Network == u.Network) { + return false + } + switch { + case v.Envelope == u.Envelope: + // equal + case v.Envelope == nil || u.Envelope == nil: + return false + case !((v.Envelope).Equal(u.Envelope)): + return false + } + if !(v.Pretend == u.Pretend) { + return false + } + + return true +} + +func (v *ValidatorUpdate) Equal(u *ValidatorUpdate) bool { + if !(v.Type == u.Type) { + return false + } + if !(bytes.Equal(v.PublicKey, u.PublicKey)) { + return false + } + if !(v.Power == u.Power) { + return false + } + + return true +} + +func (v *acceptBlockProposal) Equal(u *acceptBlockProposal) bool { + if !v.baseNodeMessage.Equal(&u.baseNodeMessage) { + return false + } + if !((&v.p).Equal(&u.p)) { + return false + } + + return true +} + +func (v *acceptedSubmission) Equal(u *acceptedSubmission) bool { + if !v.baseNodeMessage.Equal(&u.baseNodeMessage) { + return false + } + if !((&v.result).Equal(&u.result)) { + return false + } + switch { + case v.env == u.env: + // equal + case v.env == nil || u.env == nil: + return false + case !((v.env).Equal(u.env)): + return false + } + + return true +} + +func (v *baseNodeMessage) Equal(u *baseNodeMessage) bool { + if !(v.PubKeyHash == u.PubKeyHash) { + return false + } + if !(v.Network == u.Network) { + return false + } + + return true +} + +func (v *committedBlock) Equal(u *committedBlock) bool { + if !v.baseNodeMessage.Equal(&u.baseNodeMessage) { + return false + } + if !((&v.results).Equal(&u.results)) { + return false + } + + return true +} + +func (v *finalizedBlock) Equal(u *finalizedBlock) bool { + if !v.baseNodeMessage.Equal(&u.baseNodeMessage) { + return false + } + if !((&v.results).Equal(&u.results)) { + return false + } + + return true +} + +func (v *proposeBlock) Equal(u *proposeBlock) bool { + if !v.baseNodeMessage.Equal(&u.baseNodeMessage) { + return false + } + if !v.BlockProposal.Equal(&u.BlockProposal) { + return false + } + + return true +} + +func (v *proposeLeader) Equal(u *proposeLeader) bool { + if !v.baseNodeMessage.Equal(&u.baseNodeMessage) { + return false + } + if !v.LeaderProposal.Equal(&u.LeaderProposal) { + return false + } + + return true +} + +var fieldNames_BlockProposal = []string{ + 1: "LeaderProposal", + 2: "Index", + 3: "Time", + 4: "Envelopes", +} + +func (v *BlockProposal) MarshalBinary() ([]byte, error) { + if v == nil { + return []byte{encoding.EmptyObject}, nil + } + + buffer := new(bytes.Buffer) + writer := encoding.NewWriter(buffer) + + writer.WriteValue(1, v.LeaderProposal.MarshalBinary) + if !(v.Index == 0) { + writer.WriteUint(2, v.Index) + } + if !(v.Time == (time.Time{})) { + writer.WriteTime(3, v.Time) + } + if !(len(v.Envelopes) == 0) { + for _, v := range v.Envelopes { + writer.WriteValue(4, v.MarshalBinary) + } + } + + _, _, err := writer.Reset(fieldNames_BlockProposal) + if err != nil { + return nil, encoding.Error{E: err} + } + buffer.Write(v.extraData) + return buffer.Bytes(), nil +} + +func (v *BlockProposal) IsValid() error { + var errs []string + + if err := v.LeaderProposal.IsValid(); err != nil { + errs = append(errs, err.Error()) + } + if len(v.fieldsSet) > 1 && !v.fieldsSet[1] { + errs = append(errs, "field Index is missing") + } else if v.Index == 0 { + errs = append(errs, "field Index is not set") + } + if len(v.fieldsSet) > 2 && !v.fieldsSet[2] { + errs = append(errs, "field Time is missing") + } else if v.Time == (time.Time{}) { + errs = append(errs, "field Time is not set") + } + if len(v.fieldsSet) > 3 && !v.fieldsSet[3] { + errs = append(errs, "field Envelopes is missing") + } else if len(v.Envelopes) == 0 { + errs = append(errs, "field Envelopes is not set") + } + + switch len(errs) { + case 0: + return nil + case 1: + return errors.New(errs[0]) + default: + return errors.New(strings.Join(errs, "; ")) + } +} + +var fieldNames_BlockResults = []string{ + 1: "MessageResults", + 2: "ValidatorUpdates", +} + +func (v *BlockResults) MarshalBinary() ([]byte, error) { + if v == nil { + return []byte{encoding.EmptyObject}, nil + } + + buffer := new(bytes.Buffer) + writer := encoding.NewWriter(buffer) + + if !(len(v.MessageResults) == 0) { + for _, v := range v.MessageResults { + writer.WriteValue(1, v.MarshalBinary) + } + } + if !(len(v.ValidatorUpdates) == 0) { + for _, v := range v.ValidatorUpdates { + writer.WriteValue(2, v.MarshalBinary) + } + } + + _, _, err := writer.Reset(fieldNames_BlockResults) + if err != nil { + return nil, encoding.Error{E: err} + } + buffer.Write(v.extraData) + return buffer.Bytes(), nil +} + +func (v *BlockResults) IsValid() error { + var errs []string + + if len(v.fieldsSet) > 0 && !v.fieldsSet[0] { + errs = append(errs, "field MessageResults is missing") + } else if len(v.MessageResults) == 0 { + errs = append(errs, "field MessageResults is not set") + } + if len(v.fieldsSet) > 1 && !v.fieldsSet[1] { + errs = append(errs, "field ValidatorUpdates is missing") + } else if len(v.ValidatorUpdates) == 0 { + errs = append(errs, "field ValidatorUpdates is not set") + } + + switch len(errs) { + case 0: + return nil + case 1: + return errors.New(errs[0]) + default: + return errors.New(strings.Join(errs, "; ")) + } +} + +var fieldNames_CommitResult = []string{ + 1: "Hash", +} + +func (v *CommitResult) MarshalBinary() ([]byte, error) { + if v == nil { + return []byte{encoding.EmptyObject}, nil + } + + buffer := new(bytes.Buffer) + writer := encoding.NewWriter(buffer) + + if !(v.Hash == ([32]byte{})) { + writer.WriteHash(1, &v.Hash) + } + + _, _, err := writer.Reset(fieldNames_CommitResult) + if err != nil { + return nil, encoding.Error{E: err} + } + buffer.Write(v.extraData) + return buffer.Bytes(), nil +} + +func (v *CommitResult) IsValid() error { + var errs []string + + if len(v.fieldsSet) > 0 && !v.fieldsSet[0] { + errs = append(errs, "field Hash is missing") + } else if v.Hash == ([32]byte{}) { + errs = append(errs, "field Hash is not set") + } + + switch len(errs) { + case 0: + return nil + case 1: + return errors.New(errs[0]) + default: + return errors.New(strings.Join(errs, "; ")) + } +} + +var fieldNames_EnvelopeSubmitted = []string{ + 1: "Type", + 2: "Results", +} + +func (v *EnvelopeSubmitted) MarshalBinary() ([]byte, error) { + if v == nil { + return []byte{encoding.EmptyObject}, nil + } + + buffer := new(bytes.Buffer) + writer := encoding.NewWriter(buffer) + + writer.WriteEnum(1, v.Type()) + if !(len(v.Results) == 0) { + for _, v := range v.Results { + writer.WriteValue(2, v.MarshalBinary) + } + } + + _, _, err := writer.Reset(fieldNames_EnvelopeSubmitted) + if err != nil { + return nil, encoding.Error{E: err} + } + buffer.Write(v.extraData) + return buffer.Bytes(), nil +} + +func (v *EnvelopeSubmitted) IsValid() error { + var errs []string + + if len(v.fieldsSet) > 0 && !v.fieldsSet[0] { + errs = append(errs, "field Type is missing") + } + if len(v.fieldsSet) > 1 && !v.fieldsSet[1] { + errs = append(errs, "field Results is missing") + } else if len(v.Results) == 0 { + errs = append(errs, "field Results is not set") + } + + switch len(errs) { + case 0: + return nil + case 1: + return errors.New(errs[0]) + default: + return errors.New(strings.Join(errs, "; ")) + } +} + +var fieldNames_ExecutedBlock = []string{ + 1: "Type", + 2: "Network", + 3: "Node", +} + +func (v *ExecutedBlock) MarshalBinary() ([]byte, error) { + if v == nil { + return []byte{encoding.EmptyObject}, nil + } + + buffer := new(bytes.Buffer) + writer := encoding.NewWriter(buffer) + + writer.WriteEnum(1, v.Type()) + if !(len(v.Network) == 0) { + writer.WriteString(2, v.Network) + } + if !(v.Node == ([32]byte{})) { + writer.WriteHash(3, &v.Node) + } + + _, _, err := writer.Reset(fieldNames_ExecutedBlock) + if err != nil { + return nil, encoding.Error{E: err} + } + buffer.Write(v.extraData) + return buffer.Bytes(), nil +} + +func (v *ExecutedBlock) IsValid() error { + var errs []string + + if len(v.fieldsSet) > 0 && !v.fieldsSet[0] { + errs = append(errs, "field Type is missing") + } + if len(v.fieldsSet) > 1 && !v.fieldsSet[1] { + errs = append(errs, "field Network is missing") + } else if len(v.Network) == 0 { + errs = append(errs, "field Network is not set") + } + if len(v.fieldsSet) > 2 && !v.fieldsSet[2] { + errs = append(errs, "field Node is missing") + } else if v.Node == ([32]byte{}) { + errs = append(errs, "field Node is not set") + } + + switch len(errs) { + case 0: + return nil + case 1: + return errors.New(errs[0]) + default: + return errors.New(strings.Join(errs, "; ")) + } +} + +var fieldNames_LeaderProposal = []string{ + 1: "Leader", +} + +func (v *LeaderProposal) MarshalBinary() ([]byte, error) { + if v == nil { + return []byte{encoding.EmptyObject}, nil + } + + buffer := new(bytes.Buffer) + writer := encoding.NewWriter(buffer) + + if !(v.Leader == ([32]byte{})) { + writer.WriteHash(1, &v.Leader) + } + + _, _, err := writer.Reset(fieldNames_LeaderProposal) + if err != nil { + return nil, encoding.Error{E: err} + } + buffer.Write(v.extraData) + return buffer.Bytes(), nil +} + +func (v *LeaderProposal) IsValid() error { + var errs []string + + if len(v.fieldsSet) > 0 && !v.fieldsSet[0] { + errs = append(errs, "field Leader is missing") + } else if v.Leader == ([32]byte{}) { + errs = append(errs, "field Leader is not set") + } + + switch len(errs) { + case 0: + return nil + case 1: + return errors.New(errs[0]) + default: + return errors.New(strings.Join(errs, "; ")) + } +} + +var fieldNames_StartBlock = []string{ + 1: "Type", +} + +func (v *StartBlock) MarshalBinary() ([]byte, error) { + if v == nil { + return []byte{encoding.EmptyObject}, nil + } + + buffer := new(bytes.Buffer) + writer := encoding.NewWriter(buffer) + + writer.WriteEnum(1, v.Type()) + + _, _, err := writer.Reset(fieldNames_StartBlock) + if err != nil { + return nil, encoding.Error{E: err} + } + buffer.Write(v.extraData) + return buffer.Bytes(), nil +} + +func (v *StartBlock) IsValid() error { + var errs []string + + if len(v.fieldsSet) > 0 && !v.fieldsSet[0] { + errs = append(errs, "field Type is missing") + } + + switch len(errs) { + case 0: + return nil + case 1: + return errors.New(errs[0]) + default: + return errors.New(strings.Join(errs, "; ")) + } +} + +var fieldNames_SubmitEnvelope = []string{ + 1: "Type", + 2: "Network", + 3: "Envelope", + 4: "Pretend", +} + +func (v *SubmitEnvelope) MarshalBinary() ([]byte, error) { + if v == nil { + return []byte{encoding.EmptyObject}, nil + } + + buffer := new(bytes.Buffer) + writer := encoding.NewWriter(buffer) + + writer.WriteEnum(1, v.Type()) + if !(len(v.Network) == 0) { + writer.WriteString(2, v.Network) + } + if !(v.Envelope == nil) { + writer.WriteValue(3, v.Envelope.MarshalBinary) + } + if !(!v.Pretend) { + writer.WriteBool(4, v.Pretend) + } + + _, _, err := writer.Reset(fieldNames_SubmitEnvelope) + if err != nil { + return nil, encoding.Error{E: err} + } + buffer.Write(v.extraData) + return buffer.Bytes(), nil +} + +func (v *SubmitEnvelope) IsValid() error { + var errs []string + + if len(v.fieldsSet) > 0 && !v.fieldsSet[0] { + errs = append(errs, "field Type is missing") + } + if len(v.fieldsSet) > 1 && !v.fieldsSet[1] { + errs = append(errs, "field Network is missing") + } else if len(v.Network) == 0 { + errs = append(errs, "field Network is not set") + } + if len(v.fieldsSet) > 2 && !v.fieldsSet[2] { + errs = append(errs, "field Envelope is missing") + } else if v.Envelope == nil { + errs = append(errs, "field Envelope is not set") + } + if len(v.fieldsSet) > 3 && !v.fieldsSet[3] { + errs = append(errs, "field Pretend is missing") + } else if !v.Pretend { + errs = append(errs, "field Pretend is not set") + } + + switch len(errs) { + case 0: + return nil + case 1: + return errors.New(errs[0]) + default: + return errors.New(strings.Join(errs, "; ")) + } +} + +var fieldNames_ValidatorUpdate = []string{ + 1: "Type", + 2: "PublicKey", + 3: "Power", +} + +func (v *ValidatorUpdate) MarshalBinary() ([]byte, error) { + if v == nil { + return []byte{encoding.EmptyObject}, nil + } + + buffer := new(bytes.Buffer) + writer := encoding.NewWriter(buffer) + + if !(v.Type == 0) { + writer.WriteEnum(1, v.Type) + } + if !(len(v.PublicKey) == 0) { + writer.WriteBytes(2, v.PublicKey) + } + if !(v.Power == 0) { + writer.WriteInt(3, v.Power) + } + + _, _, err := writer.Reset(fieldNames_ValidatorUpdate) + if err != nil { + return nil, encoding.Error{E: err} + } + buffer.Write(v.extraData) + return buffer.Bytes(), nil +} + +func (v *ValidatorUpdate) IsValid() error { + var errs []string + + if len(v.fieldsSet) > 0 && !v.fieldsSet[0] { + errs = append(errs, "field Type is missing") + } else if v.Type == 0 { + errs = append(errs, "field Type is not set") + } + if len(v.fieldsSet) > 1 && !v.fieldsSet[1] { + errs = append(errs, "field PublicKey is missing") + } else if len(v.PublicKey) == 0 { + errs = append(errs, "field PublicKey is not set") + } + if len(v.fieldsSet) > 2 && !v.fieldsSet[2] { + errs = append(errs, "field Power is missing") + } else if v.Power == 0 { + errs = append(errs, "field Power is not set") + } + + switch len(errs) { + case 0: + return nil + case 1: + return errors.New(errs[0]) + default: + return errors.New(strings.Join(errs, "; ")) + } +} + +var fieldNames_acceptBlockProposal = []string{ + 1: "Type", + 2: "baseNodeMessage", + 3: "p", +} + +func (v *acceptBlockProposal) MarshalBinary() ([]byte, error) { + if v == nil { + return []byte{encoding.EmptyObject}, nil + } + + buffer := new(bytes.Buffer) + writer := encoding.NewWriter(buffer) + + writer.WriteEnum(1, v.Type()) + writer.WriteValue(2, v.baseNodeMessage.MarshalBinary) + if !((v.p).Equal(new(proposeBlock))) { + writer.WriteValue(3, v.p.MarshalBinary) + } + + _, _, err := writer.Reset(fieldNames_acceptBlockProposal) + if err != nil { + return nil, encoding.Error{E: err} + } + buffer.Write(v.extraData) + return buffer.Bytes(), nil +} + +func (v *acceptBlockProposal) IsValid() error { + var errs []string + + if len(v.fieldsSet) > 0 && !v.fieldsSet[0] { + errs = append(errs, "field Type is missing") + } + if err := v.baseNodeMessage.IsValid(); err != nil { + errs = append(errs, err.Error()) + } + if len(v.fieldsSet) > 2 && !v.fieldsSet[2] { + errs = append(errs, "field p is missing") + } else if (v.p).Equal(new(proposeBlock)) { + errs = append(errs, "field p is not set") + } + + switch len(errs) { + case 0: + return nil + case 1: + return errors.New(errs[0]) + default: + return errors.New(strings.Join(errs, "; ")) + } +} + +var fieldNames_acceptedSubmission = []string{ + 1: "Type", + 2: "baseNodeMessage", + 3: "result", + 4: "env", +} + +func (v *acceptedSubmission) MarshalBinary() ([]byte, error) { + if v == nil { + return []byte{encoding.EmptyObject}, nil + } + + buffer := new(bytes.Buffer) + writer := encoding.NewWriter(buffer) + + writer.WriteEnum(1, v.Type()) + writer.WriteValue(2, v.baseNodeMessage.MarshalBinary) + if !((v.result).Equal(new(EnvelopeSubmitted))) { + writer.WriteValue(3, v.result.MarshalBinary) + } + if !(v.env == nil) { + writer.WriteValue(4, v.env.MarshalBinary) + } + + _, _, err := writer.Reset(fieldNames_acceptedSubmission) + if err != nil { + return nil, encoding.Error{E: err} + } + buffer.Write(v.extraData) + return buffer.Bytes(), nil +} + +func (v *acceptedSubmission) IsValid() error { + var errs []string + + if len(v.fieldsSet) > 0 && !v.fieldsSet[0] { + errs = append(errs, "field Type is missing") + } + if err := v.baseNodeMessage.IsValid(); err != nil { + errs = append(errs, err.Error()) + } + if len(v.fieldsSet) > 2 && !v.fieldsSet[2] { + errs = append(errs, "field result is missing") + } else if (v.result).Equal(new(EnvelopeSubmitted)) { + errs = append(errs, "field result is not set") + } + if len(v.fieldsSet) > 3 && !v.fieldsSet[3] { + errs = append(errs, "field env is missing") + } else if v.env == nil { + errs = append(errs, "field env is not set") + } + + switch len(errs) { + case 0: + return nil + case 1: + return errors.New(errs[0]) + default: + return errors.New(strings.Join(errs, "; ")) + } +} + +var fieldNames_baseNodeMessage = []string{ + 1: "PubKeyHash", + 2: "Network", +} + +func (v *baseNodeMessage) MarshalBinary() ([]byte, error) { + if v == nil { + return []byte{encoding.EmptyObject}, nil + } + + buffer := new(bytes.Buffer) + writer := encoding.NewWriter(buffer) + + if !(v.PubKeyHash == ([32]byte{})) { + writer.WriteHash(1, &v.PubKeyHash) + } + if !(len(v.Network) == 0) { + writer.WriteString(2, v.Network) + } + + _, _, err := writer.Reset(fieldNames_baseNodeMessage) + if err != nil { + return nil, encoding.Error{E: err} + } + buffer.Write(v.extraData) + return buffer.Bytes(), nil +} + +func (v *baseNodeMessage) IsValid() error { + var errs []string + + if len(v.fieldsSet) > 0 && !v.fieldsSet[0] { + errs = append(errs, "field PubKeyHash is missing") + } else if v.PubKeyHash == ([32]byte{}) { + errs = append(errs, "field PubKeyHash is not set") + } + if len(v.fieldsSet) > 1 && !v.fieldsSet[1] { + errs = append(errs, "field Network is missing") + } else if len(v.Network) == 0 { + errs = append(errs, "field Network is not set") + } + + switch len(errs) { + case 0: + return nil + case 1: + return errors.New(errs[0]) + default: + return errors.New(strings.Join(errs, "; ")) + } +} + +var fieldNames_committedBlock = []string{ + 1: "Type", + 2: "baseNodeMessage", + 3: "results", +} + +func (v *committedBlock) MarshalBinary() ([]byte, error) { + if v == nil { + return []byte{encoding.EmptyObject}, nil + } + + buffer := new(bytes.Buffer) + writer := encoding.NewWriter(buffer) + + writer.WriteEnum(1, v.Type()) + writer.WriteValue(2, v.baseNodeMessage.MarshalBinary) + if !((v.results).Equal(new(CommitResult))) { + writer.WriteValue(3, v.results.MarshalBinary) + } + + _, _, err := writer.Reset(fieldNames_committedBlock) + if err != nil { + return nil, encoding.Error{E: err} + } + buffer.Write(v.extraData) + return buffer.Bytes(), nil +} + +func (v *committedBlock) IsValid() error { + var errs []string + + if len(v.fieldsSet) > 0 && !v.fieldsSet[0] { + errs = append(errs, "field Type is missing") + } + if err := v.baseNodeMessage.IsValid(); err != nil { + errs = append(errs, err.Error()) + } + if len(v.fieldsSet) > 2 && !v.fieldsSet[2] { + errs = append(errs, "field results is missing") + } else if (v.results).Equal(new(CommitResult)) { + errs = append(errs, "field results is not set") + } + + switch len(errs) { + case 0: + return nil + case 1: + return errors.New(errs[0]) + default: + return errors.New(strings.Join(errs, "; ")) + } +} + +var fieldNames_finalizedBlock = []string{ + 1: "Type", + 2: "baseNodeMessage", + 3: "results", +} + +func (v *finalizedBlock) MarshalBinary() ([]byte, error) { + if v == nil { + return []byte{encoding.EmptyObject}, nil + } + + buffer := new(bytes.Buffer) + writer := encoding.NewWriter(buffer) + + writer.WriteEnum(1, v.Type()) + writer.WriteValue(2, v.baseNodeMessage.MarshalBinary) + if !((v.results).Equal(new(BlockResults))) { + writer.WriteValue(3, v.results.MarshalBinary) + } + + _, _, err := writer.Reset(fieldNames_finalizedBlock) + if err != nil { + return nil, encoding.Error{E: err} + } + buffer.Write(v.extraData) + return buffer.Bytes(), nil +} + +func (v *finalizedBlock) IsValid() error { + var errs []string + + if len(v.fieldsSet) > 0 && !v.fieldsSet[0] { + errs = append(errs, "field Type is missing") + } + if err := v.baseNodeMessage.IsValid(); err != nil { + errs = append(errs, err.Error()) + } + if len(v.fieldsSet) > 2 && !v.fieldsSet[2] { + errs = append(errs, "field results is missing") + } else if (v.results).Equal(new(BlockResults)) { + errs = append(errs, "field results is not set") + } + + switch len(errs) { + case 0: + return nil + case 1: + return errors.New(errs[0]) + default: + return errors.New(strings.Join(errs, "; ")) + } +} + +var fieldNames_proposeBlock = []string{ + 1: "Type", + 2: "baseNodeMessage", + 3: "BlockProposal", +} + +func (v *proposeBlock) MarshalBinary() ([]byte, error) { + if v == nil { + return []byte{encoding.EmptyObject}, nil + } + + buffer := new(bytes.Buffer) + writer := encoding.NewWriter(buffer) + + writer.WriteEnum(1, v.Type()) + writer.WriteValue(2, v.baseNodeMessage.MarshalBinary) + writer.WriteValue(3, v.BlockProposal.MarshalBinary) + + _, _, err := writer.Reset(fieldNames_proposeBlock) + if err != nil { + return nil, encoding.Error{E: err} + } + buffer.Write(v.extraData) + return buffer.Bytes(), nil +} + +func (v *proposeBlock) IsValid() error { + var errs []string + + if len(v.fieldsSet) > 0 && !v.fieldsSet[0] { + errs = append(errs, "field Type is missing") + } + if err := v.baseNodeMessage.IsValid(); err != nil { + errs = append(errs, err.Error()) + } + if err := v.BlockProposal.IsValid(); err != nil { + errs = append(errs, err.Error()) + } + + switch len(errs) { + case 0: + return nil + case 1: + return errors.New(errs[0]) + default: + return errors.New(strings.Join(errs, "; ")) + } +} + +var fieldNames_proposeLeader = []string{ + 1: "Type", + 2: "baseNodeMessage", + 3: "LeaderProposal", +} + +func (v *proposeLeader) MarshalBinary() ([]byte, error) { + if v == nil { + return []byte{encoding.EmptyObject}, nil + } + + buffer := new(bytes.Buffer) + writer := encoding.NewWriter(buffer) + + writer.WriteEnum(1, v.Type()) + writer.WriteValue(2, v.baseNodeMessage.MarshalBinary) + writer.WriteValue(3, v.LeaderProposal.MarshalBinary) + + _, _, err := writer.Reset(fieldNames_proposeLeader) + if err != nil { + return nil, encoding.Error{E: err} + } + buffer.Write(v.extraData) + return buffer.Bytes(), nil +} + +func (v *proposeLeader) IsValid() error { + var errs []string + + if len(v.fieldsSet) > 0 && !v.fieldsSet[0] { + errs = append(errs, "field Type is missing") + } + if err := v.baseNodeMessage.IsValid(); err != nil { + errs = append(errs, err.Error()) + } + if err := v.LeaderProposal.IsValid(); err != nil { + errs = append(errs, err.Error()) + } + + switch len(errs) { + case 0: + return nil + case 1: + return errors.New(errs[0]) + default: + return errors.New(strings.Join(errs, "; ")) + } +} + +func (v *BlockProposal) UnmarshalBinary(data []byte) error { + return v.UnmarshalBinaryFrom(bytes.NewReader(data)) +} + +func (v *BlockProposal) UnmarshalBinaryFrom(rd io.Reader) error { + reader := encoding.NewReader(rd) + + reader.ReadValue(1, v.LeaderProposal.UnmarshalBinaryFrom) + if x, ok := reader.ReadUint(2); ok { + v.Index = x + } + if x, ok := reader.ReadTime(3); ok { + v.Time = x + } + for { + if x := new(messaging.Envelope); reader.ReadValue(4, x.UnmarshalBinaryFrom) { + v.Envelopes = append(v.Envelopes, x) + } else { + break + } + } + + seen, err := reader.Reset(fieldNames_BlockProposal) + if err != nil { + return encoding.Error{E: err} + } + v.fieldsSet = seen + v.extraData, err = reader.ReadAll() + if err != nil { + return encoding.Error{E: err} + } + return nil +} + +func (v *BlockResults) UnmarshalBinary(data []byte) error { + return v.UnmarshalBinaryFrom(bytes.NewReader(data)) +} + +func (v *BlockResults) UnmarshalBinaryFrom(rd io.Reader) error { + reader := encoding.NewReader(rd) + + for { + if x := new(protocol.TransactionStatus); reader.ReadValue(1, x.UnmarshalBinaryFrom) { + v.MessageResults = append(v.MessageResults, x) + } else { + break + } + } + for { + if x := new(ValidatorUpdate); reader.ReadValue(2, x.UnmarshalBinaryFrom) { + v.ValidatorUpdates = append(v.ValidatorUpdates, x) + } else { + break + } + } + + seen, err := reader.Reset(fieldNames_BlockResults) + if err != nil { + return encoding.Error{E: err} + } + v.fieldsSet = seen + v.extraData, err = reader.ReadAll() + if err != nil { + return encoding.Error{E: err} + } + return nil +} + +func (v *CommitResult) UnmarshalBinary(data []byte) error { + return v.UnmarshalBinaryFrom(bytes.NewReader(data)) +} + +func (v *CommitResult) UnmarshalBinaryFrom(rd io.Reader) error { + reader := encoding.NewReader(rd) + + if x, ok := reader.ReadHash(1); ok { + v.Hash = *x + } + + seen, err := reader.Reset(fieldNames_CommitResult) + if err != nil { + return encoding.Error{E: err} + } + v.fieldsSet = seen + v.extraData, err = reader.ReadAll() + if err != nil { + return encoding.Error{E: err} + } + return nil +} + +func (v *EnvelopeSubmitted) UnmarshalBinary(data []byte) error { + return v.UnmarshalBinaryFrom(bytes.NewReader(data)) +} + +func (v *EnvelopeSubmitted) UnmarshalBinaryFrom(rd io.Reader) error { + reader := encoding.NewReader(rd) + + var vType messageType + if x := new(messageType); reader.ReadEnum(1, x) { + vType = *x + } + if !(v.Type() == vType) { + return fmt.Errorf("field Type: not equal: want %v, got %v", v.Type(), vType) + } + + return v.UnmarshalFieldsFrom(reader) +} + +func (v *EnvelopeSubmitted) UnmarshalFieldsFrom(reader *encoding.Reader) error { + for { + if x := new(protocol.TransactionStatus); reader.ReadValue(2, x.UnmarshalBinaryFrom) { + v.Results = append(v.Results, x) + } else { + break + } + } + + seen, err := reader.Reset(fieldNames_EnvelopeSubmitted) + if err != nil { + return encoding.Error{E: err} + } + v.fieldsSet = seen + v.extraData, err = reader.ReadAll() + if err != nil { + return encoding.Error{E: err} + } + return nil +} + +func (v *ExecutedBlock) UnmarshalBinary(data []byte) error { + return v.UnmarshalBinaryFrom(bytes.NewReader(data)) +} + +func (v *ExecutedBlock) UnmarshalBinaryFrom(rd io.Reader) error { + reader := encoding.NewReader(rd) + + var vType messageType + if x := new(messageType); reader.ReadEnum(1, x) { + vType = *x + } + if !(v.Type() == vType) { + return fmt.Errorf("field Type: not equal: want %v, got %v", v.Type(), vType) + } + + return v.UnmarshalFieldsFrom(reader) +} + +func (v *ExecutedBlock) UnmarshalFieldsFrom(reader *encoding.Reader) error { + if x, ok := reader.ReadString(2); ok { + v.Network = x + } + if x, ok := reader.ReadHash(3); ok { + v.Node = *x + } + + seen, err := reader.Reset(fieldNames_ExecutedBlock) + if err != nil { + return encoding.Error{E: err} + } + v.fieldsSet = seen + v.extraData, err = reader.ReadAll() + if err != nil { + return encoding.Error{E: err} + } + return nil +} + +func (v *LeaderProposal) UnmarshalBinary(data []byte) error { + return v.UnmarshalBinaryFrom(bytes.NewReader(data)) +} + +func (v *LeaderProposal) UnmarshalBinaryFrom(rd io.Reader) error { + reader := encoding.NewReader(rd) + + if x, ok := reader.ReadHash(1); ok { + v.Leader = *x + } + + seen, err := reader.Reset(fieldNames_LeaderProposal) + if err != nil { + return encoding.Error{E: err} + } + v.fieldsSet = seen + v.extraData, err = reader.ReadAll() + if err != nil { + return encoding.Error{E: err} + } + return nil +} + +func (v *StartBlock) UnmarshalBinary(data []byte) error { + return v.UnmarshalBinaryFrom(bytes.NewReader(data)) +} + +func (v *StartBlock) UnmarshalBinaryFrom(rd io.Reader) error { + reader := encoding.NewReader(rd) + + var vType messageType + if x := new(messageType); reader.ReadEnum(1, x) { + vType = *x + } + if !(v.Type() == vType) { + return fmt.Errorf("field Type: not equal: want %v, got %v", v.Type(), vType) + } + + return v.UnmarshalFieldsFrom(reader) +} + +func (v *StartBlock) UnmarshalFieldsFrom(reader *encoding.Reader) error { + + seen, err := reader.Reset(fieldNames_StartBlock) + if err != nil { + return encoding.Error{E: err} + } + v.fieldsSet = seen + v.extraData, err = reader.ReadAll() + if err != nil { + return encoding.Error{E: err} + } + return nil +} + +func (v *SubmitEnvelope) UnmarshalBinary(data []byte) error { + return v.UnmarshalBinaryFrom(bytes.NewReader(data)) +} + +func (v *SubmitEnvelope) UnmarshalBinaryFrom(rd io.Reader) error { + reader := encoding.NewReader(rd) + + var vType messageType + if x := new(messageType); reader.ReadEnum(1, x) { + vType = *x + } + if !(v.Type() == vType) { + return fmt.Errorf("field Type: not equal: want %v, got %v", v.Type(), vType) + } + + return v.UnmarshalFieldsFrom(reader) +} + +func (v *SubmitEnvelope) UnmarshalFieldsFrom(reader *encoding.Reader) error { + if x, ok := reader.ReadString(2); ok { + v.Network = x + } + if x := new(messaging.Envelope); reader.ReadValue(3, x.UnmarshalBinaryFrom) { + v.Envelope = x + } + if x, ok := reader.ReadBool(4); ok { + v.Pretend = x + } + + seen, err := reader.Reset(fieldNames_SubmitEnvelope) + if err != nil { + return encoding.Error{E: err} + } + v.fieldsSet = seen + v.extraData, err = reader.ReadAll() + if err != nil { + return encoding.Error{E: err} + } + return nil +} + +func (v *ValidatorUpdate) UnmarshalBinary(data []byte) error { + return v.UnmarshalBinaryFrom(bytes.NewReader(data)) +} + +func (v *ValidatorUpdate) UnmarshalBinaryFrom(rd io.Reader) error { + reader := encoding.NewReader(rd) + + if x := new(protocol.SignatureType); reader.ReadEnum(1, x) { + v.Type = *x + } + if x, ok := reader.ReadBytes(2); ok { + v.PublicKey = x + } + if x, ok := reader.ReadInt(3); ok { + v.Power = x + } + + seen, err := reader.Reset(fieldNames_ValidatorUpdate) + if err != nil { + return encoding.Error{E: err} + } + v.fieldsSet = seen + v.extraData, err = reader.ReadAll() + if err != nil { + return encoding.Error{E: err} + } + return nil +} + +func (v *acceptBlockProposal) UnmarshalBinary(data []byte) error { + return v.UnmarshalBinaryFrom(bytes.NewReader(data)) +} + +func (v *acceptBlockProposal) UnmarshalBinaryFrom(rd io.Reader) error { + reader := encoding.NewReader(rd) + + var vType messageType + if x := new(messageType); reader.ReadEnum(1, x) { + vType = *x + } + if !(v.Type() == vType) { + return fmt.Errorf("field Type: not equal: want %v, got %v", v.Type(), vType) + } + + return v.UnmarshalFieldsFrom(reader) +} + +func (v *acceptBlockProposal) UnmarshalFieldsFrom(reader *encoding.Reader) error { + reader.ReadValue(2, v.baseNodeMessage.UnmarshalBinaryFrom) + if x := new(proposeBlock); reader.ReadValue(3, x.UnmarshalBinaryFrom) { + v.p = *x + } + + seen, err := reader.Reset(fieldNames_acceptBlockProposal) + if err != nil { + return encoding.Error{E: err} + } + v.fieldsSet = seen + v.extraData, err = reader.ReadAll() + if err != nil { + return encoding.Error{E: err} + } + return nil +} + +func (v *acceptedSubmission) UnmarshalBinary(data []byte) error { + return v.UnmarshalBinaryFrom(bytes.NewReader(data)) +} + +func (v *acceptedSubmission) UnmarshalBinaryFrom(rd io.Reader) error { + reader := encoding.NewReader(rd) + + var vType messageType + if x := new(messageType); reader.ReadEnum(1, x) { + vType = *x + } + if !(v.Type() == vType) { + return fmt.Errorf("field Type: not equal: want %v, got %v", v.Type(), vType) + } + + return v.UnmarshalFieldsFrom(reader) +} + +func (v *acceptedSubmission) UnmarshalFieldsFrom(reader *encoding.Reader) error { + reader.ReadValue(2, v.baseNodeMessage.UnmarshalBinaryFrom) + if x := new(EnvelopeSubmitted); reader.ReadValue(3, x.UnmarshalBinaryFrom) { + v.result = *x + } + if x := new(messaging.Envelope); reader.ReadValue(4, x.UnmarshalBinaryFrom) { + v.env = x + } + + seen, err := reader.Reset(fieldNames_acceptedSubmission) + if err != nil { + return encoding.Error{E: err} + } + v.fieldsSet = seen + v.extraData, err = reader.ReadAll() + if err != nil { + return encoding.Error{E: err} + } + return nil +} + +func (v *baseNodeMessage) UnmarshalBinary(data []byte) error { + return v.UnmarshalBinaryFrom(bytes.NewReader(data)) +} + +func (v *baseNodeMessage) UnmarshalBinaryFrom(rd io.Reader) error { + reader := encoding.NewReader(rd) + + if x, ok := reader.ReadHash(1); ok { + v.PubKeyHash = *x + } + if x, ok := reader.ReadString(2); ok { + v.Network = x + } + + seen, err := reader.Reset(fieldNames_baseNodeMessage) + if err != nil { + return encoding.Error{E: err} + } + v.fieldsSet = seen + v.extraData, err = reader.ReadAll() + if err != nil { + return encoding.Error{E: err} + } + return nil +} + +func (v *committedBlock) UnmarshalBinary(data []byte) error { + return v.UnmarshalBinaryFrom(bytes.NewReader(data)) +} + +func (v *committedBlock) UnmarshalBinaryFrom(rd io.Reader) error { + reader := encoding.NewReader(rd) + + var vType messageType + if x := new(messageType); reader.ReadEnum(1, x) { + vType = *x + } + if !(v.Type() == vType) { + return fmt.Errorf("field Type: not equal: want %v, got %v", v.Type(), vType) + } + + return v.UnmarshalFieldsFrom(reader) +} + +func (v *committedBlock) UnmarshalFieldsFrom(reader *encoding.Reader) error { + reader.ReadValue(2, v.baseNodeMessage.UnmarshalBinaryFrom) + if x := new(CommitResult); reader.ReadValue(3, x.UnmarshalBinaryFrom) { + v.results = *x + } + + seen, err := reader.Reset(fieldNames_committedBlock) + if err != nil { + return encoding.Error{E: err} + } + v.fieldsSet = seen + v.extraData, err = reader.ReadAll() + if err != nil { + return encoding.Error{E: err} + } + return nil +} + +func (v *finalizedBlock) UnmarshalBinary(data []byte) error { + return v.UnmarshalBinaryFrom(bytes.NewReader(data)) +} + +func (v *finalizedBlock) UnmarshalBinaryFrom(rd io.Reader) error { + reader := encoding.NewReader(rd) + + var vType messageType + if x := new(messageType); reader.ReadEnum(1, x) { + vType = *x + } + if !(v.Type() == vType) { + return fmt.Errorf("field Type: not equal: want %v, got %v", v.Type(), vType) + } + + return v.UnmarshalFieldsFrom(reader) +} + +func (v *finalizedBlock) UnmarshalFieldsFrom(reader *encoding.Reader) error { + reader.ReadValue(2, v.baseNodeMessage.UnmarshalBinaryFrom) + if x := new(BlockResults); reader.ReadValue(3, x.UnmarshalBinaryFrom) { + v.results = *x + } + + seen, err := reader.Reset(fieldNames_finalizedBlock) + if err != nil { + return encoding.Error{E: err} + } + v.fieldsSet = seen + v.extraData, err = reader.ReadAll() + if err != nil { + return encoding.Error{E: err} + } + return nil +} + +func (v *proposeBlock) UnmarshalBinary(data []byte) error { + return v.UnmarshalBinaryFrom(bytes.NewReader(data)) +} + +func (v *proposeBlock) UnmarshalBinaryFrom(rd io.Reader) error { + reader := encoding.NewReader(rd) + + var vType messageType + if x := new(messageType); reader.ReadEnum(1, x) { + vType = *x + } + if !(v.Type() == vType) { + return fmt.Errorf("field Type: not equal: want %v, got %v", v.Type(), vType) + } + + return v.UnmarshalFieldsFrom(reader) +} + +func (v *proposeBlock) UnmarshalFieldsFrom(reader *encoding.Reader) error { + reader.ReadValue(2, v.baseNodeMessage.UnmarshalBinaryFrom) + reader.ReadValue(3, v.BlockProposal.UnmarshalBinaryFrom) + + seen, err := reader.Reset(fieldNames_proposeBlock) + if err != nil { + return encoding.Error{E: err} + } + v.fieldsSet = seen + v.extraData, err = reader.ReadAll() + if err != nil { + return encoding.Error{E: err} + } + return nil +} + +func (v *proposeLeader) UnmarshalBinary(data []byte) error { + return v.UnmarshalBinaryFrom(bytes.NewReader(data)) +} + +func (v *proposeLeader) UnmarshalBinaryFrom(rd io.Reader) error { + reader := encoding.NewReader(rd) + + var vType messageType + if x := new(messageType); reader.ReadEnum(1, x) { + vType = *x + } + if !(v.Type() == vType) { + return fmt.Errorf("field Type: not equal: want %v, got %v", v.Type(), vType) + } + + return v.UnmarshalFieldsFrom(reader) +} + +func (v *proposeLeader) UnmarshalFieldsFrom(reader *encoding.Reader) error { + reader.ReadValue(2, v.baseNodeMessage.UnmarshalBinaryFrom) + reader.ReadValue(3, v.LeaderProposal.UnmarshalBinaryFrom) + + seen, err := reader.Reset(fieldNames_proposeLeader) + if err != nil { + return encoding.Error{E: err} + } + v.fieldsSet = seen + v.extraData, err = reader.ReadAll() + if err != nil { + return encoding.Error{E: err} + } + return nil +} + +func (v *BlockProposal) MarshalJSON() ([]byte, error) { + u := struct { + Leader *string `json:"leader,omitempty"` + Index uint64 `json:"index,omitempty"` + Time time.Time `json:"time,omitempty"` + Envelopes encoding.JsonList[*messaging.Envelope] `json:"envelopes,omitempty"` + }{} + if !(v.LeaderProposal.Leader == ([32]byte{})) { + + u.Leader = encoding.ChainToJSON(&v.LeaderProposal.Leader) + } + if !(v.Index == 0) { + u.Index = v.Index + } + if !(v.Time == (time.Time{})) { + u.Time = v.Time + } + if !(len(v.Envelopes) == 0) { + u.Envelopes = v.Envelopes + } + return json.Marshal(&u) +} + +func (v *BlockResults) MarshalJSON() ([]byte, error) { + u := struct { + MessageResults encoding.JsonList[*protocol.TransactionStatus] `json:"messageResults,omitempty"` + ValidatorUpdates encoding.JsonList[*ValidatorUpdate] `json:"validatorUpdates,omitempty"` + }{} + if !(len(v.MessageResults) == 0) { + u.MessageResults = v.MessageResults + } + if !(len(v.ValidatorUpdates) == 0) { + u.ValidatorUpdates = v.ValidatorUpdates + } + return json.Marshal(&u) +} + +func (v *CommitResult) MarshalJSON() ([]byte, error) { + u := struct { + Hash *string `json:"hash,omitempty"` + }{} + if !(v.Hash == ([32]byte{})) { + u.Hash = encoding.ChainToJSON(&v.Hash) + } + return json.Marshal(&u) +} + +func (v *EnvelopeSubmitted) MarshalJSON() ([]byte, error) { + u := struct { + Type messageType `json:"type"` + Results encoding.JsonList[*protocol.TransactionStatus] `json:"results,omitempty"` + }{} + u.Type = v.Type() + if !(len(v.Results) == 0) { + u.Results = v.Results + } + return json.Marshal(&u) +} + +func (v *ExecutedBlock) MarshalJSON() ([]byte, error) { + u := struct { + Type messageType `json:"type"` + Network string `json:"network,omitempty"` + Node *string `json:"node,omitempty"` + }{} + u.Type = v.Type() + if !(len(v.Network) == 0) { + u.Network = v.Network + } + if !(v.Node == ([32]byte{})) { + u.Node = encoding.ChainToJSON(&v.Node) + } + return json.Marshal(&u) +} + +func (v *LeaderProposal) MarshalJSON() ([]byte, error) { + u := struct { + Leader *string `json:"leader,omitempty"` + }{} + if !(v.Leader == ([32]byte{})) { + u.Leader = encoding.ChainToJSON(&v.Leader) + } + return json.Marshal(&u) +} + +func (v *StartBlock) MarshalJSON() ([]byte, error) { + u := struct { + Type messageType `json:"type"` + }{} + u.Type = v.Type() + return json.Marshal(&u) +} + +func (v *SubmitEnvelope) MarshalJSON() ([]byte, error) { + u := struct { + Type messageType `json:"type"` + Network string `json:"network,omitempty"` + Envelope *messaging.Envelope `json:"envelope,omitempty"` + Pretend bool `json:"pretend,omitempty"` + }{} + u.Type = v.Type() + if !(len(v.Network) == 0) { + u.Network = v.Network + } + if !(v.Envelope == nil) { + u.Envelope = v.Envelope + } + if !(!v.Pretend) { + u.Pretend = v.Pretend + } + return json.Marshal(&u) +} + +func (v *ValidatorUpdate) MarshalJSON() ([]byte, error) { + u := struct { + Type protocol.SignatureType `json:"type,omitempty"` + PublicKey *string `json:"publicKey,omitempty"` + Power int64 `json:"power,omitempty"` + }{} + if !(v.Type == 0) { + u.Type = v.Type + } + if !(len(v.PublicKey) == 0) { + u.PublicKey = encoding.BytesToJSON(v.PublicKey) + } + if !(v.Power == 0) { + u.Power = v.Power + } + return json.Marshal(&u) +} + +func (v *acceptBlockProposal) MarshalJSON() ([]byte, error) { + u := struct { + Type messageType `json:"type"` + PubKeyHash *string `json:"pubKeyHash,omitempty"` + Network string `json:"network,omitempty"` + p proposeBlock `json:"p,omitempty"` + }{} + u.Type = v.Type() + if !(v.baseNodeMessage.PubKeyHash == ([32]byte{})) { + + u.PubKeyHash = encoding.ChainToJSON(&v.baseNodeMessage.PubKeyHash) + } + if !(len(v.baseNodeMessage.Network) == 0) { + + u.Network = v.baseNodeMessage.Network + } + if !((v.p).Equal(new(proposeBlock))) { + u.p = v.p + } + return json.Marshal(&u) +} + +func (v *acceptedSubmission) MarshalJSON() ([]byte, error) { + u := struct { + Type messageType `json:"type"` + PubKeyHash *string `json:"pubKeyHash,omitempty"` + Network string `json:"network,omitempty"` + result EnvelopeSubmitted `json:"result,omitempty"` + env *messaging.Envelope `json:"env,omitempty"` + }{} + u.Type = v.Type() + if !(v.baseNodeMessage.PubKeyHash == ([32]byte{})) { + + u.PubKeyHash = encoding.ChainToJSON(&v.baseNodeMessage.PubKeyHash) + } + if !(len(v.baseNodeMessage.Network) == 0) { + + u.Network = v.baseNodeMessage.Network + } + if !((v.result).Equal(new(EnvelopeSubmitted))) { + u.result = v.result + } + if !(v.env == nil) { + u.env = v.env + } + return json.Marshal(&u) +} + +func (v *baseNodeMessage) MarshalJSON() ([]byte, error) { + u := struct { + PubKeyHash *string `json:"pubKeyHash,omitempty"` + Network string `json:"network,omitempty"` + }{} + if !(v.PubKeyHash == ([32]byte{})) { + u.PubKeyHash = encoding.ChainToJSON(&v.PubKeyHash) + } + if !(len(v.Network) == 0) { + u.Network = v.Network + } + return json.Marshal(&u) +} + +func (v *committedBlock) MarshalJSON() ([]byte, error) { + u := struct { + Type messageType `json:"type"` + PubKeyHash *string `json:"pubKeyHash,omitempty"` + Network string `json:"network,omitempty"` + results CommitResult `json:"results,omitempty"` + }{} + u.Type = v.Type() + if !(v.baseNodeMessage.PubKeyHash == ([32]byte{})) { + + u.PubKeyHash = encoding.ChainToJSON(&v.baseNodeMessage.PubKeyHash) + } + if !(len(v.baseNodeMessage.Network) == 0) { + + u.Network = v.baseNodeMessage.Network + } + if !((v.results).Equal(new(CommitResult))) { + u.results = v.results + } + return json.Marshal(&u) +} + +func (v *finalizedBlock) MarshalJSON() ([]byte, error) { + u := struct { + Type messageType `json:"type"` + PubKeyHash *string `json:"pubKeyHash,omitempty"` + Network string `json:"network,omitempty"` + results BlockResults `json:"results,omitempty"` + }{} + u.Type = v.Type() + if !(v.baseNodeMessage.PubKeyHash == ([32]byte{})) { + + u.PubKeyHash = encoding.ChainToJSON(&v.baseNodeMessage.PubKeyHash) + } + if !(len(v.baseNodeMessage.Network) == 0) { + + u.Network = v.baseNodeMessage.Network + } + if !((v.results).Equal(new(BlockResults))) { + u.results = v.results + } + return json.Marshal(&u) +} + +func (v *proposeBlock) MarshalJSON() ([]byte, error) { + u := struct { + Type messageType `json:"type"` + PubKeyHash *string `json:"pubKeyHash,omitempty"` + Network string `json:"network,omitempty"` + LeaderProposal LeaderProposal `json:"leaderProposal,omitempty"` + Index uint64 `json:"index,omitempty"` + Time time.Time `json:"time,omitempty"` + Envelopes encoding.JsonList[*messaging.Envelope] `json:"envelopes,omitempty"` + }{} + u.Type = v.Type() + if !(v.baseNodeMessage.PubKeyHash == ([32]byte{})) { + + u.PubKeyHash = encoding.ChainToJSON(&v.baseNodeMessage.PubKeyHash) + } + if !(len(v.baseNodeMessage.Network) == 0) { + + u.Network = v.baseNodeMessage.Network + } + if !((v.BlockProposal.LeaderProposal).Equal(new(LeaderProposal))) { + + u.LeaderProposal = v.BlockProposal.LeaderProposal + } + if !(v.BlockProposal.Index == 0) { + + u.Index = v.BlockProposal.Index + } + if !(v.BlockProposal.Time == (time.Time{})) { + + u.Time = v.BlockProposal.Time + } + if !(len(v.BlockProposal.Envelopes) == 0) { + + u.Envelopes = v.BlockProposal.Envelopes + } + return json.Marshal(&u) +} + +func (v *proposeLeader) MarshalJSON() ([]byte, error) { + u := struct { + Type messageType `json:"type"` + PubKeyHash *string `json:"pubKeyHash,omitempty"` + Network string `json:"network,omitempty"` + Leader *string `json:"leader,omitempty"` + }{} + u.Type = v.Type() + if !(v.baseNodeMessage.PubKeyHash == ([32]byte{})) { + + u.PubKeyHash = encoding.ChainToJSON(&v.baseNodeMessage.PubKeyHash) + } + if !(len(v.baseNodeMessage.Network) == 0) { + + u.Network = v.baseNodeMessage.Network + } + if !(v.LeaderProposal.Leader == ([32]byte{})) { + + u.Leader = encoding.ChainToJSON(&v.LeaderProposal.Leader) + } + return json.Marshal(&u) +} + +func (v *BlockProposal) UnmarshalJSON(data []byte) error { + u := struct { + Leader *string `json:"leader,omitempty"` + Index uint64 `json:"index,omitempty"` + Time time.Time `json:"time,omitempty"` + Envelopes encoding.JsonList[*messaging.Envelope] `json:"envelopes,omitempty"` + }{} + u.Leader = encoding.ChainToJSON(&v.LeaderProposal.Leader) + u.Index = v.Index + u.Time = v.Time + u.Envelopes = v.Envelopes + if err := json.Unmarshal(data, &u); err != nil { + return err + } + if x, err := encoding.ChainFromJSON(u.Leader); err != nil { + return fmt.Errorf("error decoding Leader: %w", err) + } else { + v.LeaderProposal.Leader = *x + } + v.Index = u.Index + v.Time = u.Time + v.Envelopes = u.Envelopes + return nil +} + +func (v *BlockResults) UnmarshalJSON(data []byte) error { + u := struct { + MessageResults encoding.JsonList[*protocol.TransactionStatus] `json:"messageResults,omitempty"` + ValidatorUpdates encoding.JsonList[*ValidatorUpdate] `json:"validatorUpdates,omitempty"` + }{} + u.MessageResults = v.MessageResults + u.ValidatorUpdates = v.ValidatorUpdates + if err := json.Unmarshal(data, &u); err != nil { + return err + } + v.MessageResults = u.MessageResults + v.ValidatorUpdates = u.ValidatorUpdates + return nil +} + +func (v *CommitResult) UnmarshalJSON(data []byte) error { + u := struct { + Hash *string `json:"hash,omitempty"` + }{} + u.Hash = encoding.ChainToJSON(&v.Hash) + if err := json.Unmarshal(data, &u); err != nil { + return err + } + if x, err := encoding.ChainFromJSON(u.Hash); err != nil { + return fmt.Errorf("error decoding Hash: %w", err) + } else { + v.Hash = *x + } + return nil +} + +func (v *EnvelopeSubmitted) UnmarshalJSON(data []byte) error { + u := struct { + Type messageType `json:"type"` + Results encoding.JsonList[*protocol.TransactionStatus] `json:"results,omitempty"` + }{} + u.Type = v.Type() + u.Results = v.Results + if err := json.Unmarshal(data, &u); err != nil { + return err + } + if !(v.Type() == u.Type) { + return fmt.Errorf("field Type: not equal: want %v, got %v", v.Type(), u.Type) + } + v.Results = u.Results + return nil +} + +func (v *ExecutedBlock) UnmarshalJSON(data []byte) error { + u := struct { + Type messageType `json:"type"` + Network string `json:"network,omitempty"` + Node *string `json:"node,omitempty"` + }{} + u.Type = v.Type() + u.Network = v.Network + u.Node = encoding.ChainToJSON(&v.Node) + if err := json.Unmarshal(data, &u); err != nil { + return err + } + if !(v.Type() == u.Type) { + return fmt.Errorf("field Type: not equal: want %v, got %v", v.Type(), u.Type) + } + v.Network = u.Network + if x, err := encoding.ChainFromJSON(u.Node); err != nil { + return fmt.Errorf("error decoding Node: %w", err) + } else { + v.Node = *x + } + return nil +} + +func (v *LeaderProposal) UnmarshalJSON(data []byte) error { + u := struct { + Leader *string `json:"leader,omitempty"` + }{} + u.Leader = encoding.ChainToJSON(&v.Leader) + if err := json.Unmarshal(data, &u); err != nil { + return err + } + if x, err := encoding.ChainFromJSON(u.Leader); err != nil { + return fmt.Errorf("error decoding Leader: %w", err) + } else { + v.Leader = *x + } + return nil +} + +func (v *StartBlock) UnmarshalJSON(data []byte) error { + u := struct { + Type messageType `json:"type"` + }{} + u.Type = v.Type() + if err := json.Unmarshal(data, &u); err != nil { + return err + } + if !(v.Type() == u.Type) { + return fmt.Errorf("field Type: not equal: want %v, got %v", v.Type(), u.Type) + } + return nil +} + +func (v *SubmitEnvelope) UnmarshalJSON(data []byte) error { + u := struct { + Type messageType `json:"type"` + Network string `json:"network,omitempty"` + Envelope *messaging.Envelope `json:"envelope,omitempty"` + Pretend bool `json:"pretend,omitempty"` + }{} + u.Type = v.Type() + u.Network = v.Network + u.Envelope = v.Envelope + u.Pretend = v.Pretend + if err := json.Unmarshal(data, &u); err != nil { + return err + } + if !(v.Type() == u.Type) { + return fmt.Errorf("field Type: not equal: want %v, got %v", v.Type(), u.Type) + } + v.Network = u.Network + v.Envelope = u.Envelope + v.Pretend = u.Pretend + return nil +} + +func (v *ValidatorUpdate) UnmarshalJSON(data []byte) error { + u := struct { + Type protocol.SignatureType `json:"type,omitempty"` + PublicKey *string `json:"publicKey,omitempty"` + Power int64 `json:"power,omitempty"` + }{} + u.Type = v.Type + u.PublicKey = encoding.BytesToJSON(v.PublicKey) + u.Power = v.Power + if err := json.Unmarshal(data, &u); err != nil { + return err + } + v.Type = u.Type + if x, err := encoding.BytesFromJSON(u.PublicKey); err != nil { + return fmt.Errorf("error decoding PublicKey: %w", err) + } else { + v.PublicKey = x + } + v.Power = u.Power + return nil +} + +func (v *acceptBlockProposal) UnmarshalJSON(data []byte) error { + u := struct { + Type messageType `json:"type"` + PubKeyHash *string `json:"pubKeyHash,omitempty"` + Network string `json:"network,omitempty"` + p proposeBlock `json:"p,omitempty"` + }{} + u.Type = v.Type() + u.PubKeyHash = encoding.ChainToJSON(&v.baseNodeMessage.PubKeyHash) + u.Network = v.baseNodeMessage.Network + u.p = v.p + if err := json.Unmarshal(data, &u); err != nil { + return err + } + if !(v.Type() == u.Type) { + return fmt.Errorf("field Type: not equal: want %v, got %v", v.Type(), u.Type) + } + if x, err := encoding.ChainFromJSON(u.PubKeyHash); err != nil { + return fmt.Errorf("error decoding PubKeyHash: %w", err) + } else { + v.baseNodeMessage.PubKeyHash = *x + } + v.baseNodeMessage.Network = u.Network + v.p = u.p + return nil +} + +func (v *acceptedSubmission) UnmarshalJSON(data []byte) error { + u := struct { + Type messageType `json:"type"` + PubKeyHash *string `json:"pubKeyHash,omitempty"` + Network string `json:"network,omitempty"` + result EnvelopeSubmitted `json:"result,omitempty"` + env *messaging.Envelope `json:"env,omitempty"` + }{} + u.Type = v.Type() + u.PubKeyHash = encoding.ChainToJSON(&v.baseNodeMessage.PubKeyHash) + u.Network = v.baseNodeMessage.Network + u.result = v.result + u.env = v.env + if err := json.Unmarshal(data, &u); err != nil { + return err + } + if !(v.Type() == u.Type) { + return fmt.Errorf("field Type: not equal: want %v, got %v", v.Type(), u.Type) + } + if x, err := encoding.ChainFromJSON(u.PubKeyHash); err != nil { + return fmt.Errorf("error decoding PubKeyHash: %w", err) + } else { + v.baseNodeMessage.PubKeyHash = *x + } + v.baseNodeMessage.Network = u.Network + v.result = u.result + v.env = u.env + return nil +} + +func (v *baseNodeMessage) UnmarshalJSON(data []byte) error { + u := struct { + PubKeyHash *string `json:"pubKeyHash,omitempty"` + Network string `json:"network,omitempty"` + }{} + u.PubKeyHash = encoding.ChainToJSON(&v.PubKeyHash) + u.Network = v.Network + if err := json.Unmarshal(data, &u); err != nil { + return err + } + if x, err := encoding.ChainFromJSON(u.PubKeyHash); err != nil { + return fmt.Errorf("error decoding PubKeyHash: %w", err) + } else { + v.PubKeyHash = *x + } + v.Network = u.Network + return nil +} + +func (v *committedBlock) UnmarshalJSON(data []byte) error { + u := struct { + Type messageType `json:"type"` + PubKeyHash *string `json:"pubKeyHash,omitempty"` + Network string `json:"network,omitempty"` + results CommitResult `json:"results,omitempty"` + }{} + u.Type = v.Type() + u.PubKeyHash = encoding.ChainToJSON(&v.baseNodeMessage.PubKeyHash) + u.Network = v.baseNodeMessage.Network + u.results = v.results + if err := json.Unmarshal(data, &u); err != nil { + return err + } + if !(v.Type() == u.Type) { + return fmt.Errorf("field Type: not equal: want %v, got %v", v.Type(), u.Type) + } + if x, err := encoding.ChainFromJSON(u.PubKeyHash); err != nil { + return fmt.Errorf("error decoding PubKeyHash: %w", err) + } else { + v.baseNodeMessage.PubKeyHash = *x + } + v.baseNodeMessage.Network = u.Network + v.results = u.results + return nil +} + +func (v *finalizedBlock) UnmarshalJSON(data []byte) error { + u := struct { + Type messageType `json:"type"` + PubKeyHash *string `json:"pubKeyHash,omitempty"` + Network string `json:"network,omitempty"` + results BlockResults `json:"results,omitempty"` + }{} + u.Type = v.Type() + u.PubKeyHash = encoding.ChainToJSON(&v.baseNodeMessage.PubKeyHash) + u.Network = v.baseNodeMessage.Network + u.results = v.results + if err := json.Unmarshal(data, &u); err != nil { + return err + } + if !(v.Type() == u.Type) { + return fmt.Errorf("field Type: not equal: want %v, got %v", v.Type(), u.Type) + } + if x, err := encoding.ChainFromJSON(u.PubKeyHash); err != nil { + return fmt.Errorf("error decoding PubKeyHash: %w", err) + } else { + v.baseNodeMessage.PubKeyHash = *x + } + v.baseNodeMessage.Network = u.Network + v.results = u.results + return nil +} + +func (v *proposeBlock) UnmarshalJSON(data []byte) error { + u := struct { + Type messageType `json:"type"` + PubKeyHash *string `json:"pubKeyHash,omitempty"` + Network string `json:"network,omitempty"` + LeaderProposal LeaderProposal `json:"leaderProposal,omitempty"` + Index uint64 `json:"index,omitempty"` + Time time.Time `json:"time,omitempty"` + Envelopes encoding.JsonList[*messaging.Envelope] `json:"envelopes,omitempty"` + }{} + u.Type = v.Type() + u.PubKeyHash = encoding.ChainToJSON(&v.baseNodeMessage.PubKeyHash) + u.Network = v.baseNodeMessage.Network + u.LeaderProposal = v.BlockProposal.LeaderProposal + u.Index = v.BlockProposal.Index + u.Time = v.BlockProposal.Time + u.Envelopes = v.BlockProposal.Envelopes + if err := json.Unmarshal(data, &u); err != nil { + return err + } + if !(v.Type() == u.Type) { + return fmt.Errorf("field Type: not equal: want %v, got %v", v.Type(), u.Type) + } + if x, err := encoding.ChainFromJSON(u.PubKeyHash); err != nil { + return fmt.Errorf("error decoding PubKeyHash: %w", err) + } else { + v.baseNodeMessage.PubKeyHash = *x + } + v.baseNodeMessage.Network = u.Network + v.BlockProposal.LeaderProposal = u.LeaderProposal + v.BlockProposal.Index = u.Index + v.BlockProposal.Time = u.Time + v.BlockProposal.Envelopes = u.Envelopes + return nil +} + +func (v *proposeLeader) UnmarshalJSON(data []byte) error { + u := struct { + Type messageType `json:"type"` + PubKeyHash *string `json:"pubKeyHash,omitempty"` + Network string `json:"network,omitempty"` + Leader *string `json:"leader,omitempty"` + }{} + u.Type = v.Type() + u.PubKeyHash = encoding.ChainToJSON(&v.baseNodeMessage.PubKeyHash) + u.Network = v.baseNodeMessage.Network + u.Leader = encoding.ChainToJSON(&v.LeaderProposal.Leader) + if err := json.Unmarshal(data, &u); err != nil { + return err + } + if !(v.Type() == u.Type) { + return fmt.Errorf("field Type: not equal: want %v, got %v", v.Type(), u.Type) + } + if x, err := encoding.ChainFromJSON(u.PubKeyHash); err != nil { + return fmt.Errorf("error decoding PubKeyHash: %w", err) + } else { + v.baseNodeMessage.PubKeyHash = *x + } + v.baseNodeMessage.Network = u.Network + if x, err := encoding.ChainFromJSON(u.Leader); err != nil { + return fmt.Errorf("error decoding Leader: %w", err) + } else { + v.LeaderProposal.Leader = *x + } + return nil +} diff --git a/test/simulator/consensus/unions_gen.go b/test/simulator/consensus/unions_gen.go new file mode 100644 index 000000000..30d0366a9 --- /dev/null +++ b/test/simulator/consensus/unions_gen.go @@ -0,0 +1,201 @@ +// Copyright 2022 The Accumulate Authors +// +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file or at +// https://opensource.org/licenses/MIT. + +package consensus + +// GENERATED BY go run ./tools/cmd/gen-types. DO NOT EDIT. + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + + "gitlab.com/accumulatenetwork/accumulate/pkg/types/encoding" +) + +// NewMessage creates a new Message for the specified messageType. +func NewMessage(typ messageType) (Message, error) { + switch typ { + case messageTypeEnvelopeSubmitted: + return new(EnvelopeSubmitted), nil + case messageTypeExecutedBlock: + return new(ExecutedBlock), nil + case messageTypeStartBlock: + return new(StartBlock), nil + case messageTypeSubmitEnvelope: + return new(SubmitEnvelope), nil + case messageTypeAcceptBlockProposal: + return new(acceptBlockProposal), nil + case messageTypeAcceptedSubmission: + return new(acceptedSubmission), nil + case messageTypeCommittedBlock: + return new(committedBlock), nil + case messageTypeFinalizedBlock: + return new(finalizedBlock), nil + case messageTypeProposeBlock: + return new(proposeBlock), nil + case messageTypeProposeLeader: + return new(proposeLeader), nil + } + return nil, fmt.Errorf("unknown message %v", typ) +} + +// EqualMessage is used to compare the values of the union +func EqualMessage(a, b Message) bool { + if a == b { + return true + } + switch a := a.(type) { + case *EnvelopeSubmitted: + if a == nil { + return b == nil + } + b, ok := b.(*EnvelopeSubmitted) + return ok && a.Equal(b) + case *ExecutedBlock: + if a == nil { + return b == nil + } + b, ok := b.(*ExecutedBlock) + return ok && a.Equal(b) + case *StartBlock: + if a == nil { + return b == nil + } + b, ok := b.(*StartBlock) + return ok && a.Equal(b) + case *SubmitEnvelope: + if a == nil { + return b == nil + } + b, ok := b.(*SubmitEnvelope) + return ok && a.Equal(b) + case *acceptBlockProposal: + if a == nil { + return b == nil + } + b, ok := b.(*acceptBlockProposal) + return ok && a.Equal(b) + case *acceptedSubmission: + if a == nil { + return b == nil + } + b, ok := b.(*acceptedSubmission) + return ok && a.Equal(b) + case *committedBlock: + if a == nil { + return b == nil + } + b, ok := b.(*committedBlock) + return ok && a.Equal(b) + case *finalizedBlock: + if a == nil { + return b == nil + } + b, ok := b.(*finalizedBlock) + return ok && a.Equal(b) + case *proposeBlock: + if a == nil { + return b == nil + } + b, ok := b.(*proposeBlock) + return ok && a.Equal(b) + case *proposeLeader: + if a == nil { + return b == nil + } + b, ok := b.(*proposeLeader) + return ok && a.Equal(b) + } + return false +} + +// CopyMessage copies a Message. +func CopyMessage(v Message) Message { + switch v := v.(type) { + case *EnvelopeSubmitted: + return v.Copy() + case *ExecutedBlock: + return v.Copy() + case *StartBlock: + return v.Copy() + case *SubmitEnvelope: + return v.Copy() + case *acceptBlockProposal: + return v.Copy() + case *acceptedSubmission: + return v.Copy() + case *committedBlock: + return v.Copy() + case *finalizedBlock: + return v.Copy() + case *proposeBlock: + return v.Copy() + case *proposeLeader: + return v.Copy() + default: + return v.CopyAsInterface().(Message) + } +} + +// UnmarshalMessage unmarshals a Message. +func UnmarshalMessage(data []byte) (Message, error) { + return UnmarshalMessageFrom(bytes.NewReader(data)) +} + +// UnmarshalMessageFrom unmarshals a Message. +func UnmarshalMessageFrom(rd io.Reader) (Message, error) { + reader := encoding.NewReader(rd) + + // Read the type code + var typ messageType + if !reader.ReadEnum(1, &typ) { + if reader.IsEmpty() { + return nil, nil + } + return nil, fmt.Errorf("field Type: missing") + } + + // Create a new message + v, err := NewMessage(messageType(typ)) + if err != nil { + return nil, err + } + + // Unmarshal the rest of the message + err = v.UnmarshalFieldsFrom(reader) + if err != nil { + return nil, err + } + + return v, nil +} + +// UnmarshalMessageJson unmarshals a Message. +func UnmarshalMessageJSON(data []byte) (Message, error) { + var typ *struct{ Type messageType } + err := json.Unmarshal(data, &typ) + if err != nil { + return nil, err + } + + if typ == nil { + return nil, nil + } + + acnt, err := NewMessage(typ.Type) + if err != nil { + return nil, err + } + + err = json.Unmarshal(data, acnt) + if err != nil { + return nil, err + } + + return acnt, nil +} diff --git a/test/simulator/recorder.go b/test/simulator/recorder.go index 1ce1fe01a..5dfffd0fb 100644 --- a/test/simulator/recorder.go +++ b/test/simulator/recorder.go @@ -7,6 +7,7 @@ package simulator import ( + "bytes" "encoding/json" "fmt" "io" @@ -16,7 +17,8 @@ import ( "gitlab.com/accumulatenetwork/accumulate/internal/core/execute" "gitlab.com/accumulatenetwork/accumulate/pkg/database" "gitlab.com/accumulatenetwork/accumulate/pkg/errors" - "gitlab.com/accumulatenetwork/accumulate/pkg/types/messaging" + "gitlab.com/accumulatenetwork/accumulate/pkg/types/encoding" + "gitlab.com/accumulatenetwork/accumulate/test/simulator/consensus" ) //go:generate go run gitlab.com/accumulatenetwork/accumulate/tools/cmd/gen-enum --out recorder_enums_gen.go --package simulator recorder_enums.yml @@ -34,23 +36,7 @@ type recorder struct { } func (r *recorder) WriteHeader(h *recordHeader) error { - b, err := h.MarshalBinary() - if err != nil { - return errors.EncodingError.WithFormat("encode: %w", err) - } - w, err := r.Open(recordSectionTypeHeader) - if err != nil { - return errors.UnknownError.WithFormat("open: %w", err) - } - _, err = w.Write(b) - if err != nil { - return errors.UnknownError.WithFormat("write: %w", err) - } - err = w.Close() - if err != nil { - return errors.UnknownError.WithFormat("close: %w", err) - } - return nil + return r.writeValue(recordSectionTypeHeader, h) } func (r *recorder) DidInit(snapshot ioutil.SectionReader) error { @@ -58,22 +44,14 @@ func (r *recorder) DidInit(snapshot ioutil.SectionReader) error { if err != nil { return errors.UnknownError.WithFormat("seek start: %w", err) } - w, err := r.Open(recordSectionTypeSnapshot) - if err != nil { - return errors.UnknownError.WithFormat("open: %w", err) - } - _, err = io.Copy(w, snapshot) - if err != nil { - return errors.UnknownError.WithFormat("copy: %w", err) - } - err = w.Close() - if err != nil { - return errors.UnknownError.WithFormat("close: %w", err) - } - return nil + return r.writeSection(recordSectionTypeSnapshot, snapshot) } -func (r *recorder) DidExecuteBlock(state execute.BlockState, submissions []*messaging.Envelope) error { +func (r *recorder) DidReceiveMessages(messages []consensus.Message) error { + return r.writeValue(recordSectionTypeMessages, &recordMessages{Messages: messages}) +} + +func (r *recorder) DidCommitBlock(state execute.BlockState) error { ci, err := json.Marshal(state.Params().CommitInfo) if err != nil { return errors.EncodingError.WithFormat("encode commit info: %w", err) @@ -83,12 +61,11 @@ func (r *recorder) DidExecuteBlock(state execute.BlockState, submissions []*mess return errors.EncodingError.WithFormat("encode evidence: %w", err) } b := &recordBlock{ - IsLeader: state.Params().IsLeader, - Index: state.Params().Index, - Time: state.Params().Time, - CommitInfo: ci, - Evidence: ev, - Submissions: submissions, + IsLeader: state.Params().IsLeader, + Index: state.Params().Index, + Time: state.Params().Time, + CommitInfo: ci, + Evidence: ev, } if !state.IsEmpty() { @@ -120,17 +97,25 @@ func (r *recorder) DidExecuteBlock(state execute.BlockState, submissions []*mess } } - v, err := b.MarshalBinary() + return r.writeValue(recordSectionTypeBlock, b) +} + +func (r *recorder) writeValue(typ recordSectionType, val encoding.BinaryValue) error { + b, err := val.MarshalBinary() if err != nil { return errors.EncodingError.WithFormat("encode: %w", err) } - w, err := r.Open(recordSectionTypeBlock) + return r.writeSection(typ, bytes.NewReader(b)) +} + +func (r *recorder) writeSection(typ recordSectionType, data io.Reader) error { + w, err := r.Open(typ) if err != nil { return errors.UnknownError.WithFormat("open: %w", err) } - _, err = w.Write(v) + _, err = io.Copy(w, data) if err != nil { - return errors.UnknownError.WithFormat("write: %w", err) + return errors.UnknownError.WithFormat("copy: %w", err) } err = w.Close() if err != nil { @@ -165,6 +150,24 @@ func DumpRecording(rd ioutil.SectionReader) error { } fmt.Printf(" Partition %s (%v) node %v\n", h.Partition.ID, h.Partition.Type, h.NodeID) + case recordSectionTypeMessages: + m := new(recordMessages) + err = m.UnmarshalBinaryFrom(r) + if err != nil { + return err + } + for _, m := range m.Messages { + switch m := m.(type) { + case consensus.NodeMessage: + s := m.SenderID() + fmt.Printf(" Message %v for %s from %x\n", m.Type(), m.PartitionID(), s[:4]) + case consensus.NetworkMessage: + fmt.Printf(" Message %v for %s\n", m.Type(), m.PartitionID()) + default: + fmt.Printf(" Message %v\n", m.Type()) + } + } + case recordSectionTypeBlock: b := new(recordBlock) err = b.UnmarshalBinaryFrom(r) diff --git a/test/simulator/recorder_enums.yml b/test/simulator/recorder_enums.yml index 82987ea85..687124bb3 100644 --- a/test/simulator/recorder_enums.yml +++ b/test/simulator/recorder_enums.yml @@ -4,4 +4,6 @@ recordSectionType: Snapshot: value: 2 Block: - value: 3 \ No newline at end of file + value: 3 + Messages: + value: 4 \ No newline at end of file diff --git a/test/simulator/recorder_enums_gen.go b/test/simulator/recorder_enums_gen.go index ac0fe555a..e627fb675 100644 --- a/test/simulator/recorder_enums_gen.go +++ b/test/simulator/recorder_enums_gen.go @@ -1,4 +1,4 @@ -// Copyright 2023 The Accumulate Authors +// Copyright 2024 The Accumulate Authors // // Use of this source code is governed by an MIT-style // license that can be found in the LICENSE file or at @@ -23,6 +23,9 @@ const recordSectionTypeSnapshot recordSectionType = 2 // recordSectionTypeBlock . const recordSectionTypeBlock recordSectionType = 3 +// recordSectionTypeMessages . +const recordSectionTypeMessages recordSectionType = 4 + // GetEnumValue returns the value of the record Section Type func (v recordSectionType) GetEnumValue() uint64 { return uint64(v) } @@ -30,7 +33,7 @@ func (v recordSectionType) GetEnumValue() uint64 { return uint64(v) } func (v *recordSectionType) SetEnumValue(id uint64) bool { u := recordSectionType(id) switch u { - case recordSectionTypeHeader, recordSectionTypeSnapshot, recordSectionTypeBlock: + case recordSectionTypeHeader, recordSectionTypeSnapshot, recordSectionTypeBlock, recordSectionTypeMessages: *v = u return true } @@ -46,6 +49,8 @@ func (v recordSectionType) String() string { return "snapshot" case recordSectionTypeBlock: return "block" + case recordSectionTypeMessages: + return "messages" } return fmt.Sprintf("recordSectionType:%d", v) } @@ -59,6 +64,8 @@ func recordSectionTypeByName(name string) (recordSectionType, bool) { return recordSectionTypeSnapshot, true case "block": return recordSectionTypeBlock, true + case "messages": + return recordSectionTypeMessages, true } return 0, false } diff --git a/test/simulator/recorder_types.yml b/test/simulator/recorder_types.yml index 946657f14..f03be231b 100644 --- a/test/simulator/recorder_types.yml +++ b/test/simulator/recorder_types.yml @@ -42,3 +42,10 @@ recordChange: pointer: true - name: Value type: bytes + +recordMessages: + fields: + - name: Messages + type: consensus.Message + repeatable: true + marshal-as: union diff --git a/test/simulator/recorder_types_gen.go b/test/simulator/recorder_types_gen.go index c61975895..cf86da447 100644 --- a/test/simulator/recorder_types_gen.go +++ b/test/simulator/recorder_types_gen.go @@ -24,6 +24,7 @@ import ( "gitlab.com/accumulatenetwork/accumulate/pkg/types/messaging" "gitlab.com/accumulatenetwork/accumulate/pkg/types/record" "gitlab.com/accumulatenetwork/accumulate/protocol" + "gitlab.com/accumulatenetwork/accumulate/test/simulator/consensus" ) type recordBlock struct { @@ -53,6 +54,12 @@ type recordHeader struct { extraData []byte } +type recordMessages struct { + fieldsSet []bool + Messages []consensus.Message `json:"messages,omitempty" form:"messages" query:"messages" validate:"required"` + extraData []byte +} + func (v *recordBlock) Copy() *recordBlock { u := new(recordBlock) @@ -122,6 +129,26 @@ func (v *recordHeader) Copy() *recordHeader { func (v *recordHeader) CopyAsInterface() interface{} { return v.Copy() } +func (v *recordMessages) Copy() *recordMessages { + u := new(recordMessages) + + u.Messages = make([]consensus.Message, len(v.Messages)) + for i, v := range v.Messages { + v := v + if v != nil { + u.Messages[i] = consensus.CopyMessage(v) + } + } + if len(v.extraData) > 0 { + u.extraData = make([]byte, len(v.extraData)) + copy(u.extraData, v.extraData) + } + + return u +} + +func (v *recordMessages) CopyAsInterface() interface{} { return v.Copy() } + func (v *recordBlock) Equal(u *recordBlock) bool { if !(v.IsLeader == u.IsLeader) { return false @@ -198,6 +225,19 @@ func (v *recordHeader) Equal(u *recordHeader) bool { return true } +func (v *recordMessages) Equal(u *recordMessages) bool { + if len(v.Messages) != len(u.Messages) { + return false + } + for i := range v.Messages { + if !(consensus.EqualMessage(v.Messages[i], u.Messages[i])) { + return false + } + } + + return true +} + var fieldNames_recordBlock = []string{ 1: "IsLeader", 2: "Index", @@ -412,6 +452,51 @@ func (v *recordHeader) IsValid() error { } } +var fieldNames_recordMessages = []string{ + 1: "Messages", +} + +func (v *recordMessages) MarshalBinary() ([]byte, error) { + if v == nil { + return []byte{encoding.EmptyObject}, nil + } + + buffer := new(bytes.Buffer) + writer := encoding.NewWriter(buffer) + + if !(len(v.Messages) == 0) { + for _, v := range v.Messages { + writer.WriteValue(1, v.MarshalBinary) + } + } + + _, _, err := writer.Reset(fieldNames_recordMessages) + if err != nil { + return nil, encoding.Error{E: err} + } + buffer.Write(v.extraData) + return buffer.Bytes(), nil +} + +func (v *recordMessages) IsValid() error { + var errs []string + + if len(v.fieldsSet) > 0 && !v.fieldsSet[0] { + errs = append(errs, "field Messages is missing") + } else if len(v.Messages) == 0 { + errs = append(errs, "field Messages is not set") + } + + switch len(errs) { + case 0: + return nil + case 1: + return errors.New(errs[0]) + default: + return errors.New(strings.Join(errs, "; ")) + } +} + func (v *recordBlock) UnmarshalBinary(data []byte) error { return v.UnmarshalBinaryFrom(bytes.NewReader(data)) } @@ -516,6 +601,38 @@ func (v *recordHeader) UnmarshalBinaryFrom(rd io.Reader) error { return nil } +func (v *recordMessages) UnmarshalBinary(data []byte) error { + return v.UnmarshalBinaryFrom(bytes.NewReader(data)) +} + +func (v *recordMessages) UnmarshalBinaryFrom(rd io.Reader) error { + reader := encoding.NewReader(rd) + + for { + ok := reader.ReadValue(1, func(r io.Reader) error { + x, err := consensus.UnmarshalMessageFrom(r) + if err == nil { + v.Messages = append(v.Messages, x) + } + return err + }) + if !ok { + break + } + } + + seen, err := reader.Reset(fieldNames_recordMessages) + if err != nil { + return encoding.Error{E: err} + } + v.fieldsSet = seen + v.extraData, err = reader.ReadAll() + if err != nil { + return encoding.Error{E: err} + } + return nil +} + func (v *recordBlock) MarshalJSON() ([]byte, error) { u := struct { IsLeader bool `json:"isLeader,omitempty"` @@ -564,6 +681,16 @@ func (v *recordChange) MarshalJSON() ([]byte, error) { return json.Marshal(&u) } +func (v *recordMessages) MarshalJSON() ([]byte, error) { + u := struct { + Messages *encoding.JsonUnmarshalListWith[consensus.Message] `json:"messages,omitempty"` + }{} + if !(len(v.Messages) == 0) { + u.Messages = &encoding.JsonUnmarshalListWith[consensus.Message]{Value: v.Messages, Func: consensus.UnmarshalMessageJSON} + } + return json.Marshal(&u) +} + func (v *recordBlock) UnmarshalJSON(data []byte) error { u := struct { IsLeader bool `json:"isLeader,omitempty"` @@ -612,3 +739,20 @@ func (v *recordChange) UnmarshalJSON(data []byte) error { } return nil } + +func (v *recordMessages) UnmarshalJSON(data []byte) error { + u := struct { + Messages *encoding.JsonUnmarshalListWith[consensus.Message] `json:"messages,omitempty"` + }{} + u.Messages = &encoding.JsonUnmarshalListWith[consensus.Message]{Value: v.Messages, Func: consensus.UnmarshalMessageJSON} + if err := json.Unmarshal(data, &u); err != nil { + return err + } + if u.Messages != nil { + v.Messages = make([]consensus.Message, len(u.Messages.Value)) + for i, x := range u.Messages.Value { + v.Messages[i] = x + } + } + return nil +} diff --git a/tools/cmd/gen-types/go.go b/tools/cmd/gen-types/go.go index b312bbe87..b71d379de 100644 --- a/tools/cmd/gen-types/go.go +++ b/tools/cmd/gen-types/go.go @@ -148,7 +148,7 @@ var goFuncs = template.FuncMap{ } func GoTmplUnionMethod(u *UnionSpec, method string) string { - if u.Private { + if u.PrivateUnion { method = typegen.LowerFirstWord(method) } if flags.ElidePackageType && strings.EqualFold(u.Name, u.Package) { diff --git a/tools/cmd/gen-types/templates.go b/tools/cmd/gen-types/templates.go index 05f333f9f..0b137f84c 100644 --- a/tools/cmd/gen-types/templates.go +++ b/tools/cmd/gen-types/templates.go @@ -83,7 +83,8 @@ func convert(types, refTypes typegen.Types, pkgName, subPkgName string) (*Types, union = new(UnionSpec) union.Name = typ.Union.Name union.Type = typ.Union.Type - union.Private = typ.Union.Private + union.PrivateEnum = typ.Union.Private || typ.Union.PrivateEnum + union.PrivateUnion = typ.Union.Private || typ.Union.PrivateUnion union.Registry = typ.Union.Registry union.Package = pkgName union.SubPackage = subPkgName @@ -226,13 +227,14 @@ type SingleUnionFile struct { func (f *SingleUnionFile) IsUnion() bool { return true } type UnionSpec struct { - Package string - Name string - Type string - Members []*Type - SubPackage string - Private bool - Registry bool + Package string + Name string + Type string + Members []*Type + SubPackage string + PrivateEnum bool + PrivateUnion bool + Registry bool } type Type struct { @@ -297,7 +299,7 @@ func (u *UnionSpec) interfaceName(ignorePrivate bool) string { case "transaction": return "TransactionBody" } - if !ignorePrivate && u.Private { + if !ignorePrivate && u.PrivateUnion { return typegen.LowerFirstWord(u.Name) } return typegen.TitleCase(u.Name) @@ -314,7 +316,7 @@ func (u *UnionSpec) Enumeration() string { if flags.ElidePackageType && strings.EqualFold(u.Name, u.Package) { return "Type" } - if u.Private { + if u.PrivateEnum { return typegen.LowerFirstWord(u.Type) + "Type" } return typegen.TitleCase(u.Type) + "Type" diff --git a/tools/internal/typegen/types.go b/tools/internal/typegen/types.go index 25af5d530..347426ce2 100644 --- a/tools/internal/typegen/types.go +++ b/tools/internal/typegen/types.go @@ -319,7 +319,9 @@ type Union struct { // Value is the name of the corresponding enumeration value. Value string // Private indicates the union is a private type. - Private bool + Private bool + PrivateEnum bool `yaml:"private-enum"` + PrivateUnion bool `yaml:"private-iface"` // Registry indicates the union supports registering new members. Registry bool }