Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
371b8af
WIP: Compiling but failing tests for just player
iansuvak Oct 5, 2022
83b7e80
WIP: barebones player serializes
iansuvak Oct 5, 2022
e2fa904
WIP: Player and router are encoded with some missing fields
iansuvak Oct 6, 2022
9d2c61e
Changed names back to fix reflectdecoding
iansuvak Oct 6, 2022
dc89b11
Add sort interfaces for everything except for proposalValues
iansuvak Oct 7, 2022
71464cb
add sorts for proposalvalue
iansuvak Oct 7, 2022
5d72a3d
Actually add the agreement/sort.go file
iansuvak Oct 7, 2022
ea28f9c
WIP: still wrestling with it
iansuvak Oct 13, 2022
c035014
remove serializableerrorunderlying
iansuvak Oct 13, 2022
bd34159
Fix tests failing on diffs in nil object serde
iansuvak Oct 14, 2022
869d1f4
Merge remote-tracking branch 'upstream/master' into msgp-agreement
iansuvak Oct 14, 2022
82ef464
Merge remote-tracking branch 'upstream/master' into msgp-agreement
iansuvak Oct 17, 2022
b7fe033
explicitly unexport embedded MessageHandle interface from agreement.m…
iansuvak Oct 17, 2022
e7cfbec
Add reflect flag to encode/decode and benchmarks
iansuvak Oct 17, 2022
61345ff
remove currently unused types from msgp generation
iansuvak Oct 17, 2022
f9ca8eb
add proposalmanager and voteaggregator back
iansuvak Oct 18, 2022
1fb3c04
Fix for mismatch on rootRouter object
iansuvak Oct 18, 2022
d6cac67
clean up
iansuvak Oct 18, 2022
75a8d79
Add test for full diskstate
iansuvak Oct 18, 2022
ed36eb2
Fix codegen CI msgp version
iansuvak Oct 19, 2022
02ea522
Merge remote-tracking branch 'origin/master' into msgp-agreement
iansuvak Oct 19, 2022
00b4f82
Add test for SortProposalValue.Less()
iansuvak Oct 19, 2022
e5becf8
Apply suggestions from code review
iansuvak Oct 21, 2022
4d624ab
fix reviewdog issue
iansuvak Oct 21, 2022
7ee6dc7
Backward compatibility test
algorandskiy Oct 21, 2022
732999c
Add serializableError test
algorandskiy Oct 21, 2022
abae63e
Apply suggestions from code review
iansuvak Oct 22, 2022
dc28cdd
Apply review suggestions
iansuvak Oct 22, 2022
708e6d5
Merge pull request #1 from algorandskiy/msgp-agreement
iansuvak Oct 22, 2022
a09a711
Ignore unnecessary events that got caught in making message serializable
iansuvak Oct 24, 2022
6c1f56c
manual implementation for message
iansuvak Oct 24, 2022
6651ace
Fix for randomizedEncoding running into interface
iansuvak Oct 24, 2022
5a766ef
small expansion to the test to demonstrate consistency
iansuvak Oct 24, 2022
c603420
change comment to indicate that the file is mostly autogenned
iansuvak Oct 24, 2022
bfb41e1
apply comparison optimization to all checks in SortProposalValue
iansuvak Oct 24, 2022
d30f1b9
Use msgp.Raw for backwards compatibility when changing the interface
iansuvak Oct 25, 2022
d72f50e
remove omitemptys and interface case from codec_tester
iansuvak Oct 25, 2022
65b94bb
Add test to ensure that empty maps serialize correctly
iansuvak Oct 26, 2022
d9ff09f
add more tests and cleanup
iansuvak Oct 26, 2022
fc6f835
Move SortUint64 import to sort file
iansuvak Oct 26, 2022
e88a05d
Add explicit test for proposalTable message encoding
iansuvak Oct 27, 2022
c31c713
Add a sanity check on TaskIndex on the proposalTable serialization test
iansuvak Oct 27, 2022
565833f
remove misplaced comment
iansuvak Oct 28, 2022
609bdf8
address review comments
iansuvak Oct 31, 2022
6fad072
preallocate s.Actions and s.ActionTypes
iansuvak Oct 31, 2022
aa5ad07
loop over randomized testing and properly assign into pre-allocated s…
iansuvak Oct 31, 2022
e798292
Add test to cover action serde
iansuvak Oct 31, 2022
fa48132
re-run "go generate" inside agreement
cce Oct 31, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 11 additions & 12 deletions agreement/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ import (
)

//go:generate stringer -type=actionType
//msgp:ignore actionType
type actionType int
type actionType uint8

const (
noop actionType = iota
Expand Down Expand Up @@ -103,7 +102,7 @@ type networkAction struct {

UnauthenticatedVotes []unauthenticatedVote

Err serializableError
Err *serializableError
}

func (a networkAction) t() actionType {
Expand Down Expand Up @@ -181,7 +180,7 @@ type cryptoAction struct {
Period period
Step step
Pinned bool
TaskIndex int
TaskIndex uint64
}

func (a cryptoAction) t() actionType {
Expand Down Expand Up @@ -388,7 +387,7 @@ func (a pseudonodeAction) do(ctx context.Context, s *Service) {
case nil:
// no error.
persistCompleteEvents := s.persistState(persistStateDone)
// we want to place there two one after the other. That way, the second would not get executed up until the first one is complete.
// we want to place these two one after the other. That way, the second would not get executed up until the first one is complete.
s.demux.prioritize(persistCompleteEvents)
s.demux.prioritize(voteEvents)
default:
Expand All @@ -403,12 +402,12 @@ func (a pseudonodeAction) do(ctx context.Context, s *Service) {
}
}

func ignoreAction(e messageEvent, err serializableError) action {
return networkAction{T: ignore, Err: err, h: e.Input.MessageHandle}
func ignoreAction(e messageEvent, err *serializableError) action {
return networkAction{T: ignore, Err: err, h: e.Input.messageHandle}
}

func disconnectAction(e messageEvent, err serializableError) action {
return networkAction{T: disconnect, Err: err, h: e.Input.MessageHandle}
func disconnectAction(e messageEvent, err *serializableError) action {
return networkAction{T: disconnect, Err: err, h: e.Input.messageHandle}
}

func broadcastAction(tag protocol.Tag, o interface{}) action {
Expand All @@ -427,7 +426,7 @@ func broadcastAction(tag protocol.Tag, o interface{}) action {
}

func relayAction(e messageEvent, tag protocol.Tag, o interface{}) action {
a := networkAction{T: relay, h: e.Input.MessageHandle, Tag: tag}
a := networkAction{T: relay, h: e.Input.messageHandle, Tag: tag}
// TODO would be good to have compiler check this (and related) type switch
// by specializing one method per type
switch tag {
Expand All @@ -441,7 +440,7 @@ func relayAction(e messageEvent, tag protocol.Tag, o interface{}) action {
return a
}

func verifyVoteAction(e messageEvent, r round, p period, taskIndex int) action {
func verifyVoteAction(e messageEvent, r round, p period, taskIndex uint64) action {
return cryptoAction{T: verifyVote, M: e.Input, Round: r, Period: p, TaskIndex: taskIndex}
}

Expand Down Expand Up @@ -479,7 +478,7 @@ type checkpointAction struct {
Round round
Period period
Step step
Err serializableError
Err *serializableError
done chan error // an output channel to let the pseudonode that we're done processing. We don't want to serialize that, since it's not needed in recovery/autopsy
}

Expand Down
2 changes: 1 addition & 1 deletion agreement/actiontype_string.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions agreement/asyncVoteVerifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type asyncVerifyVoteRequest struct {
l LedgerReader
uv *unauthenticatedVote
uev *unauthenticatedEquivocationVote
index int
index uint64
message message

// a channel that holds the response
Expand All @@ -39,7 +39,7 @@ type asyncVerifyVoteRequest struct {
type asyncVerifyVoteResponse struct {
v vote
ev equivocationVote
index int
index uint64
message message
err error
cancelled bool
Expand Down Expand Up @@ -131,7 +131,7 @@ func (avv *AsyncVoteVerifier) executeEqVoteVerification(task interface{}) interf
}
}

func (avv *AsyncVoteVerifier) verifyVote(verctx context.Context, l LedgerReader, uv unauthenticatedVote, index int, message message, out chan<- asyncVerifyVoteResponse) error {
func (avv *AsyncVoteVerifier) verifyVote(verctx context.Context, l LedgerReader, uv unauthenticatedVote, index uint64, message message, out chan<- asyncVerifyVoteResponse) error {
select {
case <-avv.ctx.Done(): // if we're quitting, don't enqueue the request
// case <-verctx.Done(): DO NOT DO THIS! otherwise we will lose the vote (and forget to clean up)!
Expand All @@ -151,7 +151,7 @@ func (avv *AsyncVoteVerifier) verifyVote(verctx context.Context, l LedgerReader,
return nil
}

func (avv *AsyncVoteVerifier) verifyEqVote(verctx context.Context, l LedgerReader, uev unauthenticatedEquivocationVote, index int, message message, out chan<- asyncVerifyVoteResponse) error {
func (avv *AsyncVoteVerifier) verifyEqVote(verctx context.Context, l LedgerReader, uev unauthenticatedEquivocationVote, index uint64, message message, out chan<- asyncVerifyVoteResponse) error {
select {
case <-avv.ctx.Done(): // if we're quitting, don't enqueue the request
// case <-verctx.Done(): DO NOT DO THIS! otherwise we will lose the vote (and forget to clean up)!
Expand Down
6 changes: 4 additions & 2 deletions agreement/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ func (b unauthenticatedBundle) verifyAsync(ctx context.Context, l LedgerReader,

rv := rawVote{Sender: auth.Sender, Round: b.Round, Period: b.Period, Step: b.Step, Proposal: b.Proposal}
uv := unauthenticatedVote{R: rv, Cred: auth.Cred, Sig: auth.Sig}
avv.verifyVote(ctx, l, uv, i, message{}, results)

avv.verifyVote(ctx, l, uv, uint64(i), message{}, results) //nolint:errcheck // verifyVote will call EnqueueBacklog, which blocks until the verify task is queued, or returns an error when ctx.Done(), which we are already checking
}

// create verification requests for equivocation votes
Expand All @@ -222,7 +223,8 @@ func (b unauthenticatedBundle) verifyAsync(ctx context.Context, l LedgerReader,
Proposals: auth.Proposals,
Sigs: auth.Sigs,
}
avv.verifyEqVote(ctx, l, uev, i, message{}, results)
avv.verifyEqVote(ctx, l, uev, uint64(i), message{}, results) //nolint:errcheck // verifyVote will call EnqueueBacklog, which blocks until the verify task is queued, or returns an error when ctx.Done(), which we are already checking

}

return func() (bundle, error) {
Expand Down
19 changes: 12 additions & 7 deletions agreement/cryptoVerifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,37 +82,41 @@ type (
Quit()
}

//msgp:ignore cryptoVoteRequest
Copy link
Contributor

Choose a reason for hiding this comment

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

out of curiosity, how did you figure out which types to ignore?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Anything that embeds message really and is not messageEvent. The process of adding the fields was adding the _struct field to the top levels embedded things and then seeing which structs didn't get their interfaces implemented after running make msgp. anything that embeds message got accidentally added and ignoring them didn't introduce any unimplemented method errors.

cryptoVoteRequest struct {
message // the message we would like to verify.
TaskIndex int // Caller specific number that would be passed back in the asyncVerifyVoteResponse.TaskIndex field
TaskIndex uint64 // Caller specific number that would be passed back in the asyncVerifyVoteResponse.TaskIndex field
Round round // The round that we're going to test against.
Period period // The period associated with the message we're going to test.
ctx context.Context // A context for this request, if the context is cancelled then the request is stale.
}

//msgp:ignore cryptoProposalRequest
cryptoProposalRequest struct {
message // the message we would like to verify.
TaskIndex int // Caller specific number that would be passed back in the cryptoResult.TaskIndex field
TaskIndex uint64 // Caller specific number that would be passed back in the cryptoResult.TaskIndex field
Round round // The round that we're going to test against.
Period period // The period associated with the message we're going to test.
Pinned bool // A flag that is set if this is a pinned value for the given round.
ctx context.Context // A context for this request, if the context is cancelled then the request is stale.
}

//msgp:ignore cryptoBundleRequest
cryptoBundleRequest struct {
message // the message we would like to verify.
TaskIndex int // Caller specific number that would be passed back in the asyncVerifyVoteResponse.TaskIndex field
TaskIndex uint64 // Caller specific number that would be passed back in the asyncVerifyVoteResponse.TaskIndex field
Round round // The round that we're going to test against.
Period period // The period associated with the message we're going to test.
Certify bool // A flag that set if this is a cert bundle.
ctx context.Context // A context for this request, if the context is cancelled then the request is stale.
}

//msgp:ignore cryptoResult
cryptoResult struct {
message
Err serializableError
TaskIndex int // the TaskIndex that was passed to the cryptoVerifier during the Verify call on the cryptoRequest.TaskIndex
Cancelled bool // whether the corresponding request was cancelled before verification completed
Err *serializableError
TaskIndex uint64 // the TaskIndex that was passed to the cryptoVerifier during the Verify call on the cryptoRequest.TaskIndex
Cancelled bool // whether the corresponding request was cancelled before verification completed
}

// A poolCryptoVerifier uses asynchronous goroutines to implement cryptoVerifier.
Expand Down Expand Up @@ -146,9 +150,10 @@ type (
out chan cryptoResult
}

//msgp:ignore bundleFuture
bundleFuture struct {
message
index int
index uint64
wait func() (bundle, error)
ctx context.Context
}
Expand Down
20 changes: 10 additions & 10 deletions agreement/cryptoVerifier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func makeMessage(msgHandle int, tag protocol.Tag, sender basics.Address, l Ledge
}

return message{
MessageHandle: MessageHandle(msgHandle),
messageHandle: MessageHandle(msgHandle),
Tag: tag,
UnauthenticatedVote: makeUnauthenticatedVote(l, sender, selection, voting, Round, Period, Step, proposal),
}
Expand All @@ -103,13 +103,13 @@ func makeMessage(msgHandle int, tag protocol.Tag, sender basics.Address, l Ledge
Block: e,
}
return message{
MessageHandle: MessageHandle(msgHandle),
messageHandle: MessageHandle(msgHandle),
Tag: tag,
UnauthenticatedProposal: payload,
}
default: // protocol.VoteBundleTag
return message{
MessageHandle: MessageHandle(msgHandle),
messageHandle: MessageHandle(msgHandle),
Tag: tag,
UnauthenticatedBundle: unauthenticatedBundle{
Round: Round,
Expand Down Expand Up @@ -180,9 +180,9 @@ func TestCryptoVerifierBuffers(t *testing.T) {
for _, msgType := range msgTypes {
for i := getSelectorCapacity(msgType) * 5; i > 0; i-- {
msg := <-verifier.Verified(msgType)
_, has := usedMsgIDs[msg.MessageHandle]
_, has := usedMsgIDs[msg.messageHandle]
assert.True(t, has)
delete(usedMsgIDs, msg.MessageHandle)
delete(usedMsgIDs, msg.messageHandle)
}
assert.False(t, verifier.ChannelFull(msgType))
assert.Zero(t, len(verifier.Verified(msgType)))
Expand Down Expand Up @@ -230,8 +230,8 @@ func TestCryptoVerifierBuffers(t *testing.T) {
}
msgIDMutex.Lock()
defer msgIDMutex.Unlock()
_, has := usedMsgIDs[msg.MessageHandle]
delete(usedMsgIDs, msg.MessageHandle)
_, has := usedMsgIDs[msg.messageHandle]
delete(usedMsgIDs, msg.messageHandle)
return assert.True(t, has)
}

Expand Down Expand Up @@ -333,7 +333,7 @@ func BenchmarkCryptoVerifierProposalVertification(b *testing.B) {
c := verifier.Verified(protocol.ProposalPayloadTag)
request := cryptoProposalRequest{
message: message{
MessageHandle: MessageHandle(0),
messageHandle: MessageHandle(0),
Tag: protocol.ProposalPayloadTag,
UnauthenticatedProposal: proposals[0].unauthenticatedProposal,
},
Expand Down Expand Up @@ -402,11 +402,11 @@ func TestCryptoVerifierVerificationFailures(t *testing.T) {
cryptoVerifier := makeCryptoVerifier(nil, nil, voteVerifier, logging.TestingLog(t))
defer cryptoVerifier.Quit()

cryptoVerifier.VerifyVote(context.Background(), cryptoVoteRequest{message: message{Tag: protocol.AgreementVoteTag}, Round: basics.Round(8), TaskIndex: 14})
cryptoVerifier.VerifyVote(context.Background(), cryptoVoteRequest{message: message{Tag: protocol.AgreementVoteTag}, Round: basics.Round(8), TaskIndex: uint64(14)})
// read the failed response from VerifiedVotes:
votesout := cryptoVerifier.VerifiedVotes()
voteResponse := <-votesout
require.Equal(t, context.Canceled, voteResponse.err)
require.True(t, voteResponse.cancelled)
require.Equal(t, 14, voteResponse.index)
require.Equal(t, uint64(14), voteResponse.index)
}
10 changes: 5 additions & 5 deletions agreement/demux.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,11 @@ func (d *demux) tokenizeMessages(ctx context.Context, net Network, tag protocol.
var msg message
switch tag {
case protocol.AgreementVoteTag:
msg = message{MessageHandle: raw.MessageHandle, Tag: tag, UnauthenticatedVote: o.(unauthenticatedVote)}
msg = message{messageHandle: raw.MessageHandle, Tag: tag, UnauthenticatedVote: o.(unauthenticatedVote)}
case protocol.VoteBundleTag:
msg = message{MessageHandle: raw.MessageHandle, Tag: tag, UnauthenticatedBundle: o.(unauthenticatedBundle)}
msg = message{messageHandle: raw.MessageHandle, Tag: tag, UnauthenticatedBundle: o.(unauthenticatedBundle)}
case protocol.ProposalPayloadTag:
msg = message{MessageHandle: raw.MessageHandle, Tag: tag, CompoundMessage: o.(compoundMessage)}
msg = message{messageHandle: raw.MessageHandle, Tag: tag, CompoundMessage: o.(compoundMessage)}
default:
err := fmt.Errorf("bad message tag: %v", tag)
d.UpdateEventsQueue(fmt.Sprintf("Tokenizing-%s", tag), 0)
Expand All @@ -167,7 +167,7 @@ func (d *demux) tokenizeMessages(ctx context.Context, net Network, tag protocol.
}

// verifyVote enqueues a vote message to be verified.
func (d *demux) verifyVote(ctx context.Context, m message, taskIndex int, r round, p period) {
func (d *demux) verifyVote(ctx context.Context, m message, taskIndex uint64, r round, p period) {
d.UpdateEventsQueue(eventQueueCryptoVerifierVote, 1)
d.monitor.inc(cryptoVerifierCoserviceType)
d.crypto.VerifyVote(ctx, cryptoVoteRequest{message: m, TaskIndex: taskIndex, Round: r, Period: p})
Expand Down Expand Up @@ -367,7 +367,7 @@ func setupCompoundMessage(l LedgerReader, m message) (res externalEvent) {
return
}

tailmsg := message{MessageHandle: m.MessageHandle, Tag: protocol.ProposalPayloadTag, UnauthenticatedProposal: compound.Proposal}
tailmsg := message{messageHandle: m.messageHandle, Tag: protocol.ProposalPayloadTag, UnauthenticatedProposal: compound.Proposal}
synthetic := messageEvent{T: payloadPresent, Input: tailmsg}
proto, err := l.ConsensusVersion(ParamsRound(synthetic.ConsensusRound()))
synthetic = synthetic.AttachConsensusVersion(ConsensusVersionView{Err: makeSerErr(err), Version: proto}).(messageEvent)
Expand Down
23 changes: 12 additions & 11 deletions agreement/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,38 +16,39 @@

package agreement

import "fmt"
import (
"fmt"
)

// serializableError, or state machine error, is a serializable error that
// is correctly written to cadaver files.
type serializableErrorUnderlying string
type serializableError = *serializableErrorUnderlying
type serializableError string

// implement error interface
func (e serializableErrorUnderlying) Error() string {
func (e serializableError) Error() string {
return string(e)
}

func (e serializableErrorUnderlying) String() string {
func (e serializableError) String() string {
return e.Error()
}

// makeSerErrStr returns an serializableError that formats as the given text.
func makeSerErrStr(text string) serializableError {
s := serializableErrorUnderlying(text)
func makeSerErrStr(text string) *serializableError {
s := serializableError(text)
return &s
}

func makeSerErrf(format string, a ...interface{}) serializableError {
s := serializableErrorUnderlying(fmt.Sprintf(format, a...))
func makeSerErrf(format string, a ...interface{}) *serializableError {
s := serializableError(fmt.Sprintf(format, a...))
return &s
}

// makeSerErr returns an serializableError that formats as the given error.
func makeSerErr(err error) serializableError {
func makeSerErr(err error) *serializableError {
if err == nil {
return nil
}
s := serializableErrorUnderlying(err.Error())
s := serializableError(err.Error())
return &s
}
Loading