From 664d34d5fea5f7f10e781db402b72878f86ba300 Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Fri, 15 Sep 2023 11:15:27 -0400 Subject: [PATCH 1/9] Implements "Mining" - diverting a portion of fees to proposers --- agreement/abstractions.go | 2 +- agreement/agreementtest/simulate_test.go | 3 +- agreement/common_test.go | 3 +- agreement/fuzzer/ledger_test.go | 3 +- agreement/msgp_gen.go | 502 +++++++++++------- agreement/proposal.go | 2 +- config/consensus.go | 10 + daemon/algod/api/server/v2/handlers.go | 5 +- .../server/v2/test/handlers_resources_test.go | 3 +- data/basics/fraction.go | 69 +++ data/basics/fraction_test.go | 76 +++ data/bookkeeping/block.go | 16 +- data/bookkeeping/msgp_gen.go | 304 +++++++---- data/datatest/impls.go | 4 +- data/transactions/logic/TEAL_opcodes_v10.md | 10 +- data/transactions/logic/eval.go | 7 +- data/transactions/logic/fields.go | 6 + data/transactions/logic/fields_string.go | 8 +- data/transactions/logic/langspec_v10.json | 6 +- data/transactions/logic/teal.tmLanguage.json | 2 +- data/transactions/payment.go | 5 +- data/transactions/transaction_test.go | 26 +- ledger/apply/asset_test.go | 2 +- ledger/apply/keyreg_test.go | 32 +- ledger/apply/payment_test.go | 2 +- ledger/apptxn_test.go | 41 +- ledger/double_test.go | 15 +- ledger/eval/applications.go | 3 +- ledger/eval/cow.go | 5 + ledger/eval/cow_test.go | 3 +- ledger/eval/eval.go | 38 +- .../prefetcher/prefetcher_alignment_test.go | 54 +- ledger/eval_simple_test.go | 61 +++ ledger/ledger_test.go | 3 + ledger/ledgercore/validatedBlock.go | 9 +- ledger/simple_test.go | 20 +- node/node.go | 4 +- protocol/tags.go | 2 +- test/scripts/e2e_client_runner.py | 2 +- test/scripts/e2e_subs/goal/goal.py | 18 +- test/scripts/e2e_subs/mining.py | 92 ++++ 41 files changed, 1084 insertions(+), 394 deletions(-) create mode 100644 data/basics/fraction.go create mode 100644 data/basics/fraction_test.go create mode 100755 test/scripts/e2e_subs/mining.py diff --git a/agreement/abstractions.go b/agreement/abstractions.go index 44aafa4fd8..25c920e02e 100644 --- a/agreement/abstractions.go +++ b/agreement/abstractions.go @@ -59,7 +59,7 @@ type ValidatedBlock interface { // // Calls to Seed() or to Digest() on the copy's Block must // reflect the value of the new seed. - WithSeed(committee.Seed) ValidatedBlock + WithSeed(committee.Seed, basics.Address) ValidatedBlock // Block returns the underlying block that has been validated. Block() bookkeeping.Block diff --git a/agreement/agreementtest/simulate_test.go b/agreement/agreementtest/simulate_test.go index 53c42411ed..335a781ef0 100644 --- a/agreement/agreementtest/simulate_test.go +++ b/agreement/agreementtest/simulate_test.go @@ -79,8 +79,9 @@ func (b testValidatedBlock) Block() bookkeeping.Block { return b.Inside } -func (b testValidatedBlock) WithSeed(s committee.Seed) agreement.ValidatedBlock { +func (b testValidatedBlock) WithSeed(s committee.Seed, proposer basics.Address) agreement.ValidatedBlock { b.Inside.BlockHeader.Seed = s + b.Inside.BlockHeader.Proposer = proposer return b } diff --git a/agreement/common_test.go b/agreement/common_test.go index 0c11d9553d..1b4f8d17ba 100644 --- a/agreement/common_test.go +++ b/agreement/common_test.go @@ -165,8 +165,9 @@ func (b testValidatedBlock) Block() bookkeeping.Block { return b.Inside } -func (b testValidatedBlock) WithSeed(s committee.Seed) ValidatedBlock { +func (b testValidatedBlock) WithSeed(s committee.Seed, proposer basics.Address) ValidatedBlock { b.Inside.BlockHeader.Seed = s + b.Inside.BlockHeader.Proposer = proposer return b } diff --git a/agreement/fuzzer/ledger_test.go b/agreement/fuzzer/ledger_test.go index a62caee4d9..e1f90d5d2a 100644 --- a/agreement/fuzzer/ledger_test.go +++ b/agreement/fuzzer/ledger_test.go @@ -93,8 +93,9 @@ func (b testValidatedBlock) Block() bookkeeping.Block { return b.Inside } -func (b testValidatedBlock) WithSeed(s committee.Seed) agreement.ValidatedBlock { +func (b testValidatedBlock) WithSeed(s committee.Seed, proposer basics.Address) agreement.ValidatedBlock { b.Inside.BlockHeader.Seed = s + b.Inside.BlockHeader.Proposer = proposer return b } diff --git a/agreement/msgp_gen.go b/agreement/msgp_gen.go index 16679ce797..91f877042f 100644 --- a/agreement/msgp_gen.go +++ b/agreement/msgp_gen.go @@ -4493,123 +4493,131 @@ func PlayerMaxSize() (s int) { func (z *proposal) MarshalMsg(b []byte) (o []byte) { o = msgp.Require(b, z.Msgsize()) // omitempty: check for empty values - zb0004Len := uint32(29) - var zb0004Mask uint64 /* 38 bits */ + zb0004Len := uint32(31) + var zb0004Mask uint64 /* 40 bits */ if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0 { zb0004Len-- zb0004Mask |= 0x40 } - if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero() { + if (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x80 } - if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0 { + if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x100 } - if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "" { + if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0 { zb0004Len-- zb0004Mask |= 0x200 } - if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero() { + if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "" { zb0004Len-- zb0004Mask |= 0x400 } - if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() { + if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x800 } - if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero() { + if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x1000 } - if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() { + if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x2000 } - if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0 { + if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x4000 } - if (*z).unauthenticatedProposal.OriginalPeriod == 0 { + if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0 { zb0004Len-- zb0004Mask |= 0x8000 } - if (*z).unauthenticatedProposal.OriginalProposer.MsgIsZero() { + if (*z).unauthenticatedProposal.OriginalPeriod == 0 { zb0004Len-- zb0004Mask |= 0x10000 } - if len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 { + if (*z).unauthenticatedProposal.OriginalProposer.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x20000 } - if (*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero() { + if len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 { zb0004Len-- zb0004Mask |= 0x40000 } - if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() { + if (*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x80000 } - if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0 { + if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x100000 } - if (*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero() { + if (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MsgIsZero() { + zb0004Len-- + zb0004Mask |= 0x200000 + } + if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0 { zb0004Len-- zb0004Mask |= 0x400000 } + if (*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero() { + zb0004Len-- + zb0004Mask |= 0x1000000 + } if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x800000 + zb0004Mask |= 0x2000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x1000000 + zb0004Mask |= 0x4000000 } if (*z).unauthenticatedProposal.SeedProof.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x2000000 + zb0004Mask |= 0x8000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x4000000 + zb0004Mask |= 0x10000000 } if len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0 { zb0004Len-- - zb0004Mask |= 0x8000000 + zb0004Mask |= 0x20000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0 { zb0004Len-- - zb0004Mask |= 0x10000000 + zb0004Mask |= 0x40000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0 { zb0004Len-- - zb0004Mask |= 0x20000000 + zb0004Mask |= 0x80000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x40000000 + zb0004Mask |= 0x100000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x80000000 + zb0004Mask |= 0x200000000 } if (*z).unauthenticatedProposal.Block.Payset.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x100000000 + zb0004Mask |= 0x400000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x200000000 + zb0004Mask |= 0x800000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x400000000 + zb0004Mask |= 0x1000000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false { zb0004Len-- - zb0004Mask |= 0x800000000 + zb0004Mask |= 0x2000000000 } // variable map header, size zb0004Len o = msgp.AppendMapHeader(o, zb0004Len) @@ -4620,56 +4628,61 @@ func (z *proposal) MarshalMsg(b []byte) (o []byte) { o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel) } if (zb0004Mask & 0x80) == 0 { // if not empty + // string "fc" + o = append(o, 0xa2, 0x66, 0x63) + o = (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MarshalMsg(o) + } + if (zb0004Mask & 0x100) == 0 { // if not empty // string "fees" o = append(o, 0xa4, 0x66, 0x65, 0x65, 0x73) o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MarshalMsg(o) } - if (zb0004Mask & 0x100) == 0 { // if not empty + if (zb0004Mask & 0x200) == 0 { // if not empty // string "frac" o = append(o, 0xa4, 0x66, 0x72, 0x61, 0x63) o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue) } - if (zb0004Mask & 0x200) == 0 { // if not empty + if (zb0004Mask & 0x400) == 0 { // if not empty // string "gen" o = append(o, 0xa3, 0x67, 0x65, 0x6e) o = msgp.AppendString(o, (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID) } - if (zb0004Mask & 0x400) == 0 { // if not empty + if (zb0004Mask & 0x800) == 0 { // if not empty // string "gh" o = append(o, 0xa2, 0x67, 0x68) o = (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MarshalMsg(o) } - if (zb0004Mask & 0x800) == 0 { // if not empty + if (zb0004Mask & 0x1000) == 0 { // if not empty // string "nextbefore" o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MarshalMsg(o) } - if (zb0004Mask & 0x1000) == 0 { // if not empty + if (zb0004Mask & 0x2000) == 0 { // if not empty // string "nextproto" o = append(o, 0xa9, 0x6e, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MarshalMsg(o) } - if (zb0004Mask & 0x2000) == 0 { // if not empty + if (zb0004Mask & 0x4000) == 0 { // if not empty // string "nextswitch" o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MarshalMsg(o) } - if (zb0004Mask & 0x4000) == 0 { // if not empty + if (zb0004Mask & 0x8000) == 0 { // if not empty // string "nextyes" o = append(o, 0xa7, 0x6e, 0x65, 0x78, 0x74, 0x79, 0x65, 0x73) o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals) } - if (zb0004Mask & 0x8000) == 0 { // if not empty + if (zb0004Mask & 0x10000) == 0 { // if not empty // string "oper" o = append(o, 0xa4, 0x6f, 0x70, 0x65, 0x72) o = msgp.AppendUint64(o, uint64((*z).unauthenticatedProposal.OriginalPeriod)) } - if (zb0004Mask & 0x10000) == 0 { // if not empty + if (zb0004Mask & 0x20000) == 0 { // if not empty // string "oprop" o = append(o, 0xa5, 0x6f, 0x70, 0x72, 0x6f, 0x70) o = (*z).unauthenticatedProposal.OriginalProposer.MarshalMsg(o) } - if (zb0004Mask & 0x20000) == 0 { // if not empty + if (zb0004Mask & 0x40000) == 0 { // if not empty // string "partupdrmv" o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76) if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts == nil { @@ -4681,47 +4694,52 @@ func (z *proposal) MarshalMsg(b []byte) (o []byte) { o = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].MarshalMsg(o) } } - if (zb0004Mask & 0x40000) == 0 { // if not empty + if (zb0004Mask & 0x80000) == 0 { // if not empty // string "prev" o = append(o, 0xa4, 0x70, 0x72, 0x65, 0x76) o = (*z).unauthenticatedProposal.Block.BlockHeader.Branch.MarshalMsg(o) } - if (zb0004Mask & 0x80000) == 0 { // if not empty + if (zb0004Mask & 0x100000) == 0 { // if not empty // string "proto" o = append(o, 0xa5, 0x70, 0x72, 0x6f, 0x74, 0x6f) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MarshalMsg(o) } - if (zb0004Mask & 0x100000) == 0 { // if not empty + if (zb0004Mask & 0x200000) == 0 { // if not empty + // string "prp" + o = append(o, 0xa3, 0x70, 0x72, 0x70) + o = (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MarshalMsg(o) + } + if (zb0004Mask & 0x400000) == 0 { // if not empty // string "rate" o = append(o, 0xa4, 0x72, 0x61, 0x74, 0x65) o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate) } - if (zb0004Mask & 0x400000) == 0 { // if not empty + if (zb0004Mask & 0x1000000) == 0 { // if not empty // string "rnd" o = append(o, 0xa3, 0x72, 0x6e, 0x64) o = (*z).unauthenticatedProposal.Block.BlockHeader.Round.MarshalMsg(o) } - if (zb0004Mask & 0x800000) == 0 { // if not empty + if (zb0004Mask & 0x2000000) == 0 { // if not empty // string "rwcalr" o = append(o, 0xa6, 0x72, 0x77, 0x63, 0x61, 0x6c, 0x72) o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MarshalMsg(o) } - if (zb0004Mask & 0x1000000) == 0 { // if not empty + if (zb0004Mask & 0x4000000) == 0 { // if not empty // string "rwd" o = append(o, 0xa3, 0x72, 0x77, 0x64) o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MarshalMsg(o) } - if (zb0004Mask & 0x2000000) == 0 { // if not empty + if (zb0004Mask & 0x8000000) == 0 { // if not empty // string "sdpf" o = append(o, 0xa4, 0x73, 0x64, 0x70, 0x66) o = (*z).unauthenticatedProposal.SeedProof.MarshalMsg(o) } - if (zb0004Mask & 0x4000000) == 0 { // if not empty + if (zb0004Mask & 0x10000000) == 0 { // if not empty // string "seed" o = append(o, 0xa4, 0x73, 0x65, 0x65, 0x64) o = (*z).unauthenticatedProposal.Block.BlockHeader.Seed.MarshalMsg(o) } - if (zb0004Mask & 0x8000000) == 0 { // if not empty + if (zb0004Mask & 0x20000000) == 0 { // if not empty // string "spt" o = append(o, 0xa3, 0x73, 0x70, 0x74) if (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking == nil { @@ -4741,42 +4759,42 @@ func (z *proposal) MarshalMsg(b []byte) (o []byte) { o = zb0002.MarshalMsg(o) } } - if (zb0004Mask & 0x10000000) == 0 { // if not empty + if (zb0004Mask & 0x40000000) == 0 { // if not empty // string "tc" o = append(o, 0xa2, 0x74, 0x63) o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter) } - if (zb0004Mask & 0x20000000) == 0 { // if not empty + if (zb0004Mask & 0x80000000) == 0 { // if not empty // string "ts" o = append(o, 0xa2, 0x74, 0x73) o = msgp.AppendInt64(o, (*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp) } - if (zb0004Mask & 0x40000000) == 0 { // if not empty + if (zb0004Mask & 0x100000000) == 0 { // if not empty // string "txn" o = append(o, 0xa3, 0x74, 0x78, 0x6e) o = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MarshalMsg(o) } - if (zb0004Mask & 0x80000000) == 0 { // if not empty + if (zb0004Mask & 0x200000000) == 0 { // if not empty // string "txn256" o = append(o, 0xa6, 0x74, 0x78, 0x6e, 0x32, 0x35, 0x36) o = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MarshalMsg(o) } - if (zb0004Mask & 0x100000000) == 0 { // if not empty + if (zb0004Mask & 0x400000000) == 0 { // if not empty // string "txns" o = append(o, 0xa4, 0x74, 0x78, 0x6e, 0x73) o = (*z).unauthenticatedProposal.Block.Payset.MarshalMsg(o) } - if (zb0004Mask & 0x200000000) == 0 { // if not empty + if (zb0004Mask & 0x800000000) == 0 { // if not empty // string "upgradedelay" o = append(o, 0xac, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x65, 0x6c, 0x61, 0x79) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MarshalMsg(o) } - if (zb0004Mask & 0x400000000) == 0 { // if not empty + if (zb0004Mask & 0x1000000000) == 0 { // if not empty // string "upgradeprop" o = append(o, 0xab, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x70, 0x72, 0x6f, 0x70) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MarshalMsg(o) } - if (zb0004Mask & 0x800000000) == 0 { // if not empty + if (zb0004Mask & 0x2000000000) == 0 { // if not empty // string "upgradeyes" o = append(o, 0xaa, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x65, 0x73) o = msgp.AppendBool(o, (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove) @@ -4882,6 +4900,22 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o return } } + if zb0004 > 0 { + zb0004-- + bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "Proposer") + return + } + } + if zb0004 > 0 { + zb0004-- + bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "FeesCollected") + return + } + } if zb0004 > 0 { zb0004-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st) @@ -5184,6 +5218,18 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o err = msgp.WrapError(err, "GenesisHash") return } + case "prp": + bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "Proposer") + return + } + case "fc": + bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "FeesCollected") + return + } case "fees": bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st) if err != nil { @@ -5386,7 +5432,7 @@ func (_ *proposal) CanUnmarshalMsg(z interface{}) bool { // Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message func (z *proposal) Msgsize() (s int) { - s = 3 + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.Round.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.Branch.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.Seed.Msgsize() + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.Msgsize() + 7 + (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.Msgsize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + len((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID) + 3 + (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.Msgsize() + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.Msgsize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.Msgsize() + 6 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.Msgsize() + 10 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.Msgsize() + 8 + msgp.Uint64Size + 11 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.Msgsize() + 11 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.Msgsize() + 12 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.Msgsize() + 13 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.Msgsize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + msgp.MapHeaderSize + s = 3 + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.Round.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.Branch.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.Seed.Msgsize() + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.Msgsize() + 7 + (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.Msgsize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + len((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID) + 3 + (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.Msgsize() + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.Msgsize() + 3 + (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.Msgsize() + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.Msgsize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.Msgsize() + 6 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.Msgsize() + 10 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.Msgsize() + 8 + msgp.Uint64Size + 11 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.Msgsize() + 11 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.Msgsize() + 12 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.Msgsize() + 13 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.Msgsize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + msgp.MapHeaderSize if (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking != nil { for zb0001, zb0002 := range (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking { _ = zb0001 @@ -5404,12 +5450,12 @@ func (z *proposal) Msgsize() (s int) { // MsgIsZero returns whether this is a zero value func (z *proposal) MsgIsZero() bool { - return ((*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "") && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).unauthenticatedProposal.Block.Payset.MsgIsZero()) && ((*z).unauthenticatedProposal.SeedProof.MsgIsZero()) && ((*z).unauthenticatedProposal.OriginalPeriod == 0) && ((*z).unauthenticatedProposal.OriginalProposer.MsgIsZero()) + return ((*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "") && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).unauthenticatedProposal.Block.Payset.MsgIsZero()) && ((*z).unauthenticatedProposal.SeedProof.MsgIsZero()) && ((*z).unauthenticatedProposal.OriginalPeriod == 0) && ((*z).unauthenticatedProposal.OriginalProposer.MsgIsZero()) } // MaxSize returns a maximum valid message size for this message type func ProposalMaxSize() (s int) { - s = 3 + 4 + basics.RoundMaxSize() + 5 + bookkeeping.BlockHashMaxSize() + 5 + committee.SeedMaxSize() + 4 + crypto.DigestMaxSize() + 7 + crypto.DigestMaxSize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + config.MaxGenesisIDLen + 3 + crypto.DigestMaxSize() + 5 + basics.AddressMaxSize() + 4 + basics.AddressMaxSize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + basics.RoundMaxSize() + 6 + protocol.ConsensusVersionMaxSize() + 10 + protocol.ConsensusVersionMaxSize() + 8 + msgp.Uint64Size + 11 + basics.RoundMaxSize() + 11 + basics.RoundMaxSize() + 12 + protocol.ConsensusVersionMaxSize() + 13 + basics.RoundMaxSize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + s = 3 + 4 + basics.RoundMaxSize() + 5 + bookkeeping.BlockHashMaxSize() + 5 + committee.SeedMaxSize() + 4 + crypto.DigestMaxSize() + 7 + crypto.DigestMaxSize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + config.MaxGenesisIDLen + 3 + crypto.DigestMaxSize() + 4 + basics.AddressMaxSize() + 3 + basics.MicroAlgosMaxSize() + 5 + basics.AddressMaxSize() + 4 + basics.AddressMaxSize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + basics.RoundMaxSize() + 6 + protocol.ConsensusVersionMaxSize() + 10 + protocol.ConsensusVersionMaxSize() + 8 + msgp.Uint64Size + 11 + basics.RoundMaxSize() + 11 + basics.RoundMaxSize() + 12 + protocol.ConsensusVersionMaxSize() + 13 + basics.RoundMaxSize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 s += msgp.MapHeaderSize // Adding size of map keys for z.unauthenticatedProposal.Block.BlockHeader.StateProofTracking s += protocol.NumStateProofTypes * (protocol.StateProofTypeMaxSize()) @@ -8856,127 +8902,135 @@ func ThresholdEventMaxSize() (s int) { func (z *transmittedPayload) MarshalMsg(b []byte) (o []byte) { o = msgp.Require(b, z.Msgsize()) // omitempty: check for empty values - zb0004Len := uint32(30) - var zb0004Mask uint64 /* 38 bits */ + zb0004Len := uint32(32) + var zb0004Mask uint64 /* 40 bits */ if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0 { zb0004Len-- zb0004Mask |= 0x80 } - if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero() { + if (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x100 } - if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0 { + if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x200 } - if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "" { + if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0 { zb0004Len-- zb0004Mask |= 0x400 } - if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero() { + if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "" { zb0004Len-- zb0004Mask |= 0x800 } - if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() { + if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x1000 } - if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero() { + if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x2000 } - if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() { + if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x4000 } - if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0 { + if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x8000 } - if (*z).unauthenticatedProposal.OriginalPeriod == 0 { + if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0 { zb0004Len-- zb0004Mask |= 0x10000 } - if (*z).unauthenticatedProposal.OriginalProposer.MsgIsZero() { + if (*z).unauthenticatedProposal.OriginalPeriod == 0 { zb0004Len-- zb0004Mask |= 0x20000 } - if len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 { + if (*z).unauthenticatedProposal.OriginalProposer.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x40000 } - if (*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero() { + if len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 { zb0004Len-- zb0004Mask |= 0x80000 } - if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() { + if (*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x100000 } - if (*z).PriorVote.MsgIsZero() { + if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x200000 } - if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0 { + if (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x400000 } - if (*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero() { + if (*z).PriorVote.MsgIsZero() { + zb0004Len-- + zb0004Mask |= 0x800000 + } + if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0 { zb0004Len-- zb0004Mask |= 0x1000000 } + if (*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero() { + zb0004Len-- + zb0004Mask |= 0x4000000 + } if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x2000000 + zb0004Mask |= 0x8000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x4000000 + zb0004Mask |= 0x10000000 } if (*z).unauthenticatedProposal.SeedProof.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x8000000 + zb0004Mask |= 0x20000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x10000000 + zb0004Mask |= 0x40000000 } if len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0 { zb0004Len-- - zb0004Mask |= 0x20000000 + zb0004Mask |= 0x80000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0 { zb0004Len-- - zb0004Mask |= 0x40000000 + zb0004Mask |= 0x100000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0 { zb0004Len-- - zb0004Mask |= 0x80000000 + zb0004Mask |= 0x200000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x100000000 + zb0004Mask |= 0x400000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x200000000 + zb0004Mask |= 0x800000000 } if (*z).unauthenticatedProposal.Block.Payset.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x400000000 + zb0004Mask |= 0x1000000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x800000000 + zb0004Mask |= 0x2000000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x1000000000 + zb0004Mask |= 0x4000000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false { zb0004Len-- - zb0004Mask |= 0x2000000000 + zb0004Mask |= 0x8000000000 } // variable map header, size zb0004Len o = msgp.AppendMapHeader(o, zb0004Len) @@ -8987,56 +9041,61 @@ func (z *transmittedPayload) MarshalMsg(b []byte) (o []byte) { o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel) } if (zb0004Mask & 0x100) == 0 { // if not empty + // string "fc" + o = append(o, 0xa2, 0x66, 0x63) + o = (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MarshalMsg(o) + } + if (zb0004Mask & 0x200) == 0 { // if not empty // string "fees" o = append(o, 0xa4, 0x66, 0x65, 0x65, 0x73) o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MarshalMsg(o) } - if (zb0004Mask & 0x200) == 0 { // if not empty + if (zb0004Mask & 0x400) == 0 { // if not empty // string "frac" o = append(o, 0xa4, 0x66, 0x72, 0x61, 0x63) o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue) } - if (zb0004Mask & 0x400) == 0 { // if not empty + if (zb0004Mask & 0x800) == 0 { // if not empty // string "gen" o = append(o, 0xa3, 0x67, 0x65, 0x6e) o = msgp.AppendString(o, (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID) } - if (zb0004Mask & 0x800) == 0 { // if not empty + if (zb0004Mask & 0x1000) == 0 { // if not empty // string "gh" o = append(o, 0xa2, 0x67, 0x68) o = (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MarshalMsg(o) } - if (zb0004Mask & 0x1000) == 0 { // if not empty + if (zb0004Mask & 0x2000) == 0 { // if not empty // string "nextbefore" o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MarshalMsg(o) } - if (zb0004Mask & 0x2000) == 0 { // if not empty + if (zb0004Mask & 0x4000) == 0 { // if not empty // string "nextproto" o = append(o, 0xa9, 0x6e, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MarshalMsg(o) } - if (zb0004Mask & 0x4000) == 0 { // if not empty + if (zb0004Mask & 0x8000) == 0 { // if not empty // string "nextswitch" o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MarshalMsg(o) } - if (zb0004Mask & 0x8000) == 0 { // if not empty + if (zb0004Mask & 0x10000) == 0 { // if not empty // string "nextyes" o = append(o, 0xa7, 0x6e, 0x65, 0x78, 0x74, 0x79, 0x65, 0x73) o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals) } - if (zb0004Mask & 0x10000) == 0 { // if not empty + if (zb0004Mask & 0x20000) == 0 { // if not empty // string "oper" o = append(o, 0xa4, 0x6f, 0x70, 0x65, 0x72) o = msgp.AppendUint64(o, uint64((*z).unauthenticatedProposal.OriginalPeriod)) } - if (zb0004Mask & 0x20000) == 0 { // if not empty + if (zb0004Mask & 0x40000) == 0 { // if not empty // string "oprop" o = append(o, 0xa5, 0x6f, 0x70, 0x72, 0x6f, 0x70) o = (*z).unauthenticatedProposal.OriginalProposer.MarshalMsg(o) } - if (zb0004Mask & 0x40000) == 0 { // if not empty + if (zb0004Mask & 0x80000) == 0 { // if not empty // string "partupdrmv" o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76) if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts == nil { @@ -9048,52 +9107,57 @@ func (z *transmittedPayload) MarshalMsg(b []byte) (o []byte) { o = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].MarshalMsg(o) } } - if (zb0004Mask & 0x80000) == 0 { // if not empty + if (zb0004Mask & 0x100000) == 0 { // if not empty // string "prev" o = append(o, 0xa4, 0x70, 0x72, 0x65, 0x76) o = (*z).unauthenticatedProposal.Block.BlockHeader.Branch.MarshalMsg(o) } - if (zb0004Mask & 0x100000) == 0 { // if not empty + if (zb0004Mask & 0x200000) == 0 { // if not empty // string "proto" o = append(o, 0xa5, 0x70, 0x72, 0x6f, 0x74, 0x6f) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MarshalMsg(o) } - if (zb0004Mask & 0x200000) == 0 { // if not empty + if (zb0004Mask & 0x400000) == 0 { // if not empty + // string "prp" + o = append(o, 0xa3, 0x70, 0x72, 0x70) + o = (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MarshalMsg(o) + } + if (zb0004Mask & 0x800000) == 0 { // if not empty // string "pv" o = append(o, 0xa2, 0x70, 0x76) o = (*z).PriorVote.MarshalMsg(o) } - if (zb0004Mask & 0x400000) == 0 { // if not empty + if (zb0004Mask & 0x1000000) == 0 { // if not empty // string "rate" o = append(o, 0xa4, 0x72, 0x61, 0x74, 0x65) o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate) } - if (zb0004Mask & 0x1000000) == 0 { // if not empty + if (zb0004Mask & 0x4000000) == 0 { // if not empty // string "rnd" o = append(o, 0xa3, 0x72, 0x6e, 0x64) o = (*z).unauthenticatedProposal.Block.BlockHeader.Round.MarshalMsg(o) } - if (zb0004Mask & 0x2000000) == 0 { // if not empty + if (zb0004Mask & 0x8000000) == 0 { // if not empty // string "rwcalr" o = append(o, 0xa6, 0x72, 0x77, 0x63, 0x61, 0x6c, 0x72) o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MarshalMsg(o) } - if (zb0004Mask & 0x4000000) == 0 { // if not empty + if (zb0004Mask & 0x10000000) == 0 { // if not empty // string "rwd" o = append(o, 0xa3, 0x72, 0x77, 0x64) o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MarshalMsg(o) } - if (zb0004Mask & 0x8000000) == 0 { // if not empty + if (zb0004Mask & 0x20000000) == 0 { // if not empty // string "sdpf" o = append(o, 0xa4, 0x73, 0x64, 0x70, 0x66) o = (*z).unauthenticatedProposal.SeedProof.MarshalMsg(o) } - if (zb0004Mask & 0x10000000) == 0 { // if not empty + if (zb0004Mask & 0x40000000) == 0 { // if not empty // string "seed" o = append(o, 0xa4, 0x73, 0x65, 0x65, 0x64) o = (*z).unauthenticatedProposal.Block.BlockHeader.Seed.MarshalMsg(o) } - if (zb0004Mask & 0x20000000) == 0 { // if not empty + if (zb0004Mask & 0x80000000) == 0 { // if not empty // string "spt" o = append(o, 0xa3, 0x73, 0x70, 0x74) if (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking == nil { @@ -9113,42 +9177,42 @@ func (z *transmittedPayload) MarshalMsg(b []byte) (o []byte) { o = zb0002.MarshalMsg(o) } } - if (zb0004Mask & 0x40000000) == 0 { // if not empty + if (zb0004Mask & 0x100000000) == 0 { // if not empty // string "tc" o = append(o, 0xa2, 0x74, 0x63) o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter) } - if (zb0004Mask & 0x80000000) == 0 { // if not empty + if (zb0004Mask & 0x200000000) == 0 { // if not empty // string "ts" o = append(o, 0xa2, 0x74, 0x73) o = msgp.AppendInt64(o, (*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp) } - if (zb0004Mask & 0x100000000) == 0 { // if not empty + if (zb0004Mask & 0x400000000) == 0 { // if not empty // string "txn" o = append(o, 0xa3, 0x74, 0x78, 0x6e) o = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MarshalMsg(o) } - if (zb0004Mask & 0x200000000) == 0 { // if not empty + if (zb0004Mask & 0x800000000) == 0 { // if not empty // string "txn256" o = append(o, 0xa6, 0x74, 0x78, 0x6e, 0x32, 0x35, 0x36) o = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MarshalMsg(o) } - if (zb0004Mask & 0x400000000) == 0 { // if not empty + if (zb0004Mask & 0x1000000000) == 0 { // if not empty // string "txns" o = append(o, 0xa4, 0x74, 0x78, 0x6e, 0x73) o = (*z).unauthenticatedProposal.Block.Payset.MarshalMsg(o) } - if (zb0004Mask & 0x800000000) == 0 { // if not empty + if (zb0004Mask & 0x2000000000) == 0 { // if not empty // string "upgradedelay" o = append(o, 0xac, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x65, 0x6c, 0x61, 0x79) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MarshalMsg(o) } - if (zb0004Mask & 0x1000000000) == 0 { // if not empty + if (zb0004Mask & 0x4000000000) == 0 { // if not empty // string "upgradeprop" o = append(o, 0xab, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x70, 0x72, 0x6f, 0x70) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MarshalMsg(o) } - if (zb0004Mask & 0x2000000000) == 0 { // if not empty + if (zb0004Mask & 0x8000000000) == 0 { // if not empty // string "upgradeyes" o = append(o, 0xaa, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x65, 0x73) o = msgp.AppendBool(o, (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove) @@ -9254,6 +9318,22 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal return } } + if zb0004 > 0 { + zb0004-- + bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "Proposer") + return + } + } + if zb0004 > 0 { + zb0004-- + bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "FeesCollected") + return + } + } if zb0004 > 0 { zb0004-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st) @@ -9564,6 +9644,18 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal err = msgp.WrapError(err, "GenesisHash") return } + case "prp": + bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "Proposer") + return + } + case "fc": + bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "FeesCollected") + return + } case "fees": bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st) if err != nil { @@ -9772,7 +9864,7 @@ func (_ *transmittedPayload) CanUnmarshalMsg(z interface{}) bool { // Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message func (z *transmittedPayload) Msgsize() (s int) { - s = 3 + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.Round.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.Branch.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.Seed.Msgsize() + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.Msgsize() + 7 + (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.Msgsize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + len((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID) + 3 + (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.Msgsize() + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.Msgsize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.Msgsize() + 6 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.Msgsize() + 10 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.Msgsize() + 8 + msgp.Uint64Size + 11 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.Msgsize() + 11 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.Msgsize() + 12 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.Msgsize() + 13 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.Msgsize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + msgp.MapHeaderSize + s = 3 + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.Round.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.Branch.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.Seed.Msgsize() + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.Msgsize() + 7 + (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.Msgsize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + len((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID) + 3 + (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.Msgsize() + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.Msgsize() + 3 + (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.Msgsize() + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.Msgsize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.Msgsize() + 6 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.Msgsize() + 10 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.Msgsize() + 8 + msgp.Uint64Size + 11 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.Msgsize() + 11 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.Msgsize() + 12 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.Msgsize() + 13 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.Msgsize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + msgp.MapHeaderSize if (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking != nil { for zb0001, zb0002 := range (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking { _ = zb0001 @@ -9790,12 +9882,12 @@ func (z *transmittedPayload) Msgsize() (s int) { // MsgIsZero returns whether this is a zero value func (z *transmittedPayload) MsgIsZero() bool { - return ((*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "") && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).unauthenticatedProposal.Block.Payset.MsgIsZero()) && ((*z).unauthenticatedProposal.SeedProof.MsgIsZero()) && ((*z).unauthenticatedProposal.OriginalPeriod == 0) && ((*z).unauthenticatedProposal.OriginalProposer.MsgIsZero()) && ((*z).PriorVote.MsgIsZero()) + return ((*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "") && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).unauthenticatedProposal.Block.Payset.MsgIsZero()) && ((*z).unauthenticatedProposal.SeedProof.MsgIsZero()) && ((*z).unauthenticatedProposal.OriginalPeriod == 0) && ((*z).unauthenticatedProposal.OriginalProposer.MsgIsZero()) && ((*z).PriorVote.MsgIsZero()) } // MaxSize returns a maximum valid message size for this message type func TransmittedPayloadMaxSize() (s int) { - s = 3 + 4 + basics.RoundMaxSize() + 5 + bookkeeping.BlockHashMaxSize() + 5 + committee.SeedMaxSize() + 4 + crypto.DigestMaxSize() + 7 + crypto.DigestMaxSize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + config.MaxGenesisIDLen + 3 + crypto.DigestMaxSize() + 5 + basics.AddressMaxSize() + 4 + basics.AddressMaxSize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + basics.RoundMaxSize() + 6 + protocol.ConsensusVersionMaxSize() + 10 + protocol.ConsensusVersionMaxSize() + 8 + msgp.Uint64Size + 11 + basics.RoundMaxSize() + 11 + basics.RoundMaxSize() + 12 + protocol.ConsensusVersionMaxSize() + 13 + basics.RoundMaxSize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + s = 3 + 4 + basics.RoundMaxSize() + 5 + bookkeeping.BlockHashMaxSize() + 5 + committee.SeedMaxSize() + 4 + crypto.DigestMaxSize() + 7 + crypto.DigestMaxSize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + config.MaxGenesisIDLen + 3 + crypto.DigestMaxSize() + 4 + basics.AddressMaxSize() + 3 + basics.MicroAlgosMaxSize() + 5 + basics.AddressMaxSize() + 4 + basics.AddressMaxSize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + basics.RoundMaxSize() + 6 + protocol.ConsensusVersionMaxSize() + 10 + protocol.ConsensusVersionMaxSize() + 8 + msgp.Uint64Size + 11 + basics.RoundMaxSize() + 11 + basics.RoundMaxSize() + 12 + protocol.ConsensusVersionMaxSize() + 13 + basics.RoundMaxSize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 s += msgp.MapHeaderSize // Adding size of map keys for z.unauthenticatedProposal.Block.BlockHeader.StateProofTracking s += protocol.NumStateProofTypes * (protocol.StateProofTypeMaxSize()) @@ -10516,123 +10608,131 @@ func UnauthenticatedEquivocationVoteMaxSize() (s int) { func (z *unauthenticatedProposal) MarshalMsg(b []byte) (o []byte) { o = msgp.Require(b, z.Msgsize()) // omitempty: check for empty values - zb0004Len := uint32(29) - var zb0004Mask uint64 /* 36 bits */ + zb0004Len := uint32(31) + var zb0004Mask uint64 /* 38 bits */ if (*z).Block.BlockHeader.RewardsState.RewardsLevel == 0 { zb0004Len-- zb0004Mask |= 0x40 } - if (*z).Block.BlockHeader.RewardsState.FeeSink.MsgIsZero() { + if (*z).Block.BlockHeader.FeesCollected.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x80 } - if (*z).Block.BlockHeader.RewardsState.RewardsResidue == 0 { + if (*z).Block.BlockHeader.RewardsState.FeeSink.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x100 } - if (*z).Block.BlockHeader.GenesisID == "" { + if (*z).Block.BlockHeader.RewardsState.RewardsResidue == 0 { zb0004Len-- zb0004Mask |= 0x200 } - if (*z).Block.BlockHeader.GenesisHash.MsgIsZero() { + if (*z).Block.BlockHeader.GenesisID == "" { zb0004Len-- zb0004Mask |= 0x400 } - if (*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() { + if (*z).Block.BlockHeader.GenesisHash.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x800 } - if (*z).Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero() { + if (*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x1000 } - if (*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() { + if (*z).Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x2000 } - if (*z).Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0 { + if (*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x4000 } - if (*z).OriginalPeriod == 0 { + if (*z).Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0 { zb0004Len-- zb0004Mask |= 0x8000 } - if (*z).OriginalProposer.MsgIsZero() { + if (*z).OriginalPeriod == 0 { zb0004Len-- zb0004Mask |= 0x10000 } - if len((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 { + if (*z).OriginalProposer.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x20000 } - if (*z).Block.BlockHeader.Branch.MsgIsZero() { + if len((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 { zb0004Len-- zb0004Mask |= 0x40000 } - if (*z).Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() { + if (*z).Block.BlockHeader.Branch.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x80000 } - if (*z).Block.BlockHeader.RewardsState.RewardsRate == 0 { + if (*z).Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x100000 } - if (*z).Block.BlockHeader.Round.MsgIsZero() { + if (*z).Block.BlockHeader.Proposer.MsgIsZero() { + zb0004Len-- + zb0004Mask |= 0x200000 + } + if (*z).Block.BlockHeader.RewardsState.RewardsRate == 0 { zb0004Len-- zb0004Mask |= 0x400000 } + if (*z).Block.BlockHeader.Round.MsgIsZero() { + zb0004Len-- + zb0004Mask |= 0x1000000 + } if (*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x800000 + zb0004Mask |= 0x2000000 } if (*z).Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x1000000 + zb0004Mask |= 0x4000000 } if (*z).SeedProof.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x2000000 + zb0004Mask |= 0x8000000 } if (*z).Block.BlockHeader.Seed.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x4000000 + zb0004Mask |= 0x10000000 } if len((*z).Block.BlockHeader.StateProofTracking) == 0 { zb0004Len-- - zb0004Mask |= 0x8000000 + zb0004Mask |= 0x20000000 } if (*z).Block.BlockHeader.TxnCounter == 0 { zb0004Len-- - zb0004Mask |= 0x10000000 + zb0004Mask |= 0x40000000 } if (*z).Block.BlockHeader.TimeStamp == 0 { zb0004Len-- - zb0004Mask |= 0x20000000 + zb0004Mask |= 0x80000000 } if (*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x40000000 + zb0004Mask |= 0x100000000 } if (*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x80000000 + zb0004Mask |= 0x200000000 } if (*z).Block.Payset.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x100000000 + zb0004Mask |= 0x400000000 } if (*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x200000000 + zb0004Mask |= 0x800000000 } if (*z).Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero() { zb0004Len-- - zb0004Mask |= 0x400000000 + zb0004Mask |= 0x1000000000 } if (*z).Block.BlockHeader.UpgradeVote.UpgradeApprove == false { zb0004Len-- - zb0004Mask |= 0x800000000 + zb0004Mask |= 0x2000000000 } // variable map header, size zb0004Len o = msgp.AppendMapHeader(o, zb0004Len) @@ -10643,56 +10743,61 @@ func (z *unauthenticatedProposal) MarshalMsg(b []byte) (o []byte) { o = msgp.AppendUint64(o, (*z).Block.BlockHeader.RewardsState.RewardsLevel) } if (zb0004Mask & 0x80) == 0 { // if not empty + // string "fc" + o = append(o, 0xa2, 0x66, 0x63) + o = (*z).Block.BlockHeader.FeesCollected.MarshalMsg(o) + } + if (zb0004Mask & 0x100) == 0 { // if not empty // string "fees" o = append(o, 0xa4, 0x66, 0x65, 0x65, 0x73) o = (*z).Block.BlockHeader.RewardsState.FeeSink.MarshalMsg(o) } - if (zb0004Mask & 0x100) == 0 { // if not empty + if (zb0004Mask & 0x200) == 0 { // if not empty // string "frac" o = append(o, 0xa4, 0x66, 0x72, 0x61, 0x63) o = msgp.AppendUint64(o, (*z).Block.BlockHeader.RewardsState.RewardsResidue) } - if (zb0004Mask & 0x200) == 0 { // if not empty + if (zb0004Mask & 0x400) == 0 { // if not empty // string "gen" o = append(o, 0xa3, 0x67, 0x65, 0x6e) o = msgp.AppendString(o, (*z).Block.BlockHeader.GenesisID) } - if (zb0004Mask & 0x400) == 0 { // if not empty + if (zb0004Mask & 0x800) == 0 { // if not empty // string "gh" o = append(o, 0xa2, 0x67, 0x68) o = (*z).Block.BlockHeader.GenesisHash.MarshalMsg(o) } - if (zb0004Mask & 0x800) == 0 { // if not empty + if (zb0004Mask & 0x1000) == 0 { // if not empty // string "nextbefore" o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65) o = (*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MarshalMsg(o) } - if (zb0004Mask & 0x1000) == 0 { // if not empty + if (zb0004Mask & 0x2000) == 0 { // if not empty // string "nextproto" o = append(o, 0xa9, 0x6e, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f) o = (*z).Block.BlockHeader.UpgradeState.NextProtocol.MarshalMsg(o) } - if (zb0004Mask & 0x2000) == 0 { // if not empty + if (zb0004Mask & 0x4000) == 0 { // if not empty // string "nextswitch" o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68) o = (*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MarshalMsg(o) } - if (zb0004Mask & 0x4000) == 0 { // if not empty + if (zb0004Mask & 0x8000) == 0 { // if not empty // string "nextyes" o = append(o, 0xa7, 0x6e, 0x65, 0x78, 0x74, 0x79, 0x65, 0x73) o = msgp.AppendUint64(o, (*z).Block.BlockHeader.UpgradeState.NextProtocolApprovals) } - if (zb0004Mask & 0x8000) == 0 { // if not empty + if (zb0004Mask & 0x10000) == 0 { // if not empty // string "oper" o = append(o, 0xa4, 0x6f, 0x70, 0x65, 0x72) o = msgp.AppendUint64(o, uint64((*z).OriginalPeriod)) } - if (zb0004Mask & 0x10000) == 0 { // if not empty + if (zb0004Mask & 0x20000) == 0 { // if not empty // string "oprop" o = append(o, 0xa5, 0x6f, 0x70, 0x72, 0x6f, 0x70) o = (*z).OriginalProposer.MarshalMsg(o) } - if (zb0004Mask & 0x20000) == 0 { // if not empty + if (zb0004Mask & 0x40000) == 0 { // if not empty // string "partupdrmv" o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76) if (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts == nil { @@ -10704,47 +10809,52 @@ func (z *unauthenticatedProposal) MarshalMsg(b []byte) (o []byte) { o = (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].MarshalMsg(o) } } - if (zb0004Mask & 0x40000) == 0 { // if not empty + if (zb0004Mask & 0x80000) == 0 { // if not empty // string "prev" o = append(o, 0xa4, 0x70, 0x72, 0x65, 0x76) o = (*z).Block.BlockHeader.Branch.MarshalMsg(o) } - if (zb0004Mask & 0x80000) == 0 { // if not empty + if (zb0004Mask & 0x100000) == 0 { // if not empty // string "proto" o = append(o, 0xa5, 0x70, 0x72, 0x6f, 0x74, 0x6f) o = (*z).Block.BlockHeader.UpgradeState.CurrentProtocol.MarshalMsg(o) } - if (zb0004Mask & 0x100000) == 0 { // if not empty + if (zb0004Mask & 0x200000) == 0 { // if not empty + // string "prp" + o = append(o, 0xa3, 0x70, 0x72, 0x70) + o = (*z).Block.BlockHeader.Proposer.MarshalMsg(o) + } + if (zb0004Mask & 0x400000) == 0 { // if not empty // string "rate" o = append(o, 0xa4, 0x72, 0x61, 0x74, 0x65) o = msgp.AppendUint64(o, (*z).Block.BlockHeader.RewardsState.RewardsRate) } - if (zb0004Mask & 0x400000) == 0 { // if not empty + if (zb0004Mask & 0x1000000) == 0 { // if not empty // string "rnd" o = append(o, 0xa3, 0x72, 0x6e, 0x64) o = (*z).Block.BlockHeader.Round.MarshalMsg(o) } - if (zb0004Mask & 0x800000) == 0 { // if not empty + if (zb0004Mask & 0x2000000) == 0 { // if not empty // string "rwcalr" o = append(o, 0xa6, 0x72, 0x77, 0x63, 0x61, 0x6c, 0x72) o = (*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.MarshalMsg(o) } - if (zb0004Mask & 0x1000000) == 0 { // if not empty + if (zb0004Mask & 0x4000000) == 0 { // if not empty // string "rwd" o = append(o, 0xa3, 0x72, 0x77, 0x64) o = (*z).Block.BlockHeader.RewardsState.RewardsPool.MarshalMsg(o) } - if (zb0004Mask & 0x2000000) == 0 { // if not empty + if (zb0004Mask & 0x8000000) == 0 { // if not empty // string "sdpf" o = append(o, 0xa4, 0x73, 0x64, 0x70, 0x66) o = (*z).SeedProof.MarshalMsg(o) } - if (zb0004Mask & 0x4000000) == 0 { // if not empty + if (zb0004Mask & 0x10000000) == 0 { // if not empty // string "seed" o = append(o, 0xa4, 0x73, 0x65, 0x65, 0x64) o = (*z).Block.BlockHeader.Seed.MarshalMsg(o) } - if (zb0004Mask & 0x8000000) == 0 { // if not empty + if (zb0004Mask & 0x20000000) == 0 { // if not empty // string "spt" o = append(o, 0xa3, 0x73, 0x70, 0x74) if (*z).Block.BlockHeader.StateProofTracking == nil { @@ -10764,42 +10874,42 @@ func (z *unauthenticatedProposal) MarshalMsg(b []byte) (o []byte) { o = zb0002.MarshalMsg(o) } } - if (zb0004Mask & 0x10000000) == 0 { // if not empty + if (zb0004Mask & 0x40000000) == 0 { // if not empty // string "tc" o = append(o, 0xa2, 0x74, 0x63) o = msgp.AppendUint64(o, (*z).Block.BlockHeader.TxnCounter) } - if (zb0004Mask & 0x20000000) == 0 { // if not empty + if (zb0004Mask & 0x80000000) == 0 { // if not empty // string "ts" o = append(o, 0xa2, 0x74, 0x73) o = msgp.AppendInt64(o, (*z).Block.BlockHeader.TimeStamp) } - if (zb0004Mask & 0x40000000) == 0 { // if not empty + if (zb0004Mask & 0x100000000) == 0 { // if not empty // string "txn" o = append(o, 0xa3, 0x74, 0x78, 0x6e) o = (*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MarshalMsg(o) } - if (zb0004Mask & 0x80000000) == 0 { // if not empty + if (zb0004Mask & 0x200000000) == 0 { // if not empty // string "txn256" o = append(o, 0xa6, 0x74, 0x78, 0x6e, 0x32, 0x35, 0x36) o = (*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.MarshalMsg(o) } - if (zb0004Mask & 0x100000000) == 0 { // if not empty + if (zb0004Mask & 0x400000000) == 0 { // if not empty // string "txns" o = append(o, 0xa4, 0x74, 0x78, 0x6e, 0x73) o = (*z).Block.Payset.MarshalMsg(o) } - if (zb0004Mask & 0x200000000) == 0 { // if not empty + if (zb0004Mask & 0x800000000) == 0 { // if not empty // string "upgradedelay" o = append(o, 0xac, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x65, 0x6c, 0x61, 0x79) o = (*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.MarshalMsg(o) } - if (zb0004Mask & 0x400000000) == 0 { // if not empty + if (zb0004Mask & 0x1000000000) == 0 { // if not empty // string "upgradeprop" o = append(o, 0xab, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x70, 0x72, 0x6f, 0x70) o = (*z).Block.BlockHeader.UpgradeVote.UpgradePropose.MarshalMsg(o) } - if (zb0004Mask & 0x800000000) == 0 { // if not empty + if (zb0004Mask & 0x2000000000) == 0 { // if not empty // string "upgradeyes" o = append(o, 0xaa, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x65, 0x73) o = msgp.AppendBool(o, (*z).Block.BlockHeader.UpgradeVote.UpgradeApprove) @@ -10905,6 +11015,22 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma return } } + if zb0004 > 0 { + zb0004-- + bts, err = (*z).Block.BlockHeader.Proposer.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "Proposer") + return + } + } + if zb0004 > 0 { + zb0004-- + bts, err = (*z).Block.BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "FeesCollected") + return + } + } if zb0004 > 0 { zb0004-- bts, err = (*z).Block.BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st) @@ -11207,6 +11333,18 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma err = msgp.WrapError(err, "GenesisHash") return } + case "prp": + bts, err = (*z).Block.BlockHeader.Proposer.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "Proposer") + return + } + case "fc": + bts, err = (*z).Block.BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "FeesCollected") + return + } case "fees": bts, err = (*z).Block.BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st) if err != nil { @@ -11409,7 +11547,7 @@ func (_ *unauthenticatedProposal) CanUnmarshalMsg(z interface{}) bool { // Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message func (z *unauthenticatedProposal) Msgsize() (s int) { - s = 3 + 4 + (*z).Block.BlockHeader.Round.Msgsize() + 5 + (*z).Block.BlockHeader.Branch.Msgsize() + 5 + (*z).Block.BlockHeader.Seed.Msgsize() + 4 + (*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.Msgsize() + 7 + (*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.Msgsize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + len((*z).Block.BlockHeader.GenesisID) + 3 + (*z).Block.BlockHeader.GenesisHash.Msgsize() + 5 + (*z).Block.BlockHeader.RewardsState.FeeSink.Msgsize() + 4 + (*z).Block.BlockHeader.RewardsState.RewardsPool.Msgsize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + (*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.Msgsize() + 6 + (*z).Block.BlockHeader.UpgradeState.CurrentProtocol.Msgsize() + 10 + (*z).Block.BlockHeader.UpgradeState.NextProtocol.Msgsize() + 8 + msgp.Uint64Size + 11 + (*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.Msgsize() + 11 + (*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.Msgsize() + 12 + (*z).Block.BlockHeader.UpgradeVote.UpgradePropose.Msgsize() + 13 + (*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.Msgsize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + msgp.MapHeaderSize + s = 3 + 4 + (*z).Block.BlockHeader.Round.Msgsize() + 5 + (*z).Block.BlockHeader.Branch.Msgsize() + 5 + (*z).Block.BlockHeader.Seed.Msgsize() + 4 + (*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.Msgsize() + 7 + (*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.Msgsize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + len((*z).Block.BlockHeader.GenesisID) + 3 + (*z).Block.BlockHeader.GenesisHash.Msgsize() + 4 + (*z).Block.BlockHeader.Proposer.Msgsize() + 3 + (*z).Block.BlockHeader.FeesCollected.Msgsize() + 5 + (*z).Block.BlockHeader.RewardsState.FeeSink.Msgsize() + 4 + (*z).Block.BlockHeader.RewardsState.RewardsPool.Msgsize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + (*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.Msgsize() + 6 + (*z).Block.BlockHeader.UpgradeState.CurrentProtocol.Msgsize() + 10 + (*z).Block.BlockHeader.UpgradeState.NextProtocol.Msgsize() + 8 + msgp.Uint64Size + 11 + (*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.Msgsize() + 11 + (*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.Msgsize() + 12 + (*z).Block.BlockHeader.UpgradeVote.UpgradePropose.Msgsize() + 13 + (*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.Msgsize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + msgp.MapHeaderSize if (*z).Block.BlockHeader.StateProofTracking != nil { for zb0001, zb0002 := range (*z).Block.BlockHeader.StateProofTracking { _ = zb0001 @@ -11427,12 +11565,12 @@ func (z *unauthenticatedProposal) Msgsize() (s int) { // MsgIsZero returns whether this is a zero value func (z *unauthenticatedProposal) MsgIsZero() bool { - return ((*z).Block.BlockHeader.Round.MsgIsZero()) && ((*z).Block.BlockHeader.Branch.MsgIsZero()) && ((*z).Block.BlockHeader.Seed.MsgIsZero()) && ((*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).Block.BlockHeader.TimeStamp == 0) && ((*z).Block.BlockHeader.GenesisID == "") && ((*z).Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).Block.BlockHeader.TxnCounter == 0) && (len((*z).Block.BlockHeader.StateProofTracking) == 0) && (len((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).Block.Payset.MsgIsZero()) && ((*z).SeedProof.MsgIsZero()) && ((*z).OriginalPeriod == 0) && ((*z).OriginalProposer.MsgIsZero()) + return ((*z).Block.BlockHeader.Round.MsgIsZero()) && ((*z).Block.BlockHeader.Branch.MsgIsZero()) && ((*z).Block.BlockHeader.Seed.MsgIsZero()) && ((*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).Block.BlockHeader.TimeStamp == 0) && ((*z).Block.BlockHeader.GenesisID == "") && ((*z).Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).Block.BlockHeader.Proposer.MsgIsZero()) && ((*z).Block.BlockHeader.FeesCollected.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).Block.BlockHeader.TxnCounter == 0) && (len((*z).Block.BlockHeader.StateProofTracking) == 0) && (len((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).Block.Payset.MsgIsZero()) && ((*z).SeedProof.MsgIsZero()) && ((*z).OriginalPeriod == 0) && ((*z).OriginalProposer.MsgIsZero()) } // MaxSize returns a maximum valid message size for this message type func UnauthenticatedProposalMaxSize() (s int) { - s = 3 + 4 + basics.RoundMaxSize() + 5 + bookkeeping.BlockHashMaxSize() + 5 + committee.SeedMaxSize() + 4 + crypto.DigestMaxSize() + 7 + crypto.DigestMaxSize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + config.MaxGenesisIDLen + 3 + crypto.DigestMaxSize() + 5 + basics.AddressMaxSize() + 4 + basics.AddressMaxSize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + basics.RoundMaxSize() + 6 + protocol.ConsensusVersionMaxSize() + 10 + protocol.ConsensusVersionMaxSize() + 8 + msgp.Uint64Size + 11 + basics.RoundMaxSize() + 11 + basics.RoundMaxSize() + 12 + protocol.ConsensusVersionMaxSize() + 13 + basics.RoundMaxSize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + s = 3 + 4 + basics.RoundMaxSize() + 5 + bookkeeping.BlockHashMaxSize() + 5 + committee.SeedMaxSize() + 4 + crypto.DigestMaxSize() + 7 + crypto.DigestMaxSize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + config.MaxGenesisIDLen + 3 + crypto.DigestMaxSize() + 4 + basics.AddressMaxSize() + 3 + basics.MicroAlgosMaxSize() + 5 + basics.AddressMaxSize() + 4 + basics.AddressMaxSize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + basics.RoundMaxSize() + 6 + protocol.ConsensusVersionMaxSize() + 10 + protocol.ConsensusVersionMaxSize() + 8 + msgp.Uint64Size + 11 + basics.RoundMaxSize() + 11 + basics.RoundMaxSize() + 12 + protocol.ConsensusVersionMaxSize() + 13 + basics.RoundMaxSize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 s += msgp.MapHeaderSize // Adding size of map keys for z.Block.BlockHeader.StateProofTracking s += protocol.NumStateProofTypes * (protocol.StateProofTypeMaxSize()) diff --git a/agreement/proposal.go b/agreement/proposal.go index bf021f2cfe..0d8442a065 100644 --- a/agreement/proposal.go +++ b/agreement/proposal.go @@ -251,7 +251,7 @@ func proposalForBlock(address basics.Address, vrf *crypto.VRFSecrets, ve Validat return proposal{}, proposalValue{}, fmt.Errorf("proposalForBlock: could not derive new seed: %v", err) } - ve = ve.WithSeed(newSeed) + ve = ve.WithSeed(newSeed, address) proposal := makeProposal(ve, seedProof, period, address) value := proposalValue{ OriginalPeriod: period, diff --git a/config/consensus.go b/config/consensus.go index c3592e40d9..9baae64af1 100644 --- a/config/consensus.go +++ b/config/consensus.go @@ -522,6 +522,13 @@ type ConsensusParams struct { // arrival times or is set to a static value. Even if this flag disables the // dynamic filter, it will be calculated and logged (but not used). DynamicFilterTimeout bool + + // EnableMining means that the proposer should be included in the BlockHeader. + EnableMining bool + + // MiningPercent specifies the percent of fees paid in a block that go to + // the proposer instead of the FeeSink. + MiningPercent uint64 } // PaysetCommitType enumerates possible ways for the block header to commit to @@ -1376,6 +1383,9 @@ func initConsensusProtocols() { // by reducing round time. Hence, it is commented out for now. // vFuture.DynamicFilterTimeout = true + vFuture.EnableMining = true + vFuture.MiningPercent = 75 + Consensus[protocol.ConsensusFuture] = vFuture // vAlphaX versions are an separate series of consensus parameters and versions for alphanet diff --git a/daemon/algod/api/server/v2/handlers.go b/daemon/algod/api/server/v2/handlers.go index 065337f32d..c26c7762b9 100644 --- a/daemon/algod/api/server/v2/handlers.go +++ b/daemon/algod/api/server/v2/handlers.go @@ -1396,10 +1396,7 @@ func (v2 *Handlers) getPendingTransactions(ctx echo.Context, max *uint64, format } // MatchAddress uses this to check FeeSink, we don't care about that here. - spec := transactions.SpecialAddresses{ - FeeSink: basics.Address{}, - RewardsPool: basics.Address{}, - } + spec := transactions.SpecialAddresses{} txnLimit := uint64(math.MaxUint64) if max != nil && *max != 0 { diff --git a/daemon/algod/api/server/v2/test/handlers_resources_test.go b/daemon/algod/api/server/v2/test/handlers_resources_test.go index 1de86ddc19..fc764c2fa7 100644 --- a/daemon/algod/api/server/v2/test/handlers_resources_test.go +++ b/daemon/algod/api/server/v2/test/handlers_resources_test.go @@ -19,11 +19,12 @@ package test import ( "encoding/json" "fmt" - "github.com/algorand/go-algorand/data/transactions/logic" "net/http" "net/http/httptest" "testing" + "github.com/algorand/go-algorand/data/transactions/logic" + "github.com/labstack/echo/v4" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" diff --git a/data/basics/fraction.go b/data/basics/fraction.go new file mode 100644 index 0000000000..271da85265 --- /dev/null +++ b/data/basics/fraction.go @@ -0,0 +1,69 @@ +// Copyright (C) 2019-2023 Algorand, Inc. +// This file is part of go-algorand +// +// go-algorand is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// go-algorand is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with go-algorand. If not, see . + +package basics + +import ( + "fmt" +) + +// Fraction represents the mathematical notion of rational number, but is much +// simpler than `big.Rat`. It only supports numerators and denominators of +// uint64. +type Fraction struct { + Numerator uint64 + Denominator uint64 +} + +// NewFraction creates the obvious Fraction, and checks that is not improper, +// nor dives by zero. +func NewFraction(numerator uint64, denominator uint64) Fraction { + if denominator == 0 { + panic("/0") + } + if numerator > denominator { + panic("improper fraction") + } + return Fraction{numerator, denominator} +} + +// NewPercent creates a fraction reflecting the given percentage. +func NewPercent(pct uint64) Fraction { + return NewFraction(pct, 100) +} + +// String returns a string representation of Fraction +func (frac Fraction) String() string { + return fmt.Sprintf("%d/%d", frac.Numerator, frac.Denominator) +} + +// Divvy separates a quantity into two parts according to the fraction. The first +// value is floor(q * frac), the second is q - first. +func (frac Fraction) Divvy(q uint64) (uint64, uint64) { + // can't overflow on proper fractions + first, o := Muldiv(q, frac.Numerator, frac.Denominator) + if o { + panic("overflow") + } + second := q - first + return first, second +} + +// DivvyAlgos is Divvy, but operates on MicroAlgos +func (frac Fraction) DivvyAlgos(q MicroAlgos) (MicroAlgos, MicroAlgos) { + first, second := frac.Divvy(q.Raw) + return MicroAlgos{first}, MicroAlgos{second} +} diff --git a/data/basics/fraction_test.go b/data/basics/fraction_test.go new file mode 100644 index 0000000000..9fad8dfa19 --- /dev/null +++ b/data/basics/fraction_test.go @@ -0,0 +1,76 @@ +// Copyright (C) 2019-2023 Algorand, Inc. +// This file is part of go-algorand +// +// go-algorand is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// go-algorand is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with go-algorand. If not, see . + +package basics + +import ( + "math" + "testing" + + "github.com/algorand/go-algorand/test/partitiontest" + "github.com/stretchr/testify/require" +) + +func TestFraction(t *testing.T) { + partitiontest.PartitionTest(t) + t.Parallel() + + third := Fraction{1, 3} + a, b := third.Divvy(6) + require.EqualValues(t, a, 2) + require.EqualValues(t, b, 4) + + a, b = third.Divvy(10) + require.EqualValues(t, a, 3) + require.EqualValues(t, b, 7) +} + +func TestFractionAvoidsOverflow(t *testing.T) { + partitiontest.PartitionTest(t) + t.Parallel() + + biggestEven := math.MaxUint64 - uint64(1) + + half := Fraction{biggestEven / 2, biggestEven} // should operate as 1/2 even on large numbers + a, b := half.Divvy(6) + require.EqualValues(t, a, 3) + require.EqualValues(t, b, 3) + + a, b = half.Divvy(biggestEven) + require.EqualValues(t, a, biggestEven/2) + require.EqualValues(t, b, biggestEven/2) + + // ensure that overflow is avoided even if reduction isn't possible + uhalf := Fraction{biggestEven / 2, math.MaxUint64} // should be just under half + a, b = uhalf.Divvy(6) + require.EqualValues(t, a, 2) + require.EqualValues(t, b, 4) + + a, b = uhalf.Divvy(biggestEven) + require.EqualValues(t, a, biggestEven/2-1) + require.EqualValues(t, b, biggestEven/2+1) + + // and just to be super careful, ensure that there's also no reduction + // between q and the denominator by using a q that is relatively prime to + // math.MaxUint64 + + // prove 23 is relatively prime to math.MaxUint64 + require.Positive(t, math.MaxUint64%23) + + a, b = uhalf.Divvy(23) + require.EqualValues(t, a, 11) + require.EqualValues(t, b, 12) +} diff --git a/data/bookkeeping/block.go b/data/bookkeeping/block.go index 39842aa758..c84380d86f 100644 --- a/data/bookkeeping/block.go +++ b/data/bookkeeping/block.go @@ -58,6 +58,16 @@ type ( // Genesis hash to which this block belongs. GenesisHash crypto.Digest `codec:"gh"` + // Proposer is the proposer of this block. Like the Seed, algod adds + // this after the block is built, so that the same block can be prepared + // for multiple Players in the same node. Therefore, it can not be used + // to influence block evaluation. Populated if proto.EnableMining + Proposer basics.Address `codec:"prp"` + + // FeesCollected is the sum of all fees paid by transactions in this + // block. Populated if proto.EnableMining. + FeesCollected basics.MicroAlgos `codec:"fc"` + // Rewards. // // When a block is applied, some amount of rewards are accrued to @@ -275,9 +285,13 @@ func (block Block) GenesisHash() crypto.Digest { } // WithSeed returns a copy of the Block with the seed set to s. -func (block Block) WithSeed(s committee.Seed) Block { +func (block Block) WithSeed(s committee.Seed, proposer basics.Address) Block { c := block c.BlockHeader.Seed = s + if !c.BlockHeader.Proposer.IsZero() { + panic("Attempt to re-set the proposer.") + } + c.BlockHeader.Proposer = proposer return c } diff --git a/data/bookkeeping/msgp_gen.go b/data/bookkeeping/msgp_gen.go index 7eda4de555..61630b1782 100644 --- a/data/bookkeeping/msgp_gen.go +++ b/data/bookkeeping/msgp_gen.go @@ -143,112 +143,120 @@ import ( func (z *Block) MarshalMsg(b []byte) (o []byte) { o = msgp.Require(b, z.Msgsize()) // omitempty: check for empty values - zb0004Len := uint32(26) - var zb0004Mask uint32 /* 31 bits */ + zb0004Len := uint32(28) + var zb0004Mask uint64 /* 33 bits */ if (*z).BlockHeader.RewardsState.RewardsLevel == 0 { zb0004Len-- zb0004Mask |= 0x20 } - if (*z).BlockHeader.RewardsState.FeeSink.MsgIsZero() { + if (*z).BlockHeader.FeesCollected.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x40 } - if (*z).BlockHeader.RewardsState.RewardsResidue == 0 { + if (*z).BlockHeader.RewardsState.FeeSink.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x80 } - if (*z).BlockHeader.GenesisID == "" { + if (*z).BlockHeader.RewardsState.RewardsResidue == 0 { zb0004Len-- zb0004Mask |= 0x100 } - if (*z).BlockHeader.GenesisHash.MsgIsZero() { + if (*z).BlockHeader.GenesisID == "" { zb0004Len-- zb0004Mask |= 0x200 } - if (*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() { + if (*z).BlockHeader.GenesisHash.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x400 } - if (*z).BlockHeader.UpgradeState.NextProtocol.MsgIsZero() { + if (*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x800 } - if (*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() { + if (*z).BlockHeader.UpgradeState.NextProtocol.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x1000 } - if (*z).BlockHeader.UpgradeState.NextProtocolApprovals == 0 { + if (*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x2000 } - if len((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 { + if (*z).BlockHeader.UpgradeState.NextProtocolApprovals == 0 { zb0004Len-- zb0004Mask |= 0x4000 } - if (*z).BlockHeader.Branch.MsgIsZero() { + if len((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 { zb0004Len-- zb0004Mask |= 0x8000 } - if (*z).BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() { + if (*z).BlockHeader.Branch.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x10000 } - if (*z).BlockHeader.RewardsState.RewardsRate == 0 { + if (*z).BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x20000 } - if (*z).BlockHeader.Round.MsgIsZero() { + if (*z).BlockHeader.Proposer.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x40000 } - if (*z).BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero() { + if (*z).BlockHeader.RewardsState.RewardsRate == 0 { zb0004Len-- zb0004Mask |= 0x80000 } - if (*z).BlockHeader.RewardsState.RewardsPool.MsgIsZero() { + if (*z).BlockHeader.Round.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x100000 } - if (*z).BlockHeader.Seed.MsgIsZero() { + if (*z).BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x200000 } - if len((*z).BlockHeader.StateProofTracking) == 0 { + if (*z).BlockHeader.RewardsState.RewardsPool.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x400000 } - if (*z).BlockHeader.TxnCounter == 0 { + if (*z).BlockHeader.Seed.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x800000 } - if (*z).BlockHeader.TimeStamp == 0 { + if len((*z).BlockHeader.StateProofTracking) == 0 { zb0004Len-- zb0004Mask |= 0x1000000 } - if (*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero() { + if (*z).BlockHeader.TxnCounter == 0 { zb0004Len-- zb0004Mask |= 0x2000000 } - if (*z).BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero() { + if (*z).BlockHeader.TimeStamp == 0 { zb0004Len-- zb0004Mask |= 0x4000000 } - if (*z).Payset.MsgIsZero() { + if (*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x8000000 } - if (*z).BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero() { + if (*z).BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x10000000 } - if (*z).BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero() { + if (*z).Payset.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x20000000 } - if (*z).BlockHeader.UpgradeVote.UpgradeApprove == false { + if (*z).BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x40000000 } + if (*z).BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero() { + zb0004Len-- + zb0004Mask |= 0x80000000 + } + if (*z).BlockHeader.UpgradeVote.UpgradeApprove == false { + zb0004Len-- + zb0004Mask |= 0x100000000 + } // variable map header, size zb0004Len o = msgp.AppendMapHeader(o, zb0004Len) if zb0004Len != 0 { @@ -258,46 +266,51 @@ func (z *Block) MarshalMsg(b []byte) (o []byte) { o = msgp.AppendUint64(o, (*z).BlockHeader.RewardsState.RewardsLevel) } if (zb0004Mask & 0x40) == 0 { // if not empty + // string "fc" + o = append(o, 0xa2, 0x66, 0x63) + o = (*z).BlockHeader.FeesCollected.MarshalMsg(o) + } + if (zb0004Mask & 0x80) == 0 { // if not empty // string "fees" o = append(o, 0xa4, 0x66, 0x65, 0x65, 0x73) o = (*z).BlockHeader.RewardsState.FeeSink.MarshalMsg(o) } - if (zb0004Mask & 0x80) == 0 { // if not empty + if (zb0004Mask & 0x100) == 0 { // if not empty // string "frac" o = append(o, 0xa4, 0x66, 0x72, 0x61, 0x63) o = msgp.AppendUint64(o, (*z).BlockHeader.RewardsState.RewardsResidue) } - if (zb0004Mask & 0x100) == 0 { // if not empty + if (zb0004Mask & 0x200) == 0 { // if not empty // string "gen" o = append(o, 0xa3, 0x67, 0x65, 0x6e) o = msgp.AppendString(o, (*z).BlockHeader.GenesisID) } - if (zb0004Mask & 0x200) == 0 { // if not empty + if (zb0004Mask & 0x400) == 0 { // if not empty // string "gh" o = append(o, 0xa2, 0x67, 0x68) o = (*z).BlockHeader.GenesisHash.MarshalMsg(o) } - if (zb0004Mask & 0x400) == 0 { // if not empty + if (zb0004Mask & 0x800) == 0 { // if not empty // string "nextbefore" o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65) o = (*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.MarshalMsg(o) } - if (zb0004Mask & 0x800) == 0 { // if not empty + if (zb0004Mask & 0x1000) == 0 { // if not empty // string "nextproto" o = append(o, 0xa9, 0x6e, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f) o = (*z).BlockHeader.UpgradeState.NextProtocol.MarshalMsg(o) } - if (zb0004Mask & 0x1000) == 0 { // if not empty + if (zb0004Mask & 0x2000) == 0 { // if not empty // string "nextswitch" o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68) o = (*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.MarshalMsg(o) } - if (zb0004Mask & 0x2000) == 0 { // if not empty + if (zb0004Mask & 0x4000) == 0 { // if not empty // string "nextyes" o = append(o, 0xa7, 0x6e, 0x65, 0x78, 0x74, 0x79, 0x65, 0x73) o = msgp.AppendUint64(o, (*z).BlockHeader.UpgradeState.NextProtocolApprovals) } - if (zb0004Mask & 0x4000) == 0 { // if not empty + if (zb0004Mask & 0x8000) == 0 { // if not empty // string "partupdrmv" o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76) if (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts == nil { @@ -309,42 +322,47 @@ func (z *Block) MarshalMsg(b []byte) (o []byte) { o = (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].MarshalMsg(o) } } - if (zb0004Mask & 0x8000) == 0 { // if not empty + if (zb0004Mask & 0x10000) == 0 { // if not empty // string "prev" o = append(o, 0xa4, 0x70, 0x72, 0x65, 0x76) o = (*z).BlockHeader.Branch.MarshalMsg(o) } - if (zb0004Mask & 0x10000) == 0 { // if not empty + if (zb0004Mask & 0x20000) == 0 { // if not empty // string "proto" o = append(o, 0xa5, 0x70, 0x72, 0x6f, 0x74, 0x6f) o = (*z).BlockHeader.UpgradeState.CurrentProtocol.MarshalMsg(o) } - if (zb0004Mask & 0x20000) == 0 { // if not empty + if (zb0004Mask & 0x40000) == 0 { // if not empty + // string "prp" + o = append(o, 0xa3, 0x70, 0x72, 0x70) + o = (*z).BlockHeader.Proposer.MarshalMsg(o) + } + if (zb0004Mask & 0x80000) == 0 { // if not empty // string "rate" o = append(o, 0xa4, 0x72, 0x61, 0x74, 0x65) o = msgp.AppendUint64(o, (*z).BlockHeader.RewardsState.RewardsRate) } - if (zb0004Mask & 0x40000) == 0 { // if not empty + if (zb0004Mask & 0x100000) == 0 { // if not empty // string "rnd" o = append(o, 0xa3, 0x72, 0x6e, 0x64) o = (*z).BlockHeader.Round.MarshalMsg(o) } - if (zb0004Mask & 0x80000) == 0 { // if not empty + if (zb0004Mask & 0x200000) == 0 { // if not empty // string "rwcalr" o = append(o, 0xa6, 0x72, 0x77, 0x63, 0x61, 0x6c, 0x72) o = (*z).BlockHeader.RewardsState.RewardsRecalculationRound.MarshalMsg(o) } - if (zb0004Mask & 0x100000) == 0 { // if not empty + if (zb0004Mask & 0x400000) == 0 { // if not empty // string "rwd" o = append(o, 0xa3, 0x72, 0x77, 0x64) o = (*z).BlockHeader.RewardsState.RewardsPool.MarshalMsg(o) } - if (zb0004Mask & 0x200000) == 0 { // if not empty + if (zb0004Mask & 0x800000) == 0 { // if not empty // string "seed" o = append(o, 0xa4, 0x73, 0x65, 0x65, 0x64) o = (*z).BlockHeader.Seed.MarshalMsg(o) } - if (zb0004Mask & 0x400000) == 0 { // if not empty + if (zb0004Mask & 0x1000000) == 0 { // if not empty // string "spt" o = append(o, 0xa3, 0x73, 0x70, 0x74) if (*z).BlockHeader.StateProofTracking == nil { @@ -364,42 +382,42 @@ func (z *Block) MarshalMsg(b []byte) (o []byte) { o = zb0002.MarshalMsg(o) } } - if (zb0004Mask & 0x800000) == 0 { // if not empty + if (zb0004Mask & 0x2000000) == 0 { // if not empty // string "tc" o = append(o, 0xa2, 0x74, 0x63) o = msgp.AppendUint64(o, (*z).BlockHeader.TxnCounter) } - if (zb0004Mask & 0x1000000) == 0 { // if not empty + if (zb0004Mask & 0x4000000) == 0 { // if not empty // string "ts" o = append(o, 0xa2, 0x74, 0x73) o = msgp.AppendInt64(o, (*z).BlockHeader.TimeStamp) } - if (zb0004Mask & 0x2000000) == 0 { // if not empty + if (zb0004Mask & 0x8000000) == 0 { // if not empty // string "txn" o = append(o, 0xa3, 0x74, 0x78, 0x6e) o = (*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.MarshalMsg(o) } - if (zb0004Mask & 0x4000000) == 0 { // if not empty + if (zb0004Mask & 0x10000000) == 0 { // if not empty // string "txn256" o = append(o, 0xa6, 0x74, 0x78, 0x6e, 0x32, 0x35, 0x36) o = (*z).BlockHeader.TxnCommitments.Sha256Commitment.MarshalMsg(o) } - if (zb0004Mask & 0x8000000) == 0 { // if not empty + if (zb0004Mask & 0x20000000) == 0 { // if not empty // string "txns" o = append(o, 0xa4, 0x74, 0x78, 0x6e, 0x73) o = (*z).Payset.MarshalMsg(o) } - if (zb0004Mask & 0x10000000) == 0 { // if not empty + if (zb0004Mask & 0x40000000) == 0 { // if not empty // string "upgradedelay" o = append(o, 0xac, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x65, 0x6c, 0x61, 0x79) o = (*z).BlockHeader.UpgradeVote.UpgradeDelay.MarshalMsg(o) } - if (zb0004Mask & 0x20000000) == 0 { // if not empty + if (zb0004Mask & 0x80000000) == 0 { // if not empty // string "upgradeprop" o = append(o, 0xab, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x70, 0x72, 0x6f, 0x70) o = (*z).BlockHeader.UpgradeVote.UpgradePropose.MarshalMsg(o) } - if (zb0004Mask & 0x40000000) == 0 { // if not empty + if (zb0004Mask & 0x100000000) == 0 { // if not empty // string "upgradeyes" o = append(o, 0xaa, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x65, 0x73) o = msgp.AppendBool(o, (*z).BlockHeader.UpgradeVote.UpgradeApprove) @@ -505,6 +523,22 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b return } } + if zb0004 > 0 { + zb0004-- + bts, err = (*z).BlockHeader.Proposer.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "Proposer") + return + } + } + if zb0004 > 0 { + zb0004-- + bts, err = (*z).BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "FeesCollected") + return + } + } if zb0004 > 0 { zb0004-- bts, err = (*z).BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st) @@ -779,6 +813,18 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b err = msgp.WrapError(err, "GenesisHash") return } + case "prp": + bts, err = (*z).BlockHeader.Proposer.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "Proposer") + return + } + case "fc": + bts, err = (*z).BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "FeesCollected") + return + } case "fees": bts, err = (*z).BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st) if err != nil { @@ -959,7 +1005,7 @@ func (_ *Block) CanUnmarshalMsg(z interface{}) bool { // Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message func (z *Block) Msgsize() (s int) { - s = 3 + 4 + (*z).BlockHeader.Round.Msgsize() + 5 + (*z).BlockHeader.Branch.Msgsize() + 5 + (*z).BlockHeader.Seed.Msgsize() + 4 + (*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.Msgsize() + 7 + (*z).BlockHeader.TxnCommitments.Sha256Commitment.Msgsize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + len((*z).BlockHeader.GenesisID) + 3 + (*z).BlockHeader.GenesisHash.Msgsize() + 5 + (*z).BlockHeader.RewardsState.FeeSink.Msgsize() + 4 + (*z).BlockHeader.RewardsState.RewardsPool.Msgsize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + (*z).BlockHeader.RewardsState.RewardsRecalculationRound.Msgsize() + 6 + (*z).BlockHeader.UpgradeState.CurrentProtocol.Msgsize() + 10 + (*z).BlockHeader.UpgradeState.NextProtocol.Msgsize() + 8 + msgp.Uint64Size + 11 + (*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.Msgsize() + 11 + (*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.Msgsize() + 12 + (*z).BlockHeader.UpgradeVote.UpgradePropose.Msgsize() + 13 + (*z).BlockHeader.UpgradeVote.UpgradeDelay.Msgsize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + msgp.MapHeaderSize + s = 3 + 4 + (*z).BlockHeader.Round.Msgsize() + 5 + (*z).BlockHeader.Branch.Msgsize() + 5 + (*z).BlockHeader.Seed.Msgsize() + 4 + (*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.Msgsize() + 7 + (*z).BlockHeader.TxnCommitments.Sha256Commitment.Msgsize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + len((*z).BlockHeader.GenesisID) + 3 + (*z).BlockHeader.GenesisHash.Msgsize() + 4 + (*z).BlockHeader.Proposer.Msgsize() + 3 + (*z).BlockHeader.FeesCollected.Msgsize() + 5 + (*z).BlockHeader.RewardsState.FeeSink.Msgsize() + 4 + (*z).BlockHeader.RewardsState.RewardsPool.Msgsize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + (*z).BlockHeader.RewardsState.RewardsRecalculationRound.Msgsize() + 6 + (*z).BlockHeader.UpgradeState.CurrentProtocol.Msgsize() + 10 + (*z).BlockHeader.UpgradeState.NextProtocol.Msgsize() + 8 + msgp.Uint64Size + 11 + (*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.Msgsize() + 11 + (*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.Msgsize() + 12 + (*z).BlockHeader.UpgradeVote.UpgradePropose.Msgsize() + 13 + (*z).BlockHeader.UpgradeVote.UpgradeDelay.Msgsize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + msgp.MapHeaderSize if (*z).BlockHeader.StateProofTracking != nil { for zb0001, zb0002 := range (*z).BlockHeader.StateProofTracking { _ = zb0001 @@ -977,12 +1023,12 @@ func (z *Block) Msgsize() (s int) { // MsgIsZero returns whether this is a zero value func (z *Block) MsgIsZero() bool { - return ((*z).BlockHeader.Round.MsgIsZero()) && ((*z).BlockHeader.Branch.MsgIsZero()) && ((*z).BlockHeader.Seed.MsgIsZero()) && ((*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).BlockHeader.TimeStamp == 0) && ((*z).BlockHeader.GenesisID == "") && ((*z).BlockHeader.GenesisHash.MsgIsZero()) && ((*z).BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).BlockHeader.RewardsState.RewardsRate == 0) && ((*z).BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).BlockHeader.TxnCounter == 0) && (len((*z).BlockHeader.StateProofTracking) == 0) && (len((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).Payset.MsgIsZero()) + return ((*z).BlockHeader.Round.MsgIsZero()) && ((*z).BlockHeader.Branch.MsgIsZero()) && ((*z).BlockHeader.Seed.MsgIsZero()) && ((*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).BlockHeader.TimeStamp == 0) && ((*z).BlockHeader.GenesisID == "") && ((*z).BlockHeader.GenesisHash.MsgIsZero()) && ((*z).BlockHeader.Proposer.MsgIsZero()) && ((*z).BlockHeader.FeesCollected.MsgIsZero()) && ((*z).BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).BlockHeader.RewardsState.RewardsRate == 0) && ((*z).BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).BlockHeader.TxnCounter == 0) && (len((*z).BlockHeader.StateProofTracking) == 0) && (len((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).Payset.MsgIsZero()) } // MaxSize returns a maximum valid message size for this message type func BlockMaxSize() (s int) { - s = 3 + 4 + basics.RoundMaxSize() + 5 + BlockHashMaxSize() + 5 + committee.SeedMaxSize() + 4 + crypto.DigestMaxSize() + 7 + crypto.DigestMaxSize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + config.MaxGenesisIDLen + 3 + crypto.DigestMaxSize() + 5 + basics.AddressMaxSize() + 4 + basics.AddressMaxSize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + basics.RoundMaxSize() + 6 + protocol.ConsensusVersionMaxSize() + 10 + protocol.ConsensusVersionMaxSize() + 8 + msgp.Uint64Size + 11 + basics.RoundMaxSize() + 11 + basics.RoundMaxSize() + 12 + protocol.ConsensusVersionMaxSize() + 13 + basics.RoundMaxSize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + s = 3 + 4 + basics.RoundMaxSize() + 5 + BlockHashMaxSize() + 5 + committee.SeedMaxSize() + 4 + crypto.DigestMaxSize() + 7 + crypto.DigestMaxSize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + config.MaxGenesisIDLen + 3 + crypto.DigestMaxSize() + 4 + basics.AddressMaxSize() + 3 + basics.MicroAlgosMaxSize() + 5 + basics.AddressMaxSize() + 4 + basics.AddressMaxSize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + basics.RoundMaxSize() + 6 + protocol.ConsensusVersionMaxSize() + 10 + protocol.ConsensusVersionMaxSize() + 8 + msgp.Uint64Size + 11 + basics.RoundMaxSize() + 11 + basics.RoundMaxSize() + 12 + protocol.ConsensusVersionMaxSize() + 13 + basics.RoundMaxSize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 s += msgp.MapHeaderSize // Adding size of map keys for z.BlockHeader.StateProofTracking s += protocol.NumStateProofTypes * (protocol.StateProofTypeMaxSize()) @@ -1037,108 +1083,116 @@ func BlockHashMaxSize() int { func (z *BlockHeader) MarshalMsg(b []byte) (o []byte) { o = msgp.Require(b, z.Msgsize()) // omitempty: check for empty values - zb0004Len := uint32(25) - var zb0004Mask uint32 /* 30 bits */ + zb0004Len := uint32(27) + var zb0004Mask uint32 /* 32 bits */ if (*z).RewardsState.RewardsLevel == 0 { zb0004Len-- zb0004Mask |= 0x20 } - if (*z).RewardsState.FeeSink.MsgIsZero() { + if (*z).FeesCollected.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x40 } - if (*z).RewardsState.RewardsResidue == 0 { + if (*z).RewardsState.FeeSink.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x80 } - if (*z).GenesisID == "" { + if (*z).RewardsState.RewardsResidue == 0 { zb0004Len-- zb0004Mask |= 0x100 } - if (*z).GenesisHash.MsgIsZero() { + if (*z).GenesisID == "" { zb0004Len-- zb0004Mask |= 0x200 } - if (*z).UpgradeState.NextProtocolVoteBefore.MsgIsZero() { + if (*z).GenesisHash.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x400 } - if (*z).UpgradeState.NextProtocol.MsgIsZero() { + if (*z).UpgradeState.NextProtocolVoteBefore.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x800 } - if (*z).UpgradeState.NextProtocolSwitchOn.MsgIsZero() { + if (*z).UpgradeState.NextProtocol.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x1000 } - if (*z).UpgradeState.NextProtocolApprovals == 0 { + if (*z).UpgradeState.NextProtocolSwitchOn.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x2000 } - if len((*z).ParticipationUpdates.ExpiredParticipationAccounts) == 0 { + if (*z).UpgradeState.NextProtocolApprovals == 0 { zb0004Len-- zb0004Mask |= 0x4000 } - if (*z).Branch.MsgIsZero() { + if len((*z).ParticipationUpdates.ExpiredParticipationAccounts) == 0 { zb0004Len-- zb0004Mask |= 0x8000 } - if (*z).UpgradeState.CurrentProtocol.MsgIsZero() { + if (*z).Branch.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x10000 } - if (*z).RewardsState.RewardsRate == 0 { + if (*z).UpgradeState.CurrentProtocol.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x20000 } - if (*z).Round.MsgIsZero() { + if (*z).Proposer.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x40000 } - if (*z).RewardsState.RewardsRecalculationRound.MsgIsZero() { + if (*z).RewardsState.RewardsRate == 0 { zb0004Len-- zb0004Mask |= 0x80000 } - if (*z).RewardsState.RewardsPool.MsgIsZero() { + if (*z).Round.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x100000 } - if (*z).Seed.MsgIsZero() { + if (*z).RewardsState.RewardsRecalculationRound.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x200000 } - if len((*z).StateProofTracking) == 0 { + if (*z).RewardsState.RewardsPool.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x400000 } - if (*z).TxnCounter == 0 { + if (*z).Seed.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x800000 } - if (*z).TimeStamp == 0 { + if len((*z).StateProofTracking) == 0 { zb0004Len-- zb0004Mask |= 0x1000000 } - if (*z).TxnCommitments.NativeSha512_256Commitment.MsgIsZero() { + if (*z).TxnCounter == 0 { zb0004Len-- zb0004Mask |= 0x2000000 } - if (*z).TxnCommitments.Sha256Commitment.MsgIsZero() { + if (*z).TimeStamp == 0 { zb0004Len-- zb0004Mask |= 0x4000000 } - if (*z).UpgradeVote.UpgradeDelay.MsgIsZero() { + if (*z).TxnCommitments.NativeSha512_256Commitment.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x8000000 } - if (*z).UpgradeVote.UpgradePropose.MsgIsZero() { + if (*z).TxnCommitments.Sha256Commitment.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x10000000 } - if (*z).UpgradeVote.UpgradeApprove == false { + if (*z).UpgradeVote.UpgradeDelay.MsgIsZero() { zb0004Len-- zb0004Mask |= 0x20000000 } + if (*z).UpgradeVote.UpgradePropose.MsgIsZero() { + zb0004Len-- + zb0004Mask |= 0x40000000 + } + if (*z).UpgradeVote.UpgradeApprove == false { + zb0004Len-- + zb0004Mask |= 0x80000000 + } // variable map header, size zb0004Len o = msgp.AppendMapHeader(o, zb0004Len) if zb0004Len != 0 { @@ -1148,46 +1202,51 @@ func (z *BlockHeader) MarshalMsg(b []byte) (o []byte) { o = msgp.AppendUint64(o, (*z).RewardsState.RewardsLevel) } if (zb0004Mask & 0x40) == 0 { // if not empty + // string "fc" + o = append(o, 0xa2, 0x66, 0x63) + o = (*z).FeesCollected.MarshalMsg(o) + } + if (zb0004Mask & 0x80) == 0 { // if not empty // string "fees" o = append(o, 0xa4, 0x66, 0x65, 0x65, 0x73) o = (*z).RewardsState.FeeSink.MarshalMsg(o) } - if (zb0004Mask & 0x80) == 0 { // if not empty + if (zb0004Mask & 0x100) == 0 { // if not empty // string "frac" o = append(o, 0xa4, 0x66, 0x72, 0x61, 0x63) o = msgp.AppendUint64(o, (*z).RewardsState.RewardsResidue) } - if (zb0004Mask & 0x100) == 0 { // if not empty + if (zb0004Mask & 0x200) == 0 { // if not empty // string "gen" o = append(o, 0xa3, 0x67, 0x65, 0x6e) o = msgp.AppendString(o, (*z).GenesisID) } - if (zb0004Mask & 0x200) == 0 { // if not empty + if (zb0004Mask & 0x400) == 0 { // if not empty // string "gh" o = append(o, 0xa2, 0x67, 0x68) o = (*z).GenesisHash.MarshalMsg(o) } - if (zb0004Mask & 0x400) == 0 { // if not empty + if (zb0004Mask & 0x800) == 0 { // if not empty // string "nextbefore" o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65) o = (*z).UpgradeState.NextProtocolVoteBefore.MarshalMsg(o) } - if (zb0004Mask & 0x800) == 0 { // if not empty + if (zb0004Mask & 0x1000) == 0 { // if not empty // string "nextproto" o = append(o, 0xa9, 0x6e, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f) o = (*z).UpgradeState.NextProtocol.MarshalMsg(o) } - if (zb0004Mask & 0x1000) == 0 { // if not empty + if (zb0004Mask & 0x2000) == 0 { // if not empty // string "nextswitch" o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68) o = (*z).UpgradeState.NextProtocolSwitchOn.MarshalMsg(o) } - if (zb0004Mask & 0x2000) == 0 { // if not empty + if (zb0004Mask & 0x4000) == 0 { // if not empty // string "nextyes" o = append(o, 0xa7, 0x6e, 0x65, 0x78, 0x74, 0x79, 0x65, 0x73) o = msgp.AppendUint64(o, (*z).UpgradeState.NextProtocolApprovals) } - if (zb0004Mask & 0x4000) == 0 { // if not empty + if (zb0004Mask & 0x8000) == 0 { // if not empty // string "partupdrmv" o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76) if (*z).ParticipationUpdates.ExpiredParticipationAccounts == nil { @@ -1199,42 +1258,47 @@ func (z *BlockHeader) MarshalMsg(b []byte) (o []byte) { o = (*z).ParticipationUpdates.ExpiredParticipationAccounts[zb0003].MarshalMsg(o) } } - if (zb0004Mask & 0x8000) == 0 { // if not empty + if (zb0004Mask & 0x10000) == 0 { // if not empty // string "prev" o = append(o, 0xa4, 0x70, 0x72, 0x65, 0x76) o = (*z).Branch.MarshalMsg(o) } - if (zb0004Mask & 0x10000) == 0 { // if not empty + if (zb0004Mask & 0x20000) == 0 { // if not empty // string "proto" o = append(o, 0xa5, 0x70, 0x72, 0x6f, 0x74, 0x6f) o = (*z).UpgradeState.CurrentProtocol.MarshalMsg(o) } - if (zb0004Mask & 0x20000) == 0 { // if not empty + if (zb0004Mask & 0x40000) == 0 { // if not empty + // string "prp" + o = append(o, 0xa3, 0x70, 0x72, 0x70) + o = (*z).Proposer.MarshalMsg(o) + } + if (zb0004Mask & 0x80000) == 0 { // if not empty // string "rate" o = append(o, 0xa4, 0x72, 0x61, 0x74, 0x65) o = msgp.AppendUint64(o, (*z).RewardsState.RewardsRate) } - if (zb0004Mask & 0x40000) == 0 { // if not empty + if (zb0004Mask & 0x100000) == 0 { // if not empty // string "rnd" o = append(o, 0xa3, 0x72, 0x6e, 0x64) o = (*z).Round.MarshalMsg(o) } - if (zb0004Mask & 0x80000) == 0 { // if not empty + if (zb0004Mask & 0x200000) == 0 { // if not empty // string "rwcalr" o = append(o, 0xa6, 0x72, 0x77, 0x63, 0x61, 0x6c, 0x72) o = (*z).RewardsState.RewardsRecalculationRound.MarshalMsg(o) } - if (zb0004Mask & 0x100000) == 0 { // if not empty + if (zb0004Mask & 0x400000) == 0 { // if not empty // string "rwd" o = append(o, 0xa3, 0x72, 0x77, 0x64) o = (*z).RewardsState.RewardsPool.MarshalMsg(o) } - if (zb0004Mask & 0x200000) == 0 { // if not empty + if (zb0004Mask & 0x800000) == 0 { // if not empty // string "seed" o = append(o, 0xa4, 0x73, 0x65, 0x65, 0x64) o = (*z).Seed.MarshalMsg(o) } - if (zb0004Mask & 0x400000) == 0 { // if not empty + if (zb0004Mask & 0x1000000) == 0 { // if not empty // string "spt" o = append(o, 0xa3, 0x73, 0x70, 0x74) if (*z).StateProofTracking == nil { @@ -1254,37 +1318,37 @@ func (z *BlockHeader) MarshalMsg(b []byte) (o []byte) { o = zb0002.MarshalMsg(o) } } - if (zb0004Mask & 0x800000) == 0 { // if not empty + if (zb0004Mask & 0x2000000) == 0 { // if not empty // string "tc" o = append(o, 0xa2, 0x74, 0x63) o = msgp.AppendUint64(o, (*z).TxnCounter) } - if (zb0004Mask & 0x1000000) == 0 { // if not empty + if (zb0004Mask & 0x4000000) == 0 { // if not empty // string "ts" o = append(o, 0xa2, 0x74, 0x73) o = msgp.AppendInt64(o, (*z).TimeStamp) } - if (zb0004Mask & 0x2000000) == 0 { // if not empty + if (zb0004Mask & 0x8000000) == 0 { // if not empty // string "txn" o = append(o, 0xa3, 0x74, 0x78, 0x6e) o = (*z).TxnCommitments.NativeSha512_256Commitment.MarshalMsg(o) } - if (zb0004Mask & 0x4000000) == 0 { // if not empty + if (zb0004Mask & 0x10000000) == 0 { // if not empty // string "txn256" o = append(o, 0xa6, 0x74, 0x78, 0x6e, 0x32, 0x35, 0x36) o = (*z).TxnCommitments.Sha256Commitment.MarshalMsg(o) } - if (zb0004Mask & 0x8000000) == 0 { // if not empty + if (zb0004Mask & 0x20000000) == 0 { // if not empty // string "upgradedelay" o = append(o, 0xac, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x65, 0x6c, 0x61, 0x79) o = (*z).UpgradeVote.UpgradeDelay.MarshalMsg(o) } - if (zb0004Mask & 0x10000000) == 0 { // if not empty + if (zb0004Mask & 0x40000000) == 0 { // if not empty // string "upgradeprop" o = append(o, 0xab, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x70, 0x72, 0x6f, 0x70) o = (*z).UpgradeVote.UpgradePropose.MarshalMsg(o) } - if (zb0004Mask & 0x20000000) == 0 { // if not empty + if (zb0004Mask & 0x80000000) == 0 { // if not empty // string "upgradeyes" o = append(o, 0xaa, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x65, 0x73) o = msgp.AppendBool(o, (*z).UpgradeVote.UpgradeApprove) @@ -1390,6 +1454,22 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) return } } + if zb0004 > 0 { + zb0004-- + bts, err = (*z).Proposer.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "Proposer") + return + } + } + if zb0004 > 0 { + zb0004-- + bts, err = (*z).FeesCollected.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "FeesCollected") + return + } + } if zb0004 > 0 { zb0004-- bts, err = (*z).RewardsState.FeeSink.UnmarshalMsgWithState(bts, st) @@ -1656,6 +1736,18 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) err = msgp.WrapError(err, "GenesisHash") return } + case "prp": + bts, err = (*z).Proposer.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "Proposer") + return + } + case "fc": + bts, err = (*z).FeesCollected.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "FeesCollected") + return + } case "fees": bts, err = (*z).RewardsState.FeeSink.UnmarshalMsgWithState(bts, st) if err != nil { @@ -1830,7 +1922,7 @@ func (_ *BlockHeader) CanUnmarshalMsg(z interface{}) bool { // Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message func (z *BlockHeader) Msgsize() (s int) { - s = 3 + 4 + (*z).Round.Msgsize() + 5 + (*z).Branch.Msgsize() + 5 + (*z).Seed.Msgsize() + 4 + (*z).TxnCommitments.NativeSha512_256Commitment.Msgsize() + 7 + (*z).TxnCommitments.Sha256Commitment.Msgsize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + len((*z).GenesisID) + 3 + (*z).GenesisHash.Msgsize() + 5 + (*z).RewardsState.FeeSink.Msgsize() + 4 + (*z).RewardsState.RewardsPool.Msgsize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + (*z).RewardsState.RewardsRecalculationRound.Msgsize() + 6 + (*z).UpgradeState.CurrentProtocol.Msgsize() + 10 + (*z).UpgradeState.NextProtocol.Msgsize() + 8 + msgp.Uint64Size + 11 + (*z).UpgradeState.NextProtocolVoteBefore.Msgsize() + 11 + (*z).UpgradeState.NextProtocolSwitchOn.Msgsize() + 12 + (*z).UpgradeVote.UpgradePropose.Msgsize() + 13 + (*z).UpgradeVote.UpgradeDelay.Msgsize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + msgp.MapHeaderSize + s = 3 + 4 + (*z).Round.Msgsize() + 5 + (*z).Branch.Msgsize() + 5 + (*z).Seed.Msgsize() + 4 + (*z).TxnCommitments.NativeSha512_256Commitment.Msgsize() + 7 + (*z).TxnCommitments.Sha256Commitment.Msgsize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + len((*z).GenesisID) + 3 + (*z).GenesisHash.Msgsize() + 4 + (*z).Proposer.Msgsize() + 3 + (*z).FeesCollected.Msgsize() + 5 + (*z).RewardsState.FeeSink.Msgsize() + 4 + (*z).RewardsState.RewardsPool.Msgsize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + (*z).RewardsState.RewardsRecalculationRound.Msgsize() + 6 + (*z).UpgradeState.CurrentProtocol.Msgsize() + 10 + (*z).UpgradeState.NextProtocol.Msgsize() + 8 + msgp.Uint64Size + 11 + (*z).UpgradeState.NextProtocolVoteBefore.Msgsize() + 11 + (*z).UpgradeState.NextProtocolSwitchOn.Msgsize() + 12 + (*z).UpgradeVote.UpgradePropose.Msgsize() + 13 + (*z).UpgradeVote.UpgradeDelay.Msgsize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + msgp.MapHeaderSize if (*z).StateProofTracking != nil { for zb0001, zb0002 := range (*z).StateProofTracking { _ = zb0001 @@ -1847,12 +1939,12 @@ func (z *BlockHeader) Msgsize() (s int) { // MsgIsZero returns whether this is a zero value func (z *BlockHeader) MsgIsZero() bool { - return ((*z).Round.MsgIsZero()) && ((*z).Branch.MsgIsZero()) && ((*z).Seed.MsgIsZero()) && ((*z).TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).TimeStamp == 0) && ((*z).GenesisID == "") && ((*z).GenesisHash.MsgIsZero()) && ((*z).RewardsState.FeeSink.MsgIsZero()) && ((*z).RewardsState.RewardsPool.MsgIsZero()) && ((*z).RewardsState.RewardsLevel == 0) && ((*z).RewardsState.RewardsRate == 0) && ((*z).RewardsState.RewardsResidue == 0) && ((*z).RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).UpgradeState.NextProtocol.MsgIsZero()) && ((*z).UpgradeState.NextProtocolApprovals == 0) && ((*z).UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).UpgradeVote.UpgradeApprove == false) && ((*z).TxnCounter == 0) && (len((*z).StateProofTracking) == 0) && (len((*z).ParticipationUpdates.ExpiredParticipationAccounts) == 0) + return ((*z).Round.MsgIsZero()) && ((*z).Branch.MsgIsZero()) && ((*z).Seed.MsgIsZero()) && ((*z).TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).TimeStamp == 0) && ((*z).GenesisID == "") && ((*z).GenesisHash.MsgIsZero()) && ((*z).Proposer.MsgIsZero()) && ((*z).FeesCollected.MsgIsZero()) && ((*z).RewardsState.FeeSink.MsgIsZero()) && ((*z).RewardsState.RewardsPool.MsgIsZero()) && ((*z).RewardsState.RewardsLevel == 0) && ((*z).RewardsState.RewardsRate == 0) && ((*z).RewardsState.RewardsResidue == 0) && ((*z).RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).UpgradeState.NextProtocol.MsgIsZero()) && ((*z).UpgradeState.NextProtocolApprovals == 0) && ((*z).UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).UpgradeVote.UpgradeApprove == false) && ((*z).TxnCounter == 0) && (len((*z).StateProofTracking) == 0) && (len((*z).ParticipationUpdates.ExpiredParticipationAccounts) == 0) } // MaxSize returns a maximum valid message size for this message type func BlockHeaderMaxSize() (s int) { - s = 3 + 4 + basics.RoundMaxSize() + 5 + BlockHashMaxSize() + 5 + committee.SeedMaxSize() + 4 + crypto.DigestMaxSize() + 7 + crypto.DigestMaxSize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + config.MaxGenesisIDLen + 3 + crypto.DigestMaxSize() + 5 + basics.AddressMaxSize() + 4 + basics.AddressMaxSize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + basics.RoundMaxSize() + 6 + protocol.ConsensusVersionMaxSize() + 10 + protocol.ConsensusVersionMaxSize() + 8 + msgp.Uint64Size + 11 + basics.RoundMaxSize() + 11 + basics.RoundMaxSize() + 12 + protocol.ConsensusVersionMaxSize() + 13 + basics.RoundMaxSize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + s = 3 + 4 + basics.RoundMaxSize() + 5 + BlockHashMaxSize() + 5 + committee.SeedMaxSize() + 4 + crypto.DigestMaxSize() + 7 + crypto.DigestMaxSize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + config.MaxGenesisIDLen + 3 + crypto.DigestMaxSize() + 4 + basics.AddressMaxSize() + 3 + basics.MicroAlgosMaxSize() + 5 + basics.AddressMaxSize() + 4 + basics.AddressMaxSize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + basics.RoundMaxSize() + 6 + protocol.ConsensusVersionMaxSize() + 10 + protocol.ConsensusVersionMaxSize() + 8 + msgp.Uint64Size + 11 + basics.RoundMaxSize() + 11 + basics.RoundMaxSize() + 12 + protocol.ConsensusVersionMaxSize() + 13 + basics.RoundMaxSize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 s += msgp.MapHeaderSize // Adding size of map keys for z.StateProofTracking s += protocol.NumStateProofTypes * (protocol.StateProofTypeMaxSize()) diff --git a/data/datatest/impls.go b/data/datatest/impls.go index fefcb054da..8e14885c96 100644 --- a/data/datatest/impls.go +++ b/data/datatest/impls.go @@ -65,8 +65,8 @@ func (i entryFactoryImpl) AssembleBlock(round basics.Round) (agreement.Validated } // WithSeed implements the agreement.ValidatedBlock interface. -func (ve validatedBlock) WithSeed(s committee.Seed) agreement.ValidatedBlock { - newblock := ve.blk.WithSeed(s) +func (ve validatedBlock) WithSeed(s committee.Seed, proposer basics.Address) agreement.ValidatedBlock { + newblock := ve.blk.WithSeed(s, proposer) return validatedBlock{blk: &newblock} } diff --git a/data/transactions/logic/TEAL_opcodes_v10.md b/data/transactions/logic/TEAL_opcodes_v10.md index 4ec00a52bb..0ae3f35ca6 100644 --- a/data/transactions/logic/TEAL_opcodes_v10.md +++ b/data/transactions/logic/TEAL_opcodes_v10.md @@ -1635,10 +1635,12 @@ Standards Fields -| Index | Name | Type | Notes | -| - | ------ | -- | --------- | -| 0 | BlkSeed | []byte | | -| 1 | BlkTimestamp | uint64 | | +| Index | Name | Type | In | Notes | +| - | ------ | -- | - | --------- | +| 0 | BlkSeed | []byte | | | +| 1 | BlkTimestamp | uint64 | | | +| 2 | BlkProposer | address | v10 | | +| 3 | BlkFeesCollected | uint64 | v10 | | ## ec_add diff --git a/data/transactions/logic/eval.go b/data/transactions/logic/eval.go index 2db51b24a7..08cc62feef 100644 --- a/data/transactions/logic/eval.go +++ b/data/transactions/logic/eval.go @@ -5578,17 +5578,20 @@ func opBlock(cx *EvalContext) error { switch fs.field { case BlkSeed: cx.Stack[last].Bytes = hdr.Seed[:] - return nil case BlkTimestamp: cx.Stack[last].Bytes = nil if hdr.TimeStamp < 0 { return fmt.Errorf("block(%d) timestamp %d < 0", round, hdr.TimeStamp) } cx.Stack[last].Uint = uint64(hdr.TimeStamp) - return nil + case BlkProposer: + cx.Stack[last].Bytes = hdr.Proposer[:] + case BlkFeesCollected: + cx.Stack[last].Uint = hdr.FeesCollected.Raw default: return fmt.Errorf("invalid block field %d", fs.field) } + return nil } // pcDetails return PC and disassembled instructions at PC up to 2 opcodes back diff --git a/data/transactions/logic/fields.go b/data/transactions/logic/fields.go index bb5c2179e9..c99b03fbbf 100644 --- a/data/transactions/logic/fields.go +++ b/data/transactions/logic/fields.go @@ -961,6 +961,10 @@ const ( BlkSeed BlockField = iota // BlkTimestamp is the Block's timestamp, seconds from epoch BlkTimestamp + // BlkProposer is the Block's proposer, or ZeroAddress, pre EnableMining + BlkProposer + // BlkFeesCollected is the sum of fees for the block, or 0, pre EnableMining + BlkFeesCollected invalidBlockField // compile-time constant for number of fields ) @@ -975,6 +979,8 @@ type blockFieldSpec struct { var blockFieldSpecs = [...]blockFieldSpec{ {BlkSeed, StackBytes, randomnessVersion}, {BlkTimestamp, StackUint64, randomnessVersion}, + {BlkProposer, StackAddress, 10}, + {BlkFeesCollected, StackUint64, 10}, } func blockFieldSpecByField(r BlockField) (blockFieldSpec, bool) { diff --git a/data/transactions/logic/fields_string.go b/data/transactions/logic/fields_string.go index 7d3c2b42f2..2bf79d7a82 100644 --- a/data/transactions/logic/fields_string.go +++ b/data/transactions/logic/fields_string.go @@ -351,12 +351,14 @@ func _() { var x [1]struct{} _ = x[BlkSeed-0] _ = x[BlkTimestamp-1] - _ = x[invalidBlockField-2] + _ = x[BlkProposer-2] + _ = x[BlkFeesCollected-3] + _ = x[invalidBlockField-4] } -const _BlockField_name = "BlkSeedBlkTimestampinvalidBlockField" +const _BlockField_name = "BlkSeedBlkTimestampBlkProposerBlkFeesCollectedinvalidBlockField" -var _BlockField_index = [...]uint8{0, 7, 19, 36} +var _BlockField_index = [...]uint8{0, 7, 19, 30, 46, 63} func (i BlockField) String() string { if i < 0 || i >= BlockField(len(_BlockField_index)-1) { diff --git a/data/transactions/logic/langspec_v10.json b/data/transactions/logic/langspec_v10.json index 7ee54fb98d..daaa484a73 100644 --- a/data/transactions/logic/langspec_v10.json +++ b/data/transactions/logic/langspec_v10.json @@ -4623,10 +4623,14 @@ "Size": 2, "ArgEnum": [ "BlkSeed", - "BlkTimestamp" + "BlkTimestamp", + "BlkProposer", + "BlkFeesCollected" ], "ArgEnumTypes": [ "[]byte", + "uint64", + "address", "uint64" ], "DocCost": "1", diff --git a/data/transactions/logic/teal.tmLanguage.json b/data/transactions/logic/teal.tmLanguage.json index 56cf7b5dc8..a8f72ea280 100644 --- a/data/transactions/logic/teal.tmLanguage.json +++ b/data/transactions/logic/teal.tmLanguage.json @@ -112,7 +112,7 @@ }, { "name": "variable.parameter.teal", - "match": "\\b(unknown|pay|keyreg|acfg|axfer|afrz|appl|NoOp|OptIn|CloseOut|ClearState|UpdateApplication|DeleteApplication|Secp256k1|Secp256r1|Sender|Fee|FirstValid|FirstValidTime|LastValid|Note|Lease|Receiver|Amount|CloseRemainderTo|VotePK|SelectionPK|VoteFirst|VoteLast|VoteKeyDilution|Type|TypeEnum|XferAsset|AssetAmount|AssetSender|AssetReceiver|AssetCloseTo|GroupIndex|TxID|ApplicationID|OnCompletion|NumAppArgs|NumAccounts|ApprovalProgram|ClearStateProgram|RekeyTo|ConfigAsset|ConfigAssetTotal|ConfigAssetDecimals|ConfigAssetDefaultFrozen|ConfigAssetUnitName|ConfigAssetName|ConfigAssetURL|ConfigAssetMetadataHash|ConfigAssetManager|ConfigAssetReserve|ConfigAssetFreeze|ConfigAssetClawback|FreezeAsset|FreezeAssetAccount|FreezeAssetFrozen|NumAssets|NumApplications|GlobalNumUint|GlobalNumByteSlice|LocalNumUint|LocalNumByteSlice|ExtraProgramPages|Nonparticipation|NumLogs|CreatedAssetID|CreatedApplicationID|LastLog|StateProofPK|NumApprovalProgramPages|NumClearStateProgramPages|MinTxnFee|MinBalance|MaxTxnLife|ZeroAddress|GroupSize|LogicSigVersion|Round|LatestTimestamp|CurrentApplicationID|CreatorAddress|CurrentApplicationAddress|GroupID|OpcodeBudget|CallerApplicationID|CallerApplicationAddress|AssetCreateMinBalance|AssetOptInMinBalance|ApplicationArgs|Accounts|Assets|Applications|Logs|ApprovalProgramPages|ClearStateProgramPages|URLEncoding|StdEncoding|JSONString|JSONUint64|JSONObject|AssetBalance|AssetFrozen|AssetTotal|AssetDecimals|AssetDefaultFrozen|AssetUnitName|AssetName|AssetURL|AssetMetadataHash|AssetManager|AssetReserve|AssetFreeze|AssetClawback|AssetCreator|AppApprovalProgram|AppClearStateProgram|AppGlobalNumUint|AppGlobalNumByteSlice|AppLocalNumUint|AppLocalNumByteSlice|AppExtraProgramPages|AppCreator|AppAddress|AcctBalance|AcctMinBalance|AcctAuthAddr|AcctTotalNumUint|AcctTotalNumByteSlice|AcctTotalExtraAppPages|AcctTotalAppsCreated|AcctTotalAppsOptedIn|AcctTotalAssetsCreated|AcctTotalAssets|AcctTotalBoxes|AcctTotalBoxBytes|VrfAlgorand|BlkSeed|BlkTimestamp|BN254g1|BN254g2|BLS12_381g1|BLS12_381g2)\\b" + "match": "\\b(unknown|pay|keyreg|acfg|axfer|afrz|appl|NoOp|OptIn|CloseOut|ClearState|UpdateApplication|DeleteApplication|Secp256k1|Secp256r1|Sender|Fee|FirstValid|FirstValidTime|LastValid|Note|Lease|Receiver|Amount|CloseRemainderTo|VotePK|SelectionPK|VoteFirst|VoteLast|VoteKeyDilution|Type|TypeEnum|XferAsset|AssetAmount|AssetSender|AssetReceiver|AssetCloseTo|GroupIndex|TxID|ApplicationID|OnCompletion|NumAppArgs|NumAccounts|ApprovalProgram|ClearStateProgram|RekeyTo|ConfigAsset|ConfigAssetTotal|ConfigAssetDecimals|ConfigAssetDefaultFrozen|ConfigAssetUnitName|ConfigAssetName|ConfigAssetURL|ConfigAssetMetadataHash|ConfigAssetManager|ConfigAssetReserve|ConfigAssetFreeze|ConfigAssetClawback|FreezeAsset|FreezeAssetAccount|FreezeAssetFrozen|NumAssets|NumApplications|GlobalNumUint|GlobalNumByteSlice|LocalNumUint|LocalNumByteSlice|ExtraProgramPages|Nonparticipation|NumLogs|CreatedAssetID|CreatedApplicationID|LastLog|StateProofPK|NumApprovalProgramPages|NumClearStateProgramPages|MinTxnFee|MinBalance|MaxTxnLife|ZeroAddress|GroupSize|LogicSigVersion|Round|LatestTimestamp|CurrentApplicationID|CreatorAddress|CurrentApplicationAddress|GroupID|OpcodeBudget|CallerApplicationID|CallerApplicationAddress|AssetCreateMinBalance|AssetOptInMinBalance|ApplicationArgs|Accounts|Assets|Applications|Logs|ApprovalProgramPages|ClearStateProgramPages|URLEncoding|StdEncoding|JSONString|JSONUint64|JSONObject|AssetBalance|AssetFrozen|AssetTotal|AssetDecimals|AssetDefaultFrozen|AssetUnitName|AssetName|AssetURL|AssetMetadataHash|AssetManager|AssetReserve|AssetFreeze|AssetClawback|AssetCreator|AppApprovalProgram|AppClearStateProgram|AppGlobalNumUint|AppGlobalNumByteSlice|AppLocalNumUint|AppLocalNumByteSlice|AppExtraProgramPages|AppCreator|AppAddress|AcctBalance|AcctMinBalance|AcctAuthAddr|AcctTotalNumUint|AcctTotalNumByteSlice|AcctTotalExtraAppPages|AcctTotalAppsCreated|AcctTotalAppsOptedIn|AcctTotalAssetsCreated|AcctTotalAssets|AcctTotalBoxes|AcctTotalBoxBytes|VrfAlgorand|BlkSeed|BlkTimestamp|BlkProposer|BlkFeesCollected|BN254g1|BN254g2|BLS12_381g1|BLS12_381g2)\\b" } ] }, diff --git a/data/transactions/payment.go b/data/transactions/payment.go index fee9c395ee..62f3e8ca6a 100644 --- a/data/transactions/payment.go +++ b/data/transactions/payment.go @@ -42,8 +42,11 @@ func (payment PaymentTxnFields) checkSpender(header Header, spec SpecialAddresse return fmt.Errorf("transaction cannot close account to its sender %v", header.Sender) } - // the FeeSink account may only spend to the IncentivePool + // the FeeSink account may only spend to the IncentivePool (not at all, if EnableMining) if header.Sender == spec.FeeSink { + if proto.EnableMining { + return fmt.Errorf("cannot spend from fee sink address %v", header.Sender) + } if payment.Receiver != spec.RewardsPool { return fmt.Errorf("cannot spend from fee sink's address %v to non incentive pool address %v", header.Sender, payment.Receiver) } diff --git a/data/transactions/transaction_test.go b/data/transactions/transaction_test.go index 0f3cf18258..77d8feabb2 100644 --- a/data/transactions/transaction_test.go +++ b/data/transactions/transaction_test.go @@ -101,13 +101,13 @@ func TestGoOnlineGoNonparticipatingContradiction(t *testing.T) { tx.KeyregTxnFields = KeyregTxnFields{ VotePK: v.OneTimeSignatureVerifier, SelectionPK: vrf.PK, + VoteKeyDilution: 1, Nonparticipation: true, } // this tx tries to both register keys to go online, and mark an account as non-participating. // it is not well-formed. - feeSink := basics.Address{0x7, 0xda, 0xcb, 0x4b, 0x6d, 0x9e, 0xd1, 0x41, 0xb1, 0x75, 0x76, 0xbd, 0x45, 0x9a, 0xe6, 0x42, 0x1d, 0x48, 0x6d, 0xa3, 0xd4, 0xef, 0x22, 0x47, 0xc4, 0x9, 0xa3, 0x96, 0xb8, 0x2e, 0xa2, 0x21} - err = tx.WellFormed(SpecialAddresses{FeeSink: feeSink}, config.Consensus[protocol.ConsensusCurrentVersion]) - require.Error(t, err) + err = tx.WellFormed(SpecialAddresses{}, config.Consensus[protocol.ConsensusCurrentVersion]) + require.ErrorContains(t, err, "go online, but vote last is set to zero") } func TestGoNonparticipatingWellFormed(t *testing.T) { @@ -125,19 +125,17 @@ func TestGoNonparticipatingWellFormed(t *testing.T) { } // this tx is well-formed - feeSink := basics.Address{0x7, 0xda, 0xcb, 0x4b, 0x6d, 0x9e, 0xd1, 0x41, 0xb1, 0x75, 0x76, 0xbd, 0x45, 0x9a, 0xe6, 0x42, 0x1d, 0x48, 0x6d, 0xa3, 0xd4, 0xef, 0x22, 0x47, 0xc4, 0x9, 0xa3, 0x96, 0xb8, 0x2e, 0xa2, 0x21} - err = tx.WellFormed(SpecialAddresses{FeeSink: feeSink}, curProto) + err = tx.WellFormed(SpecialAddresses{}, curProto) require.NoError(t, err) // but it should stop being well-formed if the protocol does not support it curProto.SupportBecomeNonParticipatingTransactions = false - err = tx.WellFormed(SpecialAddresses{FeeSink: feeSink}, curProto) - require.Error(t, err) + err = tx.WellFormed(SpecialAddresses{}, curProto) + require.ErrorContains(t, err, "mark an account as nonparticipating, but") } func TestAppCallCreateWellFormed(t *testing.T) { partitiontest.PartitionTest(t) - feeSink := basics.Address{0x7, 0xda, 0xcb, 0x4b, 0x6d, 0x9e, 0xd1, 0x41, 0xb1, 0x75, 0x76, 0xbd, 0x45, 0x9a, 0xe6, 0x42, 0x1d, 0x48, 0x6d, 0xa3, 0xd4, 0xef, 0x22, 0x47, 0xc4, 0x9, 0xa3, 0x96, 0xb8, 0x2e, 0xa2, 0x21} curProto := config.Consensus[protocol.ConsensusCurrentVersion] futureProto := config.Consensus[protocol.ConsensusFuture] addr1, err := basics.UnmarshalChecksumAddress("NDQCJNNY5WWWFLP4GFZ7MEF2QJSMZYK6OWIV2AQ7OMAVLEFCGGRHFPKJJA") @@ -253,7 +251,7 @@ func TestAppCallCreateWellFormed(t *testing.T) { } for i, usecase := range usecases { t.Run(fmt.Sprintf("i=%d", i), func(t *testing.T) { - err := usecase.tx.WellFormed(SpecialAddresses{FeeSink: feeSink}, usecase.proto) + err := usecase.tx.WellFormed(SpecialAddresses{}, usecase.proto) if usecase.expectedError != "" { require.Error(t, err) require.Contains(t, err.Error(), usecase.expectedError) @@ -267,8 +265,6 @@ func TestAppCallCreateWellFormed(t *testing.T) { func TestWellFormedErrors(t *testing.T) { partitiontest.PartitionTest(t) - feeSink := basics.Address{0x7, 0xda, 0xcb, 0x4b, 0x6d, 0x9e, 0xd1, 0x41, 0xb1, 0x75, 0x76, 0xbd, 0x45, 0x9a, 0xe6, 0x42, 0x1d, 0x48, 0x6d, 0xa3, 0xd4, 0xef, 0x22, 0x47, 0xc4, 0x9, 0xa3, 0x96, 0xb8, 0x2e, 0xa2, 0x21} - specialAddr := SpecialAddresses{FeeSink: feeSink} curProto := config.Consensus[protocol.ConsensusCurrentVersion] futureProto := config.Consensus[protocol.ConsensusFuture] protoV27 := config.Consensus[protocol.ConsensusV27] @@ -595,7 +591,7 @@ func TestWellFormedErrors(t *testing.T) { }, } for _, usecase := range usecases { - err := usecase.tx.WellFormed(specialAddr, usecase.proto) + err := usecase.tx.WellFormed(SpecialAddresses{}, usecase.proto) require.Equal(t, usecase.expectedError, err) } } @@ -632,14 +628,12 @@ func TestWellFormedKeyRegistrationTx(t *testing.T) { tx := generateDummyGoNonparticpatingTransaction(addr) curProto := config.Consensus[protocol.ConsensusCurrentVersion] - feeSink := basics.Address{0x7, 0xda, 0xcb, 0x4b, 0x6d, 0x9e, 0xd1, 0x41, 0xb1, 0x75, 0x76, 0xbd, 0x45, 0x9a, 0xe6, 0x42, 0x1d, 0x48, 0x6d, 0xa3, 0xd4, 0xef, 0x22, 0x47, 0xc4, 0x9, 0xa3, 0x96, 0xb8, 0x2e, 0xa2, 0x21} - spec := SpecialAddresses{FeeSink: feeSink} if !curProto.SupportBecomeNonParticipatingTransactions { t.Skipf("Skipping rest of test because current protocol version %v does not support become-nonparticipating transactions", protocol.ConsensusCurrentVersion) } // this tx is well-formed - err = tx.WellFormed(spec, curProto) + err = tx.WellFormed(SpecialAddresses{}, curProto) require.NoError(t, err) type keyRegTestCase struct { @@ -677,7 +671,7 @@ func TestWellFormedKeyRegistrationTx(t *testing.T) { curProto.EnableKeyregCoherencyCheck = testCase.enableKeyregCoherencyCheck curProto.EnableStateProofKeyregCheck = testCase.enableStateProofKeyregCheck curProto.MaxKeyregValidPeriod = maxValidPeriod // TODO: remove this when MaxKeyregValidPeriod is in CurrentVersion - return tx.WellFormed(spec, curProto) + return tx.WellFormed(SpecialAddresses{}, curProto) } if *generateFlag == true { diff --git a/ledger/apply/asset_test.go b/ledger/apply/asset_test.go index 802c692c82..c096f8aca8 100644 --- a/ledger/apply/asset_test.go +++ b/ledger/apply/asset_test.go @@ -90,7 +90,7 @@ func TestAssetTransfer(t *testing.T) { } var ad transactions.ApplyData - err := AssetTransfer(tx.AssetTransferTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, &ad) + err := AssetTransfer(tx.AssetTransferTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, &ad) require.NoError(t, err) if config.Consensus[protocol.ConsensusCurrentVersion].EnableAssetCloseAmount { diff --git a/ledger/apply/keyreg_test.go b/ledger/apply/keyreg_test.go index 7589b9fb1f..bb04e23f90 100644 --- a/ledger/apply/keyreg_test.go +++ b/ledger/apply/keyreg_test.go @@ -136,20 +136,20 @@ func TestKeyregApply(t *testing.T) { // Going from offline to online should be okay mockBal.addrs[src] = basics.AccountData{Status: basics.Offline} - err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0)) + err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0)) require.NoError(t, err) // Going from online to nonparticipatory should be okay, if the protocol supports that if mockBal.ConsensusParams().SupportBecomeNonParticipatingTransactions { tx.KeyregTxnFields = transactions.KeyregTxnFields{} tx.KeyregTxnFields.Nonparticipation = true - err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0)) + err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0)) require.NoError(t, err) // Nonparticipatory accounts should not be able to change status mockBal.addrs[src] = basics.AccountData{Status: basics.NotParticipating} - err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0)) - require.Error(t, err) + err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0)) + require.ErrorContains(t, err, "cannot change online/offline status of non-participating account") } mockBal.version = "future" @@ -171,25 +171,25 @@ func TestKeyregApply(t *testing.T) { }, } mockBal.addrs[src] = basics.AccountData{Status: basics.Offline} - err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(999)) + err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(999)) require.NoError(t, err) - err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(1000)) + err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(1000)) require.Equal(t, errKeyregGoingOnlineExpiredParticipationKey, err) - err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(1001)) + err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(1001)) require.Equal(t, errKeyregGoingOnlineExpiredParticipationKey, err) tx.KeyregTxnFields.VoteFirst = basics.Round(1100) tx.KeyregTxnFields.VoteLast = basics.Round(1200) - err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(1098)) + err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(1098)) require.Equal(t, errKeyregGoingOnlineFirstVotingInFuture, err) - err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(1099)) + err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(1099)) require.NoError(t, err) - err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(1100)) + err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(1100)) require.NoError(t, err) testStateProofPKBeingStored(t, tx, mockBal) @@ -197,7 +197,7 @@ func TestKeyregApply(t *testing.T) { } func testStateProofPKBeingStored(t *testing.T, tx transactions.Transaction, mockBal *keyregTestBalances) { - err := Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(1100)) + err := Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(1100)) require.NoError(t, err) // expects no error with empty keyRegistration attempt rec, err := mockBal.Get(tx.Header.Sender, false) @@ -215,7 +215,7 @@ func TestStateProofPKKeyReg(t *testing.T) { tx := createTestTxn(t, src, secretParticipation, vrfSecrets) mockBal := makeMockBalances(protocol.ConsensusV30) - err := Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0)) + err := Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0)) require.NoError(t, err) acct, err := mockBal.Get(tx.Src(), false) @@ -223,7 +223,7 @@ func TestStateProofPKKeyReg(t *testing.T) { require.True(t, acct.StateProofID.IsEmpty()) mockBal = makeMockBalances(protocol.ConsensusCurrentVersion) - err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0)) + err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0)) require.NoError(t, err) acct, err = mockBal.Get(tx.Src(), false) @@ -232,7 +232,7 @@ func TestStateProofPKKeyReg(t *testing.T) { // go offline in current consensus version: StateProofID should be empty emptyKeyreg := transactions.KeyregTxnFields{} - err = Keyreg(emptyKeyreg, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0)) + err = Keyreg(emptyKeyreg, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0)) require.NoError(t, err) acct, err = mockBal.Get(tx.Src(), false) @@ -241,7 +241,7 @@ func TestStateProofPKKeyReg(t *testing.T) { // run same test using vFuture mockBal = makeMockBalances(protocol.ConsensusFuture) - err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0)) + err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0)) require.NoError(t, err) acct, err = mockBal.Get(tx.Src(), false) @@ -249,7 +249,7 @@ func TestStateProofPKKeyReg(t *testing.T) { require.False(t, acct.StateProofID.IsEmpty()) // go offline in vFuture: StateProofID should be empty - err = Keyreg(emptyKeyreg, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0)) + err = Keyreg(emptyKeyreg, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0)) require.NoError(t, err) acct, err = mockBal.Get(tx.Src(), false) diff --git a/ledger/apply/payment_test.go b/ledger/apply/payment_test.go index db82869e23..59b28ad899 100644 --- a/ledger/apply/payment_test.go +++ b/ledger/apply/payment_test.go @@ -104,7 +104,7 @@ func TestPaymentApply(t *testing.T) { }, } var ad transactions.ApplyData - err := Payment(tx.PaymentTxnFields, tx.Header, mockBalV0, transactions.SpecialAddresses{FeeSink: feeSink}, &ad) + err := Payment(tx.PaymentTxnFields, tx.Header, mockBalV0, transactions.SpecialAddresses{}, &ad) require.NoError(t, err) } diff --git a/ledger/apptxn_test.go b/ledger/apptxn_test.go index 982c9f01b2..cbdcb1791f 100644 --- a/ledger/apptxn_test.go +++ b/ledger/apptxn_test.go @@ -58,6 +58,10 @@ func TestPayAction(t *testing.T) { itxn_submit `)) + // We're going to test some mining effects here too, so that we have an inner transaction example. + // Do a block with no txns, so the fee sink balance as we start the next block is stable + dl.fullBlock() + payout1 := txntest.Txn{ Type: "appl", Sender: addrs[1], @@ -65,7 +69,40 @@ func TestPayAction(t *testing.T) { Accounts: []basics.Address{addrs[1]}, // pay self } - dl.fullBlock(&payout1) + proposer := addrs[7] + presink := micros(dl.t, dl.generator, genBalances.FeeSink) + preprop := micros(dl.t, dl.generator, proposer) + dl.beginBlock() + dl.txns(&payout1) + vb := dl.endBlock(proposer) + // First MiningPct > 0 + if ver >= 39 { + require.True(t, dl.generator.GenesisProto().EnableMining) + require.EqualValues(t, proposer, vb.Block().BlockHeader.Proposer) + require.EqualValues(t, 2000, vb.Block().BlockHeader.FeesCollected.Raw) + } else { + require.False(t, dl.generator.GenesisProto().EnableMining) + require.Zero(t, vb.Block().BlockHeader.Proposer) + require.Zero(t, vb.Block().BlockHeader.FeesCollected) + } + + postsink := micros(dl.t, dl.generator, genBalances.FeeSink) + postprop := micros(dl.t, dl.generator, proposer) + + // Mining checks + require.EqualValues(t, 0, postprop-preprop) // mining not moved yet + require.EqualValues(t, 2000, postsink-presink) + + dl.fullBlock() + postsink = micros(dl.t, dl.generator, genBalances.FeeSink) + postprop = micros(dl.t, dl.generator, proposer) + // First MiningPct > 0 + if ver >= 39 { + require.EqualValues(t, 500, postsink-presink) // based on 75% in config/consensus.go + require.EqualValues(t, 1500, postprop-preprop) + } else { + require.EqualValues(t, 2000, postsink-presink) // no mining yet + } ad0 := micros(dl.t, dl.generator, addrs[0]) ad1 := micros(dl.t, dl.generator, addrs[1]) @@ -90,7 +127,7 @@ func TestPayAction(t *testing.T) { ApplicationID: ai, Accounts: []basics.Address{addrs[2]}, // pay other } - vb := dl.fullBlock(&payout2) + vb = dl.fullBlock(&payout2) // confirm that modifiedAccounts can see account in inner txn deltas := vb.Delta() diff --git a/ledger/double_test.go b/ledger/double_test.go index 16d38e7681..419a8da55f 100644 --- a/ledger/double_test.go +++ b/ledger/double_test.go @@ -48,6 +48,9 @@ type DoubleLedger struct { validator *Ledger eval *eval.BlockEvaluator + + // proposer is the default proposer unless one is supplied to endBlock. + proposer basics.Address } func (dl DoubleLedger) Close() { @@ -59,7 +62,7 @@ func (dl DoubleLedger) Close() { func NewDoubleLedger(t testing.TB, balances bookkeeping.GenesisBalances, cv protocol.ConsensusVersion, cfg config.Local, opts ...simpleLedgerOption) DoubleLedger { g := newSimpleLedgerWithConsensusVersion(t, balances, cv, cfg, opts...) v := newSimpleLedgerFull(t, balances, cv, g.GenesisHash(), cfg, opts...) - return DoubleLedger{t, g, v, nil} + return DoubleLedger{t, g, v, nil, balances.FeeSink} // FeeSink as proposer will make old code work as expected } func (dl *DoubleLedger) beginBlock() *eval.BlockEvaluator { @@ -134,8 +137,12 @@ func (dl *DoubleLedger) fullBlock(txs ...*txntest.Txn) *ledgercore.ValidatedBloc return dl.endBlock() } -func (dl *DoubleLedger) endBlock() *ledgercore.ValidatedBlock { - vb := endBlock(dl.t, dl.generator, dl.eval) +func (dl *DoubleLedger) endBlock(proposer ...basics.Address) *ledgercore.ValidatedBlock { + prp := dl.proposer + if len(proposer) > 0 { + prp = proposer[0] + } + vb := endBlock(dl.t, dl.generator, dl.eval, prp) if dl.validator != nil { // Allows setting to nil while debugging, to simplify checkBlock(dl.t, dl.validator, vb) } @@ -195,7 +202,7 @@ func checkBlock(t testing.TB, checkLedger *Ledger, vb *ledgercore.ValidatedBlock require.NoError(t, err, "%+v", reconstituted.Payset) } check.SetGenerateForTesting(true) - cb := endBlock(t, checkLedger, check) + cb := endBlock(t, checkLedger, check, vb.Block().Proposer) check.SetGenerateForTesting(false) require.Equal(t, vb.Block(), cb.Block()) diff --git a/ledger/eval/applications.go b/ledger/eval/applications.go index 5419bc9525..36d0734ec2 100644 --- a/ledger/eval/applications.go +++ b/ledger/eval/applications.go @@ -290,8 +290,7 @@ func (cs *roundCowState) DelBox(appIdx basics.AppIndex, key string, appAddr basi func (cs *roundCowState) Perform(gi int, ep *logic.EvalParams) error { txn := &ep.TxnGroup[gi] - // move fee to pool - err := cs.Move(txn.Txn.Sender, ep.Specials.FeeSink, txn.Txn.Fee, &txn.ApplyData.SenderRewards, nil) + err := cs.takeFee(&txn.Txn, &txn.ApplyData.SenderRewards, ep) if err != nil { return err } diff --git a/ledger/eval/cow.go b/ledger/eval/cow.go index d797a4a560..1d48d8abf7 100644 --- a/ledger/eval/cow.go +++ b/ledger/eval/cow.go @@ -93,6 +93,8 @@ type roundCowState struct { // prevTotals contains the accounts totals for the previous round. It's being used to calculate the totals for the new round // so that we could perform the validation test on these to ensure the block evaluator generate a valid changeset. prevTotals ledgercore.AccountTotals + + feesCollected basics.MicroAlgos } var childPool = sync.Pool{ @@ -293,6 +295,8 @@ func (cb *roundCowState) commitToParent() { cb.commitParent.mods.Txids[txid] = ledgercore.IncludedTransactions{LastValid: incTxn.LastValid, Intra: commitParentBaseIdx + incTxn.Intra} } cb.commitParent.txnCount += cb.txnCount + // no overflow because of 10B algo cap + cb.commitParent.feesCollected, _ = basics.OAddA(cb.commitParent.feesCollected, cb.feesCollected) for txl, expires := range cb.mods.Txleases { cb.commitParent.mods.AddTxLease(txl, expires) @@ -336,6 +340,7 @@ func (cb *roundCowState) reset() { cb.compatibilityMode = false maps.Clear(cb.compatibilityGetKeyCache) cb.prevTotals = ledgercore.AccountTotals{} + cb.feesCollected = basics.MicroAlgos{} } // recycle resets the roundcowstate and returns it to the sync.Pool diff --git a/ledger/eval/cow_test.go b/ledger/eval/cow_test.go index 225b037997..eb4bc5e38b 100644 --- a/ledger/eval/cow_test.go +++ b/ledger/eval/cow_test.go @@ -281,6 +281,7 @@ func TestCowChildReflect(t *testing.T) { "compatibilityMode": {}, "compatibilityGetKeyCache": {}, "prevTotals": {}, + "feesCollected": {}, } cow := roundCowState{} @@ -288,7 +289,7 @@ func TestCowChildReflect(t *testing.T) { st := v.Type() for i := 0; i < v.NumField(); i++ { reflectedCowName := st.Field(i).Name - require.Containsf(t, cowFieldNames, reflectedCowName, "new field:\"%v\" added to roundCowState, please update roundCowState.reset() to handle it before fixing the test", reflectedCowName) + require.Containsf(t, cowFieldNames, reflectedCowName, "new field:\"%v\" added to roundCowState, please update roundCowState.reset() to handle it before fixing this test", reflectedCowName) } } diff --git a/ledger/eval/eval.go b/ledger/eval/eval.go index 66b1133457..c8450886f0 100644 --- a/ledger/eval/eval.go +++ b/ledger/eval/eval.go @@ -783,6 +783,13 @@ func StartEvaluator(l LedgerForEvaluator, hdr bookkeeping.BlockHeader, evalOpts return nil, fmt.Errorf("overflowed subtracting rewards for block %v", hdr.Round) } + miningIncentive, _ := basics.NewPercent(proto.MiningPercent).DivvyAlgos(prevHeader.FeesCollected) + err = eval.state.Move(prevHeader.FeeSink, prevHeader.Proposer, miningIncentive, nil, nil) + if err != nil { + // This should be impossible. The fees were just collected, and the FeeSink cannot be emptied. + return nil, fmt.Errorf("unable to Move mining incentive") + } + if eval.Tracer != nil { eval.Tracer.BeforeBlock(&eval.block.BlockHeader) } @@ -1160,12 +1167,27 @@ func (eval *BlockEvaluator) transaction(txn transactions.SignedTxn, evalParams * return nil } +func (cs *roundCowState) takeFee(tx *transactions.Transaction, senderRewards *basics.MicroAlgos, ep *logic.EvalParams) error { + err := cs.Move(tx.Sender, ep.Specials.FeeSink, tx.Fee, senderRewards, nil) + if err != nil { + return err + } + // transactions from FeeSink should be exceedingly rare. But we can't count + // them in feesCollected because there are no net algos added to the Sink + if tx.Sender == ep.Specials.FeeSink { + return nil + } + // overflow impossible, since these sum the fees actually paid. 10B algo limit + cs.feesCollected, _ = basics.OAddA(cs.feesCollected, tx.Fee) + return nil + +} + // applyTransaction changes the balances according to this transaction. func (eval *BlockEvaluator) applyTransaction(tx transactions.Transaction, cow *roundCowState, evalParams *logic.EvalParams, gi int, ctr uint64) (ad transactions.ApplyData, err error) { params := cow.ConsensusParams() - // move fee to pool - err = cow.Move(tx.Sender, eval.specials.FeeSink, tx.Fee, &ad.SenderRewards, nil) + err = cow.takeFee(&tx, &ad.SenderRewards, evalParams) if err != nil { return } @@ -1267,6 +1289,10 @@ func (eval *BlockEvaluator) endOfBlock() error { eval.block.TxnCounter = 0 } + if eval.proto.EnableMining { + eval.block.FeesCollected = eval.state.feesCollected + } + eval.generateExpiredOnlineAccountsList() if eval.proto.StateProofInterval > 0 { @@ -1311,6 +1337,14 @@ func (eval *BlockEvaluator) endOfBlock() error { return fmt.Errorf("txn count wrong: %d != %d", eval.block.TxnCounter, expectedTxnCount) } + var expectedFeesCollected basics.MicroAlgos + if eval.proto.EnableMining { + expectedFeesCollected = eval.state.feesCollected + } + if eval.block.FeesCollected != expectedFeesCollected { + return fmt.Errorf("fees collected wrong: %v != %v", eval.block.FeesCollected, expectedFeesCollected) + } + expectedVoters, expectedVotersWeight, err2 := eval.stateProofVotersAndTotal() if err2 != nil { return err2 diff --git a/ledger/eval/prefetcher/prefetcher_alignment_test.go b/ledger/eval/prefetcher/prefetcher_alignment_test.go index 81ce168d43..c64ae6d3db 100644 --- a/ledger/eval/prefetcher/prefetcher_alignment_test.go +++ b/ledger/eval/prefetcher/prefetcher_alignment_test.go @@ -58,6 +58,10 @@ func rewardsPool() basics.Address { return makeAddress(101) } +func proposer() basics.Address { + return basics.Address{} +} + func genesisBlock() (bookkeeping.Block, error) { block, err := bookkeeping.MakeGenesisBlock( proto, @@ -261,6 +265,18 @@ type ledgerData struct { Creators map[creatable]struct{} } +// pretend adds the `before` addresses to the Accounts. It "pretends" that the +// addresses were prefetched, so we can get agreement with what was actually +// requested. We do this to include two addresses that are going to end up +// requested *before* prefetch is even attempted. So there's no point in +// PrefetchAccounts being modified to return them, they have been "prefetched" +// simply by accessing them. +func (ld *ledgerData) pretend(before ...basics.Address) { + for _, a := range before { + ld.Accounts[a] = struct{}{} + } +} + func prefetch(t *testing.T, l prefetcher.Ledger, txn transactions.Transaction) ledgerData { group := makeGroupFromTxn(txn) @@ -361,7 +377,7 @@ func TestEvaluatorPrefetcherAlignmentPayment(t *testing.T) { requested, prefetched := run(t, l, txn) - prefetched.Accounts[rewardsPool()] = struct{}{} + prefetched.pretend(rewardsPool(), proposer()) require.Equal(t, requested, prefetched) } @@ -393,7 +409,7 @@ func TestEvaluatorPrefetcherAlignmentCreateAsset(t *testing.T) { requested, prefetched := run(t, l, txn) - prefetched.Accounts[rewardsPool()] = struct{}{} + prefetched.pretend(rewardsPool(), proposer()) // Only one (non-existing) asset is requested. Ignore it. require.Len(t, requested.Assets, 1) require.Len(t, requested.Assets[makeAddress(1)], 1) @@ -449,7 +465,7 @@ func TestEvaluatorPrefetcherAlignmentReconfigAsset(t *testing.T) { requested, prefetched := run(t, l, txn) - prefetched.Accounts[rewardsPool()] = struct{}{} + prefetched.pretend(rewardsPool(), proposer()) require.Equal(t, requested, prefetched) } @@ -504,7 +520,7 @@ func TestEvaluatorPrefetcherAlignmentAssetOptIn(t *testing.T) { requested, prefetched := run(t, l, txn) - prefetched.Accounts[rewardsPool()] = struct{}{} + prefetched.pretend(rewardsPool(), proposer()) require.Equal(t, requested, prefetched) } @@ -570,7 +586,7 @@ func TestEvaluatorPrefetcherAlignmentAssetOptInCloseTo(t *testing.T) { requested, prefetched := run(t, l, txn) - prefetched.Accounts[rewardsPool()] = struct{}{} + prefetched.pretend(rewardsPool(), proposer()) require.Equal(t, requested, prefetched) } @@ -641,7 +657,7 @@ func TestEvaluatorPrefetcherAlignmentAssetTransfer(t *testing.T) { requested, prefetched := run(t, l, txn) - prefetched.Accounts[rewardsPool()] = struct{}{} + prefetched.pretend(rewardsPool(), proposer()) require.Equal(t, requested, prefetched) // zero transfer of any asset @@ -660,7 +676,7 @@ func TestEvaluatorPrefetcherAlignmentAssetTransfer(t *testing.T) { requested, prefetched = run(t, l, txn) - prefetched.Accounts[rewardsPool()] = struct{}{} + prefetched.pretend(rewardsPool(), proposer()) require.Equal(t, requested, prefetched) } @@ -741,7 +757,7 @@ func TestEvaluatorPrefetcherAlignmentAssetClawback(t *testing.T) { requested, prefetched := run(t, l, txn) - prefetched.Accounts[rewardsPool()] = struct{}{} + prefetched.pretend(rewardsPool(), proposer()) require.Equal(t, requested, prefetched) } @@ -811,7 +827,7 @@ func TestEvaluatorPrefetcherAlignmentAssetFreeze(t *testing.T) { requested, prefetched := run(t, l, txn) - prefetched.Accounts[rewardsPool()] = struct{}{} + prefetched.pretend(rewardsPool(), proposer()) require.Equal(t, requested, prefetched) } @@ -858,7 +874,7 @@ func TestEvaluatorPrefetcherAlignmentKeyreg(t *testing.T) { requested, prefetched := run(t, l, txn) - prefetched.Accounts[rewardsPool()] = struct{}{} + prefetched.pretend(rewardsPool(), proposer()) require.Equal(t, requested, prefetched) } @@ -895,7 +911,7 @@ func TestEvaluatorPrefetcherAlignmentCreateApplication(t *testing.T) { requested, prefetched := run(t, l, txn) - prefetched.Accounts[rewardsPool()] = struct{}{} + prefetched.pretend(rewardsPool(), proposer()) // Only one (non-existing) asset is requested. Ignore it. require.Len(t, requested.Apps, 1) require.Len(t, requested.Apps[makeAddress(1)], 1) @@ -953,7 +969,7 @@ func TestEvaluatorPrefetcherAlignmentDeleteApplication(t *testing.T) { requested, prefetched := run(t, l, txn) - prefetched.Accounts[rewardsPool()] = struct{}{} + prefetched.pretend(rewardsPool(), proposer()) require.Equal(t, requested, prefetched) } @@ -1011,7 +1027,7 @@ func TestEvaluatorPrefetcherAlignmentApplicationOptIn(t *testing.T) { requested, prefetched := run(t, l, txn) - prefetched.Accounts[rewardsPool()] = struct{}{} + prefetched.pretend(rewardsPool(), proposer()) require.Equal(t, requested, prefetched) } @@ -1075,7 +1091,7 @@ func TestEvaluatorPrefetcherAlignmentApplicationCloseOut(t *testing.T) { requested, prefetched := run(t, l, txn) - prefetched.Accounts[rewardsPool()] = struct{}{} + prefetched.pretend(rewardsPool(), proposer()) require.Equal(t, requested, prefetched) } @@ -1139,7 +1155,7 @@ func TestEvaluatorPrefetcherAlignmentApplicationClearState(t *testing.T) { requested, prefetched := run(t, l, txn) - prefetched.Accounts[rewardsPool()] = struct{}{} + prefetched.pretend(rewardsPool(), proposer()) require.Equal(t, requested, prefetched) } @@ -1203,7 +1219,7 @@ func TestEvaluatorPrefetcherAlignmentApplicationCallAccountsDeclaration(t *testi requested, prefetched := run(t, l, txn) - prefetched.Accounts[rewardsPool()] = struct{}{} + prefetched.pretend(rewardsPool(), proposer()) // Foreign accounts are not loaded, ensure they are not prefetched require.NotContains(t, prefetched.Accounts, makeAddress(5)) require.NotContains(t, prefetched.Accounts, makeAddress(3)) @@ -1271,7 +1287,7 @@ func TestEvaluatorPrefetcherAlignmentApplicationCallForeignAppsDeclaration(t *te requested, prefetched := run(t, l, txn) - prefetched.Accounts[rewardsPool()] = struct{}{} + prefetched.pretend(rewardsPool(), proposer()) // Foreign apps are not loaded, ensure they are not prefetched require.NotContains(t, prefetched.Creators, creatable{cindex: 6, ctype: basics.AppCreatable}) require.NotContains(t, prefetched.Creators, creatable{cindex: 8, ctype: basics.AppCreatable}) @@ -1338,7 +1354,7 @@ func TestEvaluatorPrefetcherAlignmentApplicationCallForeignAssetsDeclaration(t * requested, prefetched := run(t, l, txn) - prefetched.Accounts[rewardsPool()] = struct{}{} + prefetched.pretend(rewardsPool(), proposer()) // Foreign apps are not loaded, ensure they are not prefetched require.NotContains(t, prefetched.Creators, creatable{cindex: 6, ctype: basics.AssetCreatable}) require.NotContains(t, prefetched.Creators, creatable{cindex: 8, ctype: basics.AssetCreatable}) @@ -1385,6 +1401,6 @@ func TestEvaluatorPrefetcherAlignmentStateProof(t *testing.T) { requested, prefetched := run(t, l, txn) - prefetched.Accounts[rewardsPool()] = struct{}{} + prefetched.pretend(rewardsPool(), proposer()) require.Equal(t, requested, prefetched) } diff --git a/ledger/eval_simple_test.go b/ledger/eval_simple_test.go index 606ee4931d..86269cabd5 100644 --- a/ledger/eval_simple_test.go +++ b/ledger/eval_simple_test.go @@ -211,6 +211,67 @@ func TestBlockEvaluator(t *testing.T) { require.Equal(t, bal2new.MicroAlgos.Raw, bal2.MicroAlgos.Raw-minFee.Raw) } +// TestMiningFees ensures that the proper portion of tx fees go to the proposer, +// starting in v39. +func TestMiningFees(t *testing.T) { + partitiontest.PartitionTest(t) + t.Parallel() + + genBalances, addrs, _ := ledgertesting.NewTestGenesis() + // Mining begins in v39. Start checking in v38 to test that is unchanged. + ledgertesting.TestConsensusRange(t, 38, 0, func(t *testing.T, ver int, cv protocol.ConsensusVersion, cfg config.Local) { + dl := NewDoubleLedger(t, genBalances, cv, cfg) + defer dl.Close() + + dl.fullBlock() + + pay := txntest.Txn{ + Type: "pay", + Sender: addrs[1], + Receiver: addrs[2], + Amount: 100000, + } + + proposer := addrs[7] + presink := micros(dl.t, dl.generator, genBalances.FeeSink) + preprop := micros(dl.t, dl.generator, proposer) + dl.beginBlock() + dl.txns(&pay, pay.Args("again")) + vb := dl.endBlock(proposer) + + if ver >= 39 { + require.True(t, dl.generator.GenesisProto().EnableMining) // version sanity check + // new fields are in the header + require.EqualValues(t, proposer, vb.Block().BlockHeader.Proposer) + require.EqualValues(t, 2000, vb.Block().BlockHeader.FeesCollected.Raw) + } else { + require.False(t, dl.generator.GenesisProto().EnableMining) + // new fields are not in the header + require.Zero(t, vb.Block().BlockHeader.Proposer) + require.Zero(t, vb.Block().BlockHeader.FeesCollected) + } + + postsink := micros(dl.t, dl.generator, genBalances.FeeSink) + postprop := micros(dl.t, dl.generator, proposer) + + // At the end of the block, all fees are still in the sink. + require.EqualValues(t, 2000, postsink-presink) + require.EqualValues(t, 0, postprop-preprop) + + // Do the next block, which moves part of the fees to proposer + dl.fullBlock() + postsink = micros(dl.t, dl.generator, genBalances.FeeSink) + postprop = micros(dl.t, dl.generator, proposer) + + if ver >= 39 { + require.EqualValues(t, 500, postsink-presink) // based on 75% in config/consensus.go + require.EqualValues(t, 1500, postprop-preprop) + } else { + require.EqualValues(t, 2000, postsink-presink) // no mining yet + } + }) +} + // TestHoldingGet tests some of the corner cases for the asset_holding_get // opcode: the asset doesn't exist, the account doesn't exist, account not opted // in, vs it has none of the asset. This is tested here, even though it should diff --git a/ledger/ledger_test.go b/ledger/ledger_test.go index 19bb6a0796..602fc7f8b6 100644 --- a/ledger/ledger_test.go +++ b/ledger/ledger_test.go @@ -174,6 +174,9 @@ func (l *Ledger) appendUnvalidatedSignedTx(t *testing.T, initAccounts map[basics if proto.TxnCounter { blk.TxnCounter = blk.TxnCounter + 1 } + if proto.EnableMining { + blk.FeesCollected = stx.Txn.Fee + } blk.Payset = append(blk.Payset, txib) blk.TxnCommitments, err = blk.PaysetCommit() require.NoError(t, err) diff --git a/ledger/ledgercore/validatedBlock.go b/ledger/ledgercore/validatedBlock.go index 84d09e2a9a..ced5265635 100644 --- a/ledger/ledgercore/validatedBlock.go +++ b/ledger/ledgercore/validatedBlock.go @@ -17,6 +17,7 @@ package ledgercore import ( + "github.com/algorand/go-algorand/data/basics" "github.com/algorand/go-algorand/data/bookkeeping" "github.com/algorand/go-algorand/data/committee" ) @@ -39,11 +40,15 @@ func (vb ValidatedBlock) Delta() StateDelta { return vb.delta } -// WithSeed returns a copy of the ValidatedBlock with a modified seed. -func (vb ValidatedBlock) WithSeed(s committee.Seed) ValidatedBlock { +// WithSeed returns a copy of the ValidatedBlock with a modified seed and associated proposer +func (vb ValidatedBlock) WithSeed(s committee.Seed, proposer basics.Address) ValidatedBlock { newblock := vb.blk newblock.BlockHeader.Seed = s + if vb.blk.ConsensusProtocol().EnableMining { + newblock.BlockHeader.Proposer = proposer + } + return ValidatedBlock{ blk: newblock, delta: vb.delta, diff --git a/ledger/simple_test.go b/ledger/simple_test.go index 1f4c612902..efe81bfc87 100644 --- a/ledger/simple_test.go +++ b/ledger/simple_test.go @@ -26,6 +26,7 @@ import ( "github.com/algorand/go-algorand/crypto" "github.com/algorand/go-algorand/data/basics" "github.com/algorand/go-algorand/data/bookkeeping" + "github.com/algorand/go-algorand/data/committee" "github.com/algorand/go-algorand/data/transactions" "github.com/algorand/go-algorand/data/txntest" "github.com/algorand/go-algorand/ledger/eval" @@ -136,11 +137,20 @@ func txgroup(t testing.TB, ledger *Ledger, eval *eval.BlockEvaluator, txns ...*t return eval.TransactionGroup(transactions.WrapSignedTxnsWithAD(txgroup)) } -// endBlock completes the block being created, returns the ValidatedBlock for inspection -func endBlock(t testing.TB, ledger *Ledger, eval *eval.BlockEvaluator) *ledgercore.ValidatedBlock { - validatedBlock, err := eval.GenerateBlock() +// endBlock completes the block being created, returns the ValidatedBlock for +// inspection. Proposer is optional - if unset, blocks will be finished with +// ZeroAddress proposer. +func endBlock(t testing.TB, ledger *Ledger, eval *eval.BlockEvaluator, proposer ...basics.Address) *ledgercore.ValidatedBlock { + vb, err := eval.GenerateBlock() require.NoError(t, err) - err = ledger.AddValidatedBlock(*validatedBlock, agreement.Certificate{}) + + var prp basics.Address + if len(proposer) > 0 { + prp = proposer[0] + } + *vb = vb.WithSeed(committee.Seed{}, prp) + + err = ledger.AddValidatedBlock(*vb, agreement.Certificate{}) require.NoError(t, err) // `rndBQ` gives the latest known block round added to the ledger // we should wait until `rndBQ` block to be committed to blockQueue, @@ -152,7 +162,7 @@ func endBlock(t testing.TB, ledger *Ledger, eval *eval.BlockEvaluator) *ledgerco // then we return the result and continue the execution. rndBQ := ledger.Latest() ledger.WaitForCommit(rndBQ) - return validatedBlock + return vb } // main wraps up some TEAL source in a header and footer so that it is diff --git a/node/node.go b/node/node.go index 4c18ad1d51..63815f08eb 100644 --- a/node/node.go +++ b/node/node.go @@ -1271,8 +1271,8 @@ type validatedBlock struct { } // WithSeed satisfies the agreement.ValidatedBlock interface. -func (vb validatedBlock) WithSeed(s committee.Seed) agreement.ValidatedBlock { - lvb := vb.vb.WithSeed(s) +func (vb validatedBlock) WithSeed(s committee.Seed, proposer basics.Address) agreement.ValidatedBlock { + lvb := vb.vb.WithSeed(s, proposer) return validatedBlock{vb: &lvb} } diff --git a/protocol/tags.go b/protocol/tags.go index a9eb2a6bbc..11dbb55d4e 100644 --- a/protocol/tags.go +++ b/protocol/tags.go @@ -73,7 +73,7 @@ const PingReplyTagMaxSize = 8 // ProposalPayloadTagMaxSize is the maximum size of a ProposalPayloadTag message // This value is dominated by the MaxTxnBytesPerBlock -const ProposalPayloadTagMaxSize = 5247980 +const ProposalPayloadTagMaxSize = 5248065 // StateProofSigTagMaxSize is the maximum size of a StateProofSigTag message const StateProofSigTagMaxSize = 6378 diff --git a/test/scripts/e2e_client_runner.py b/test/scripts/e2e_client_runner.py index 7b425ef925..15a877e043 100755 --- a/test/scripts/e2e_client_runner.py +++ b/test/scripts/e2e_client_runner.py @@ -114,7 +114,7 @@ def _script_thread_inner(runset, scriptname, timeout): params = algod.suggested_params() round = params.first max_init_wait_rounds = 5 - txn = algosdk.transaction.PaymentTxn(sender=maxpubaddr, fee=params.min_fee, first=round, last=round+max_init_wait_rounds, gh=params.gh, receiver=addr, amt=1000000000000, flat_fee=True) + txn = algosdk.transaction.PaymentTxn(sender=maxpubaddr, fee=params.min_fee, first=round, last=round+max_init_wait_rounds, gh=params.gh, receiver=addr, amt=1_000_000_000_000, flat_fee=True) stxn = kmd.sign_transaction(pubw, '', txn) txid = algod.send_transaction(stxn) ptxinfo = None diff --git a/test/scripts/e2e_subs/goal/goal.py b/test/scripts/e2e_subs/goal/goal.py index d36241fd78..605f732eb7 100755 --- a/test/scripts/e2e_subs/goal/goal.py +++ b/test/scripts/e2e_subs/goal/goal.py @@ -229,19 +229,19 @@ def finish(self, tx, send): def keyreg(self, sender, votekey=None, selkey=None, votefst=None, votelst=None, votekd=None, send=None, **kwargs): - params = self.algod.suggested_params() + params = self.params(kwargs.pop("lifetime", 1000)) tx = txn.KeyregTxn(sender, params, votekey, selkey, votefst, votelst, votekd, **kwargs) return self.finish(tx, send) def pay(self, sender, receiver, amt: int, send=None, **kwargs): - params = self.algod.suggested_params() + params = self.params(kwargs.pop("lifetime", 1000)) tx = txn.PaymentTxn(sender, params, receiver, amt, **kwargs) return self.finish(tx, send) def acfg(self, sender, send=None, **kwargs): - params = self.algod.suggested_params() + params = self.params(kwargs.pop("lifetime", 1000)) tx = txn.AssetConfigTxn( sender, params, **kwargs, strict_empty_address_check=False ) @@ -252,7 +252,7 @@ def asset_create(self, sender, **kwargs): return self.acfg(sender, **kwargs) def axfer(self, sender, receiver, amt: int, index: int, send=None, **kwargs): - params = self.algod.suggested_params() + params = self.params(kwargs.pop("lifetime", 1000)) tx = txn.AssetTransferTxn( sender, params, receiver, amt, index, **kwargs ) @@ -263,7 +263,7 @@ def asset_optin(self, sender, index: int, **kwargs): return self.axfer(sender, sender, 0, index, **kwargs) def afrz(self, sender, index: int, target, frozen, send=None, **kwargs): - params = self.algod.suggested_params() + params = self.params(kwargs.pop("lifetime", 1000)) tx = txn.AssetFreezeTxn(sender, params, index, target, frozen, **kwargs) return self.finish(tx, send) @@ -274,9 +274,15 @@ def coerce_schema(self, values): return values return txn.StateSchema(num_uints=values[0], num_byte_slices=values[1]) + + def params(self, lifetime): + params = self.algod.suggested_params() + params.last = params.first + lifetime + return params + def appl(self, sender, index: int, on_complete=txn.OnComplete.NoOpOC, send=None, **kwargs): - params = self.algod.suggested_params() + params = self.params(kwargs.pop("lifetime", 1000)) local_schema = self.coerce_schema(kwargs.pop("local_schema", None)) global_schema = self.coerce_schema(kwargs.pop("global_schema", None)) tx = txn.ApplicationCallTxn( diff --git a/test/scripts/e2e_subs/mining.py b/test/scripts/e2e_subs/mining.py new file mode 100755 index 0000000000..79b23e9fd2 --- /dev/null +++ b/test/scripts/e2e_subs/mining.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python + +import base64 +import os +import sys +from goal import Goal +import algosdk.encoding as enc + +from datetime import datetime + +stamp = datetime.now().strftime("%Y%m%d_%H%M%S") +print(f"{os.path.basename(sys.argv[0])} start {stamp}") + +goal = Goal(sys.argv[1], autosend=True) + +joe = goal.new_account() + +_, err = goal.pay(goal.account, joe, amt=500_000) +assert not err, err + +# Turn off rewards for precise balance checking +_, err = goal.keyreg(joe, nonpart=True) +assert not err, err + +get_proposer = """ +#pragma version 10 + txn ApplicationArgs 0; btoi + block BlkProposer; global ZeroAddress; !=; assert + + txn ApplicationArgs 0; btoi + block BlkProposer; log + + txn ApplicationArgs 0; btoi + block BlkFeesCollected; itob; log + + int 1 +""" + + + +# During construction, the app examines an arbitrary round, a little before the latest. +examined = max(goal.params(1).first-5, 1) +txinfo, err = goal.app_create(joe, goal.assemble(get_proposer), app_args=[examined], lifetime=50) +assert not err, err +getter = txinfo['application-index'] +assert getter + +# There should be two logs, the proposer of the examined round, and the fees from that round +rnd = txinfo['confirmed-round'] +# Look at the block of the creation. We know fees collected is non-zero +block = goal.algod.block_info(rnd)['block'] +assert "fc" in block +assert block["fc"] > 0 # We don't test exact, because other tests are running +assert "prp" in block +assert block["prp"] != "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ" + +create_proposer = block["prp"] +immediately_after = goal.balance(create_proposer) +assert immediately_after > 10000000 # Our proposers in e2e tests have pretty much all the money + +# Compare the examined block's header to what the AVM saw (and logged) +block = goal.algod.block_info(examined)['block'] +print("creation", txinfo['logs'], block) +assert base64.b64decode(txinfo['logs'][0]) == enc.decode_address(block['prp']) +assert base64.b64decode(txinfo['logs'][1]) == block.get('fc',0).to_bytes(8, "big") + +# Now have the app examine the round the app was constructed, so we +# can check the log and know there should be a fee. +goal.wait_for_block(rnd+1) # because fv is set to current latest (rnd), so it `block rnd` wouldn't work +txinfo, err = goal.app_call(joe, getter, app_args=[rnd], lifetime=10) +assert not err, err + +block = goal.algod.block_info(rnd)['block'] +# note we use block['fc'], not block.get('fc', 0) +print("call", txinfo['logs'], block) +assert base64.b64decode(txinfo['logs'][0]) == enc.decode_address(block['prp']) +assert base64.b64decode(txinfo['logs'][1]) == block['fc'].to_bytes(8, "big") + +# Now let's confirm the proposer got paid. It's somewhat tricky, +# because in our e2e tests, we have only two proposers, and their +# balances may be changing all the time, because e2e_client_runner is +# taking out 1M algos at a time to run parallel subtests. We'll work +# with the balance mod 1M, so we can see the small fees being added to +# it, even if the blance has dropped by 1M. +after_mining_credit = goal.balance(create_proposer) +assertion = str(after_mining_credit)+" > "+str(immediately_after) +print("credit", assertion) +M = 1_000_000 +assert after_mining_credit % M > immediately_after % M, assertion + +stamp = datetime.now().strftime("%Y%m%d_%H%M%S") +print(f"{os.path.basename(sys.argv[0])} OK {stamp}") From 9be91348c062c62671af572be59c205d49895315 Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Tue, 26 Sep 2023 15:14:49 -0400 Subject: [PATCH 2/9] Check the proposer field of a proposed block (header) --- agreement/proposal.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/agreement/proposal.go b/agreement/proposal.go index 0d8442a065..fcee3442f3 100644 --- a/agreement/proposal.go +++ b/agreement/proposal.go @@ -197,6 +197,12 @@ func verifyNewSeed(p unauthenticatedProposal, ledger LedgerReader) error { return fmt.Errorf("failed to obtain consensus parameters in round %d: %v", ParamsRound(rnd), err) } + if cparams.EnableMining { + if p.BlockHeader.Proposer != value.OriginalProposer { + return fmt.Errorf("payload has wrong proposer (%v != %v)", p.Proposer, value.OriginalProposer) + } + } + balanceRound := balanceRound(rnd, cparams) proposerRecord, err := ledger.LookupAgreement(balanceRound, value.OriginalProposer) if err != nil { @@ -241,6 +247,7 @@ func verifyNewSeed(p unauthenticatedProposal, ledger LedgerReader) error { if p.Seed() != committee.Seed(crypto.HashObj(input)) { return fmt.Errorf("payload seed malformed (%v != %v)", committee.Seed(crypto.HashObj(input)), p.Seed()) } + return nil } From 285930b206eae69d2f5abd9b3038235a3a0387d0 Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Thu, 28 Sep 2023 09:50:46 -0400 Subject: [PATCH 3/9] Notice if the mining credit causes wraparound --- agreement/proposal.go | 1 - data/transactions/logic/fields.go | 4 ++-- data/transactions/logic/opcodes.go | 3 ++- test/scripts/e2e_subs/mining.py | 10 ++++++++-- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/agreement/proposal.go b/agreement/proposal.go index fcee3442f3..51e1407f99 100644 --- a/agreement/proposal.go +++ b/agreement/proposal.go @@ -247,7 +247,6 @@ func verifyNewSeed(p unauthenticatedProposal, ledger LedgerReader) error { if p.Seed() != committee.Seed(crypto.HashObj(input)) { return fmt.Errorf("payload seed malformed (%v != %v)", committee.Seed(crypto.HashObj(input)), p.Seed()) } - return nil } diff --git a/data/transactions/logic/fields.go b/data/transactions/logic/fields.go index c99b03fbbf..77e3de23e0 100644 --- a/data/transactions/logic/fields.go +++ b/data/transactions/logic/fields.go @@ -979,8 +979,8 @@ type blockFieldSpec struct { var blockFieldSpecs = [...]blockFieldSpec{ {BlkSeed, StackBytes, randomnessVersion}, {BlkTimestamp, StackUint64, randomnessVersion}, - {BlkProposer, StackAddress, 10}, - {BlkFeesCollected, StackUint64, 10}, + {BlkProposer, StackAddress, incentiveVersion}, + {BlkFeesCollected, StackUint64, incentiveVersion}, } func blockFieldSpecByField(r BlockField) (blockFieldSpec, bool) { diff --git a/data/transactions/logic/opcodes.go b/data/transactions/logic/opcodes.go index dc2d44bc09..1f98bfaf61 100644 --- a/data/transactions/logic/opcodes.go +++ b/data/transactions/logic/opcodes.go @@ -74,7 +74,8 @@ const sharedResourcesVersion = 9 // apps can access resources from other transac // EXPERIMENTAL. These should be revisited whenever a new LogicSigVersion is // moved from vFuture to a new consensus version. If they remain unready, bump // their version, and fixup TestAssemble() in assembler_test.go. -const pairingVersion = 10 // bn256 opcodes. will add bls12-381, and unify the available opcodes. +const pairingVersion = 10 // bn256 opcodes. will add bls12-381, and unify the available opcodes. +const incentiveVersion = 10 // block fields, heartbeat // Unlimited Global Storage opcodes const boxVersion = 8 // box_* diff --git a/test/scripts/e2e_subs/mining.py b/test/scripts/e2e_subs/mining.py index 79b23e9fd2..5a52b4482c 100755 --- a/test/scripts/e2e_subs/mining.py +++ b/test/scripts/e2e_subs/mining.py @@ -81,12 +81,18 @@ # balances may be changing all the time, because e2e_client_runner is # taking out 1M algos at a time to run parallel subtests. We'll work # with the balance mod 1M, so we can see the small fees being added to -# it, even if the blance has dropped by 1M. +# it, even if the balance has dropped by 1M. But then we _also_ need +# to worry about wraparound. after_mining_credit = goal.balance(create_proposer) assertion = str(after_mining_credit)+" > "+str(immediately_after) print("credit", assertion) M = 1_000_000 -assert after_mining_credit % M > immediately_after % M, assertion +before = immediately_after % M +after = after_mining_credit % M +# Detect that the mining credit wrapped around with respect to 1M. +if after < M/4 and before > 3*M/4: + after += M +assert after > before, assertion stamp = datetime.now().strftime("%Y%m%d_%H%M%S") print(f"{os.path.basename(sys.argv[0])} OK {stamp}") From 293e3f3cfe6f35aa1302750292904f9298b074fd Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Tue, 26 Sep 2023 14:07:10 -0400 Subject: [PATCH 4/9] Adds LastProposed fields, and logic for checking absenteeism --- agreement/msgp_gen.go | 1567 ++++++++++------- cmd/goal/accountsList.go | 2 + cmd/incorporate/incorporate.go | 2 + config/consensus.go | 23 +- daemon/algod/api/Makefile | 1 + daemon/algod/api/algod.oas2.json | 8 + daemon/algod/api/algod.oas3.yml | 8 + daemon/algod/api/server/v2/account.go | 14 + .../api/server/v2/generated/data/routes.go | 253 +-- .../v2/generated/experimental/routes.go | 409 ++--- .../api/server/v2/generated/model/types.go | 6 + .../nonparticipating/private/routes.go | 411 ++--- .../nonparticipating/public/routes.go | 405 ++--- .../generated/participating/private/routes.go | 421 ++--- .../generated/participating/public/routes.go | 275 +-- daemon/algod/api/server/v2/handlers.go | 2 + data/basics/msgp_gen.go | 768 ++++---- data/basics/userBalance.go | 25 +- data/bookkeeping/block.go | 4 + data/bookkeeping/msgp_gen.go | 1101 +++++++----- data/txntest/txn.go | 47 +- ledger/acctdeltas.go | 6 +- ledger/acctdeltas_test.go | 2 +- ledger/acctupdates_test.go | 2 +- ledger/apply/keyreg.go | 3 + ledger/eval/eval.go | 144 +- ledger/eval_simple_test.go | 67 + ledger/ledgercore/accountdata.go | 15 + ledger/ledgercore/totals.go | 2 +- ledger/simple_test.go | 3 + ledger/store/trackerdb/data.go | 19 +- ledger/store/trackerdb/data_test.go | 2 +- ledger/store/trackerdb/msgp_gen.go | 58 +- ledger/testing/randomAccounts.go | 16 +- test/scripts/e2e_subs/absentee.py | 35 + 35 files changed, 3556 insertions(+), 2570 deletions(-) create mode 100755 test/scripts/e2e_subs/absentee.py diff --git a/agreement/msgp_gen.go b/agreement/msgp_gen.go index 91f877042f..2906e73048 100644 --- a/agreement/msgp_gen.go +++ b/agreement/msgp_gen.go @@ -4493,196 +4493,212 @@ func PlayerMaxSize() (s int) { func (z *proposal) MarshalMsg(b []byte) (o []byte) { o = msgp.Require(b, z.Msgsize()) // omitempty: check for empty values - zb0004Len := uint32(31) - var zb0004Mask uint64 /* 40 bits */ + zb0005Len := uint32(32) + var zb0005Mask uint64 /* 41 bits */ if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0 { - zb0004Len-- - zb0004Mask |= 0x40 + zb0005Len-- + zb0005Mask |= 0x40 } if (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x80 + zb0005Len-- + zb0005Mask |= 0x80 } if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x100 + zb0005Len-- + zb0005Mask |= 0x100 } if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0 { - zb0004Len-- - zb0004Mask |= 0x200 + zb0005Len-- + zb0005Mask |= 0x200 } if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "" { - zb0004Len-- - zb0004Mask |= 0x400 + zb0005Len-- + zb0005Mask |= 0x400 } if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x800 + zb0005Len-- + zb0005Mask |= 0x800 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x1000 + zb0005Len-- + zb0005Mask |= 0x1000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x2000 + zb0005Len-- + zb0005Mask |= 0x2000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x4000 + zb0005Len-- + zb0005Mask |= 0x4000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0 { - zb0004Len-- - zb0004Mask |= 0x8000 + zb0005Len-- + zb0005Mask |= 0x8000 } if (*z).unauthenticatedProposal.OriginalPeriod == 0 { - zb0004Len-- - zb0004Mask |= 0x10000 + zb0005Len-- + zb0005Mask |= 0x10000 } if (*z).unauthenticatedProposal.OriginalProposer.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x20000 + zb0005Len-- + zb0005Mask |= 0x20000 + } + if len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) == 0 { + zb0005Len-- + zb0005Mask |= 0x40000 } if len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 { - zb0004Len-- - zb0004Mask |= 0x40000 + zb0005Len-- + zb0005Mask |= 0x80000 } if (*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x80000 + zb0005Len-- + zb0005Mask |= 0x100000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x100000 + zb0005Len-- + zb0005Mask |= 0x200000 } if (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x200000 + zb0005Len-- + zb0005Mask |= 0x400000 } if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0 { - zb0004Len-- - zb0004Mask |= 0x400000 + zb0005Len-- + zb0005Mask |= 0x800000 } if (*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x1000000 + zb0005Len-- + zb0005Mask |= 0x2000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x2000000 + zb0005Len-- + zb0005Mask |= 0x4000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x4000000 + zb0005Len-- + zb0005Mask |= 0x8000000 } if (*z).unauthenticatedProposal.SeedProof.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x8000000 + zb0005Len-- + zb0005Mask |= 0x10000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x10000000 + zb0005Len-- + zb0005Mask |= 0x20000000 } if len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0 { - zb0004Len-- - zb0004Mask |= 0x20000000 + zb0005Len-- + zb0005Mask |= 0x40000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0 { - zb0004Len-- - zb0004Mask |= 0x40000000 + zb0005Len-- + zb0005Mask |= 0x80000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0 { - zb0004Len-- - zb0004Mask |= 0x80000000 + zb0005Len-- + zb0005Mask |= 0x100000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x100000000 + zb0005Len-- + zb0005Mask |= 0x200000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x200000000 + zb0005Len-- + zb0005Mask |= 0x400000000 } if (*z).unauthenticatedProposal.Block.Payset.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x400000000 + zb0005Len-- + zb0005Mask |= 0x800000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x800000000 + zb0005Len-- + zb0005Mask |= 0x1000000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x1000000000 + zb0005Len-- + zb0005Mask |= 0x2000000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false { - zb0004Len-- - zb0004Mask |= 0x2000000000 + zb0005Len-- + zb0005Mask |= 0x4000000000 } - // variable map header, size zb0004Len - o = msgp.AppendMapHeader(o, zb0004Len) - if zb0004Len != 0 { - if (zb0004Mask & 0x40) == 0 { // if not empty + // variable map header, size zb0005Len + o = msgp.AppendMapHeader(o, zb0005Len) + if zb0005Len != 0 { + if (zb0005Mask & 0x40) == 0 { // if not empty // string "earn" o = append(o, 0xa4, 0x65, 0x61, 0x72, 0x6e) o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel) } - if (zb0004Mask & 0x80) == 0 { // if not empty + if (zb0005Mask & 0x80) == 0 { // if not empty // string "fc" o = append(o, 0xa2, 0x66, 0x63) o = (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MarshalMsg(o) } - if (zb0004Mask & 0x100) == 0 { // if not empty + if (zb0005Mask & 0x100) == 0 { // if not empty // string "fees" o = append(o, 0xa4, 0x66, 0x65, 0x65, 0x73) o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MarshalMsg(o) } - if (zb0004Mask & 0x200) == 0 { // if not empty + if (zb0005Mask & 0x200) == 0 { // if not empty // string "frac" o = append(o, 0xa4, 0x66, 0x72, 0x61, 0x63) o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue) } - if (zb0004Mask & 0x400) == 0 { // if not empty + if (zb0005Mask & 0x400) == 0 { // if not empty // string "gen" o = append(o, 0xa3, 0x67, 0x65, 0x6e) o = msgp.AppendString(o, (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID) } - if (zb0004Mask & 0x800) == 0 { // if not empty + if (zb0005Mask & 0x800) == 0 { // if not empty // string "gh" o = append(o, 0xa2, 0x67, 0x68) o = (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MarshalMsg(o) } - if (zb0004Mask & 0x1000) == 0 { // if not empty + if (zb0005Mask & 0x1000) == 0 { // if not empty // string "nextbefore" o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MarshalMsg(o) } - if (zb0004Mask & 0x2000) == 0 { // if not empty + if (zb0005Mask & 0x2000) == 0 { // if not empty // string "nextproto" o = append(o, 0xa9, 0x6e, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MarshalMsg(o) } - if (zb0004Mask & 0x4000) == 0 { // if not empty + if (zb0005Mask & 0x4000) == 0 { // if not empty // string "nextswitch" o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MarshalMsg(o) } - if (zb0004Mask & 0x8000) == 0 { // if not empty + if (zb0005Mask & 0x8000) == 0 { // if not empty // string "nextyes" o = append(o, 0xa7, 0x6e, 0x65, 0x78, 0x74, 0x79, 0x65, 0x73) o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals) } - if (zb0004Mask & 0x10000) == 0 { // if not empty + if (zb0005Mask & 0x10000) == 0 { // if not empty // string "oper" o = append(o, 0xa4, 0x6f, 0x70, 0x65, 0x72) o = msgp.AppendUint64(o, uint64((*z).unauthenticatedProposal.OriginalPeriod)) } - if (zb0004Mask & 0x20000) == 0 { // if not empty + if (zb0005Mask & 0x20000) == 0 { // if not empty // string "oprop" o = append(o, 0xa5, 0x6f, 0x70, 0x72, 0x6f, 0x70) o = (*z).unauthenticatedProposal.OriginalProposer.MarshalMsg(o) } - if (zb0004Mask & 0x40000) == 0 { // if not empty + if (zb0005Mask & 0x40000) == 0 { // if not empty + // string "partupdabs" + o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x61, 0x62, 0x73) + if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts == nil { + o = msgp.AppendNil(o) + } else { + o = msgp.AppendArrayHeader(o, uint32(len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts))) + } + for zb0004 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts { + o = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].MarshalMsg(o) + } + } + if (zb0005Mask & 0x80000) == 0 { // if not empty // string "partupdrmv" o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76) if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts == nil { @@ -4694,52 +4710,52 @@ func (z *proposal) MarshalMsg(b []byte) (o []byte) { o = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].MarshalMsg(o) } } - if (zb0004Mask & 0x80000) == 0 { // if not empty + if (zb0005Mask & 0x100000) == 0 { // if not empty // string "prev" o = append(o, 0xa4, 0x70, 0x72, 0x65, 0x76) o = (*z).unauthenticatedProposal.Block.BlockHeader.Branch.MarshalMsg(o) } - if (zb0004Mask & 0x100000) == 0 { // if not empty + if (zb0005Mask & 0x200000) == 0 { // if not empty // string "proto" o = append(o, 0xa5, 0x70, 0x72, 0x6f, 0x74, 0x6f) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MarshalMsg(o) } - if (zb0004Mask & 0x200000) == 0 { // if not empty + if (zb0005Mask & 0x400000) == 0 { // if not empty // string "prp" o = append(o, 0xa3, 0x70, 0x72, 0x70) o = (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MarshalMsg(o) } - if (zb0004Mask & 0x400000) == 0 { // if not empty + if (zb0005Mask & 0x800000) == 0 { // if not empty // string "rate" o = append(o, 0xa4, 0x72, 0x61, 0x74, 0x65) o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate) } - if (zb0004Mask & 0x1000000) == 0 { // if not empty + if (zb0005Mask & 0x2000000) == 0 { // if not empty // string "rnd" o = append(o, 0xa3, 0x72, 0x6e, 0x64) o = (*z).unauthenticatedProposal.Block.BlockHeader.Round.MarshalMsg(o) } - if (zb0004Mask & 0x2000000) == 0 { // if not empty + if (zb0005Mask & 0x4000000) == 0 { // if not empty // string "rwcalr" o = append(o, 0xa6, 0x72, 0x77, 0x63, 0x61, 0x6c, 0x72) o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MarshalMsg(o) } - if (zb0004Mask & 0x4000000) == 0 { // if not empty + if (zb0005Mask & 0x8000000) == 0 { // if not empty // string "rwd" o = append(o, 0xa3, 0x72, 0x77, 0x64) o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MarshalMsg(o) } - if (zb0004Mask & 0x8000000) == 0 { // if not empty + if (zb0005Mask & 0x10000000) == 0 { // if not empty // string "sdpf" o = append(o, 0xa4, 0x73, 0x64, 0x70, 0x66) o = (*z).unauthenticatedProposal.SeedProof.MarshalMsg(o) } - if (zb0004Mask & 0x10000000) == 0 { // if not empty + if (zb0005Mask & 0x20000000) == 0 { // if not empty // string "seed" o = append(o, 0xa4, 0x73, 0x65, 0x65, 0x64) o = (*z).unauthenticatedProposal.Block.BlockHeader.Seed.MarshalMsg(o) } - if (zb0004Mask & 0x20000000) == 0 { // if not empty + if (zb0005Mask & 0x40000000) == 0 { // if not empty // string "spt" o = append(o, 0xa3, 0x73, 0x70, 0x74) if (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking == nil { @@ -4759,42 +4775,42 @@ func (z *proposal) MarshalMsg(b []byte) (o []byte) { o = zb0002.MarshalMsg(o) } } - if (zb0004Mask & 0x40000000) == 0 { // if not empty + if (zb0005Mask & 0x80000000) == 0 { // if not empty // string "tc" o = append(o, 0xa2, 0x74, 0x63) o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter) } - if (zb0004Mask & 0x80000000) == 0 { // if not empty + if (zb0005Mask & 0x100000000) == 0 { // if not empty // string "ts" o = append(o, 0xa2, 0x74, 0x73) o = msgp.AppendInt64(o, (*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp) } - if (zb0004Mask & 0x100000000) == 0 { // if not empty + if (zb0005Mask & 0x200000000) == 0 { // if not empty // string "txn" o = append(o, 0xa3, 0x74, 0x78, 0x6e) o = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MarshalMsg(o) } - if (zb0004Mask & 0x200000000) == 0 { // if not empty + if (zb0005Mask & 0x400000000) == 0 { // if not empty // string "txn256" o = append(o, 0xa6, 0x74, 0x78, 0x6e, 0x32, 0x35, 0x36) o = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MarshalMsg(o) } - if (zb0004Mask & 0x400000000) == 0 { // if not empty + if (zb0005Mask & 0x800000000) == 0 { // if not empty // string "txns" o = append(o, 0xa4, 0x74, 0x78, 0x6e, 0x73) o = (*z).unauthenticatedProposal.Block.Payset.MarshalMsg(o) } - if (zb0004Mask & 0x800000000) == 0 { // if not empty + if (zb0005Mask & 0x1000000000) == 0 { // if not empty // string "upgradedelay" o = append(o, 0xac, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x65, 0x6c, 0x61, 0x79) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MarshalMsg(o) } - if (zb0004Mask & 0x1000000000) == 0 { // if not empty + if (zb0005Mask & 0x2000000000) == 0 { // if not empty // string "upgradeprop" o = append(o, 0xab, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x70, 0x72, 0x6f, 0x70) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MarshalMsg(o) } - if (zb0004Mask & 0x2000000000) == 0 { // if not empty + if (zb0005Mask & 0x4000000000) == 0 { // if not empty // string "upgradeyes" o = append(o, 0xaa, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x65, 0x73) o = msgp.AppendBool(o, (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove) @@ -4817,73 +4833,73 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o st.AllowableDepth-- var field []byte _ = field - var zb0004 int - var zb0005 bool - zb0004, zb0005, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0005 int + var zb0006 bool + zb0005, zb0006, bts, err = msgp.ReadMapHeaderBytes(bts) if _, ok := err.(msgp.TypeError); ok { - zb0004, zb0005, bts, err = msgp.ReadArrayHeaderBytes(bts) + zb0005, zb0006, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err) return } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Round.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Round") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Branch.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Branch") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Seed.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Seed") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NativeSha512_256Commitment") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Sha256Commitment") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp, bts, err = msgp.ReadInt64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "TimeStamp") return } } - if zb0004 > 0 { - zb0004-- - var zb0006 int - zb0006, err = msgp.ReadBytesBytesHeader(bts) + if zb0005 > 0 { + zb0005-- + var zb0007 int + zb0007, err = msgp.ReadBytesBytesHeader(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "GenesisID") return } - if zb0006 > config.MaxGenesisIDLen { - err = msgp.ErrOverflow(uint64(zb0006), uint64(config.MaxGenesisIDLen)) + if zb0007 > config.MaxGenesisIDLen { + err = msgp.ErrOverflow(uint64(zb0007), uint64(config.MaxGenesisIDLen)) return } (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID, bts, err = msgp.ReadStringBytes(bts) @@ -4892,173 +4908,173 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "GenesisHash") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Proposer") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "FeesCollected") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "FeeSink") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsPool") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsLevel") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsRate") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsResidue") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsRecalculationRound") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "CurrentProtocol") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NextProtocol") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NextProtocolApprovals") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NextProtocolVoteBefore") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NextProtocolSwitchOn") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "UpgradePropose") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "UpgradeDelay") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove, bts, err = msgp.ReadBoolBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "UpgradeApprove") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "TxnCounter") return } } - if zb0004 > 0 { - zb0004-- - var zb0007 int - var zb0008 bool - zb0007, zb0008, bts, err = msgp.ReadMapHeaderBytes(bts) + if zb0005 > 0 { + zb0005-- + var zb0008 int + var zb0009 bool + zb0008, zb0009, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "StateProofTracking") return } - if zb0007 > protocol.NumStateProofTypes { - err = msgp.ErrOverflow(uint64(zb0007), uint64(protocol.NumStateProofTypes)) + if zb0008 > protocol.NumStateProofTypes { + err = msgp.ErrOverflow(uint64(zb0008), uint64(protocol.NumStateProofTypes)) err = msgp.WrapError(err, "struct-from-array", "StateProofTracking") return } - if zb0008 { + if zb0009 { (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = nil } else if (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking == nil { - (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0007) + (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0008) } - for zb0007 > 0 { + for zb0008 > 0 { var zb0001 protocol.StateProofType var zb0002 bookkeeping.StateProofTrackingData - zb0007-- + zb0008-- bts, err = zb0001.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "StateProofTracking") @@ -5072,26 +5088,26 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking[zb0001] = zb0002 } } - if zb0004 > 0 { - zb0004-- - var zb0009 int - var zb0010 bool - zb0009, zb0010, bts, err = msgp.ReadArrayHeaderBytes(bts) + if zb0005 > 0 { + zb0005-- + var zb0010 int + var zb0011 bool + zb0010, zb0011, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts") return } - if zb0009 > config.MaxProposedExpiredOnlineAccounts { - err = msgp.ErrOverflow(uint64(zb0009), uint64(config.MaxProposedExpiredOnlineAccounts)) + if zb0010 > config.MaxProposedExpiredOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0010), uint64(config.MaxProposedExpiredOnlineAccounts)) err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts") return } - if zb0010 { + if zb0011 { (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = nil - } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0009 { - (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0009] + } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0010 { + (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0010] } else { - (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0009) + (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0010) } for zb0003 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts { bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].UnmarshalMsgWithState(bts, st) @@ -5101,44 +5117,73 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o } } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- + var zb0012 int + var zb0013 bool + zb0012, zb0013, bts, err = msgp.ReadArrayHeaderBytes(bts) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts") + return + } + if zb0012 > config.MaxProposedAbsentOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0012), uint64(config.MaxProposedAbsentOnlineAccounts)) + err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts") + return + } + if zb0013 { + (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = nil + } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) >= zb0012 { + (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts)[:zb0012] + } else { + (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = make([]basics.Address, zb0012) + } + for zb0004 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts { + bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts", zb0004) + return + } + } + } + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.Payset.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Payset") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.SeedProof.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "SeedProof") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- { - var zb0011 uint64 - zb0011, bts, err = msgp.ReadUint64Bytes(bts) + var zb0014 uint64 + zb0014, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "OriginalPeriod") return } - (*z).unauthenticatedProposal.OriginalPeriod = period(zb0011) + (*z).unauthenticatedProposal.OriginalPeriod = period(zb0014) } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.OriginalProposer.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "OriginalProposer") return } } - if zb0004 > 0 { - err = msgp.ErrTooManyArrayFields(zb0004) + if zb0005 > 0 { + err = msgp.ErrTooManyArrayFields(zb0005) if err != nil { err = msgp.WrapError(err, "struct-from-array") return @@ -5149,11 +5194,11 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o err = msgp.WrapError(err) return } - if zb0005 { + if zb0006 { (*z) = proposal{} } - for zb0004 > 0 { - zb0004-- + for zb0005 > 0 { + zb0005-- field, bts, err = msgp.ReadMapKeyZC(bts) if err != nil { err = msgp.WrapError(err) @@ -5197,14 +5242,14 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o return } case "gen": - var zb0012 int - zb0012, err = msgp.ReadBytesBytesHeader(bts) + var zb0015 int + zb0015, err = msgp.ReadBytesBytesHeader(bts) if err != nil { err = msgp.WrapError(err, "GenesisID") return } - if zb0012 > config.MaxGenesisIDLen { - err = msgp.ErrOverflow(uint64(zb0012), uint64(config.MaxGenesisIDLen)) + if zb0015 > config.MaxGenesisIDLen { + err = msgp.ErrOverflow(uint64(zb0015), uint64(config.MaxGenesisIDLen)) return } (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID, bts, err = msgp.ReadStringBytes(bts) @@ -5321,27 +5366,27 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o return } case "spt": - var zb0013 int - var zb0014 bool - zb0013, zb0014, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0016 int + var zb0017 bool + zb0016, zb0017, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "StateProofTracking") return } - if zb0013 > protocol.NumStateProofTypes { - err = msgp.ErrOverflow(uint64(zb0013), uint64(protocol.NumStateProofTypes)) + if zb0016 > protocol.NumStateProofTypes { + err = msgp.ErrOverflow(uint64(zb0016), uint64(protocol.NumStateProofTypes)) err = msgp.WrapError(err, "StateProofTracking") return } - if zb0014 { + if zb0017 { (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = nil } else if (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking == nil { - (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0013) + (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0016) } - for zb0013 > 0 { + for zb0016 > 0 { var zb0001 protocol.StateProofType var zb0002 bookkeeping.StateProofTrackingData - zb0013-- + zb0016-- bts, err = zb0001.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "StateProofTracking") @@ -5355,24 +5400,24 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking[zb0001] = zb0002 } case "partupdrmv": - var zb0015 int - var zb0016 bool - zb0015, zb0016, bts, err = msgp.ReadArrayHeaderBytes(bts) + var zb0018 int + var zb0019 bool + zb0018, zb0019, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "ExpiredParticipationAccounts") return } - if zb0015 > config.MaxProposedExpiredOnlineAccounts { - err = msgp.ErrOverflow(uint64(zb0015), uint64(config.MaxProposedExpiredOnlineAccounts)) + if zb0018 > config.MaxProposedExpiredOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0018), uint64(config.MaxProposedExpiredOnlineAccounts)) err = msgp.WrapError(err, "ExpiredParticipationAccounts") return } - if zb0016 { + if zb0019 { (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = nil - } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0015 { - (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0015] + } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0018 { + (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0018] } else { - (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0015) + (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0018) } for zb0003 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts { bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].UnmarshalMsgWithState(bts, st) @@ -5381,6 +5426,33 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o return } } + case "partupdabs": + var zb0020 int + var zb0021 bool + zb0020, zb0021, bts, err = msgp.ReadArrayHeaderBytes(bts) + if err != nil { + err = msgp.WrapError(err, "AbsentParticipationAccounts") + return + } + if zb0020 > config.MaxProposedAbsentOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0020), uint64(config.MaxProposedAbsentOnlineAccounts)) + err = msgp.WrapError(err, "AbsentParticipationAccounts") + return + } + if zb0021 { + (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = nil + } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) >= zb0020 { + (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts)[:zb0020] + } else { + (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = make([]basics.Address, zb0020) + } + for zb0004 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts { + bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "AbsentParticipationAccounts", zb0004) + return + } + } case "txns": bts, err = (*z).unauthenticatedProposal.Block.Payset.UnmarshalMsgWithState(bts, st) if err != nil { @@ -5395,13 +5467,13 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o } case "oper": { - var zb0017 uint64 - zb0017, bts, err = msgp.ReadUint64Bytes(bts) + var zb0022 uint64 + zb0022, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "OriginalPeriod") return } - (*z).unauthenticatedProposal.OriginalPeriod = period(zb0017) + (*z).unauthenticatedProposal.OriginalPeriod = period(zb0022) } case "oprop": bts, err = (*z).unauthenticatedProposal.OriginalProposer.UnmarshalMsgWithState(bts, st) @@ -5444,13 +5516,17 @@ func (z *proposal) Msgsize() (s int) { for zb0003 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts { s += (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].Msgsize() } + s += 11 + msgp.ArrayHeaderSize + for zb0004 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts { + s += (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].Msgsize() + } s += 5 + (*z).unauthenticatedProposal.Block.Payset.Msgsize() + 5 + (*z).unauthenticatedProposal.SeedProof.Msgsize() + 5 + msgp.Uint64Size + 6 + (*z).unauthenticatedProposal.OriginalProposer.Msgsize() return } // MsgIsZero returns whether this is a zero value func (z *proposal) MsgIsZero() bool { - return ((*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "") && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).unauthenticatedProposal.Block.Payset.MsgIsZero()) && ((*z).unauthenticatedProposal.SeedProof.MsgIsZero()) && ((*z).unauthenticatedProposal.OriginalPeriod == 0) && ((*z).unauthenticatedProposal.OriginalProposer.MsgIsZero()) + return ((*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "") && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) == 0) && ((*z).unauthenticatedProposal.Block.Payset.MsgIsZero()) && ((*z).unauthenticatedProposal.SeedProof.MsgIsZero()) && ((*z).unauthenticatedProposal.OriginalPeriod == 0) && ((*z).unauthenticatedProposal.OriginalProposer.MsgIsZero()) } // MaxSize returns a maximum valid message size for this message type @@ -5464,6 +5540,9 @@ func ProposalMaxSize() (s int) { s += 11 // Calculating size of slice: z.unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts s += msgp.ArrayHeaderSize + ((config.MaxProposedExpiredOnlineAccounts) * (basics.AddressMaxSize())) + s += 11 + // Calculating size of slice: z.unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts + s += msgp.ArrayHeaderSize + ((config.MaxProposedAbsentOnlineAccounts) * (basics.AddressMaxSize())) s += 5 // Using maxtotalbytes for: z.unauthenticatedProposal.Block.Payset s += config.MaxTxnBytesPerBlock @@ -8902,200 +8981,216 @@ func ThresholdEventMaxSize() (s int) { func (z *transmittedPayload) MarshalMsg(b []byte) (o []byte) { o = msgp.Require(b, z.Msgsize()) // omitempty: check for empty values - zb0004Len := uint32(32) - var zb0004Mask uint64 /* 40 bits */ + zb0005Len := uint32(33) + var zb0005Mask uint64 /* 41 bits */ if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0 { - zb0004Len-- - zb0004Mask |= 0x80 + zb0005Len-- + zb0005Mask |= 0x80 } if (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x100 + zb0005Len-- + zb0005Mask |= 0x100 } if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x200 + zb0005Len-- + zb0005Mask |= 0x200 } if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0 { - zb0004Len-- - zb0004Mask |= 0x400 + zb0005Len-- + zb0005Mask |= 0x400 } if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "" { - zb0004Len-- - zb0004Mask |= 0x800 + zb0005Len-- + zb0005Mask |= 0x800 } if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x1000 + zb0005Len-- + zb0005Mask |= 0x1000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x2000 + zb0005Len-- + zb0005Mask |= 0x2000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x4000 + zb0005Len-- + zb0005Mask |= 0x4000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x8000 + zb0005Len-- + zb0005Mask |= 0x8000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0 { - zb0004Len-- - zb0004Mask |= 0x10000 + zb0005Len-- + zb0005Mask |= 0x10000 } if (*z).unauthenticatedProposal.OriginalPeriod == 0 { - zb0004Len-- - zb0004Mask |= 0x20000 + zb0005Len-- + zb0005Mask |= 0x20000 } if (*z).unauthenticatedProposal.OriginalProposer.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x40000 + zb0005Len-- + zb0005Mask |= 0x40000 + } + if len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) == 0 { + zb0005Len-- + zb0005Mask |= 0x80000 } if len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 { - zb0004Len-- - zb0004Mask |= 0x80000 + zb0005Len-- + zb0005Mask |= 0x100000 } if (*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x100000 + zb0005Len-- + zb0005Mask |= 0x200000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x200000 + zb0005Len-- + zb0005Mask |= 0x400000 } if (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x400000 + zb0005Len-- + zb0005Mask |= 0x800000 } if (*z).PriorVote.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x800000 + zb0005Len-- + zb0005Mask |= 0x1000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0 { - zb0004Len-- - zb0004Mask |= 0x1000000 + zb0005Len-- + zb0005Mask |= 0x2000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x4000000 + zb0005Len-- + zb0005Mask |= 0x8000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x8000000 + zb0005Len-- + zb0005Mask |= 0x10000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x10000000 + zb0005Len-- + zb0005Mask |= 0x20000000 } if (*z).unauthenticatedProposal.SeedProof.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x20000000 + zb0005Len-- + zb0005Mask |= 0x40000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x40000000 + zb0005Len-- + zb0005Mask |= 0x80000000 } if len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0 { - zb0004Len-- - zb0004Mask |= 0x80000000 + zb0005Len-- + zb0005Mask |= 0x100000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0 { - zb0004Len-- - zb0004Mask |= 0x100000000 + zb0005Len-- + zb0005Mask |= 0x200000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0 { - zb0004Len-- - zb0004Mask |= 0x200000000 + zb0005Len-- + zb0005Mask |= 0x400000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x400000000 + zb0005Len-- + zb0005Mask |= 0x800000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x800000000 + zb0005Len-- + zb0005Mask |= 0x1000000000 } if (*z).unauthenticatedProposal.Block.Payset.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x1000000000 + zb0005Len-- + zb0005Mask |= 0x2000000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x2000000000 + zb0005Len-- + zb0005Mask |= 0x4000000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x4000000000 + zb0005Len-- + zb0005Mask |= 0x8000000000 } if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false { - zb0004Len-- - zb0004Mask |= 0x8000000000 + zb0005Len-- + zb0005Mask |= 0x10000000000 } - // variable map header, size zb0004Len - o = msgp.AppendMapHeader(o, zb0004Len) - if zb0004Len != 0 { - if (zb0004Mask & 0x80) == 0 { // if not empty + // variable map header, size zb0005Len + o = msgp.AppendMapHeader(o, zb0005Len) + if zb0005Len != 0 { + if (zb0005Mask & 0x80) == 0 { // if not empty // string "earn" o = append(o, 0xa4, 0x65, 0x61, 0x72, 0x6e) o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel) } - if (zb0004Mask & 0x100) == 0 { // if not empty + if (zb0005Mask & 0x100) == 0 { // if not empty // string "fc" o = append(o, 0xa2, 0x66, 0x63) o = (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MarshalMsg(o) } - if (zb0004Mask & 0x200) == 0 { // if not empty + if (zb0005Mask & 0x200) == 0 { // if not empty // string "fees" o = append(o, 0xa4, 0x66, 0x65, 0x65, 0x73) o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MarshalMsg(o) } - if (zb0004Mask & 0x400) == 0 { // if not empty + if (zb0005Mask & 0x400) == 0 { // if not empty // string "frac" o = append(o, 0xa4, 0x66, 0x72, 0x61, 0x63) o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue) } - if (zb0004Mask & 0x800) == 0 { // if not empty + if (zb0005Mask & 0x800) == 0 { // if not empty // string "gen" o = append(o, 0xa3, 0x67, 0x65, 0x6e) o = msgp.AppendString(o, (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID) } - if (zb0004Mask & 0x1000) == 0 { // if not empty + if (zb0005Mask & 0x1000) == 0 { // if not empty // string "gh" o = append(o, 0xa2, 0x67, 0x68) o = (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MarshalMsg(o) } - if (zb0004Mask & 0x2000) == 0 { // if not empty + if (zb0005Mask & 0x2000) == 0 { // if not empty // string "nextbefore" o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MarshalMsg(o) } - if (zb0004Mask & 0x4000) == 0 { // if not empty + if (zb0005Mask & 0x4000) == 0 { // if not empty // string "nextproto" o = append(o, 0xa9, 0x6e, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MarshalMsg(o) } - if (zb0004Mask & 0x8000) == 0 { // if not empty + if (zb0005Mask & 0x8000) == 0 { // if not empty // string "nextswitch" o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MarshalMsg(o) } - if (zb0004Mask & 0x10000) == 0 { // if not empty + if (zb0005Mask & 0x10000) == 0 { // if not empty // string "nextyes" o = append(o, 0xa7, 0x6e, 0x65, 0x78, 0x74, 0x79, 0x65, 0x73) o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals) } - if (zb0004Mask & 0x20000) == 0 { // if not empty + if (zb0005Mask & 0x20000) == 0 { // if not empty // string "oper" o = append(o, 0xa4, 0x6f, 0x70, 0x65, 0x72) o = msgp.AppendUint64(o, uint64((*z).unauthenticatedProposal.OriginalPeriod)) } - if (zb0004Mask & 0x40000) == 0 { // if not empty + if (zb0005Mask & 0x40000) == 0 { // if not empty // string "oprop" o = append(o, 0xa5, 0x6f, 0x70, 0x72, 0x6f, 0x70) o = (*z).unauthenticatedProposal.OriginalProposer.MarshalMsg(o) } - if (zb0004Mask & 0x80000) == 0 { // if not empty + if (zb0005Mask & 0x80000) == 0 { // if not empty + // string "partupdabs" + o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x61, 0x62, 0x73) + if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts == nil { + o = msgp.AppendNil(o) + } else { + o = msgp.AppendArrayHeader(o, uint32(len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts))) + } + for zb0004 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts { + o = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].MarshalMsg(o) + } + } + if (zb0005Mask & 0x100000) == 0 { // if not empty // string "partupdrmv" o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76) if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts == nil { @@ -9107,57 +9202,57 @@ func (z *transmittedPayload) MarshalMsg(b []byte) (o []byte) { o = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].MarshalMsg(o) } } - if (zb0004Mask & 0x100000) == 0 { // if not empty + if (zb0005Mask & 0x200000) == 0 { // if not empty // string "prev" o = append(o, 0xa4, 0x70, 0x72, 0x65, 0x76) o = (*z).unauthenticatedProposal.Block.BlockHeader.Branch.MarshalMsg(o) } - if (zb0004Mask & 0x200000) == 0 { // if not empty + if (zb0005Mask & 0x400000) == 0 { // if not empty // string "proto" o = append(o, 0xa5, 0x70, 0x72, 0x6f, 0x74, 0x6f) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MarshalMsg(o) } - if (zb0004Mask & 0x400000) == 0 { // if not empty + if (zb0005Mask & 0x800000) == 0 { // if not empty // string "prp" o = append(o, 0xa3, 0x70, 0x72, 0x70) o = (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MarshalMsg(o) } - if (zb0004Mask & 0x800000) == 0 { // if not empty + if (zb0005Mask & 0x1000000) == 0 { // if not empty // string "pv" o = append(o, 0xa2, 0x70, 0x76) o = (*z).PriorVote.MarshalMsg(o) } - if (zb0004Mask & 0x1000000) == 0 { // if not empty + if (zb0005Mask & 0x2000000) == 0 { // if not empty // string "rate" o = append(o, 0xa4, 0x72, 0x61, 0x74, 0x65) o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate) } - if (zb0004Mask & 0x4000000) == 0 { // if not empty + if (zb0005Mask & 0x8000000) == 0 { // if not empty // string "rnd" o = append(o, 0xa3, 0x72, 0x6e, 0x64) o = (*z).unauthenticatedProposal.Block.BlockHeader.Round.MarshalMsg(o) } - if (zb0004Mask & 0x8000000) == 0 { // if not empty + if (zb0005Mask & 0x10000000) == 0 { // if not empty // string "rwcalr" o = append(o, 0xa6, 0x72, 0x77, 0x63, 0x61, 0x6c, 0x72) o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MarshalMsg(o) } - if (zb0004Mask & 0x10000000) == 0 { // if not empty + if (zb0005Mask & 0x20000000) == 0 { // if not empty // string "rwd" o = append(o, 0xa3, 0x72, 0x77, 0x64) o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MarshalMsg(o) } - if (zb0004Mask & 0x20000000) == 0 { // if not empty + if (zb0005Mask & 0x40000000) == 0 { // if not empty // string "sdpf" o = append(o, 0xa4, 0x73, 0x64, 0x70, 0x66) o = (*z).unauthenticatedProposal.SeedProof.MarshalMsg(o) } - if (zb0004Mask & 0x40000000) == 0 { // if not empty + if (zb0005Mask & 0x80000000) == 0 { // if not empty // string "seed" o = append(o, 0xa4, 0x73, 0x65, 0x65, 0x64) o = (*z).unauthenticatedProposal.Block.BlockHeader.Seed.MarshalMsg(o) } - if (zb0004Mask & 0x80000000) == 0 { // if not empty + if (zb0005Mask & 0x100000000) == 0 { // if not empty // string "spt" o = append(o, 0xa3, 0x73, 0x70, 0x74) if (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking == nil { @@ -9177,42 +9272,42 @@ func (z *transmittedPayload) MarshalMsg(b []byte) (o []byte) { o = zb0002.MarshalMsg(o) } } - if (zb0004Mask & 0x100000000) == 0 { // if not empty + if (zb0005Mask & 0x200000000) == 0 { // if not empty // string "tc" o = append(o, 0xa2, 0x74, 0x63) o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter) } - if (zb0004Mask & 0x200000000) == 0 { // if not empty + if (zb0005Mask & 0x400000000) == 0 { // if not empty // string "ts" o = append(o, 0xa2, 0x74, 0x73) o = msgp.AppendInt64(o, (*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp) } - if (zb0004Mask & 0x400000000) == 0 { // if not empty + if (zb0005Mask & 0x800000000) == 0 { // if not empty // string "txn" o = append(o, 0xa3, 0x74, 0x78, 0x6e) o = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MarshalMsg(o) } - if (zb0004Mask & 0x800000000) == 0 { // if not empty + if (zb0005Mask & 0x1000000000) == 0 { // if not empty // string "txn256" o = append(o, 0xa6, 0x74, 0x78, 0x6e, 0x32, 0x35, 0x36) o = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MarshalMsg(o) } - if (zb0004Mask & 0x1000000000) == 0 { // if not empty + if (zb0005Mask & 0x2000000000) == 0 { // if not empty // string "txns" o = append(o, 0xa4, 0x74, 0x78, 0x6e, 0x73) o = (*z).unauthenticatedProposal.Block.Payset.MarshalMsg(o) } - if (zb0004Mask & 0x2000000000) == 0 { // if not empty + if (zb0005Mask & 0x4000000000) == 0 { // if not empty // string "upgradedelay" o = append(o, 0xac, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x65, 0x6c, 0x61, 0x79) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MarshalMsg(o) } - if (zb0004Mask & 0x4000000000) == 0 { // if not empty + if (zb0005Mask & 0x8000000000) == 0 { // if not empty // string "upgradeprop" o = append(o, 0xab, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x70, 0x72, 0x6f, 0x70) o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MarshalMsg(o) } - if (zb0004Mask & 0x8000000000) == 0 { // if not empty + if (zb0005Mask & 0x10000000000) == 0 { // if not empty // string "upgradeyes" o = append(o, 0xaa, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x65, 0x73) o = msgp.AppendBool(o, (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove) @@ -9235,73 +9330,73 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal st.AllowableDepth-- var field []byte _ = field - var zb0004 int - var zb0005 bool - zb0004, zb0005, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0005 int + var zb0006 bool + zb0005, zb0006, bts, err = msgp.ReadMapHeaderBytes(bts) if _, ok := err.(msgp.TypeError); ok { - zb0004, zb0005, bts, err = msgp.ReadArrayHeaderBytes(bts) + zb0005, zb0006, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err) return } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Round.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Round") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Branch.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Branch") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Seed.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Seed") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NativeSha512_256Commitment") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Sha256Commitment") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp, bts, err = msgp.ReadInt64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "TimeStamp") return } } - if zb0004 > 0 { - zb0004-- - var zb0006 int - zb0006, err = msgp.ReadBytesBytesHeader(bts) + if zb0005 > 0 { + zb0005-- + var zb0007 int + zb0007, err = msgp.ReadBytesBytesHeader(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "GenesisID") return } - if zb0006 > config.MaxGenesisIDLen { - err = msgp.ErrOverflow(uint64(zb0006), uint64(config.MaxGenesisIDLen)) + if zb0007 > config.MaxGenesisIDLen { + err = msgp.ErrOverflow(uint64(zb0007), uint64(config.MaxGenesisIDLen)) return } (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID, bts, err = msgp.ReadStringBytes(bts) @@ -9310,173 +9405,173 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "GenesisHash") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Proposer") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "FeesCollected") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "FeeSink") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsPool") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsLevel") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsRate") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsResidue") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsRecalculationRound") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "CurrentProtocol") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NextProtocol") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NextProtocolApprovals") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NextProtocolVoteBefore") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NextProtocolSwitchOn") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "UpgradePropose") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "UpgradeDelay") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove, bts, err = msgp.ReadBoolBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "UpgradeApprove") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "TxnCounter") return } } - if zb0004 > 0 { - zb0004-- - var zb0007 int - var zb0008 bool - zb0007, zb0008, bts, err = msgp.ReadMapHeaderBytes(bts) + if zb0005 > 0 { + zb0005-- + var zb0008 int + var zb0009 bool + zb0008, zb0009, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "StateProofTracking") return } - if zb0007 > protocol.NumStateProofTypes { - err = msgp.ErrOverflow(uint64(zb0007), uint64(protocol.NumStateProofTypes)) + if zb0008 > protocol.NumStateProofTypes { + err = msgp.ErrOverflow(uint64(zb0008), uint64(protocol.NumStateProofTypes)) err = msgp.WrapError(err, "struct-from-array", "StateProofTracking") return } - if zb0008 { + if zb0009 { (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = nil } else if (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking == nil { - (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0007) + (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0008) } - for zb0007 > 0 { + for zb0008 > 0 { var zb0001 protocol.StateProofType var zb0002 bookkeeping.StateProofTrackingData - zb0007-- + zb0008-- bts, err = zb0001.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "StateProofTracking") @@ -9490,26 +9585,26 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking[zb0001] = zb0002 } } - if zb0004 > 0 { - zb0004-- - var zb0009 int - var zb0010 bool - zb0009, zb0010, bts, err = msgp.ReadArrayHeaderBytes(bts) + if zb0005 > 0 { + zb0005-- + var zb0010 int + var zb0011 bool + zb0010, zb0011, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts") return } - if zb0009 > config.MaxProposedExpiredOnlineAccounts { - err = msgp.ErrOverflow(uint64(zb0009), uint64(config.MaxProposedExpiredOnlineAccounts)) + if zb0010 > config.MaxProposedExpiredOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0010), uint64(config.MaxProposedExpiredOnlineAccounts)) err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts") return } - if zb0010 { + if zb0011 { (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = nil - } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0009 { - (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0009] + } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0010 { + (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0010] } else { - (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0009) + (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0010) } for zb0003 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts { bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].UnmarshalMsgWithState(bts, st) @@ -9519,52 +9614,81 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal } } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- + var zb0012 int + var zb0013 bool + zb0012, zb0013, bts, err = msgp.ReadArrayHeaderBytes(bts) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts") + return + } + if zb0012 > config.MaxProposedAbsentOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0012), uint64(config.MaxProposedAbsentOnlineAccounts)) + err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts") + return + } + if zb0013 { + (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = nil + } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) >= zb0012 { + (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts)[:zb0012] + } else { + (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = make([]basics.Address, zb0012) + } + for zb0004 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts { + bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts", zb0004) + return + } + } + } + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.Block.Payset.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Payset") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.SeedProof.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "SeedProof") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- { - var zb0011 uint64 - zb0011, bts, err = msgp.ReadUint64Bytes(bts) + var zb0014 uint64 + zb0014, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "OriginalPeriod") return } - (*z).unauthenticatedProposal.OriginalPeriod = period(zb0011) + (*z).unauthenticatedProposal.OriginalPeriod = period(zb0014) } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).unauthenticatedProposal.OriginalProposer.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "OriginalProposer") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).PriorVote.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "PriorVote") return } } - if zb0004 > 0 { - err = msgp.ErrTooManyArrayFields(zb0004) + if zb0005 > 0 { + err = msgp.ErrTooManyArrayFields(zb0005) if err != nil { err = msgp.WrapError(err, "struct-from-array") return @@ -9575,11 +9699,11 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal err = msgp.WrapError(err) return } - if zb0005 { + if zb0006 { (*z) = transmittedPayload{} } - for zb0004 > 0 { - zb0004-- + for zb0005 > 0 { + zb0005-- field, bts, err = msgp.ReadMapKeyZC(bts) if err != nil { err = msgp.WrapError(err) @@ -9623,14 +9747,14 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal return } case "gen": - var zb0012 int - zb0012, err = msgp.ReadBytesBytesHeader(bts) + var zb0015 int + zb0015, err = msgp.ReadBytesBytesHeader(bts) if err != nil { err = msgp.WrapError(err, "GenesisID") return } - if zb0012 > config.MaxGenesisIDLen { - err = msgp.ErrOverflow(uint64(zb0012), uint64(config.MaxGenesisIDLen)) + if zb0015 > config.MaxGenesisIDLen { + err = msgp.ErrOverflow(uint64(zb0015), uint64(config.MaxGenesisIDLen)) return } (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID, bts, err = msgp.ReadStringBytes(bts) @@ -9747,27 +9871,27 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal return } case "spt": - var zb0013 int - var zb0014 bool - zb0013, zb0014, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0016 int + var zb0017 bool + zb0016, zb0017, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "StateProofTracking") return } - if zb0013 > protocol.NumStateProofTypes { - err = msgp.ErrOverflow(uint64(zb0013), uint64(protocol.NumStateProofTypes)) + if zb0016 > protocol.NumStateProofTypes { + err = msgp.ErrOverflow(uint64(zb0016), uint64(protocol.NumStateProofTypes)) err = msgp.WrapError(err, "StateProofTracking") return } - if zb0014 { + if zb0017 { (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = nil } else if (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking == nil { - (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0013) + (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0016) } - for zb0013 > 0 { + for zb0016 > 0 { var zb0001 protocol.StateProofType var zb0002 bookkeeping.StateProofTrackingData - zb0013-- + zb0016-- bts, err = zb0001.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "StateProofTracking") @@ -9781,24 +9905,24 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking[zb0001] = zb0002 } case "partupdrmv": - var zb0015 int - var zb0016 bool - zb0015, zb0016, bts, err = msgp.ReadArrayHeaderBytes(bts) + var zb0018 int + var zb0019 bool + zb0018, zb0019, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "ExpiredParticipationAccounts") return } - if zb0015 > config.MaxProposedExpiredOnlineAccounts { - err = msgp.ErrOverflow(uint64(zb0015), uint64(config.MaxProposedExpiredOnlineAccounts)) + if zb0018 > config.MaxProposedExpiredOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0018), uint64(config.MaxProposedExpiredOnlineAccounts)) err = msgp.WrapError(err, "ExpiredParticipationAccounts") return } - if zb0016 { + if zb0019 { (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = nil - } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0015 { - (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0015] + } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0018 { + (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0018] } else { - (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0015) + (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0018) } for zb0003 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts { bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].UnmarshalMsgWithState(bts, st) @@ -9807,6 +9931,33 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal return } } + case "partupdabs": + var zb0020 int + var zb0021 bool + zb0020, zb0021, bts, err = msgp.ReadArrayHeaderBytes(bts) + if err != nil { + err = msgp.WrapError(err, "AbsentParticipationAccounts") + return + } + if zb0020 > config.MaxProposedAbsentOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0020), uint64(config.MaxProposedAbsentOnlineAccounts)) + err = msgp.WrapError(err, "AbsentParticipationAccounts") + return + } + if zb0021 { + (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = nil + } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) >= zb0020 { + (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts)[:zb0020] + } else { + (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = make([]basics.Address, zb0020) + } + for zb0004 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts { + bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "AbsentParticipationAccounts", zb0004) + return + } + } case "txns": bts, err = (*z).unauthenticatedProposal.Block.Payset.UnmarshalMsgWithState(bts, st) if err != nil { @@ -9821,13 +9972,13 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal } case "oper": { - var zb0017 uint64 - zb0017, bts, err = msgp.ReadUint64Bytes(bts) + var zb0022 uint64 + zb0022, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "OriginalPeriod") return } - (*z).unauthenticatedProposal.OriginalPeriod = period(zb0017) + (*z).unauthenticatedProposal.OriginalPeriod = period(zb0022) } case "oprop": bts, err = (*z).unauthenticatedProposal.OriginalProposer.UnmarshalMsgWithState(bts, st) @@ -9876,13 +10027,17 @@ func (z *transmittedPayload) Msgsize() (s int) { for zb0003 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts { s += (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].Msgsize() } + s += 11 + msgp.ArrayHeaderSize + for zb0004 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts { + s += (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].Msgsize() + } s += 5 + (*z).unauthenticatedProposal.Block.Payset.Msgsize() + 5 + (*z).unauthenticatedProposal.SeedProof.Msgsize() + 5 + msgp.Uint64Size + 6 + (*z).unauthenticatedProposal.OriginalProposer.Msgsize() + 3 + (*z).PriorVote.Msgsize() return } // MsgIsZero returns whether this is a zero value func (z *transmittedPayload) MsgIsZero() bool { - return ((*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "") && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).unauthenticatedProposal.Block.Payset.MsgIsZero()) && ((*z).unauthenticatedProposal.SeedProof.MsgIsZero()) && ((*z).unauthenticatedProposal.OriginalPeriod == 0) && ((*z).unauthenticatedProposal.OriginalProposer.MsgIsZero()) && ((*z).PriorVote.MsgIsZero()) + return ((*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "") && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) == 0) && ((*z).unauthenticatedProposal.Block.Payset.MsgIsZero()) && ((*z).unauthenticatedProposal.SeedProof.MsgIsZero()) && ((*z).unauthenticatedProposal.OriginalPeriod == 0) && ((*z).unauthenticatedProposal.OriginalProposer.MsgIsZero()) && ((*z).PriorVote.MsgIsZero()) } // MaxSize returns a maximum valid message size for this message type @@ -9896,6 +10051,9 @@ func TransmittedPayloadMaxSize() (s int) { s += 11 // Calculating size of slice: z.unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts s += msgp.ArrayHeaderSize + ((config.MaxProposedExpiredOnlineAccounts) * (basics.AddressMaxSize())) + s += 11 + // Calculating size of slice: z.unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts + s += msgp.ArrayHeaderSize + ((config.MaxProposedAbsentOnlineAccounts) * (basics.AddressMaxSize())) s += 5 // Using maxtotalbytes for: z.unauthenticatedProposal.Block.Payset s += config.MaxTxnBytesPerBlock @@ -10608,196 +10766,212 @@ func UnauthenticatedEquivocationVoteMaxSize() (s int) { func (z *unauthenticatedProposal) MarshalMsg(b []byte) (o []byte) { o = msgp.Require(b, z.Msgsize()) // omitempty: check for empty values - zb0004Len := uint32(31) - var zb0004Mask uint64 /* 38 bits */ + zb0005Len := uint32(32) + var zb0005Mask uint64 /* 39 bits */ if (*z).Block.BlockHeader.RewardsState.RewardsLevel == 0 { - zb0004Len-- - zb0004Mask |= 0x40 + zb0005Len-- + zb0005Mask |= 0x40 } if (*z).Block.BlockHeader.FeesCollected.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x80 + zb0005Len-- + zb0005Mask |= 0x80 } if (*z).Block.BlockHeader.RewardsState.FeeSink.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x100 + zb0005Len-- + zb0005Mask |= 0x100 } if (*z).Block.BlockHeader.RewardsState.RewardsResidue == 0 { - zb0004Len-- - zb0004Mask |= 0x200 + zb0005Len-- + zb0005Mask |= 0x200 } if (*z).Block.BlockHeader.GenesisID == "" { - zb0004Len-- - zb0004Mask |= 0x400 + zb0005Len-- + zb0005Mask |= 0x400 } if (*z).Block.BlockHeader.GenesisHash.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x800 + zb0005Len-- + zb0005Mask |= 0x800 } if (*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x1000 + zb0005Len-- + zb0005Mask |= 0x1000 } if (*z).Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x2000 + zb0005Len-- + zb0005Mask |= 0x2000 } if (*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x4000 + zb0005Len-- + zb0005Mask |= 0x4000 } if (*z).Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0 { - zb0004Len-- - zb0004Mask |= 0x8000 + zb0005Len-- + zb0005Mask |= 0x8000 } if (*z).OriginalPeriod == 0 { - zb0004Len-- - zb0004Mask |= 0x10000 + zb0005Len-- + zb0005Mask |= 0x10000 } if (*z).OriginalProposer.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x20000 + zb0005Len-- + zb0005Mask |= 0x20000 + } + if len((*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) == 0 { + zb0005Len-- + zb0005Mask |= 0x40000 } if len((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 { - zb0004Len-- - zb0004Mask |= 0x40000 + zb0005Len-- + zb0005Mask |= 0x80000 } if (*z).Block.BlockHeader.Branch.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x80000 + zb0005Len-- + zb0005Mask |= 0x100000 } if (*z).Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x100000 + zb0005Len-- + zb0005Mask |= 0x200000 } if (*z).Block.BlockHeader.Proposer.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x200000 + zb0005Len-- + zb0005Mask |= 0x400000 } if (*z).Block.BlockHeader.RewardsState.RewardsRate == 0 { - zb0004Len-- - zb0004Mask |= 0x400000 + zb0005Len-- + zb0005Mask |= 0x800000 } if (*z).Block.BlockHeader.Round.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x1000000 + zb0005Len-- + zb0005Mask |= 0x2000000 } if (*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x2000000 + zb0005Len-- + zb0005Mask |= 0x4000000 } if (*z).Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x4000000 + zb0005Len-- + zb0005Mask |= 0x8000000 } if (*z).SeedProof.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x8000000 + zb0005Len-- + zb0005Mask |= 0x10000000 } if (*z).Block.BlockHeader.Seed.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x10000000 + zb0005Len-- + zb0005Mask |= 0x20000000 } if len((*z).Block.BlockHeader.StateProofTracking) == 0 { - zb0004Len-- - zb0004Mask |= 0x20000000 + zb0005Len-- + zb0005Mask |= 0x40000000 } if (*z).Block.BlockHeader.TxnCounter == 0 { - zb0004Len-- - zb0004Mask |= 0x40000000 + zb0005Len-- + zb0005Mask |= 0x80000000 } if (*z).Block.BlockHeader.TimeStamp == 0 { - zb0004Len-- - zb0004Mask |= 0x80000000 + zb0005Len-- + zb0005Mask |= 0x100000000 } if (*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x100000000 + zb0005Len-- + zb0005Mask |= 0x200000000 } if (*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x200000000 + zb0005Len-- + zb0005Mask |= 0x400000000 } if (*z).Block.Payset.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x400000000 + zb0005Len-- + zb0005Mask |= 0x800000000 } if (*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x800000000 + zb0005Len-- + zb0005Mask |= 0x1000000000 } if (*z).Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x1000000000 + zb0005Len-- + zb0005Mask |= 0x2000000000 } if (*z).Block.BlockHeader.UpgradeVote.UpgradeApprove == false { - zb0004Len-- - zb0004Mask |= 0x2000000000 + zb0005Len-- + zb0005Mask |= 0x4000000000 } - // variable map header, size zb0004Len - o = msgp.AppendMapHeader(o, zb0004Len) - if zb0004Len != 0 { - if (zb0004Mask & 0x40) == 0 { // if not empty + // variable map header, size zb0005Len + o = msgp.AppendMapHeader(o, zb0005Len) + if zb0005Len != 0 { + if (zb0005Mask & 0x40) == 0 { // if not empty // string "earn" o = append(o, 0xa4, 0x65, 0x61, 0x72, 0x6e) o = msgp.AppendUint64(o, (*z).Block.BlockHeader.RewardsState.RewardsLevel) } - if (zb0004Mask & 0x80) == 0 { // if not empty + if (zb0005Mask & 0x80) == 0 { // if not empty // string "fc" o = append(o, 0xa2, 0x66, 0x63) o = (*z).Block.BlockHeader.FeesCollected.MarshalMsg(o) } - if (zb0004Mask & 0x100) == 0 { // if not empty + if (zb0005Mask & 0x100) == 0 { // if not empty // string "fees" o = append(o, 0xa4, 0x66, 0x65, 0x65, 0x73) o = (*z).Block.BlockHeader.RewardsState.FeeSink.MarshalMsg(o) } - if (zb0004Mask & 0x200) == 0 { // if not empty + if (zb0005Mask & 0x200) == 0 { // if not empty // string "frac" o = append(o, 0xa4, 0x66, 0x72, 0x61, 0x63) o = msgp.AppendUint64(o, (*z).Block.BlockHeader.RewardsState.RewardsResidue) } - if (zb0004Mask & 0x400) == 0 { // if not empty + if (zb0005Mask & 0x400) == 0 { // if not empty // string "gen" o = append(o, 0xa3, 0x67, 0x65, 0x6e) o = msgp.AppendString(o, (*z).Block.BlockHeader.GenesisID) } - if (zb0004Mask & 0x800) == 0 { // if not empty + if (zb0005Mask & 0x800) == 0 { // if not empty // string "gh" o = append(o, 0xa2, 0x67, 0x68) o = (*z).Block.BlockHeader.GenesisHash.MarshalMsg(o) } - if (zb0004Mask & 0x1000) == 0 { // if not empty + if (zb0005Mask & 0x1000) == 0 { // if not empty // string "nextbefore" o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65) o = (*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MarshalMsg(o) } - if (zb0004Mask & 0x2000) == 0 { // if not empty + if (zb0005Mask & 0x2000) == 0 { // if not empty // string "nextproto" o = append(o, 0xa9, 0x6e, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f) o = (*z).Block.BlockHeader.UpgradeState.NextProtocol.MarshalMsg(o) } - if (zb0004Mask & 0x4000) == 0 { // if not empty + if (zb0005Mask & 0x4000) == 0 { // if not empty // string "nextswitch" o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68) o = (*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MarshalMsg(o) } - if (zb0004Mask & 0x8000) == 0 { // if not empty + if (zb0005Mask & 0x8000) == 0 { // if not empty // string "nextyes" o = append(o, 0xa7, 0x6e, 0x65, 0x78, 0x74, 0x79, 0x65, 0x73) o = msgp.AppendUint64(o, (*z).Block.BlockHeader.UpgradeState.NextProtocolApprovals) } - if (zb0004Mask & 0x10000) == 0 { // if not empty + if (zb0005Mask & 0x10000) == 0 { // if not empty // string "oper" o = append(o, 0xa4, 0x6f, 0x70, 0x65, 0x72) o = msgp.AppendUint64(o, uint64((*z).OriginalPeriod)) } - if (zb0004Mask & 0x20000) == 0 { // if not empty + if (zb0005Mask & 0x20000) == 0 { // if not empty // string "oprop" o = append(o, 0xa5, 0x6f, 0x70, 0x72, 0x6f, 0x70) o = (*z).OriginalProposer.MarshalMsg(o) } - if (zb0004Mask & 0x40000) == 0 { // if not empty + if (zb0005Mask & 0x40000) == 0 { // if not empty + // string "partupdabs" + o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x61, 0x62, 0x73) + if (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts == nil { + o = msgp.AppendNil(o) + } else { + o = msgp.AppendArrayHeader(o, uint32(len((*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts))) + } + for zb0004 := range (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts { + o = (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].MarshalMsg(o) + } + } + if (zb0005Mask & 0x80000) == 0 { // if not empty // string "partupdrmv" o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76) if (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts == nil { @@ -10809,52 +10983,52 @@ func (z *unauthenticatedProposal) MarshalMsg(b []byte) (o []byte) { o = (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].MarshalMsg(o) } } - if (zb0004Mask & 0x80000) == 0 { // if not empty + if (zb0005Mask & 0x100000) == 0 { // if not empty // string "prev" o = append(o, 0xa4, 0x70, 0x72, 0x65, 0x76) o = (*z).Block.BlockHeader.Branch.MarshalMsg(o) } - if (zb0004Mask & 0x100000) == 0 { // if not empty + if (zb0005Mask & 0x200000) == 0 { // if not empty // string "proto" o = append(o, 0xa5, 0x70, 0x72, 0x6f, 0x74, 0x6f) o = (*z).Block.BlockHeader.UpgradeState.CurrentProtocol.MarshalMsg(o) } - if (zb0004Mask & 0x200000) == 0 { // if not empty + if (zb0005Mask & 0x400000) == 0 { // if not empty // string "prp" o = append(o, 0xa3, 0x70, 0x72, 0x70) o = (*z).Block.BlockHeader.Proposer.MarshalMsg(o) } - if (zb0004Mask & 0x400000) == 0 { // if not empty + if (zb0005Mask & 0x800000) == 0 { // if not empty // string "rate" o = append(o, 0xa4, 0x72, 0x61, 0x74, 0x65) o = msgp.AppendUint64(o, (*z).Block.BlockHeader.RewardsState.RewardsRate) } - if (zb0004Mask & 0x1000000) == 0 { // if not empty + if (zb0005Mask & 0x2000000) == 0 { // if not empty // string "rnd" o = append(o, 0xa3, 0x72, 0x6e, 0x64) o = (*z).Block.BlockHeader.Round.MarshalMsg(o) } - if (zb0004Mask & 0x2000000) == 0 { // if not empty + if (zb0005Mask & 0x4000000) == 0 { // if not empty // string "rwcalr" o = append(o, 0xa6, 0x72, 0x77, 0x63, 0x61, 0x6c, 0x72) o = (*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.MarshalMsg(o) } - if (zb0004Mask & 0x4000000) == 0 { // if not empty + if (zb0005Mask & 0x8000000) == 0 { // if not empty // string "rwd" o = append(o, 0xa3, 0x72, 0x77, 0x64) o = (*z).Block.BlockHeader.RewardsState.RewardsPool.MarshalMsg(o) } - if (zb0004Mask & 0x8000000) == 0 { // if not empty + if (zb0005Mask & 0x10000000) == 0 { // if not empty // string "sdpf" o = append(o, 0xa4, 0x73, 0x64, 0x70, 0x66) o = (*z).SeedProof.MarshalMsg(o) } - if (zb0004Mask & 0x10000000) == 0 { // if not empty + if (zb0005Mask & 0x20000000) == 0 { // if not empty // string "seed" o = append(o, 0xa4, 0x73, 0x65, 0x65, 0x64) o = (*z).Block.BlockHeader.Seed.MarshalMsg(o) } - if (zb0004Mask & 0x20000000) == 0 { // if not empty + if (zb0005Mask & 0x40000000) == 0 { // if not empty // string "spt" o = append(o, 0xa3, 0x73, 0x70, 0x74) if (*z).Block.BlockHeader.StateProofTracking == nil { @@ -10874,42 +11048,42 @@ func (z *unauthenticatedProposal) MarshalMsg(b []byte) (o []byte) { o = zb0002.MarshalMsg(o) } } - if (zb0004Mask & 0x40000000) == 0 { // if not empty + if (zb0005Mask & 0x80000000) == 0 { // if not empty // string "tc" o = append(o, 0xa2, 0x74, 0x63) o = msgp.AppendUint64(o, (*z).Block.BlockHeader.TxnCounter) } - if (zb0004Mask & 0x80000000) == 0 { // if not empty + if (zb0005Mask & 0x100000000) == 0 { // if not empty // string "ts" o = append(o, 0xa2, 0x74, 0x73) o = msgp.AppendInt64(o, (*z).Block.BlockHeader.TimeStamp) } - if (zb0004Mask & 0x100000000) == 0 { // if not empty + if (zb0005Mask & 0x200000000) == 0 { // if not empty // string "txn" o = append(o, 0xa3, 0x74, 0x78, 0x6e) o = (*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MarshalMsg(o) } - if (zb0004Mask & 0x200000000) == 0 { // if not empty + if (zb0005Mask & 0x400000000) == 0 { // if not empty // string "txn256" o = append(o, 0xa6, 0x74, 0x78, 0x6e, 0x32, 0x35, 0x36) o = (*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.MarshalMsg(o) } - if (zb0004Mask & 0x400000000) == 0 { // if not empty + if (zb0005Mask & 0x800000000) == 0 { // if not empty // string "txns" o = append(o, 0xa4, 0x74, 0x78, 0x6e, 0x73) o = (*z).Block.Payset.MarshalMsg(o) } - if (zb0004Mask & 0x800000000) == 0 { // if not empty + if (zb0005Mask & 0x1000000000) == 0 { // if not empty // string "upgradedelay" o = append(o, 0xac, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x65, 0x6c, 0x61, 0x79) o = (*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.MarshalMsg(o) } - if (zb0004Mask & 0x1000000000) == 0 { // if not empty + if (zb0005Mask & 0x2000000000) == 0 { // if not empty // string "upgradeprop" o = append(o, 0xab, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x70, 0x72, 0x6f, 0x70) o = (*z).Block.BlockHeader.UpgradeVote.UpgradePropose.MarshalMsg(o) } - if (zb0004Mask & 0x2000000000) == 0 { // if not empty + if (zb0005Mask & 0x4000000000) == 0 { // if not empty // string "upgradeyes" o = append(o, 0xaa, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x65, 0x73) o = msgp.AppendBool(o, (*z).Block.BlockHeader.UpgradeVote.UpgradeApprove) @@ -10932,73 +11106,73 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma st.AllowableDepth-- var field []byte _ = field - var zb0004 int - var zb0005 bool - zb0004, zb0005, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0005 int + var zb0006 bool + zb0005, zb0006, bts, err = msgp.ReadMapHeaderBytes(bts) if _, ok := err.(msgp.TypeError); ok { - zb0004, zb0005, bts, err = msgp.ReadArrayHeaderBytes(bts) + zb0005, zb0006, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err) return } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Block.BlockHeader.Round.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Round") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Block.BlockHeader.Branch.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Branch") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Block.BlockHeader.Seed.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Seed") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NativeSha512_256Commitment") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Sha256Commitment") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).Block.BlockHeader.TimeStamp, bts, err = msgp.ReadInt64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "TimeStamp") return } } - if zb0004 > 0 { - zb0004-- - var zb0006 int - zb0006, err = msgp.ReadBytesBytesHeader(bts) + if zb0005 > 0 { + zb0005-- + var zb0007 int + zb0007, err = msgp.ReadBytesBytesHeader(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "GenesisID") return } - if zb0006 > config.MaxGenesisIDLen { - err = msgp.ErrOverflow(uint64(zb0006), uint64(config.MaxGenesisIDLen)) + if zb0007 > config.MaxGenesisIDLen { + err = msgp.ErrOverflow(uint64(zb0007), uint64(config.MaxGenesisIDLen)) return } (*z).Block.BlockHeader.GenesisID, bts, err = msgp.ReadStringBytes(bts) @@ -11007,173 +11181,173 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Block.BlockHeader.GenesisHash.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "GenesisHash") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Block.BlockHeader.Proposer.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Proposer") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Block.BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "FeesCollected") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Block.BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "FeeSink") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Block.BlockHeader.RewardsState.RewardsPool.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsPool") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).Block.BlockHeader.RewardsState.RewardsLevel, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsLevel") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).Block.BlockHeader.RewardsState.RewardsRate, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsRate") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).Block.BlockHeader.RewardsState.RewardsResidue, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsResidue") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsRecalculationRound") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Block.BlockHeader.UpgradeState.CurrentProtocol.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "CurrentProtocol") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Block.BlockHeader.UpgradeState.NextProtocol.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NextProtocol") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).Block.BlockHeader.UpgradeState.NextProtocolApprovals, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NextProtocolApprovals") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NextProtocolVoteBefore") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NextProtocolSwitchOn") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Block.BlockHeader.UpgradeVote.UpgradePropose.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "UpgradePropose") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "UpgradeDelay") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).Block.BlockHeader.UpgradeVote.UpgradeApprove, bts, err = msgp.ReadBoolBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "UpgradeApprove") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).Block.BlockHeader.TxnCounter, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "TxnCounter") return } } - if zb0004 > 0 { - zb0004-- - var zb0007 int - var zb0008 bool - zb0007, zb0008, bts, err = msgp.ReadMapHeaderBytes(bts) + if zb0005 > 0 { + zb0005-- + var zb0008 int + var zb0009 bool + zb0008, zb0009, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "StateProofTracking") return } - if zb0007 > protocol.NumStateProofTypes { - err = msgp.ErrOverflow(uint64(zb0007), uint64(protocol.NumStateProofTypes)) + if zb0008 > protocol.NumStateProofTypes { + err = msgp.ErrOverflow(uint64(zb0008), uint64(protocol.NumStateProofTypes)) err = msgp.WrapError(err, "struct-from-array", "StateProofTracking") return } - if zb0008 { + if zb0009 { (*z).Block.BlockHeader.StateProofTracking = nil } else if (*z).Block.BlockHeader.StateProofTracking == nil { - (*z).Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0007) + (*z).Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0008) } - for zb0007 > 0 { + for zb0008 > 0 { var zb0001 protocol.StateProofType var zb0002 bookkeeping.StateProofTrackingData - zb0007-- + zb0008-- bts, err = zb0001.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "StateProofTracking") @@ -11187,26 +11361,26 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma (*z).Block.BlockHeader.StateProofTracking[zb0001] = zb0002 } } - if zb0004 > 0 { - zb0004-- - var zb0009 int - var zb0010 bool - zb0009, zb0010, bts, err = msgp.ReadArrayHeaderBytes(bts) + if zb0005 > 0 { + zb0005-- + var zb0010 int + var zb0011 bool + zb0010, zb0011, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts") return } - if zb0009 > config.MaxProposedExpiredOnlineAccounts { - err = msgp.ErrOverflow(uint64(zb0009), uint64(config.MaxProposedExpiredOnlineAccounts)) + if zb0010 > config.MaxProposedExpiredOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0010), uint64(config.MaxProposedExpiredOnlineAccounts)) err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts") return } - if zb0010 { + if zb0011 { (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = nil - } else if (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0009 { - (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0009] + } else if (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0010 { + (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0010] } else { - (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0009) + (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0010) } for zb0003 := range (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts { bts, err = (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].UnmarshalMsgWithState(bts, st) @@ -11216,44 +11390,73 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma } } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- + var zb0012 int + var zb0013 bool + zb0012, zb0013, bts, err = msgp.ReadArrayHeaderBytes(bts) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts") + return + } + if zb0012 > config.MaxProposedAbsentOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0012), uint64(config.MaxProposedAbsentOnlineAccounts)) + err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts") + return + } + if zb0013 { + (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = nil + } else if (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts != nil && cap((*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) >= zb0012 { + (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = ((*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts)[:zb0012] + } else { + (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = make([]basics.Address, zb0012) + } + for zb0004 := range (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts { + bts, err = (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts", zb0004) + return + } + } + } + if zb0005 > 0 { + zb0005-- bts, err = (*z).Block.Payset.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Payset") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).SeedProof.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "SeedProof") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- { - var zb0011 uint64 - zb0011, bts, err = msgp.ReadUint64Bytes(bts) + var zb0014 uint64 + zb0014, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "OriginalPeriod") return } - (*z).OriginalPeriod = period(zb0011) + (*z).OriginalPeriod = period(zb0014) } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).OriginalProposer.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "OriginalProposer") return } } - if zb0004 > 0 { - err = msgp.ErrTooManyArrayFields(zb0004) + if zb0005 > 0 { + err = msgp.ErrTooManyArrayFields(zb0005) if err != nil { err = msgp.WrapError(err, "struct-from-array") return @@ -11264,11 +11467,11 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma err = msgp.WrapError(err) return } - if zb0005 { + if zb0006 { (*z) = unauthenticatedProposal{} } - for zb0004 > 0 { - zb0004-- + for zb0005 > 0 { + zb0005-- field, bts, err = msgp.ReadMapKeyZC(bts) if err != nil { err = msgp.WrapError(err) @@ -11312,14 +11515,14 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma return } case "gen": - var zb0012 int - zb0012, err = msgp.ReadBytesBytesHeader(bts) + var zb0015 int + zb0015, err = msgp.ReadBytesBytesHeader(bts) if err != nil { err = msgp.WrapError(err, "GenesisID") return } - if zb0012 > config.MaxGenesisIDLen { - err = msgp.ErrOverflow(uint64(zb0012), uint64(config.MaxGenesisIDLen)) + if zb0015 > config.MaxGenesisIDLen { + err = msgp.ErrOverflow(uint64(zb0015), uint64(config.MaxGenesisIDLen)) return } (*z).Block.BlockHeader.GenesisID, bts, err = msgp.ReadStringBytes(bts) @@ -11436,27 +11639,27 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma return } case "spt": - var zb0013 int - var zb0014 bool - zb0013, zb0014, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0016 int + var zb0017 bool + zb0016, zb0017, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "StateProofTracking") return } - if zb0013 > protocol.NumStateProofTypes { - err = msgp.ErrOverflow(uint64(zb0013), uint64(protocol.NumStateProofTypes)) + if zb0016 > protocol.NumStateProofTypes { + err = msgp.ErrOverflow(uint64(zb0016), uint64(protocol.NumStateProofTypes)) err = msgp.WrapError(err, "StateProofTracking") return } - if zb0014 { + if zb0017 { (*z).Block.BlockHeader.StateProofTracking = nil } else if (*z).Block.BlockHeader.StateProofTracking == nil { - (*z).Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0013) + (*z).Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0016) } - for zb0013 > 0 { + for zb0016 > 0 { var zb0001 protocol.StateProofType var zb0002 bookkeeping.StateProofTrackingData - zb0013-- + zb0016-- bts, err = zb0001.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "StateProofTracking") @@ -11470,24 +11673,24 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma (*z).Block.BlockHeader.StateProofTracking[zb0001] = zb0002 } case "partupdrmv": - var zb0015 int - var zb0016 bool - zb0015, zb0016, bts, err = msgp.ReadArrayHeaderBytes(bts) + var zb0018 int + var zb0019 bool + zb0018, zb0019, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "ExpiredParticipationAccounts") return } - if zb0015 > config.MaxProposedExpiredOnlineAccounts { - err = msgp.ErrOverflow(uint64(zb0015), uint64(config.MaxProposedExpiredOnlineAccounts)) + if zb0018 > config.MaxProposedExpiredOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0018), uint64(config.MaxProposedExpiredOnlineAccounts)) err = msgp.WrapError(err, "ExpiredParticipationAccounts") return } - if zb0016 { + if zb0019 { (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = nil - } else if (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0015 { - (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0015] + } else if (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0018 { + (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0018] } else { - (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0015) + (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0018) } for zb0003 := range (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts { bts, err = (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].UnmarshalMsgWithState(bts, st) @@ -11496,6 +11699,33 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma return } } + case "partupdabs": + var zb0020 int + var zb0021 bool + zb0020, zb0021, bts, err = msgp.ReadArrayHeaderBytes(bts) + if err != nil { + err = msgp.WrapError(err, "AbsentParticipationAccounts") + return + } + if zb0020 > config.MaxProposedAbsentOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0020), uint64(config.MaxProposedAbsentOnlineAccounts)) + err = msgp.WrapError(err, "AbsentParticipationAccounts") + return + } + if zb0021 { + (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = nil + } else if (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts != nil && cap((*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) >= zb0020 { + (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = ((*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts)[:zb0020] + } else { + (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = make([]basics.Address, zb0020) + } + for zb0004 := range (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts { + bts, err = (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "AbsentParticipationAccounts", zb0004) + return + } + } case "txns": bts, err = (*z).Block.Payset.UnmarshalMsgWithState(bts, st) if err != nil { @@ -11510,13 +11740,13 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma } case "oper": { - var zb0017 uint64 - zb0017, bts, err = msgp.ReadUint64Bytes(bts) + var zb0022 uint64 + zb0022, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "OriginalPeriod") return } - (*z).OriginalPeriod = period(zb0017) + (*z).OriginalPeriod = period(zb0022) } case "oprop": bts, err = (*z).OriginalProposer.UnmarshalMsgWithState(bts, st) @@ -11559,13 +11789,17 @@ func (z *unauthenticatedProposal) Msgsize() (s int) { for zb0003 := range (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts { s += (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].Msgsize() } + s += 11 + msgp.ArrayHeaderSize + for zb0004 := range (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts { + s += (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].Msgsize() + } s += 5 + (*z).Block.Payset.Msgsize() + 5 + (*z).SeedProof.Msgsize() + 5 + msgp.Uint64Size + 6 + (*z).OriginalProposer.Msgsize() return } // MsgIsZero returns whether this is a zero value func (z *unauthenticatedProposal) MsgIsZero() bool { - return ((*z).Block.BlockHeader.Round.MsgIsZero()) && ((*z).Block.BlockHeader.Branch.MsgIsZero()) && ((*z).Block.BlockHeader.Seed.MsgIsZero()) && ((*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).Block.BlockHeader.TimeStamp == 0) && ((*z).Block.BlockHeader.GenesisID == "") && ((*z).Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).Block.BlockHeader.Proposer.MsgIsZero()) && ((*z).Block.BlockHeader.FeesCollected.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).Block.BlockHeader.TxnCounter == 0) && (len((*z).Block.BlockHeader.StateProofTracking) == 0) && (len((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).Block.Payset.MsgIsZero()) && ((*z).SeedProof.MsgIsZero()) && ((*z).OriginalPeriod == 0) && ((*z).OriginalProposer.MsgIsZero()) + return ((*z).Block.BlockHeader.Round.MsgIsZero()) && ((*z).Block.BlockHeader.Branch.MsgIsZero()) && ((*z).Block.BlockHeader.Seed.MsgIsZero()) && ((*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).Block.BlockHeader.TimeStamp == 0) && ((*z).Block.BlockHeader.GenesisID == "") && ((*z).Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).Block.BlockHeader.Proposer.MsgIsZero()) && ((*z).Block.BlockHeader.FeesCollected.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).Block.BlockHeader.TxnCounter == 0) && (len((*z).Block.BlockHeader.StateProofTracking) == 0) && (len((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && (len((*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) == 0) && ((*z).Block.Payset.MsgIsZero()) && ((*z).SeedProof.MsgIsZero()) && ((*z).OriginalPeriod == 0) && ((*z).OriginalProposer.MsgIsZero()) } // MaxSize returns a maximum valid message size for this message type @@ -11579,6 +11813,9 @@ func UnauthenticatedProposalMaxSize() (s int) { s += 11 // Calculating size of slice: z.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts s += msgp.ArrayHeaderSize + ((config.MaxProposedExpiredOnlineAccounts) * (basics.AddressMaxSize())) + s += 11 + // Calculating size of slice: z.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts + s += msgp.ArrayHeaderSize + ((config.MaxProposedAbsentOnlineAccounts) * (basics.AddressMaxSize())) s += 5 // Using maxtotalbytes for: z.Block.Payset s += config.MaxTxnBytesPerBlock diff --git a/cmd/goal/accountsList.go b/cmd/goal/accountsList.go index 390d3b2b07..2a0f43203d 100644 --- a/cmd/goal/accountsList.go +++ b/cmd/goal/accountsList.go @@ -216,6 +216,8 @@ func (accountList *AccountsList) outputAccount(addr string, acctInfo model.Accou status = "offline" case basics.NotParticipating.String(): status = "excluded" + case basics.Suspended.String(): + status = "suspended" default: panic(fmt.Sprintf("unexpected account status: %v", acctInfo.Status)) } diff --git a/cmd/incorporate/incorporate.go b/cmd/incorporate/incorporate.go index 97d4b44d66..7256dcdff7 100644 --- a/cmd/incorporate/incorporate.go +++ b/cmd/incorporate/incorporate.go @@ -235,6 +235,8 @@ func parseRecord(cols []string) (rec record) { rec.Status = basics.Offline case "NotParticipating": rec.Status = basics.NotParticipating + case "Suspended": + rec.Status = basics.Suspended default: log.Fatalf("unknown status: %s", cols[3]) } diff --git a/config/consensus.go b/config/consensus.go index 9baae64af1..b9cb9df3ac 100644 --- a/config/consensus.go +++ b/config/consensus.go @@ -440,10 +440,14 @@ type ConsensusParams struct { EnableExtraPagesOnAppUpdate bool - // MaxProposedExpiredOnlineAccounts is the maximum number of online accounts, which need - // to be taken offline, that would be proposed to be taken offline. + // MaxProposedExpiredOnlineAccounts is the maximum number of online accounts + // that a proposer can take offline for having expired voting keys. MaxProposedExpiredOnlineAccounts int + // MaxProposedAbsentOnlineAccounts is the maximum number of online accounts, + // that a proposer can suspend for not proposing "lately" (TBD) + MaxProposedAbsentOnlineAccounts int + // EnableAccountDataResourceSeparation enables the support for extended application and asset storage // in a separate table. EnableAccountDataResourceSeparation bool @@ -531,6 +535,10 @@ type ConsensusParams struct { MiningPercent uint64 } +func (cp ConsensusParams) EnableAbsenteeTracking() bool { + return cp.MaxProposedAbsentOnlineAccounts > 0 +} + // PaysetCommitType enumerates possible ways for the block header to commit to // the set of transactions in the block. type PaysetCommitType int @@ -603,10 +611,14 @@ var MaxExtraAppProgramLen int // supported supported by any of the consensus protocols. used for decoding purposes. var MaxAvailableAppProgramLen int -// MaxProposedExpiredOnlineAccounts is the maximum number of online accounts, which need -// to be taken offline, that would be proposed to be taken offline. +// MaxProposedExpiredOnlineAccounts is the maximum number of online accounts +// that a proposer can take offline for having expired voting keys. var MaxProposedExpiredOnlineAccounts int +// MaxProposedAbsentOnlineAccounts is the maximum number of online accounts, +// that a proposer can suspend for not proposing "lately" (TBD) +var MaxProposedAbsentOnlineAccounts int + // MaxAppTotalArgLen is the maximum number of bytes across all arguments of an application // max sum([len(arg) for arg in txn.ApplicationArgs]) var MaxAppTotalArgLen int @@ -677,6 +689,7 @@ func checkSetAllocBounds(p ConsensusParams) { checkSetMax(p.MaxAppProgramLen, &MaxLogCalls) checkSetMax(p.MaxInnerTransactions*p.MaxTxGroupSize, &MaxInnerTransactionsPerDelta) checkSetMax(p.MaxProposedExpiredOnlineAccounts, &MaxProposedExpiredOnlineAccounts) + checkSetMax(p.MaxProposedAbsentOnlineAccounts, &MaxProposedAbsentOnlineAccounts) // These bounds are exported to make them available to the msgp generator for calculating // maximum valid message size for each message going across the wire. @@ -1379,6 +1392,8 @@ func initConsensusProtocols() { vFuture.LogicSigVersion = 10 // When moving this to a release, put a new higher LogicSigVersion here vFuture.EnableLogicSigCostPooling = true + vFuture.MaxProposedAbsentOnlineAccounts = 32 + // Setting DynamicFilterTimeout in vFuture will impact e2e test performance // by reducing round time. Hence, it is commented out for now. // vFuture.DynamicFilterTimeout = true diff --git a/daemon/algod/api/Makefile b/daemon/algod/api/Makefile index c4104d9e80..c45093e6b4 100644 --- a/daemon/algod/api/Makefile +++ b/daemon/algod/api/Makefile @@ -30,6 +30,7 @@ server/v2/generated/model/types.go: algod.oas3.yml $(GOPATH1)/bin/oapi-codegen -config ./server/v2/generated/model/model_types.yml algod.oas3.yml algod.oas3.yml: algod.oas2.json + jq < algod.oas2.json # fail with a nice explantion if json is malformed curl -s -X POST "https://converter.swagger.io/api/convert" -H "accept: application/json" -H "Content-Type: application/json" -d @./algod.oas2.json -o .3tmp.json python3 jsoncanon.py < .3tmp.json > algod.oas3.yml rm -f .3tmp.json diff --git a/daemon/algod/api/algod.oas2.json b/daemon/algod/api/algod.oas2.json index b37f2001c4..c51902064f 100644 --- a/daemon/algod/api/algod.oas2.json +++ b/daemon/algod/api/algod.oas2.json @@ -3016,6 +3016,14 @@ "description": "\\[spend\\] the address against which signing should be checked. If empty, the address of the current account is used. This field can be updated in any transaction by setting the RekeyTo field.", "type": "string", "x-algorand-format": "Address" + }, + "last-proposed": { + "description": "The round in which this account last proposed the block.", + "type": "integer" + }, + "last-heartbeat": { + "description": "The round in which this account last went online, or explicitly renewed their online status.", + "type": "integer" } } }, diff --git a/daemon/algod/api/algod.oas3.yml b/daemon/algod/api/algod.oas3.yml index c8c82e0d98..bb7508bb43 100644 --- a/daemon/algod/api/algod.oas3.yml +++ b/daemon/algod/api/algod.oas3.yml @@ -1067,6 +1067,14 @@ }, "type": "array" }, + "last-heartbeat": { + "description": "The round in which this account last went online, or explicitly renewed their online status.", + "type": "integer" + }, + "last-proposed": { + "description": "The round in which this account last proposed the block.", + "type": "integer" + }, "min-balance": { "description": "MicroAlgo balance required by the account.\n\nThe requirement grows based on asset and application usage.", "type": "integer" diff --git a/daemon/algod/api/server/v2/account.go b/daemon/algod/api/server/v2/account.go index 31483d63b9..875d9ed3f5 100644 --- a/daemon/algod/api/server/v2/account.go +++ b/daemon/algod/api/server/v2/account.go @@ -137,6 +137,8 @@ func AccountDataToAccount( TotalBoxes: omitEmpty(record.TotalBoxes), TotalBoxBytes: omitEmpty(record.TotalBoxBytes), MinBalance: minBalance.Raw, + LastProposed: omitEmpty(uint64(record.LastProposed)), + LastHeartbeat: omitEmpty(uint64(record.LastHeartbeat)), }, nil } @@ -340,6 +342,16 @@ func AccountToAccountData(a *model.Account) (basics.AccountData, error) { totalBoxBytes = *a.TotalBoxBytes } + var lastProposed uint64 + if a.LastProposed != nil { + lastProposed = *a.LastProposed + } + + var lastHeartbeat uint64 + if a.LastHeartbeat != nil { + lastHeartbeat = *a.LastHeartbeat + } + status, err := basics.UnmarshalStatus(a.Status) if err != nil { return basics.AccountData{}, err @@ -362,6 +374,8 @@ func AccountToAccountData(a *model.Account) (basics.AccountData, error) { TotalExtraAppPages: totalExtraPages, TotalBoxes: totalBoxes, TotalBoxBytes: totalBoxBytes, + LastProposed: basics.Round(lastProposed), + LastHeartbeat: basics.Round(lastHeartbeat), } if a.AuthAddr != nil { diff --git a/daemon/algod/api/server/v2/generated/data/routes.go b/daemon/algod/api/server/v2/generated/data/routes.go index 9fd389f273..0c4722b9a6 100644 --- a/daemon/algod/api/server/v2/generated/data/routes.go +++ b/daemon/algod/api/server/v2/generated/data/routes.go @@ -192,132 +192,133 @@ var swaggerSpec = []string{ "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", - "AA==", + "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", + "AAA=", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/daemon/algod/api/server/v2/generated/experimental/routes.go b/daemon/algod/api/server/v2/generated/experimental/routes.go index 1888e71ef1..b27b87907c 100644 --- a/daemon/algod/api/server/v2/generated/experimental/routes.go +++ b/daemon/algod/api/server/v2/generated/experimental/routes.go @@ -90,210 +90,211 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", - "JZpUkq0x7+7Hz/83AAD//8gL9x7v8QAA", + "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", + "WaJJJdka8+6+//h/AwAA//8xVaDS7PIAAA==", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/daemon/algod/api/server/v2/generated/model/types.go b/daemon/algod/api/server/v2/generated/model/types.go index c30caa6c94..c99830a35a 100644 --- a/daemon/algod/api/server/v2/generated/model/types.go +++ b/daemon/algod/api/server/v2/generated/model/types.go @@ -185,6 +185,12 @@ type Account struct { // Note: the raw account uses `map[int] -> Asset` for this type. CreatedAssets *[]Asset `json:"created-assets,omitempty"` + // LastHeartbeat The round in which this account last went online, or explicitly renewed their online status. + LastHeartbeat *uint64 `json:"last-heartbeat,omitempty"` + + // LastProposed The round in which this account last proposed the block. + LastProposed *uint64 `json:"last-proposed,omitempty"` + // MinBalance MicroAlgo balance required by the account. // // The requirement grows based on asset and application usage. diff --git a/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go b/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go index 3d3c20de36..0ecc35d394 100644 --- a/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go +++ b/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go @@ -140,211 +140,212 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL var swaggerSpec = []string{ "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", "AAA=", } diff --git a/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go b/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go index 89202c3fb1..059f7ef6d9 100644 --- a/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go +++ b/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go @@ -802,208 +802,209 @@ var swaggerSpec = []string{ "ERd3ar/yRcLiS8BHuIX4jhE3asf/ZfcryO299Ha18oM7u1TqRWLOdnRVypC435mqdtDcCFk+GkOxOWqr", "rszSFEi6gPTc1b+BZaE348bnPuDHCZqedTBlKyPZzDyszYEOiimQssioE8Up37SLJCjQ2ocVv4Fz2JyJ", "urTHPlURmkn6qu+gIqUG0qUh1vDYujHam++iylCxLwqf645Jj54snlZ04b/pP8hW5D3AIY4RRSOJvA8R", - "VEYQYYm/BwWXWKgZ70qkH1ue0TKm9uaLVEnyvJ+4V2rlyQWAhatBq7t9vgQssyYuFJlSI7cLVyHMJqIH", - "XKxUdA49EnLoIxqY7t3wK+Egu+696E0nZu0LrXPfREG2LydmzVFKAfPEkAoqM62wPz+TdUM6zwQW/nQI", - "m+YoJlXxkZbpUNnw1dlKhn2gxQkYJK8FDg9GEyOhZLOgyhcvwxpv/iwPkgGusbDCtnI6J0HEWlDIrSqW", - "43lu+5x2tEtXVMdX0vHlc0LVckApHCPhY5B8bDsERwEogxzmduH2ZU8odZGHeoMMHD/PZjnjQJJY8Ftg", - "Bg2uGTcHGPn4PiHWAk8GjxAj4wBsdK/jwOSVCM8mn+8DJHdFKqgfGx3zwd8QTx+z4eBG5BGFYeGsx6uV", - "eg5AXcRkdX+14nZxGML4mBg2t6K5YXNO46sH6VR1QbG1VcPFBXjc6xNntzhA7MWy15rsVXSZ1YQykwc6", - "LtBtgXgq1onNH41KvNP11NB7NEIes1ljB9PWz7mjyFSsMWgIrxYbkb0Dln44PBiBhr9mCukVv+u7zS0w", - "26bdLk3FqFAhyThzXkUufeLEkKl7JJg+crkblMS5FAAtY0ddX9opvzuV1KZ40r3M61ttXJd688lHsePf", - "d4Siu9SDv64Vpipi87otsUTtFM3Yl2b9nkCEjBG9YRNdJ03XFaQgB1QKkoYQlZzHPKdGtwG8cU79Z4Hx", - "AqsEUb65FwRUSZgzpaE2ovs4iU9hnqRYnFCIWf/qdCFnZn1vhKiuKetGxA8by7zxFWBE8oxJpRP0QESX", - "YF76QaFS/YN5NS4rNUO2bClflsV5A057DpskY3kZp1c370/PzbSvKpaoyinyW8ZtwMoUS09HAzm3TG1j", - "fbcu+IVd8At6sPUOOw3mVTOxNOTSnOMLORctzruNHUQIMEYc3V3rRekWBhkk4Ha5YyA3BT7+yTbra+cw", - "ZX7snVE7Pg24746yI0XXEhgMtq6CoZvIiCVMB5Wbu5mxPWeAFgXL1i1bqB21V2Omexk8fL27FhZwd91g", - "OzDQjMuLhjk3agW66D9n8zlCAfnIiHA2HNDFuoFELcfmhGalRKNaI9iuW5iyEuwGrv2nX0+1kHQOzjCa", - "WJCuNAQuZx80BGUfFdHMejgzNptBaBBUlzFmNYBrm32izR0GEFncalgyrr9+EiOjHdRTw7gbZXGKidBC", - "n5vorGt49WJVoHdWnUuCrbmE9TSaQfoTbJJfjYZCCsqkqiPGnCW0yf/22PXV8ifY4Mg7A7EMYDt2BdXU", - "N4A0GDMLVo9s4kSlAoU1TLHoQ2ML99ip4/guHWhrXNXZfuKvw7IbVVmbS7nKwaj9dgaWIbtxGneXmdMD", - "TcS3SXnXJrAeY1xIjoHIFU7FlO/R072KqvToXbR7BjT3xIvLGX0cj67mnIrdZm7EHbh+XV2gUTxj8JN1", - "VjR8zXuinBaFFCuaJ86F13f5S7Fylz++7j1+NyxMxin77PvjF68d+B/HozQHKpNKGetdFb5XfDGrsnVq", - "t18lKLF4q4hV1oPNr4prhm6/iwW4ZgqBvt+p+ly7dIOj6NyAs3gM5k7e57zPdolbvNBQVE7o2kFifdBN", - "vzNdUZZ7z4SHtideEhc3rHR4lCuEA1zZfx2EISQHZTed0x0/HTV17eBJONfPWC0trnFwV0sNWZHzR9OD", - "S08/CNlg/i5ZJurPvj6xygjZFo894YO+QU9bmJoQK3i9n783p/H+/fCo3b8/Ju9z9yAAEH+fut9Rv7h/", - "P+pqiFoSDJNAQwGnS7hXBf72bsTNmp04XAy7oI9Xy0qyFP1kWFGodUx7dF847F1I5vCZuV8yyMH8tDu3", - "rrXpFt0hMENO0GlfckwV97S0PYEUEbwd5od5WYa0kNkvKVY9t56b7hHi5RK9HYnKWRr3A/OpMuyV2/ge", - "8zLBl3sMZmbEkvWEi/GSBWOZ14aU8WsBGcwRRaaKVhKscTcV7niXnP27BMIyo9XMGEi811pXnVcOcNSO", - "QGpUz+5cbmAbRVAPfxU7SFjxvy0zIhDbjSBhNFEH3OeVWd8vtPKa1TrTvkGJ4Ywdxr0loNDRh6Nmm2Cx", - "aEYFDdNjhvSG9IzOtR7omSPa65GpZCbFHxC3RaMJP5Kb7XscMIzE/QNC9SzscNZgKZUHqm5ZWc++a7uH", - "68Z9G39lXdgvumqrcJnLNH6q99vIyyi9Kl5B1CG5TwkL3ZHNaNUe1oLHK4jPwor2PlSBcnuebGJyI+kh", - "firD9KIjO359Kh3MnZSsnF5Maazcv9GFDEzB9jaCKrQg/mO/AapKu7WzkyCosHqX2eJGBci6NkW3UOIl", - "9Ro77WCNplZgkKJC1WVsA8FyJSLDlPyCctsm0Xxn+ZX7WoH1gpqvLoTE0mQqHv+RQcqWUXPs27e/ZWnX", - "15+xObMdAEsFQYs5N5DtrmqpyLXpq5LJHWpOZuTBOOhz6XYjYyum2DQHfOOhfWNKFV6XlUey+sQsD7he", - "KHz90YDXFyXPJGR6oSxilSCV7olCXhXFNAV9AcDJA3zv4TfkLsZvKbaCewaLTggaPX34DXrf7R8PYres", - "6+C4jWVnyLP/4Xh2nI4xgM2OYZikG3USreJkWzj33w5bTpP9dMhZwjfdhbL7LC0pp3OIhwwvd8Bkv8Xd", - "RI9qCy/cegNAaSk2hOn4/KCp4U89aYiG/VkwSCqWS6aXLspHiaWhp7p/nJ3UD2ebmbrWHx4u/xCD5Qof", - "K9Sydd2wGkOXPWkEGNL4ii6hidYxobYeXc7qMFbfkIic+HKX2AulaoFicWPmMktHWRKjWmekkIxrtH+U", - "epb8zajFkqaG/U36wE2mXz+J9BRplt3n+wF+43iXoECu4qiXPWTvZRb3LbnLBU+WhqNk9+q03+BU9kb1", - "xeO3+oLItg89VPI1oyS95FY2yI0GnPpKhMe3DHhFUqzWsxc97r2yG6fMUsbJg5Zmh35588JJGUshYzWs", - "6+PuJA4JWjJYYRJHfJPMmFfcC5kP2oWrQP9pQ1C8yBmIZf4sRxWBwKO5LX/TSPG/vqyL8aJj1SbHtGyA", - "Qkasnc5ud8MBX/tZ3dr+Wxuzg896MDcYbbbTewcrPaG6Nha3+uaG03mj5l675w2D48P3RBodHOX4+/cR", - "6Pv3x04Mfv+o+diy9/v34zUxoyY382uNhatoxPhtbA+/ExEDmG9AVQUUuZTdiAGy75IyDwwTnLqhxqTZ", - "7OfmpYjDJIPEA/7ip+Dt29/wiccD/tFGxCdmlriBdUhz/2FvNjuLkkxWPQ9CjSn5TqyHEk7rDvLE8xmg", - "qAclA81zuJJOM7eou35nvEhAo2bUKeTCKJlhn4rQnv/l4NksfrwF2yXLs1/rckOti0RSni6igZpT8+Hv", - "ddP1aomWVUZL3y8o55BHh7O67e9eB45o6f8SQ+dZMj7w3XYzQbvc1uJqwJtgeqD8hAa9TOdmghCrzUou", - "VaZwPhcZwXnqOus1c+x25Qxahf27BKVjRwMf2GwldHYZ5ms7VRHgGVq/JuRHrKlgYGkU0UWrky9P2CzV", - "VRa5oNkYyyaefX/8gthZ7Te2dbDtlDVHo0tzFVEr+fDSZVUX4HhO/vBxticJm1UrnVSNrWJVj8wbdest", - "1gqdQHNMiJ0JeW4tYcrbWewkBItvyiVkQR8tq4shTZj/aE3TBZqYGhdZP8kPb/HmqbI2wAf9oqu+Cnju", - "DNyuy5tt8jYmQi9AXjAFmIUJK2gWWqqqjjkTpy+81FyeLDm3lDLZQ6aouijsi3YPnBVIvG84ClkL8Xsa", - "GGyHxH073p3iV9Eyz+32eS3nrS/bU/UBfulsxCnlgrMUiyzHBCIsCjPM2zSgHnXcTaRG7oRGDle0aV+V", - "/+Ww2NvGzzNCh7iu5zZ4ajbVUof9U8PaNXOZg1aOs0E29r0nnV+DcQWuT4YhopBPChmJTYnGs1d+8D3J", - "COs99BiqfjDPXjkzJiZCnzOOBguHNidmW89Drhg6GDlhmswFKLeeZtEr9Zv5ZoL1nzJYv5u8EHOWnrI5", - "jmGjocyybehfd6hjHwjoAu/Mu8/Mu64qb/VzI6rHTnpcFG7S/s6k8XbMa96L4Fj4iY8HCJBbjR+OtoXc", - "tkbw4n1qCA1WGHwEBd7DHcKounS2WmIbFcFSFL5BbG5StDQf4xEwXjDuPWHxCyKNXgm4MXhee75TqaTa", - "ioCDeNoZ0Lwnjh1z/awr9apDtWsSG5TgGv0c/dtYNxjtYRzVC7XgRvmG+ENhqDsQJp7RvIqAjbQLRanK", - "CVEZ5oi0GojGGIdh3L5FcfMC2NGVfFx/jnW+972J+qofTctsDjqhWRZrW/IdPiX41Of6wBrSsmpvURQk", - "xWKfzeqnXWpzE6WCq3K5ZS7/whWnCzryRqgh7ArsdxirK0w3+O8+/eKr2Ne989t8oGu2X8nfbr5eTOo1", - "NJ0oNk+GYwLvlKujo576coRef39QSs/FvAnIpzCS9nC5cI9i/O17c3GEJQE7Ycb2aqkq9mFIr8DnvshF", - "VWuqyZXwKut0MEHnddWnfbsZor/j+hgvv56c0tDkbe9XawbuyyxNexOhqXYlWTQlW1lQb5kLG/LZMqJ3", - "PUF9YZ42yvNwxme31q0I7XfB/NRwuNhQn5pZ9DpaLucLqTd4X2fIT6u+ZGNfARyftzsyn4Or01ZIWDFR", - "+iAaH8rqVUL7a6O/cZXuHV1/NED8Uxufe03lZ64znl2m08l/+tU60whwLTefgeG8s+mdXs9dadeap+pX", - "SNVUaVCTpcatOKQ6fqwQu5MNG92md/TK7pDV8yHiQLf39Xh0ku11YcaK+Y/sKLFjF+9k3V/ruK5vjEes", - "EIrVvc1iLa4HxoyfYZfqoFZzdywfS7iCVGNDuzpGSgLsU7nZTOZt97c1j/vV6Sq03pU63lbfuNvFbscd", - "3ylBEpTRsR3AJsOr+R5XkbA2keeCKqx9L9HG3Ux9HZyAN5tBqtlqR8mXfyyAB+VExt4ug7DMggowrEpH", - "wYqh+1sda4C2VWTZCk9Quf/K4PSlI5/D5o4iDWqItiSrcrEuUywSMYDcITEkIlQs0swakl3wD1MVZSAW", - "fGSn/Rzqstu93YyDAkaXnMuTpLk46qJGW6aMt1MdNJf5dK9SX5hZ0VcVptuNsV//eI7NL5WLc6JVsclQ", - "Sycn3ZL8F65YJRboqXwnvmwlKP+br8ZlZ8nZOYT9ltFTdUFl5t+Iml68VSfZch91Srn4ToJtoGfVzKyO", - "w+/6qiNFnjGlJc2FESOSvrygZuh7FTd2R9kAv7oOC8I1A+n60qP8mwsFiRY+bn8bHNtQYaMYL4UE1dtY", - "wQLXW+70TV3PFRvMUCxvSl3wYrhAImFJDXQyqLraP+c2ZD+zz30utW8wstPCVNHr7k53PgODqQ4SQ6qf", - "EXdb7s7RvoyxiXEOMvGep3YJVg6y6Q0ppMjK1F7Q4cGoDHKDS6BsYSVRO03aXWVLRwhync9hc2SVIN8i", - "0O9gCLSVnCzoQem+1iYf1PymYnDPDwLep7RcjUeFEHnS4+w46daNbVP8OUvPISPmpvCRyj3dX8ldtLFX", - "3uyLxcbXSS0K4JDdmxByzG1uiHdsNxsXtSbnd/S2+dc4a1baUs7OqDZ5y+NB9lhkWV6Rm/lhtvMwBYbV", - "XXEqO8iOqqTrnpq1kl5EeiFPhmrlXVdzuz9tTVQWiphMcmo9Vs/woMcMR5jJHpRcQEcmJc7TRVQuYiGZ", - "l8m2N0PFMRVOhgBp4EOSviso3OBRBEQ7rkZOoa1g5mqXiRmRUDuRL1vErdscNqbRt2euZmnyu5mQ0Gjz", - "ar4WMvMiD1N1P2Yqp0xLKjeXKbXWaU7bsZ70YnlnOFYViVUvpI7G6uIwz8VFgswqqWqbx1Rb855qXsa+", - "nUv9nTnVUwjiuqhygtqGLGhGUiElpOEX8bQ9C9VSSEhygWFeMQ/0TBu5e4m5OpzkYk5EkYoMbI+AOAX1", - "zVVyTlFsgiCqJooCSzuY9Gm/Ceh44JSH6oxsi/PYRSfWl9kTeArKFeNxGLIvd+Hd0lV4r+r8JzO0CDGM", - "dWnmXlvpM+ytDHu2VmZ57g0Gfd2VyS+qxHAkTLwxUzwhS6G00+zsSKoaqg7xupsKrqXI86YRyIrEc2fZ", - "fknXx2mqXwhxPqXp+T3UI7nQ1UqzsU9LbQfj1TPJVkWmgW2gzxYROy/O4k/d3r2eHefYu0VrAOa73Rxr", - "t437ONbKurmudm923lM7U4slS+M0/GVFt/XGpMVYQrTUk+2SZJPz8TVk1OHlUAUzIEvqohm4IdjYfjme", - "5py6yDzMf1HibY9LZuAuiZ6LqcsnndSSpL2yVQsAhNRmjOpS2tZKoeRTcRUxtxnm6JJuAzqQi2Pkz9Vg", - "MyMcHCgNVwKqE21YAXjXKvtjW5LLRi5Oxdo/v1fX7LoU8B+3U3msHX3kFFek5brl+/oePRwhXhl4a/wR", - "Ng73N+juKKSqDd7AGzUAoD8uqQHDoOikfcGYUZZDllDdc7mjTWgcaLYuo6Xd3JQpx8lTai/sBRAzdinB", - "1ZuwInWrGXpBDSmJ6vWu5ZZnsAaFxSBsR2eqrJ/B+zsgt22lWsq3KJIcVtAI13JFMEoU7dgK/Leq+phk", - "AAV6/9o2qVgcUniXtwwVbu1JEMkyBLtRy4VFrN0pssMsETWirHlij4kaepQMRCuWlbSBP7WvyNE0u5mj", - "HEFVRyZPvN42dJpf7Ahv/ADH/vuYKOMx8W4YH9qbBcVRt40B7YxLLFXfqefxsMSwwkvl0MDZssrxaUm8", - "5huqoBe83wDYJflavRm4T0zwALHfryFFqaYZd3d1nBAcjKhW9aZeEVxWO3x5Q/InoeGtJNw7XkzVUIAM", - "dqulxtOFE9jxBWxnyY3Ya6RmbCHl+L/jf2PswG8HMnq17WgVanDPwXvssKB05axwAi2rLjQfXzh29QTb", - "SjkLIquXdEOExH+MvvbvkuZstsETasH3nxG1oIaEnIvQ+q5dvKKZeLtgMvaAebuA8FPZdbOhYwbDbcwo", - "AdDmCnTGKawMdA7hNqBb3nKeVBuWo8rpkimFl11rO7tYcIv3NSGWNAt1ZKxM12wl6muVmq//nzprK5zK", - "F5Qqcpr6/mVAFF22DOK2R6EnLr2A5fa0vq567Emg6ntYE6306bzZJYx7e0ZuxGLl+/o9NMDu9IPrtLq4", - "0jL2aVBcZ0ZvSYgctJRD78LQ+JAO0Ohk9lW9doBvqzH6CmA3gf9o0ci+ZQwB/3PBe08bvRBe2zHvBrDc", - "SPmPwGrtqlOxTiTM1K5QCGtYNYqwrIsFeOMk46kEqmxsyMnPTmWrayIyblRIG71Yed+qUTKYMV4zS8aL", - "Ukc0ACyNyDcBwkLzNKK1x9nTJyUYMWxF859XICXL+jbOnA7bxiusSe9N8u7biPJf3andAZiqtR/MJIQ6", - "Uy14zVzgtuuNDSxUmvKMyix8nXGSgjT3PrmgG3V534eBVpZGvtjh/aCBNNPMbw/8IEjaFpB849yXV/RM", - "VADSA7ooBrgWMII14lawRhEtejwJXRjiZRXoOsnFHPPLegjQFZ9E349VVgRHg62Vh/abR7E/YPs0WHfb", - "HXwtcNYhU2w/Zz8j6lDh+YUzvfWkWWtaO+HPRmTag+Dpn8/rsHC7OV36j+VonmESQyNPs9103u+1DQ+x", - "80GPJ6Npwe3ZRXSQuwTf0Fw7vJ9R0wcfywS1OmyCuq3aEvgNqg5ypqkL3OkafTpKsUXK2OXR7mkTspZk", - "fw/0gGc71bqz1Zy2CqYw4+zTBGp75mxSiCJJh0QD2tL8mTNoO0ibMPbQR2Cu7ll3FTihqmYVjcImja4V", - "+/bB6u2ascsvU6TblOw+g0YPB20ay8UMeRkeYWvGwRyPyngxbmcfNQ02FZMglEhIS4kGzQu62d1XqKck", - "7Onfj796+Oj3R199TcwLJGNzUHVZ4VZfnjpijPG2neVmY8Q6y9PxTfB56RZx3lPm022qTXFnzXJbVdcM", - "7HQl2scSGrkAIscx0g/mUnuF49RB35/XdsUWefAdi6HgevbMRbbGF3DMnf4iZmQ7z2j2/NNxfmGE/8gl", - "5bf2Egvss8f250Vfhh5rg+xnQ4WRRO+D0V613OuguKiUebn2uYNA6yb9RsgDAejJ5mvkYYXdtet6ldLa", - "dtEK7B1m7UvsZe1I2xl2jpD4D3aAF6bn1e9VkdIOnE9c+PFlhZRgKe/6KKGx/F0Zf26Btecx2CKn6moN", - "yrIl0RUugnRO9azKkuyRbTvJlNhK2+g3eR5JwrTaN56pkHCMYClXNL95roE91o8RH5C96U+9CDPxQiRb", - "VKrL1QF7QQfNHWTdHW5q/hoTP/8BZo+i95wbyjkdO7cZ2k6wsfHc3wo2l5Rc4Jg2qOTh12TqarIXElKm", - "2s5M63EKogJXINnMBfDBWu/IdNu1zl+FvgIZz3zkAXkVOCUEGn9qCOsj+omZSs/JjVJ5jPo6ZBHBX4xH", - "hT0cd1wXV6zffbmyEkGBqD3LSnS7Uw5dni2dYC6dUkF3nYNv6wZuIxd1vbahNVEGlwF/+/Y3PR1SyiRe", - "stt8jrVUDlK7e6/K3ddQRcXiyI3h5o1RzK99dTVt7cieEq6t/ShZvjPMoFGQ9+N4NAcOiiksOfu7azFw", - "s3eph8BmdnePqoX1KuUoLGIia21MHkwVlNodUGXXfRapqYtZU2kpmd5ge0lvhmG/R+u9/FjVDnC1JyoP", - "iLv7tDiHqsVvXWmgVP52/VHQHO8j65jh5hYS+YR8v6bLIndGRfLtnel/wOO/PckePH74H9O/PfjqQQpP", - "vvrmwQP6zRP68JvHD+HR37568gAezr7+Zvooe/Tk0fTJoydff/VN+vjJw+mTr7/5jzuGDxmQLaC+AvTT", - "0X8nx/lcJMevT5IzA2yNE1qwn8DsDerKM4HtzwxSUzyJsKQsHz31P/2//oRNUrGsh/e/jlwbj9FC60I9", - "PTq6uLiYhJ8czTG1ONGiTBdHfh5sStWQV16fVDHJNnoCd7S2QeKmOlI4xmdvvj89I8evTyY1wYyejh5M", - "Hkweug6onBZs9HT0GH/C07PAfT9yxDZ6+uHjeHS0AJpjJQ7zxxK0ZKl/JIFmG/d/dUHnc5ATDDu3P60e", - "HXmx4uiDS7H+aGaIem1sQeagCq9vt1OU05ylvpgRU9acaCODVdhM0NpZSzUmU9tu0gcf8gwDRGzWsgpb", - "rp5kBmH285OaafmOmejVGz39LVL2xkes+0aOYchPEAz0X6c/vyJCEqfevKbpeRWt79Mz6pSUMDvDfDnx", - "9PvvEuSmpi/H+cIG88DLpWEiLux/qeZFswJkLVXFrD4dXPuZDVkEhF0VRKgZF/r4AkhqNmxY64Pkm3cf", - "vvrbx9EAQLA6hwLs6/We5vl7mwkDa4wIbMU9jPsiUsZ1gj1+UO/kGC1S1dPg8/qdZuHk91xweN+3DQ6w", - "6D7QPDcvCg6xPXiHnaeQWPDMPXrwwDMaJ8YH0B25MzUa2N/b1wq3tuZqFE8Slxioy5DsozdVDT1JC3sW", - "3ROb7+es/falieE7Tw640Galvysvtz1cZ9Hf0YxIl+eIS3n4xS7lhNtIPHOx2Avw43j01Re8Nyfc8Bya", - "E3wzaOvYvWh+4edcXHD/phF+yuWSyg2KNrrihe0+BHSu0MWGLNKe7aBME5+P3n3svfWOwpCzow+NGivZ", - "le5EG2XT6OKx45q8o/o4J44VNpQnd4+LAiPuTqvnx0Vhu8SiVxkY3n6wZkqrexPyY/g1cm9MdbQdvEqJ", - "UUO1OcXcelXTVN+KteE5DdqvRS/tRvby7f39ae/v46axo9HdPAZM4xRshakTu3LVC7Sb3BDUUtk3HLWq", - "o+tEi8S12hk4hu/dfrA+UgNKKNiZ3sVUwZ2M+hZ3PbjrE5MCeCuJqW5idTOs2ZfkrG6SxpVxjYz7Cxf6", - "XtLc0Emw3FbrC9vy/1YY/MsIg1XpvrmVzoriAOIhxsQffXC15g4hEqLuO0gYDNXq4Nsgrvlui53cm5Dj", - "9juX4xmuVt9OMc+8dyvgfQ4Cni12uEu0c3T8SYW6MKVmnwyXhjRifh/08Rcuxf2FkdUrthlIdwtsl2Cf", - "HWHMMetrY6t/SiHMIe1W/PpLi19VBd0rCWBhgOqRy/AO3FhXst61rXNMV5JYs4pywNmwCALmOtsjPK5D", - "ug2LseHCLlBYjb1miO5UqzTazRp39MauiPUjhArqd5uT57ukqy/IzjO4GWrkFojvzXXz0qjb4c3NuB2G", - "8aYnD57cHAThLrwSmvyAt/g1c8hrZWlxstqXhW3jSEdT23h/G1fiLbZUlc2yDfUDHlVVRxwHz83bNkrj", - "LmZTNtvn3JsQ3+a/rrDgsoXnwjAqnxVE5dx+ZHidQQa54/98iuPfmZAfMNdNqzEGm2ElJXyRcf304aPH", - "T9wrkl7YWK72e9Ovnzw9/vZb91ohGdcYD2D1nM7rSsunC8hz4T5wd0R3XPPg6X//838mk8mdnWxVrL/b", - "vLL9Nj8X3jqO1WGrCKBvt77wTYpp664P6k7U3Yj7/juxjt4CYn17C32yW8hg/09x+0ybZOQU0cqS2ejI", - "ccDbyB6Tfe6jsW+pb/hOdZlMyCvhmiOVOZW29gYW9lRkXlJJuQbIJp5SsayTss1g0pxhmrgkCuQKZKJY", - "VUC3lFAViCgkrDBGvi492YBgN6PHSNrPlsm/pOsgRXpaXdNauCWj2XNJ1wSr/WuiQI9tdao1+fZb8mBc", - "ay95bgZIKsTEmOuSrkc3aPWriG1oyZXnDjtC7g7QxbGHWJBq6aeqelerGn91zv3FSu6W3N3GHohz7u34", - "qR07oR3BtSDaakGwgp3GGq2qLIp8U1fnNFKeF6HiLM7MMNQ48Bn7CHaapqNKaBu9t4f41ghwJVbSJqg9", - "2QZmnaqjD6iXhzyjc24xa+6v5S4NfEdSLL3zSJAZ6HThEnZbqI+wJ+mSBvt505JxtjRQPhhfu1SDu9it", - "LRt2gM2oTZMf0mQoyKVEBx7ICBH/7Huim8dsZgtO+zYEvlIcuqZczd6q7aJVvm0jVhfP7/N6C9poI7kb", - "ymf15F2BDNFyCP/nLYL3Q3CHOX7vahLY4+UW8WeI+PeqZEJeiTpt3GpQf0rX43Xe7Ne9oFeCg/WxG8nX", - "0uKtO7USOwzjsEjx9UKs/lI3/bmsCHLk6+xslUP+bl7aIYsMub2xZs+XeIX/PVqNqHHLmLVNdhZDqEcb", - "wpzNi7bWfLP//CfUYj4JP/0MVZtPwbFuhsXgIfV8xokF/LBMB0vwWGI+qlqP93GgF+blQC577Rr3D+RG", - "WlRhaBCp/UOmkAs+V58nK9pGHXG8RKjEVpqyLSs665/8Bc/uM9dPwrf0dvWeFOMpECWWgCqDkdGxx4EN", - "lnzy4G83B6FmS9+/l4e5q5+Yu3z14PHNTX8KcsVSIGewLISkkuUb8guv+kZchdspQt2eh9bgCHNgHL1N", - "zbpgaVjE6PJMsBG69kGvWfZxNzMMCinuyQcZD/hgWESbFgVQeXkGuNt11W4yefI8jA4WVakRvys9oBgU", - "7Rkg/39GA+1OmPYuZu7yK7kF1Ff/cmzChe6K2bgKjjFSgJg9JW/5faIW1BendH8++urrHsuZmccV7ena", - "zuqBzGM7zBAD2hdtDjys1F7h9+lN7/Z+mzgesWwd7TEP66B0eLMJnhPL7ihS0I0Po+0UoSrihSgraSAc", - "dglGjFcLVtx8sUOl2TRe7dWrP1Uz1RP+XaUF24p8RvguPkWRu/FIS4AMCr3YWfsS36p3E1wVTKZc1Xtb", - "oXBM2AQmtoBf3Q0km4OyGjUlOdBZ1dZDiCHJEwGfMYTmqSLAeriQITpplH6wYAgS5c0rp3WSgb3oPPJk", - "6875pIKu/lRKaoI6KnAv2DTR8ulkSjBvjgN3dyGFFqnIbexKWRRC6up0q8kgcQ/63HYNaa+PcK8kzK1Z", - "pnba0c7wrQMY0pqUrb4YO9qZR1PMkBZb1CUr8tVzDWFpZ6IgnSauBoRPytdujW4xftayuX3pJjfdS3oH", - "tsClVKeLsjj6gP/BioQf60QprNWujvSaH2FPpaMPW0OakKXmRjaRtsx7Q4+OtoTumvXw87qk/A9Cdnr6", - "7wpZaiFt3L70bX8ojH2KsMfr0Sb/0krYVntla8Ov7oKLjNg5r1UecNDlpqLdoFGBT+21Pa4iJHzrMv68", - "FlQbcWeMZ4QG29iyNVV9aL0O8LcvdtGfwi58837yr77gc/ZKaHKyLGzDf8iuFm1I2hzO3x5br9v9BAN3", - "9XdDErt3fnjj+0DqShbZecHvofcEpSPAT0cl1nIwd/X1qDu3N/nnfZM/8yXSG2R4ey9/Ofey9OHft1fw", - "538FP/5iV3ONjuOBV7K/iS59Ddea+J4XckcYcDasluFgm18ZVe/2KtUPQvp2PLe3+BfqFLU7OTjJcoiF", - "Zpcl1k15iFD/zwr6YXaGPI9YGvoO6tj2JtMLYFgkS6QM+x2cZGpsD7EzTrhTfCv4fNaCT7DXt3LPrenh", - "CzM99Eg5TuvP8yGCxr4C0GopMvCOVTGbuaKUfdJPs1eWIU+l6bIg9suolGOdsGwJp+bNn+0UB71ia7Bb", - "YlELPIMsBangmRoQxeFGvew9hI6mfgBu3LNZ7YCHxZWrmFyaZN8ENa86lEDayFfY48wX53TIyGBFDAFO", - "DkC2Rx/sv2hOK4SKrObUE3BnY+66bbHVRu24DQDJaxRCXUd/95WYkQe26GjJMbOwbmZKeUa03BhB1ddY", - "kkBzkjYyiio4uifntPfk7FQFOqvrWVNcFxD1CT1kBEMrm/OnGz8Azyh3JN9FkBaEEg5zqtkKvMt/clsB", - "5NK3mau/sYUBjgnNMnsa602AFcgNUeVUGVmHNwPD76jmedmDYcC6AMnMFU3z2gFv1YQjW95jWxzRqX3j", - "ipdWixfZoiKyGbXob1ZXckTMyEuWSnGcz4XycahqozQsO61C3ae/9xSJ9oaEbsyq4DnjkCwFjzWw/Bmf", - "vsSHsa+xRErfx2fmYd+3rfu2CX8LrOY8Q+7kq+L3Mzn9Vwp0aa1WQiGk0W6ntqm2pf89j5I/NBuedk/S", - "hqeBU8s9DAYK2102fj7y6QiN5pfRNz80/nRlgNybalHqTFwEs6ANwIYzDqkAErTgv4TNrdXKXl2v1e06", - "vU0BHmJnq3oaaWpYP+zva/gXzXxzzpmQSDAoPRUrkKqlyN2mv/2p0t8G7/te3Ng28d3F0Up1WNnllcjA", - "jtvsoR2rPM9FBq7XcFdkqcIi4ylD/v6q32slcaS0nC80KQuiRSxdpP4woallsolVhOITBrUerbqE0y3o", - "CgjNsYMzmQJwIqZm0fVNioukCqtt+pwTF/wZFZoCuAopUlAKssRX2t8FWtXBGUPV9RY8IeAIcDULUYLM", - "qLwysOernXCewyZBZViRuz/9alTrG4fXCo3bEWtr/EXQW9URcnJhF+ph028juPbkIdlRCcSLBpgiJ5ZF", - "Di5JLoLCvXDSu39tiDq7eHW0YBYZu2aK95NcjYAqUK+Z3q8KbVkk5v7ugvjMPj1jS5TEOOXCWyBjg+VU", - "6WQXWzYvhWtRZgUBJ4xxYhy4RzV9QZV+4/KlM6ytZa8TnMfK2GaKfoCrnv2xkX+1D2Njp+Y+5KpUxI3g", - "c6Agi62Bw3rLXK9gXc2FCet+7CrJytoCd43ch6VgfIesoN0AoTrw+5vhIotDSyV1powuKhtA1IjYBsip", - "fyvAbujw7wGEqRrRlnCwfHJIOVMhcqDc5qqKojDcQiclr77rQ9OpfftY/1K/2yUuqut7OxOgwgQ4B/mF", - "xaxCU+6CKuLgIEt67nLk5q59XBdmcxgTrG2RbKN8NO6at8IjsPOQlsVc0gySDHIaMbr8Yh8T+3jbALjj", - "njyTldCQTGEmJMQ3vaZk2WtMqoYWOJ6KCY8En5DUHEGjPNcE4r7eMXIGOHaMOTk6ulMNhXNFt8iPh8u2", - "W91jwDJjmB139IAgO44+BOAePFRDXx4V+HFSmw/aU/wTlJugkiP2n2QDqm8J9fh7LaBt+AsvsMZN0WLv", - "LQ4cZZu9bGwHH+k7sjFT4xfpFmhHOV1jkl3T1BoogJPLKLdHF5TpZCakFaQTOtMgd4bO/4My7zj36bvC", - "VV0hOIK7N904yOTDJj6Oi1gQiLsuDIlMyNkCJJg7jJKHZMl4qe0TUeqxrTkqgaYLI7SHNlg7ErZhdI0J", - "JcypzHJs0Ter7k0h8TJiunXBI9CRfMSmxm/W/YOQgyoZN+t1UaZJyTXLg24Old7++Vkvby0StxaJW4vE", - "rUXi1iJxa5G4tUjcWiRuLRK3Folbi8StReKva5H4VGWSEi9x+IqNXPCkHUx5G0v5pyrlW11V3kCC1okL", - "yrTrTeyrFPTbLfYwBGmgOeKA5dAf3W2DTs++P35BlChlCiQ1EDJOipwa1QDWuuqU2ezB7LvD23a7tr0z", - "VfD4ETn9+7GvOLpwlTGb7949tvFqROlNDvdcLxrgmZVEfVMa4AbpricN9VeC76jp+ouyHCPjFfke334O", - "K8hFAdIWMyRalpGW9GdA82cONzsMPv8wk7tQ2/dmtPfjhtHLoW1JCy/m+7VSRajNuCTPgxzM9zOaK3jf", - "l4Zpx1vSItbUsrr4rCkImcl3Itu0TojZtSPcwObZqOuOMk7lJlIlqpsC0SYNLQy7coTVtWV9PHh13C7R", - "dslsF4XFpHUJKnqOt1F5tCxstWGdoWyi7qxFJ6NYjmm7FuqoAnBQYUBMk7B7Qt7Y7z5tGUCEyB2xmpl/", - "NlGMzTcrpoHvGiXCsZ4vNZfAIz56evHsjw1hZ2UKhGlFfIHd3dfLeLROzEhz4IljQMlUZJukwb5GjVso", - "Y4oqBcvp7pso5J+ujbu7fMyT7ffUp7lGngeL28aTQ6JZJ44B93DnjYbBvLnCFo7o2HOA8etm0X1sNASB", - "OP4UMyq1eN++TK+eZnPL+G4ZX3AaWxIB464geZuJTK6R8cmNLHk/z/t+DWlpgAtP8l20zqNLDta64WTN", - "YFrO59iOvuOjM0sDHI8J/olYoV3uUC64HwXZwasWxVdNUm8P1+UuQd74XV+Z8R5uB+UbdGYsC8o33uUL", - "iWLLMrc4tJ08D8tobc3wWInp2vbXZ9V+7U1+ge3WXbXN3y1ayAVVxO4vZKTkmct46tS2XvPhdU7s0Gdr", - "XrPprTVN7Hojq3PzDrki/C43U80VKUAmes3tgWocJtfBwJ7cyW0b7r/GtWET1aGHwXar8dcM4UC3hwz4", - "Gl4fQc+lOjGv0YmJNtMJG8/QotGf4hI2Z7JvHjSwpDN8M76kNrc4/ynkBaEkzRl6VwVXWpapfssp+m+C", - "hU26sSfeUN3P+575V+IuxIiHzw31llMMMqq8OlEeOIOIC+MHAM9iVTmfgzJ8NCSgGcBb7t5inJTcaGFi", - "RpYslSKxqbXmfBnZZWLfXNINmWFFE0H+ACnI1Nz6wa5bW7LSLM9dsIuZhojZW041yYEqTV4yw4HNcL6c", - "QhVyBvpCyPMKC/FePXPgoJhK4oaZH+1TbIfjlu8NgGjMtI/rNhY32wfHw86yXshPnmOMGlZjzpnSdXxE", - "B/Yb840vGU+iRHa2AOLCxdq0Re5iDThHQPeajiO9gLfc3H5aEOT4VF+OHNoeoM5ZtKejRTWNjWg5ivxa", - "B6l/B+EyJMJkbt0uf6IU0oAOvGcTN97W12/t/Z4ulsaVCzwzT3suZPvUtU/seckpEA0jWavAjXvjrAHy", - "Vv/Fl19W8vC6pEfjwbTJ7oBddtVskId48xs+JjQXfG7rKhrtUuA+MV6UGgPAr9OAByuaJ2IFUrIM1MCV", - "MsG/X9H85+qzj+MRrCFNtKQpJNaiMBRrZ+YbS6fYaJAzzWieoFY9FCA4sV+d2o923MdBt9HlEjJGNeQb", - "UkhIIbOFyJgitT4/sQUaSLqgfI5XtxTlfGFfs+NcgISqMaNRodtDxAvBrHlii9J1YTwm1hYa1u0Fmi4i", - "jWPwgjM6uyeorNGTauAeNEqO9inp41GvoG2QuqpD5yxymmxmgBTRkAcC/NQTH6JG6y3R3xL9l070sZKK", - "iLpZy1ph8RVuyzWbta67gOgNWsk+SXXh2xL9f/YS/Z4DKUKJpA0dJN4bjirCNLnAskhTIOb+KtE67xru", - "OX0dM+2Co+4qbSrXni9dUMZdTZ0qrwHh0K5bvPbtaa/FsGmZGVo0DTogLSXTG9RaaMF+Pwfz/3dG7Fcg", - "V16hKWU+ejpaaF08PTrKRUrzhVD6aPRxHD5TrYfvKvg/eF2kkGxl9KuP7z7+3wAAAP//BgzyFgmnAQA=", + "VEYQYYm/BwWXWKgZ70qkH1seqhwLoFJPgeqtpnQe5rt7YFFruzDEa41oYyIkgbVBKdNoFONwYQR3tMXY", + "d1yA8KQ/xMtct0JBdkl4/Oe1MD7pVSen9tqPlIjyFx9xr9Sao4t+C7cS4bLPl4A15sSFIlNqoBCuPJrN", + "wg9YeKnoHHrUg9BBNjDXveFUw0F2XfrRa17M2rd557KNgmxfTsyao8cEzBNzTlCTa8U8+pmsD9a5ZbDq", + "qUPYNEcZsQoOtXtPZcNRacs49oEWP70geS1teTCaGAnFugVVvnIbFrjzjGyQAHSNVSW21RI6CcL1gip2", + "VaUgf+G0mVRHtXYVhXwZIV87KNSrB9QBMuoNZgjEtkNwlP4yyGFuF25f9oRSV7ioN8jA8fNshrwliUX+", + "BTbg4I51c4BRDu4TYt0PZPAIMTIOwMbYAhyYvBLh2eTzfYDkrkIH9WNjVELwN8Rz52wsvJH3RGHuL9bj", + "0ks9B6AuXLS6vFtByzgMYXxMDJtb0dywOafu1oN0StqgzN4qYOOiW+71yfJbvD/2Vt1rTfYevsxqQoHR", + "Ax2XZrdAPBXrxCbPRsX96Xpq6D2aHoCpvLGDaYsH3VFkKtYYMYVXiw1H3wFLPxwejMC8sWYK6RW/6xNl", + "LDDbpt0uSsaoUCHJOFtmRS59stSQqXvEtz5yuRvUA7oUAC1LT11c22n+OzX0pnjSvczrW21c17nzmVex", + "4993hKK71IO/rgmqquDzui2xRI00zcCfZvGiQH6OEb1hE10PVdcPpiAH1IiShhCVnMfcxkaxA7xxTv1n", + "geUGSyRRvrkXRJNJmDOlofYg+CCRT2GbpViZUYhZ/+p0IWdmfW+EqK4p60PFDxvLvPEVYDj2jEmlE3S/", + "RJdgXvpBoUXhB/NqXFZqxqvZOsYsi/MGnPYcNknG8jJOr27en56baV9VLFGVU+S3jNtonSnW3Y5GsW6Z", + "2gY6b13wC7vgF/Rg6x12GsyrZmJpyKU5xxdyLlqcdxs7iBBgjDi6u9aL0i0MMsg+7nLHQG4KAhwm20zP", + "ncOU+bF3hiz5HOi+O8qOFF1LYC3ZugqGPjIjljAdlK3upgX3nAFaFCxbtwzBdtRejZnuZe3xxf5aWMDd", + "dYPtwEAzKDEa490olOhCH53B6wgF5CMjwtlYSBfoBxK1HJsQm5USLYqNSMNuVc5KsBu49p9+PdVC0jk4", + "q3BiQbrSELicfdAQ1LxURDPr3s3YbAahNVRdxpLXAK5t84p2thhAZHGTacm4/vpJjIx2UE8N426UxSkm", + "Qgt9PrKzrtXZi1WB3lm1bQm25hKm42j67E+wSX41GgopKJOqDpdzZuAm/9tj11fLn2CDI++MQjOA7dgV", + "VFPfANJgzCxYPbJZI5UKFBZwxYoXjS3cY6eO47t0oK1xJXf7ib+OSW+UpG0u5SoHo3ZaGliG7MZp3Fdo", + "Tg80Ed8m5V2bwHqMcSE5BiJXOBVTvkFR9yqqcsN30e4Z0NwTLy5n9HE8uppnLnabuRF34Pp1dYFG8YyR", + "X9ZT03C074lyWhRSrGieOP9l3+Uvxcpd/vi6d3fesDAZp+yz749fvHbgfxyP0hyoTCplrHdV+F7xxazK", + "FundfpWgxOKtIlZZDza/qiwa+jwvFuA6SQT6fqfkde3PDo6i84HO4gGoO3mfc73bJW5xwUNReeBrB4l1", + "wDed7nRFWe49Ex7anmBRXNywuulRrhAOcGXnfRCDkRyU3XROd/x01NS1gyfhXD9jqbi4xsFdITlkRc4Z", + "Tw8uPf0gZIP5u0yhqDP/+sQqI2RbPPbETvruRG1hakKs4PV+/t6cxvv3w6N2//6YvM/dgwBA/H3qfkf9", + "4v79qKshakkwTAINBZwu4V4V9dy7ETdrduJwMeyCPl4tK8lS9JNhRaHWK+/RfeGwdyGZw2fmfskgB/PT", + "7sTC1qZbdIfADDlBp32ZQVXQ19I2RFJE8HaMIyalGdJCZr+kWPLdem66R4iXS/R2JCpnadwPzKfKsFdu", + "g5vMywRf7jGYmRFL1hMrx0sWjGVeG1LDsAVkMEcUmSpaRrHG3VS4411y9u8SCMuMVjNjIPFea111XjnA", + "UTsCqVE9u3O5gW0UQT38VewgYbuDtsyIQGw3goShVB1wn1dmfb/QymtW60z7RmSGM3YY95ZoSkcfjppt", + "dsmiGRI1TI8Z0hjTMzrXd6FnjmijS6aSmRR/QNwWjSb8SGK6b/DAMAz5DwjVs7C9W4OlVB6oul9nPfuu", + "7R6uG/dt/JV1Yb/oqqfEZS7T+KnebyMvo/SqePlUh+Q+JSx0RzZDdXtYCx6vIDgNy/n7UAXK7XmyWdmN", + "jI/4qQxzq47s+PWpdDB38tFyejGlsV4HRhcyMAXb2wiq0IL4j/0GqCrn2M5OgojK6l1mKzsVIOvCHN0q", + "kZfUa+y0gzWaWoFBigpVl7ENBMuViAxT8gvKbY9I853lV+5rBdYLar66EBLrsql4/EcGKVtGzbFv3/6W", + "pV1ff8bmzLY/LBUE/fXcQLa1rKUi16OwyqR3qDmZkQfjoMmn242MrZhi0xzwjYf2jSlVeF1WHsnqE7M8", + "4Hqh8PVHA15flDyTkOmFsohVglS6Jwp5VRTTFPQFACcP8L2H35C7GL+l2AruGSw6IWj09OE36H23fzyI", + "3bKufeU2lp0hz/6H49lxOsYANjuGYZJu1Em0hJXtX91/O2w5TfbTIWcJ33QXyu6ztKScziEeL73cAZP9", + "FncTPaotvHDrDQClpdgQpuPzg6aGP/XkYBr2Z8EgqVgumV66KB8lloae6uZ5dlI/nO3k6vqeeLj8QwyW", + "K3ysUMvWdcNqDF325FBgSOMruoQmWseE2mJ8OavDWH03JnLia31iI5iq/4vFjZnLLB1lSYxqnZFCMq7R", + "/lHqWfI3oxZLmhr2N+kDN5l+/STSUKXZc4DvB/iN412CArmKo172kL2XWdy35C4XPFkajpLdq3Oeg1PZ", + "G9UXj9/qCyLbPvRQydeMkvSSW9kgNxpw6isRHt8y4BVJsVrPXvS498punDJLGScPWpod+uXNCydlLIWM", + "FfCuj7uTOCRoyWCFGSzxTTJjXnEvZD5oF64C/acNQfEiZyCW+bMcVQQCj+a25FUjxf/6sq5EjI5VmxnU", + "sgEKGbF2OrvdDQd87Wd1a/tvbcwOPuvB3GC02Tb3Haz0hOraWNzqmxvOZY6ae+2eNwyOD98TaXRwlOPv", + "30eg798fOzH4/aPmY8ve79+PFwSNmtzMrzUWrqIR47exPfxORAxgvvtWFVDk8pUjBsi+S8o8MExw6oYa", + "k2ano5uXIg6TDBIP+Iufgrdvf8MnHg/4RxsRn5hZ4gbWIc39h73Z6S1KMln1PAg1puQ7sR5KOK07yBPP", + "Z4CiHpQMNM/hSjqd7KLu+p3xIgGNmlGnkAujZIZNOkJ7/peDZ7P48RZslyzPfq1rLbUuEkl5uogGak7N", + "h7/XHeerJVpWGa37v6CcQx4dzuq2v3sdOKKl/0sMnWfJ+MB3250U7XJbi6sBb4LpgfITGvQynZsJQqw2", + "y9hUadL5XGQE56mLzNfMsduSNOiT9u8SlI4dDXxgs5XQ2WWYr23TRYBnaP2akB+xoISBpVFBGK1OvjZj", + "s05ZWeSCZmOsGXn2/fELYme139i+ybZN2ByNLs1VRK3kw+u2VS2Q4wUJho+zPUParFrppOrqFSv5ZN6o", + "+46xVugEmmNC7EzIc2sJU97OYichWHlULiELmohZXQxpwvxHa5ou0MTUuMj6SX54fztPlbUBPmiWXTWV", + "wHNn4HYt7myHuzERegHyginALExYQbPKVFVyzZk4fdWp5vJkybmllMkeMkXVQmJftHvgrEDifcNRyFqI", + "39PAYNtD7tvu7xS/ita4bvcObDlvfc2iqgnyS2cjTikXnKVYYTomEGFFnGHepgHFuONuIjVyJzRyuKId", + "C6v8L4fF3h6GnhE6xHU9t8FTs6mWOuyfGtauk80ctHKcDbKxb7zp/BqMK3BNQgwRhXxSyEhsSjSevfKD", + "70lGWOyix1D1g3n2ypkxMRH6nHE0WDi0OTHbeh5yxdDByAnTZC5AufU0K36p38w3Eyx+lcH63eSFmLP0", + "lM1xDBsNZZZtQ/+6Qx37QEAXeGfefWbedSWJq58bUT120uOicJP2t2WN96Je814Ex8JPfDxAgNxq/HC0", + "LeS2NYIX71NDaLDC4CMo8B7uEEbVorTVD9yoCJai8A1ic5OidQkZj4DxgnHvCYtfEGn0SsCNwfPa851K", + "JdVWBBzE086A5j1x7JjrZ12pVx2qXZDZoATX6Ofo38a6u2oP46heqAU3yjfEHwpD3YEw8YzmVQRspFcq", + "SlVOiMowR6TVPTXGOAzj9v2ZmxfAjpbs4/pzLHK+703UV/ppWmZz0AnNslg5k+/wKcGnPtcH1pCWVW+P", + "oiApVjptln7tUpubKBVclcstc/kXrjhd0I44Qg1hS2S/w1hdYbrBf/dpll/Fvu6d3+YDXbP96h138/Vi", + "Uq+h6USxeTIcE3inXB0d9dSXI/T6+4NSei7mTUA+hZG0h8uFexTjb9+biyOsh9gJM7ZXS1WuEEN6BT73", + "RS6qQltNroRXWad9Czqvqyb1280Q/e3mx3j59eSUhiZve79aM3BfZmnamwhNtSvJoinZyoJ6y1zYkM+W", + "Eb3rCeoL87RRnoczPru1bkVovwvmp4bDxYb61Myi19FyOV9IvcH7OkN+WvUlG/vy5/i83Y76HFyRukLC", + "ionSB9H4UFavEtpfG82dq3Tv6PqjAeKf2vjcayo/c20B7TKdTv7Tr9aZRoBrufkMDOedTe80uu5Ku9Y8", + "Vb9Cqo5SgzpMNW7FIa0BYlXonWzYaLW9o1F4h6yeDxEHuo2/x6OTbK8LM9bJYGRHiR27eBvv/kLPdXFn", + "PGKFUKxu7Bbr7z0wZvwMW3QHhaq7Y/lYwhWkGrv51TFSEmCfstVmMm+7vy343K9OV6H1rs7ztuLO3RZ+", + "O+74TgmSoIyObX82GV7K+LiKhLWJPBdUYeF/iTbuZurr4AS82QxSzVY7Sr78YwE8KCcy9nYZhGUWVIBh", + "VToKlkvd3+pYA7StIstWeIK2BVcGpy8d+Rw2dxRpUEO0H1uVi3WZYpGIAeQOrvxmLNLMGpJd8A9TFWUg", + "Fnxkpyu/Wdcc763zGRQwuuRcniTNxVEXNdoyZbyX7KC5zKd7lfrCzIq+qjDdVpT9+sdz7PypXJwTrYpN", + "hlo6Oen2I7hwxSqxQE/lO/FlK0H533w1LjtLzs4hbDaNnqoLKjP/RtT04q06yZb7qFPKxbdRbAM9q2Zm", + "dRx+11cdqXCNKS1pLowYkfTlBTVD36u4sTvKBvjVdVgQrhlI15Qf5d9cKEi08HH72+DYhgobxXgpJKje", + "rhIWuN5yp2/qeq7YXYdieVPqghfDBRIJS2qgk0HV1f45tyH7mX3uc6l9d5WdFqaKXne3+fMZGEx1kBhS", + "/Yy423J3jvZljE2Mc5CJ9zy1S7BykE1vSCFFVqb2gg4PRmWQG1wCZQsridpp0u4qWzpCkOt8DpsjqwT5", + "/oh+B0OgreRkQQ9K97U2+aDmNxWDe34Q8D6l5Wo8KoTIkx5nx0m3bmyb4s9Zeg4ZMTeFj1TuaX1L7qKN", + "vfJmXyw2vk5qUQCH7N6EkGNuc0O8Y7vZtak1Ob+jt82/xlmz0pZydka1yVseD7LHIsvyitzMD7Odhykw", + "rO6KU9lBdlQlXffUrJX0ItIIejJUK++6mtvNeWuislDEZJJT67F6hgc9ZjjCTPag5AI6Milxni6ichEL", + "ybxMtr0ZKo6pcDIESAMfkvRdQeEGjyIg2m42cgptBTNXu0zMiITaiXzZIm7dzrgxjb49czVLk9/NhIRG", + "j1vztZCZF3mYqptRUzllWlK5uUyptU5n3o71pBfLO8OxqkiseiF1NFYXh3kuLhJkVklV2zym2pr3VPMy", + "9r1s6u/MqZ5CENdFlRPUNmRBM5IKKSENv4in7VmolkJCkgsM84p5oGfayN1LzNXhJBdzIopUZGB7BMQp", + "qG+uknOKYhMEUTVRFFjawaRP+01AxwOnPFRbaFucxy46sb7MnsBTUK4Yj8OQfbkL75aWyntV5z+ZoUWI", + "YaxLM/faSp9hY2nYs680y3NvMOhrLU1+USWGI2HijZniCVkKpZ1mZ0dS1VB1iNfdVHAtRZ43jUBWJJ47", + "y/ZLuj5OU/1CiPMpTc/voR7Jha5Wmo19Wmo7GK+eSbYqMg3sgX22iNh5cRZ/6vZudO04x979aQMw3+3m", + "WLtt3MexPt7NdbUb0/Oe2plaLFkap+EvK7qtNyYtxhKipZ5siyibnI+vIaMOL4cqmAFZUhfNwA3BxvbL", + "8TTn1EXmYf6LEm97XDIDd0n0XExdPumkliTtla1aACCkNmNUl9L2lQoln4qriLnNMEeXdBvQgVwcI3+u", + "BpsZ4eBAabgSUJ1owwrAu1bZH9uSXDZycSrW/vm9umbXpYD/uJ3KY734I6e4Ii1pg6p8fY8ejhCvDLw1", + "/gi7pvsbdHcUUtUDcOCNGgDQH5fUgGFQdNK+YMwoyyFLYv2tTiqb0DjQbF1GS7uzK1OOk6e09O2lzNil", + "BFdvworUrU7wBTWkJKrXu5ZbnsEaFBaDsO2sqbJ+Bu/vgNy2lWop36JIclhBI1zLFcEoUbRjK/Dfqupj", + "kgEU6P1r26RicUjhXd4yVLi1J0EkyxDsRi0XFrF2p8gOs0TUiLLmiT0mauhRMhCtWFbSBv7UviJH0+xm", + "jnIEVR2ZPPF629BpfrEjvPEDHPvvY6KMx8S7YXxobxYUR902BrQzLrFUfaeex8MSwwovlUMDZ8sqx6cl", + "8ZpvqIJe8H4DYJfka/Vm4D4xwQPEfr+GFKWaZtzd1XFCcDCiWtWbekVwWe3w5Q3Jn4SGt5Jw73gxVUMB", + "MtitlhpPF05gxxewlyc3Yq+RmrGFlOP/jv+NybT0Axm92na0CjW45+A9dlhQunJWOIGWVReajy8cu3qC", + "baWcBZHVS7ohQuI/Rl/7d0lzNtvgCbXg+8+IWlBDQs5FaH3XLl7RTLxdMBl7wLxdQPip7LrZ0DGD4TZm", + "lABocwU64xRWBjqHcBvQLW85T6oNy1HldMmUwsuutZ1dLLjF+5oQS5qFOjJWpmv2UfW1Ss3X/0+dtRVO", + "5QtKFTlNff8yIIouWwZx26PQE5dewHJ7Wl9XPfYkUPU9rIlW+nTe7BLGvT0jN2Kx8n39Hhpgd/rBdVpd", + "XGkZ+3RnrjOjtyREDlrKoXdhaHxIB2h0MvuqXjvAt9UYfQWwm8B/tGhk3zKGgP+54L2njV4Ir+2YdwNY", + "bqT8R2C1dtWpWCcSZmpXKIQ1rBpFWNbFArxxkvFUAlU2NuTkZ6ey1TURGTcqpI1erLxv1SgZzBivmSXj", + "RakjGgCWRuSbAGGheRrR2uPs6ZMSjBi2ovnPK5CSZX0bZ06HbeMV1qT3Jnn3bUT5r+7U7gBM1doPZhJC", + "nakWvGYucNv1xgYWKk15RmUWvs44SUGae59c0I26vO/DQCtLI1/s8H7QQJpp5rcHfhAkbQtIvnHuyyt6", + "JioA6QFdFANcCxjBGnErWKOIFj2ehC4M8bIKdJ3kYo75ZT0E6IpPou/HKiuCo8HWykP7zaPYH7B9Gqy7", + "7Q6+FjjrkCm2n7OfEXWo8PzCmd560qw1rZ3wZyMy7UHw9M/ndVi43Zwu/cdyNM8wiaGRp9nuuO/32oaH", + "2Pmgx5PRtOD27CI6yF2Cb2iuHd7PqOmDj2WCWh02Qd1WbQn8BlUHOdPUBe50jT4dpdgiZezyaPe0CVlL", + "sr8HesCznWrd2WpOWwVTmHH2aQK1PXM2KUSRpEOiAW1p/swZtB2kTRh76CMwV/esuwqcUFWzikZhk0bX", + "in37YPV2zdjllynSbUp2n0Gjh4M2jeVihrwMj7A142COR2W8GLezj5oGm4pJEEokpKVEg+YF3ezuK9RT", + "Evb078dfPXz0+6OvvibmBZKxOai6rHCrL08dMcZ4285yszFineXp+Cb4vHSLOO8p8+k21aa4s2a5rapr", + "Bna6Eu1jCY1cAJHjGOkHc6m9wnHqoO/Pa7tiizz4jsVQcD175iJb4ws45k5/ETOynWc0e/7pOL8wwn/k", + "kvJbe4kF9tlj+/OiL0OPtUH2s6HCSKL3wWivWu51UFxUyrxc+9xBoHWTfiPkgQD0ZPM18rDC7tp1vUpp", + "bbtoBfYOs/Yl9rJ2pO0MO0dI/Ac7wAvT8+r3qkhpB84nLvz4skJKsJR3fZTQWP6ujD+3wNrzGGyRU3W1", + "BmXZkugKF0E6p3pWZUn2yLadZEpspW30mzyPJGFa7RvPVEg4RrCUK5rfPNfAHuvHiA/I3vSnXoSZeCGS", + "LSrV5eqAvaCD5g6y7g43NX+NiZ//ALNH0XvODeWcjp3bDG0n2Nh47m8Fm0tKLnBMG1Ty8GsydTXZCwkp", + "U21npvU4BVGBK5Bs5gL4YK13ZLrtWuevQl+BjGc+8oC8CpwSAo0/NYT1Ef3ETKXn5EapPEZ9HbKI4C/G", + "o8IejjuuiyvW775cWYmgQNSeZSW63SmHLs+WTjCXTqmgu87Bt3UDt5GLul7b0Joog8uAv337m54OKWUS", + "L9ltPsdaKgep3b1X5e5rqKJiceTGcPPGKObXvrqatnZkTwnX1n6ULN8ZZtAoyPtxPJoDB8UUlpz93bUY", + "uNm71ENgM7u7R9XCepVyFBYxkbU2Jg+mCkrtDqiy6z6L1NTFrKm0lExvsL2kN8Ow36P1Xn6sage42hOV", + "B8TdfVqcQ9Xit640UCp/u/4oaI73kXXMcHMLiXxCvl/TZZE7oyL59s70P+Dx355kDx4//I/p3x589SCF", + "J1998+AB/eYJffjN44fw6G9fPXkAD2dffzN9lD168mj65NGTr7/6Jn385OH0ydff/Mcdw4cMyBZQXwH6", + "6ei/k+N8LpLj1yfJmQG2xgkt2E9g9gZ15ZnA9mcGqSmeRFhSlo+e+p/+X3/CJqlY1sP7X0eujcdooXWh", + "nh4dXVxcTMJPjuaYWpxoUaaLIz8PNqVqyCuvT6qYZBs9gTta2yBxUx0pHOOzN9+fnpHj1yeTmmBGT0cP", + "Jg8mD10HVE4LNno6eow/4elZ4L4fOWIbPf3wcTw6WgDNsRKH+WMJWrLUP5JAs437v7qg8znICYad259W", + "j468WHH0waVYfzQzRL02tiBzUIXXt9spymnOUl/MiClrTrSRwSpsJmjtrKUak6ltN+mDD3mGASI2a1mF", + "LVdPMoMw+/lJzbR8x0z06o2e/hYpe+Mj1n0jxzDkJwgG+q/Tn18RIYlTb17T9LyK1vfpGXVKSpidYb6c", + "ePr9dwlyU9OX43xhg3ng5dIwERf2v1TzolkBspaqYlafDq79zIYsAsKuCiLUjAt9fAEkNRs2rPVB8s27", + "D1/97eNoACBYnUMB9vV6T/P8vc2EgTVGBLbiHsZ9ESnjOsEeP6h3cowWqepp8Hn9TrNw8nsuOLzv2wYH", + "WHQfaJ6bFwWH2B68w85TSCx45h49eOAZjRPjA+iO3JkaDezv7WuFW1tzNYoniUsM1GVI9tGbqoaepIU9", + "i+6Jzfdz1n770sTwnScHXGiz0t+Vl9serrPo72hGpMtzxKU8/GKXcsJtJJ65WOwF+HE8+uoL3psTbngO", + "zQm+GbR17F40v/BzLi64f9MIP+VySeUGRRtd8cJ2HwI6V+hiQxZpz3ZQponPR+8+9t56R2HI2dGHRo2V", + "7Ep3oo2yaXTx2HFN3lF9nBPHChvKk7vHRYERd6fV8+OisF1i0asMDG8/WDOl1b0J+TH8Grk3pjraDl6l", + "xKih2pxibr2qaapvxdrwnAbt16KXdiN7+fb+/rT393HT2NHobh4DpnEKtsLUiV256gXaTW4IaqnsG45a", + "1dF1okXiWu0MHMP3bj9YH6kBJRTsTO9iquBORn2Lux7c9YlJAbyVxFQ3sboZ1uxLclY3SePKuEbG/YUL", + "fS9pbugkWG6r9YVt+X8rDP5lhMGqdN/cSmdFcQDxEGPijz64WnOHEAlR9x0kDIZqdfBtENd8t8VO7k3I", + "cfudy/EMV6tvp5hn3rsV8D4HAc8WO9wl2jk6/qRCXZhSs0+GS0MaMb8P+vgLl+L+wsjqFdsMpLsFtkuw", + "z44w5pj1tbHVP6UQ5pB2K379pcWvqoLulQSwMED1yGV4B26sK1nv2tY5pitJrFlFOeBsWAQBc53tER7X", + "Id2GxdhwYRcorMZeM0R3qlUa7WaNO3pjV8T6EUIF9bvNyfNd0tUXZOcZ3Aw1cgvE9+a6eWnU7fDmZtwO", + "w3jTkwdPbg6CcBdeCU1+wFv8mjnktbK0OFnty8K2caSjqW28v40r8RZbqspm2Yb6AY+qqiOOg+fmbRul", + "cRezKZvtc+5NiG/zX1dYcNnCc2EYlc8KonJuPzK8ziCD3PF/PsXx70zID5jrptUYg82wkhK+yLh++vDR", + "4yfuFUkvbCxX+73p10+eHn/7rXutkIxrjAewek7ndaXl0wXkuXAfuDuiO6558PS///k/k8nkzk62Ktbf", + "bV7ZfpufC28dx+qwVQTQt1tf+CbFtHXXB3Un6m7Eff+dWEdvAbG+vYU+2S1ksP+nuH2mTTJyimhlyWx0", + "5DjgbWSPyT730di31Dd8p7pMJuSVcM2RypxKW3sDC3sqMi+ppFwDZBNPqVjWSdlmMGnOME1cEgVyBTJR", + "rCqgW0qoCkQUElYYI1+XnmxAsJvRYyTtZ8vkX9J1kCI9ra5pLdyS0ey5pGuC1f41UaDHtjrVmnz7LXkw", + "rrWXPDcDJBViYsx1SdejG7T6VcQ2tOTKc4cdIXcH6OLYQyxItfRTVb2rVY2/Ouf+YiV3S+5uYw/EOfd2", + "/NSOndCO4FoQbbUgWMFOY41WVRZFvqmrcxopz4tQcRZnZhhqHPiMfQQ7TdNRJbSN3ttDfGsEuBIraRPU", + "nmwDs07V0QfUy0Oe0Tm3mDX313KXBr4jKZbeeSTIDHS6cAm7LdRH2JN0SYP9vGnJOFsaKB+Mr12qwV3s", + "1pYNO8Bm1KbJD2kyFORSogMPZISIf/Y90c1jNrMFp30bAl8pDl1TrmZv1XbRKt+2EauL5/d5vQVttJHc", + "DeWzevKuQIZoOYT/8xbB+yG4wxy/dzUJ7PFyi/gzRPx7VTIhr0SdNm41qD+l6/E6b/brXtArwcH62I3k", + "a2nx1p1aiR2GcVik+HohVn+pm/5cVgQ58nV2tsohfzcv7ZBFhtzeWLPnS7zC/x6tRtS4ZczaJjuLIdSj", + "DWHO5kVba77Zf/4TajGfhJ9+hqrNp+BYN8Ni8JB6PuPEAn5YpoMleCwxH1Wtx/s40AvzciCXvXaN+wdy", + "Iy2qMDSI1P4hU8gFn6vPkxVto444XiJUYitN2ZYVnfVP/oJn95nrJ+Fbert6T4rxFIgSS0CVwcjo2OPA", + "Bks+efC3m4NQs6Xv38vD3NVPzF2+evD45qY/BbliKZAzWBZCUsnyDfmFV30jrsLtFKFuz0NrcIQ5MI7e", + "pmZdsDQsYnR5JtgIXfug1yz7uJsZBoUU9+SDjAd8MCyiTYsCqLw8A9ztumo3mTx5HkYHi6rUiN+VHlAM", + "ivYMkP8/o4F2J0x7FzN3+ZXcAuqrfzk24UJ3xWxcBccYKUDMnpK3/D5RC+qLU7o/H331dY/lzMzjivZ0", + "bWf1QOaxHWaIAe2LNgceVmqv8Pv0pnd7v00cj1i2jvaYh3VQOrzZBM+JZXcUKejGh9F2ilAV8UKUlTQQ", + "DrsEI8arBStuvtih0mwar/bq1Z+qmeoJ/67Sgm1FPiN8F5+iyN14pCVABoVe7Kx9iW/VuwmuCiZTruq9", + "rVA4JmwCE1vAr+4Gks1BWY2akhzorGrrIcSQ5ImAzxhC81QRYD1cyBCdNEo/WDAEifLmldM6ycBedB55", + "snXnfFJBV38qJTVBHRW4F2yaaPl0MiWYN8eBu7uQQotU5DZ2pSwKIXV1utVkkLgHfW67hrTXR7hXEubW", + "LFM77Whn+NYBDGlNylZfjB3tzKMpZkiLLeqSFfnquYawtDNRkE4TVwPCJ+Vrt0a3GD9r2dy+dJOb7iW9", + "A1vgUqrTRVkcfcD/YEXCj3WiFNZqV0d6zY+wp9LRh60hTchScyObSFvmvaFHR1tCd816+HldUv4HITs9", + "/XeFLLWQNm5f+rY/FMY+Rdjj9WiTf2klbKu9srXhV3fBRUbsnNcqDzjoclPRbtCowKf22h5XERK+dRl/", + "XguqjbgzxjNCg21s2ZqqPrReB/jbF7voT2EXvnk/+Vdf8Dl7JTQ5WRa24T9kV4s2JG0O52+PrdftfoKB", + "u/q7IYndOz+88X0gdSWL7Lzg99B7gtIR4KejEms5mLv6etSd25v8877Jn/kS6Q0yvL2Xv5x7Wfrw79sr", + "+PO/gh9/sau5RsfxwCvZ30SXvoZrTXzPC7kjDDgbVstwsM2vjKp3e5XqByF9O57bW/wLdYranRycZDnE", + "QrPLEuumPESo/2cF/TA7Q55HLA19B3Vse5PpBTAskiVShv0OTjI1tofYGSfcKb4VfD5rwSfY61u559b0", + "8IWZHnqkHKf15/kQQWNfAWi1FBl4x6qYzVxRyj7pp9kry5Cn0nRZEPtlVMqxTli2hFPz5s92ioNesTXY", + "LbGoBZ5BloJU8EwNiOJwo172HkJHUz8AN+7ZrHbAw+LKVUwuTbJvgppXHUogbeQr7HHmi3M6ZGSwIoYA", + "Jwcg26MP9l80pxVCRVZz6gm4szF33bbYaqN23AaA5DUKoa6jv/tKzMgDW3S05JhZWDczpTwjWm6MoOpr", + "LEmgOUkbGUUVHN2Tc9p7cnaqAp3V9awprguI+oQeMoKhlc35040fgGeUO5LvIkgLQgmHOdVsBd7lP7mt", + "AHLp28zV39jCAMeEZpk9jfUmwArkhqhyqoysw5uB4XdU87zswTBgXYBk5oqmee2At2rCkS3vsS2O6NS+", + "ccVLq8WLbFER2Yxa9DerKzkiZuQlS6U4zudC+ThUtVEalp1Woe7T33uKRHtDQjdmVfCccUiWgscaWP6M", + "T1/iw9jXWCKl7+Mz87Dv29Z924S/BVZzniF38lXx+5mc/isFurRWK6EQ0mi3U9tU29L/nkfJH5oNT7sn", + "acPTwKnlHgYDhe0uGz8f+XSERvPL6JsfGn+6MkDuTbUodSYuglnQBmDDGYdUAAla8F/C5tZqZa+u1+p2", + "nd6mAA+xs1U9jTQ1rB/29zX8i2a+OedMSCQYlJ6KFUjVUuRu09/+VOlvg/d9L25sm/ju4milOqzs8kpk", + "YMdt9tCOVZ7nIgPXa7grslRhkfGUIX9/1e+1kjhSWs4XmpQF0SKWLlJ/mNDUMtnEKkLxCYNaj1ZdwukW", + "dAWE5tjBmUwBOBFTs+j6JsVFUoXVNn3OiQv+jApNAVyFFCkoBVniK+3vAq3q4Iyh6noLnhBwBLiahShB", + "ZlReGdjz1U44z2GToDKsyN2ffjWq9Y3Da4XG7Yi1Nf4i6K3qCDm5sAv1sOm3EVx78pDsqATiRQNMkRPL", + "IgeXJBdB4V446d2/NkSdXbw6WjCLjF0zxftJrkZAFajXTO9XhbYsEnN/d0F8Zp+esSVKYpxy4S2QscFy", + "qnSyiy2bl8K1KLOCgBPGODEO3KOavqBKv3H50hnW1rLXCc5jZWwzRT/AVc/+2Mi/2oexsVNzH3JVKuJG", + "8DlQkMXWwGG9Za5XsK7mwoR1P3aVZGVtgbtG7sNSML5DVtBugFAd+P3NcJHFoaWSOlNGF5UNIGpEbAPk", + "1L8VYDd0+PcAwlSNaEs4WD45pJypEDlQbnNVRVEYbqGTklff9aHp1L59rH+p3+0SF9X1vZ0JUGECnIP8", + "wmJWoSl3QRVxcJAlPXc5cnPXPq4LszmMCda2SLZRPhp3zVvhEdh5SMtiLmkGSQY5jRhdfrGPiX28bQDc", + "cU+eyUpoSKYwExLim15Tsuw1JlVDCxxPxYRHgk9Iao6gUZ5rAnFf7xg5Axw7xpwcHd2phsK5olvkx8Nl", + "263uMWCZMcyOO3pAkB1HHwJwDx6qoS+PCvw4qc0H7Sn+CcpNUMkR+0+yAdW3hHr8vRbQNvyFF1jjpmix", + "9xYHjrLNXja2g4/0HdmYqfGLdAu0o5yuMcmuaWoNFMDJZZTbowvKdDIT0grSCZ1pkDtD5/9BmXec+/Rd", + "4aquEBzB3ZtuHGTyYRMfx0UsCMRdF4ZEJuRsARLMHUbJQ7JkvNT2iSj12NYclUDThRHaQxusHQnbMLrG", + "hBLmVGY5tuibVfemkHgZMd264BHoSD5iU+M36/5ByEGVjJv1uijTpOSa5UE3h0pv//ysl7cWiVuLxK1F", + "4tYicWuRuLVI3Fokbi0StxaJW4vErUXi1iLx17VIfKoySYmXOHzFRi540g6mvI2l/FOV8q2uKm8gQevE", + "BWXa9Sb2VQr67RZ7GII00BxxwHLoj+62Qadn3x+/IEqUMgWSGggZJ0VOjWoAa111ymz2YPbd4W27Xdve", + "mSp4/Iic/v3YVxxduMqYzXfvHtt4NaL0Jod7rhcN8MxKor4pDXCDdNeThvorwXfUdP1FWY6R8Yp8j28/", + "hxXkogBpixkSLctIS/ozoPkzh5sdBp9/mMldqO17M9r7ccPo5dC2pIUX8/1aqSLUZlyS50EO5vsZzRW8", + "70vDtOMtaRFralldfNYUhMzkO5FtWifE7NoRbmDzbNR1RxmnchOpEtVNgWiThhaGXTnC6tqyPh68Om6X", + "aLtktovCYtK6BBU9x9uoPFoWttqwzlA2UXfWopNRLMe0XQt1VAE4qDAgpknYPSFv7HeftgwgQuSOWM3M", + "P5soxuabFdPAd40S4VjPl5pL4BEfPb149seGsLMyBcK0Ir7A7u7rZTxaJ2akOfDEMaBkKrJN0mBfo8Yt", + "lDFFlYLldPdNFPJP18bdXT7myfZ76tNcI8+DxW3jySHRrBPHgHu480bDYN5cYQtHdOw5wPh1s+g+NhqC", + "QBx/ihmVWrxvX6ZXT7O5ZXy3jC84jS2JgHFXkLzNRCbXyPjkRpa8n+d9v4a0NMCFJ/kuWufRJQdr3XCy", + "ZjAt53NsR9/x0ZmlAY7HBP9ErNAudygX3I+C7OBVi+KrJqm3h+tylyBv/K6vzHgPt4PyDTozlgXlG+/y", + "hUSxZZlbHNpOnodltLZmeKzEdG3767Nqv/Ymv8B2667a5u8WLeSCKmL3FzJS8sxlPHVqW6/58Donduiz", + "Na/Z9NaaJna9kdW5eYdcEX6Xm6nmihQgE73m9kA1DpPrYGBP7uS2Dfdf49qwierQw2C71fhrhnCg20MG", + "fA2vj6DnUp2Y1+jERJvphI1naNHoT3EJmzPZNw8aWNIZvhlfUptbnP8U8oJQkuYMvauCKy3LVL/lFP03", + "wcIm3dgTb6ju533P/CtxF2LEw+eGesspBhlVXp0oD5xBxIXxA4Bnsaqcz0EZPhoS0AzgLXdvMU5KbrQw", + "MSNLlkqR2NRac76M7DKxby7phsywookgf4AUZGpu/WDXrS1ZaZbnLtjFTEPE7C2nmuRAlSYvmeHAZjhf", + "TqEKOQN9IeR5hYV4r545cFBMJXHDzI/2KbbDccv3BkA0ZtrHdRuLm+2D42FnWS/kJ88xRg2rMedM6To+", + "ogP7jfnGl4wnUSI7WwBx4WJt2iJ3sQacI6B7TceRXsBbbm4/LQhyfKovRw5tD1DnLNrT0aKaxka0HEV+", + "rYPUv4NwGRJhMrdulz9RCmlAB96ziRtv6+u39n5PF0vjygWemac9F7J96ton9rzkFIiGkaxV4Ma9cdYA", + "eav/4ssvK3l4XdKj8WDaZHfALrtqNshDvPkNHxOaCz63dRWNdilwnxgvSo0B4NdpwIMVzROxAilZBmrg", + "Spng369o/nP12cfxCNaQJlrSFBJrURiKtTPzjaVTbDTImWY0T1CrHgoQnNivTu1HO+7joNvocgkZoxry", + "DSkkpJDZQmRMkVqfn9gCDSRdUD7Hq1uKcr6wr9lxLkBC1ZjRqNDtIeKFYNY8sUXpujAeE2sLDev2Ak0X", + "kcYxeMEZnd0TVNboSTVwDxolR/uU9PGoV9A2SF3VoXMWOU02M0CKaMgDAX7qiQ9Ro/WW6G+J/ksn+lhJ", + "RUTdrGWtsPgKt+WazVrXXUD0Bq1kn6S68G2J/j97iX7PgRShRNKGDhLvDUcVYZpcYFmkKRBzf5VonXcN", + "95y+jpl2wVF3lTaVa8+XLijjrqZOldeAcGjXLV779rTXYti0zAwtmgYdkJaS6Q1qLbRgv5+D+f87I/Yr", + "kCuv0JQyHz0dLbQunh4d5SKl+UIofTT6OA6fqdbDdxX8H7wuUki2MvrVx3cf/28AAAD//9NaXScGqAEA", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/daemon/algod/api/server/v2/generated/participating/private/routes.go b/daemon/algod/api/server/v2/generated/participating/private/routes.go index 79a65f5721..3ed2dcfedd 100644 --- a/daemon/algod/api/server/v2/generated/participating/private/routes.go +++ b/daemon/algod/api/server/v2/generated/participating/private/routes.go @@ -203,216 +203,217 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", - "CB++b8jjQ3OPODL5+P7j/wsAAP//bjFnIYoHAQA=", + "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/daemon/algod/api/server/v2/generated/participating/public/routes.go b/daemon/algod/api/server/v2/generated/participating/public/routes.go index 67e59f47b8..4d6fcda0f7 100644 --- a/daemon/algod/api/server/v2/generated/participating/public/routes.go +++ b/daemon/algod/api/server/v2/generated/participating/public/routes.go @@ -255,143 +255,144 @@ var swaggerSpec = []string{ "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/daemon/algod/api/server/v2/handlers.go b/daemon/algod/api/server/v2/handlers.go index c26c7762b9..f65ffe4995 100644 --- a/daemon/algod/api/server/v2/handlers.go +++ b/daemon/algod/api/server/v2/handlers.go @@ -537,6 +537,8 @@ func (v2 *Handlers) basicAccountInformation(ctx echo.Context, addr basics.Addres TotalBoxes: omitEmpty(record.TotalBoxes), TotalBoxBytes: omitEmpty(record.TotalBoxBytes), MinBalance: record.MinBalance(&consensus).Raw, + LastProposed: omitEmpty(uint64(record.LastProposed)), + LastHeartbeat: omitEmpty(uint64(record.LastHeartbeat)), } response := model.AccountResponse(account) return ctx.JSON(http.StatusOK, response) diff --git a/data/basics/msgp_gen.go b/data/basics/msgp_gen.go index 06190153d6..7e60ace888 100644 --- a/data/basics/msgp_gen.go +++ b/data/basics/msgp_gen.go @@ -250,8 +250,8 @@ import ( func (z *AccountData) MarshalMsg(b []byte) (o []byte) { o = msgp.Require(b, z.Msgsize()) // omitempty: check for empty values - zb0009Len := uint32(19) - var zb0009Mask uint32 /* 20 bits */ + zb0009Len := uint32(21) + var zb0009Mask uint32 /* 22 bits */ if (*z).MicroAlgos.MsgIsZero() { zb0009Len-- zb0009Mask |= 0x2 @@ -280,54 +280,62 @@ func (z *AccountData) MarshalMsg(b []byte) (o []byte) { zb0009Len-- zb0009Mask |= 0x80 } - if (*z).Status == 0 { + if (*z).LastHeartbeat == 0 { zb0009Len-- zb0009Mask |= 0x100 } - if (*z).SelectionID.MsgIsZero() { + if (*z).LastProposed == 0 { zb0009Len-- zb0009Mask |= 0x200 } - if (*z).AuthAddr.MsgIsZero() { + if (*z).Status == 0 { zb0009Len-- zb0009Mask |= 0x400 } - if (*z).StateProofID.MsgIsZero() { + if (*z).SelectionID.MsgIsZero() { zb0009Len-- zb0009Mask |= 0x800 } - if (*z).TotalBoxes == 0 { + if (*z).AuthAddr.MsgIsZero() { zb0009Len-- zb0009Mask |= 0x1000 } - if (*z).TotalBoxBytes == 0 { + if (*z).StateProofID.MsgIsZero() { zb0009Len-- zb0009Mask |= 0x2000 } - if (*z).TotalExtraAppPages == 0 { + if (*z).TotalBoxes == 0 { zb0009Len-- zb0009Mask |= 0x4000 } - if ((*z).TotalAppSchema.NumUint == 0) && ((*z).TotalAppSchema.NumByteSlice == 0) { + if (*z).TotalBoxBytes == 0 { zb0009Len-- zb0009Mask |= 0x8000 } - if (*z).VoteID.MsgIsZero() { + if (*z).TotalExtraAppPages == 0 { zb0009Len-- zb0009Mask |= 0x10000 } - if (*z).VoteFirstValid == 0 { + if ((*z).TotalAppSchema.NumUint == 0) && ((*z).TotalAppSchema.NumByteSlice == 0) { zb0009Len-- zb0009Mask |= 0x20000 } - if (*z).VoteKeyDilution == 0 { + if (*z).VoteID.MsgIsZero() { zb0009Len-- zb0009Mask |= 0x40000 } - if (*z).VoteLastValid == 0 { + if (*z).VoteFirstValid == 0 { zb0009Len-- zb0009Mask |= 0x80000 } + if (*z).VoteKeyDilution == 0 { + zb0009Len-- + zb0009Mask |= 0x100000 + } + if (*z).VoteLastValid == 0 { + zb0009Len-- + zb0009Mask |= 0x200000 + } // variable map header, size zb0009Len o = msgp.AppendMapHeader(o, zb0009Len) if zb0009Len != 0 { @@ -451,41 +459,51 @@ func (z *AccountData) MarshalMsg(b []byte) (o []byte) { o = (*z).RewardedMicroAlgos.MarshalMsg(o) } if (zb0009Mask & 0x100) == 0 { // if not empty + // string "lhb" + o = append(o, 0xa3, 0x6c, 0x68, 0x62) + o = msgp.AppendUint64(o, uint64((*z).LastHeartbeat)) + } + if (zb0009Mask & 0x200) == 0 { // if not empty + // string "lpr" + o = append(o, 0xa3, 0x6c, 0x70, 0x72) + o = msgp.AppendUint64(o, uint64((*z).LastProposed)) + } + if (zb0009Mask & 0x400) == 0 { // if not empty // string "onl" o = append(o, 0xa3, 0x6f, 0x6e, 0x6c) o = msgp.AppendByte(o, byte((*z).Status)) } - if (zb0009Mask & 0x200) == 0 { // if not empty + if (zb0009Mask & 0x800) == 0 { // if not empty // string "sel" o = append(o, 0xa3, 0x73, 0x65, 0x6c) o = (*z).SelectionID.MarshalMsg(o) } - if (zb0009Mask & 0x400) == 0 { // if not empty + if (zb0009Mask & 0x1000) == 0 { // if not empty // string "spend" o = append(o, 0xa5, 0x73, 0x70, 0x65, 0x6e, 0x64) o = (*z).AuthAddr.MarshalMsg(o) } - if (zb0009Mask & 0x800) == 0 { // if not empty + if (zb0009Mask & 0x2000) == 0 { // if not empty // string "stprf" o = append(o, 0xa5, 0x73, 0x74, 0x70, 0x72, 0x66) o = (*z).StateProofID.MarshalMsg(o) } - if (zb0009Mask & 0x1000) == 0 { // if not empty + if (zb0009Mask & 0x4000) == 0 { // if not empty // string "tbx" o = append(o, 0xa3, 0x74, 0x62, 0x78) o = msgp.AppendUint64(o, (*z).TotalBoxes) } - if (zb0009Mask & 0x2000) == 0 { // if not empty + if (zb0009Mask & 0x8000) == 0 { // if not empty // string "tbxb" o = append(o, 0xa4, 0x74, 0x62, 0x78, 0x62) o = msgp.AppendUint64(o, (*z).TotalBoxBytes) } - if (zb0009Mask & 0x4000) == 0 { // if not empty + if (zb0009Mask & 0x10000) == 0 { // if not empty // string "teap" o = append(o, 0xa4, 0x74, 0x65, 0x61, 0x70) o = msgp.AppendUint32(o, (*z).TotalExtraAppPages) } - if (zb0009Mask & 0x8000) == 0 { // if not empty + if (zb0009Mask & 0x20000) == 0 { // if not empty // string "tsch" o = append(o, 0xa4, 0x74, 0x73, 0x63, 0x68) // omitempty: check for empty values @@ -512,22 +530,22 @@ func (z *AccountData) MarshalMsg(b []byte) (o []byte) { o = msgp.AppendUint64(o, (*z).TotalAppSchema.NumUint) } } - if (zb0009Mask & 0x10000) == 0 { // if not empty + if (zb0009Mask & 0x40000) == 0 { // if not empty // string "vote" o = append(o, 0xa4, 0x76, 0x6f, 0x74, 0x65) o = (*z).VoteID.MarshalMsg(o) } - if (zb0009Mask & 0x20000) == 0 { // if not empty + if (zb0009Mask & 0x80000) == 0 { // if not empty // string "voteFst" o = append(o, 0xa7, 0x76, 0x6f, 0x74, 0x65, 0x46, 0x73, 0x74) o = msgp.AppendUint64(o, uint64((*z).VoteFirstValid)) } - if (zb0009Mask & 0x40000) == 0 { // if not empty + if (zb0009Mask & 0x100000) == 0 { // if not empty // string "voteKD" o = append(o, 0xa6, 0x76, 0x6f, 0x74, 0x65, 0x4b, 0x44) o = msgp.AppendUint64(o, (*z).VoteKeyDilution) } - if (zb0009Mask & 0x80000) == 0 { // if not empty + if (zb0009Mask & 0x200000) == 0 { // if not empty // string "voteLst" o = append(o, 0xa7, 0x76, 0x6f, 0x74, 0x65, 0x4c, 0x73, 0x74) o = msgp.AppendUint64(o, uint64((*z).VoteLastValid)) @@ -653,27 +671,51 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) } if zb0009 > 0 { zb0009-- - var zb0014 int - var zb0015 bool - zb0014, zb0015, bts, err = msgp.ReadMapHeaderBytes(bts) + { + var zb0014 uint64 + zb0014, bts, err = msgp.ReadUint64Bytes(bts) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "LastProposed") + return + } + (*z).LastProposed = Round(zb0014) + } + } + if zb0009 > 0 { + zb0009-- + { + var zb0015 uint64 + zb0015, bts, err = msgp.ReadUint64Bytes(bts) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "LastHeartbeat") + return + } + (*z).LastHeartbeat = Round(zb0015) + } + } + if zb0009 > 0 { + zb0009-- + var zb0016 int + var zb0017 bool + zb0016, zb0017, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "AssetParams") return } - if zb0014 > encodedMaxAssetsPerAccount { - err = msgp.ErrOverflow(uint64(zb0014), uint64(encodedMaxAssetsPerAccount)) + if zb0016 > encodedMaxAssetsPerAccount { + err = msgp.ErrOverflow(uint64(zb0016), uint64(encodedMaxAssetsPerAccount)) err = msgp.WrapError(err, "struct-from-array", "AssetParams") return } - if zb0015 { + if zb0017 { (*z).AssetParams = nil } else if (*z).AssetParams == nil { - (*z).AssetParams = make(map[AssetIndex]AssetParams, zb0014) + (*z).AssetParams = make(map[AssetIndex]AssetParams, zb0016) } - for zb0014 > 0 { + for zb0016 > 0 { var zb0001 AssetIndex var zb0002 AssetParams - zb0014-- + zb0016-- bts, err = zb0001.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "AssetParams") @@ -689,59 +731,59 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) } if zb0009 > 0 { zb0009-- - var zb0016 int - var zb0017 bool - zb0016, zb0017, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0018 int + var zb0019 bool + zb0018, zb0019, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Assets") return } - if zb0016 > encodedMaxAssetsPerAccount { - err = msgp.ErrOverflow(uint64(zb0016), uint64(encodedMaxAssetsPerAccount)) + if zb0018 > encodedMaxAssetsPerAccount { + err = msgp.ErrOverflow(uint64(zb0018), uint64(encodedMaxAssetsPerAccount)) err = msgp.WrapError(err, "struct-from-array", "Assets") return } - if zb0017 { + if zb0019 { (*z).Assets = nil } else if (*z).Assets == nil { - (*z).Assets = make(map[AssetIndex]AssetHolding, zb0016) + (*z).Assets = make(map[AssetIndex]AssetHolding, zb0018) } - for zb0016 > 0 { + for zb0018 > 0 { var zb0003 AssetIndex var zb0004 AssetHolding - zb0016-- + zb0018-- bts, err = zb0003.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Assets") return } - var zb0018 int - var zb0019 bool - zb0018, zb0019, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0020 int + var zb0021 bool + zb0020, zb0021, bts, err = msgp.ReadMapHeaderBytes(bts) if _, ok := err.(msgp.TypeError); ok { - zb0018, zb0019, bts, err = msgp.ReadArrayHeaderBytes(bts) + zb0020, zb0021, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003) return } - if zb0018 > 0 { - zb0018-- + if zb0020 > 0 { + zb0020-- zb0004.Amount, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003, "struct-from-array", "Amount") return } } - if zb0018 > 0 { - zb0018-- + if zb0020 > 0 { + zb0020-- zb0004.Frozen, bts, err = msgp.ReadBoolBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003, "struct-from-array", "Frozen") return } } - if zb0018 > 0 { - err = msgp.ErrTooManyArrayFields(zb0018) + if zb0020 > 0 { + err = msgp.ErrTooManyArrayFields(zb0020) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003, "struct-from-array") return @@ -752,11 +794,11 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003) return } - if zb0019 { + if zb0021 { zb0004 = AssetHolding{} } - for zb0018 > 0 { - zb0018-- + for zb0020 > 0 { + zb0020-- field, bts, err = msgp.ReadMapKeyZC(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003) @@ -797,27 +839,27 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) } if zb0009 > 0 { zb0009-- - var zb0020 int - var zb0021 bool - zb0020, zb0021, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0022 int + var zb0023 bool + zb0022, zb0023, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "AppLocalStates") return } - if zb0020 > EncodedMaxAppLocalStates { - err = msgp.ErrOverflow(uint64(zb0020), uint64(EncodedMaxAppLocalStates)) + if zb0022 > EncodedMaxAppLocalStates { + err = msgp.ErrOverflow(uint64(zb0022), uint64(EncodedMaxAppLocalStates)) err = msgp.WrapError(err, "struct-from-array", "AppLocalStates") return } - if zb0021 { + if zb0023 { (*z).AppLocalStates = nil } else if (*z).AppLocalStates == nil { - (*z).AppLocalStates = make(map[AppIndex]AppLocalState, zb0020) + (*z).AppLocalStates = make(map[AppIndex]AppLocalState, zb0022) } - for zb0020 > 0 { + for zb0022 > 0 { var zb0005 AppIndex var zb0006 AppLocalState - zb0020-- + zb0022-- bts, err = zb0005.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "AppLocalStates") @@ -833,27 +875,27 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) } if zb0009 > 0 { zb0009-- - var zb0022 int - var zb0023 bool - zb0022, zb0023, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0024 int + var zb0025 bool + zb0024, zb0025, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "AppParams") return } - if zb0022 > EncodedMaxAppParams { - err = msgp.ErrOverflow(uint64(zb0022), uint64(EncodedMaxAppParams)) + if zb0024 > EncodedMaxAppParams { + err = msgp.ErrOverflow(uint64(zb0024), uint64(EncodedMaxAppParams)) err = msgp.WrapError(err, "struct-from-array", "AppParams") return } - if zb0023 { + if zb0025 { (*z).AppParams = nil } else if (*z).AppParams == nil { - (*z).AppParams = make(map[AppIndex]AppParams, zb0022) + (*z).AppParams = make(map[AppIndex]AppParams, zb0024) } - for zb0022 > 0 { + for zb0024 > 0 { var zb0007 AppIndex var zb0008 AppParams - zb0022-- + zb0024-- bts, err = zb0007.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "AppParams") @@ -869,33 +911,33 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) } if zb0009 > 0 { zb0009-- - var zb0024 int - var zb0025 bool - zb0024, zb0025, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0026 int + var zb0027 bool + zb0026, zb0027, bts, err = msgp.ReadMapHeaderBytes(bts) if _, ok := err.(msgp.TypeError); ok { - zb0024, zb0025, bts, err = msgp.ReadArrayHeaderBytes(bts) + zb0026, zb0027, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema") return } - if zb0024 > 0 { - zb0024-- + if zb0026 > 0 { + zb0026-- (*z).TotalAppSchema.NumUint, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema", "struct-from-array", "NumUint") return } } - if zb0024 > 0 { - zb0024-- + if zb0026 > 0 { + zb0026-- (*z).TotalAppSchema.NumByteSlice, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema", "struct-from-array", "NumByteSlice") return } } - if zb0024 > 0 { - err = msgp.ErrTooManyArrayFields(zb0024) + if zb0026 > 0 { + err = msgp.ErrTooManyArrayFields(zb0026) if err != nil { err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema", "struct-from-array") return @@ -906,11 +948,11 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema") return } - if zb0025 { + if zb0027 { (*z).TotalAppSchema = StateSchema{} } - for zb0024 > 0 { - zb0024-- + for zb0026 > 0 { + zb0026-- field, bts, err = msgp.ReadMapKeyZC(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema") @@ -988,13 +1030,13 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) switch string(field) { case "onl": { - var zb0026 byte - zb0026, bts, err = msgp.ReadByteBytes(bts) + var zb0028 byte + zb0028, bts, err = msgp.ReadByteBytes(bts) if err != nil { err = msgp.WrapError(err, "Status") return } - (*z).Status = Status(zb0026) + (*z).Status = Status(zb0028) } case "algo": bts, err = (*z).MicroAlgos.UnmarshalMsgWithState(bts, st) @@ -1034,23 +1076,23 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) } case "voteFst": { - var zb0027 uint64 - zb0027, bts, err = msgp.ReadUint64Bytes(bts) + var zb0029 uint64 + zb0029, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "VoteFirstValid") return } - (*z).VoteFirstValid = Round(zb0027) + (*z).VoteFirstValid = Round(zb0029) } case "voteLst": { - var zb0028 uint64 - zb0028, bts, err = msgp.ReadUint64Bytes(bts) + var zb0030 uint64 + zb0030, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "VoteLastValid") return } - (*z).VoteLastValid = Round(zb0028) + (*z).VoteLastValid = Round(zb0030) } case "voteKD": (*z).VoteKeyDilution, bts, err = msgp.ReadUint64Bytes(bts) @@ -1058,28 +1100,48 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) err = msgp.WrapError(err, "VoteKeyDilution") return } + case "lpr": + { + var zb0031 uint64 + zb0031, bts, err = msgp.ReadUint64Bytes(bts) + if err != nil { + err = msgp.WrapError(err, "LastProposed") + return + } + (*z).LastProposed = Round(zb0031) + } + case "lhb": + { + var zb0032 uint64 + zb0032, bts, err = msgp.ReadUint64Bytes(bts) + if err != nil { + err = msgp.WrapError(err, "LastHeartbeat") + return + } + (*z).LastHeartbeat = Round(zb0032) + } case "apar": - var zb0029 int - var zb0030 bool - zb0029, zb0030, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0033 int + var zb0034 bool + zb0033, zb0034, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "AssetParams") return } - if zb0029 > encodedMaxAssetsPerAccount { - err = msgp.ErrOverflow(uint64(zb0029), uint64(encodedMaxAssetsPerAccount)) + if zb0033 > encodedMaxAssetsPerAccount { + err = msgp.ErrOverflow(uint64(zb0033), uint64(encodedMaxAssetsPerAccount)) err = msgp.WrapError(err, "AssetParams") return } - if zb0030 { + if zb0034 { (*z).AssetParams = nil } else if (*z).AssetParams == nil { - (*z).AssetParams = make(map[AssetIndex]AssetParams, zb0029) + (*z).AssetParams = make(map[AssetIndex]AssetParams, zb0033) } - for zb0029 > 0 { + for zb0033 > 0 { var zb0001 AssetIndex var zb0002 AssetParams - zb0029-- + zb0033-- bts, err = zb0001.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "AssetParams") @@ -1093,59 +1155,59 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (*z).AssetParams[zb0001] = zb0002 } case "asset": - var zb0031 int - var zb0032 bool - zb0031, zb0032, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0035 int + var zb0036 bool + zb0035, zb0036, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "Assets") return } - if zb0031 > encodedMaxAssetsPerAccount { - err = msgp.ErrOverflow(uint64(zb0031), uint64(encodedMaxAssetsPerAccount)) + if zb0035 > encodedMaxAssetsPerAccount { + err = msgp.ErrOverflow(uint64(zb0035), uint64(encodedMaxAssetsPerAccount)) err = msgp.WrapError(err, "Assets") return } - if zb0032 { + if zb0036 { (*z).Assets = nil } else if (*z).Assets == nil { - (*z).Assets = make(map[AssetIndex]AssetHolding, zb0031) + (*z).Assets = make(map[AssetIndex]AssetHolding, zb0035) } - for zb0031 > 0 { + for zb0035 > 0 { var zb0003 AssetIndex var zb0004 AssetHolding - zb0031-- + zb0035-- bts, err = zb0003.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "Assets") return } - var zb0033 int - var zb0034 bool - zb0033, zb0034, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0037 int + var zb0038 bool + zb0037, zb0038, bts, err = msgp.ReadMapHeaderBytes(bts) if _, ok := err.(msgp.TypeError); ok { - zb0033, zb0034, bts, err = msgp.ReadArrayHeaderBytes(bts) + zb0037, zb0038, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "Assets", zb0003) return } - if zb0033 > 0 { - zb0033-- + if zb0037 > 0 { + zb0037-- zb0004.Amount, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "Assets", zb0003, "struct-from-array", "Amount") return } } - if zb0033 > 0 { - zb0033-- + if zb0037 > 0 { + zb0037-- zb0004.Frozen, bts, err = msgp.ReadBoolBytes(bts) if err != nil { err = msgp.WrapError(err, "Assets", zb0003, "struct-from-array", "Frozen") return } } - if zb0033 > 0 { - err = msgp.ErrTooManyArrayFields(zb0033) + if zb0037 > 0 { + err = msgp.ErrTooManyArrayFields(zb0037) if err != nil { err = msgp.WrapError(err, "Assets", zb0003, "struct-from-array") return @@ -1156,11 +1218,11 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) err = msgp.WrapError(err, "Assets", zb0003) return } - if zb0034 { + if zb0038 { zb0004 = AssetHolding{} } - for zb0033 > 0 { - zb0033-- + for zb0037 > 0 { + zb0037-- field, bts, err = msgp.ReadMapKeyZC(bts) if err != nil { err = msgp.WrapError(err, "Assets", zb0003) @@ -1197,27 +1259,27 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) return } case "appl": - var zb0035 int - var zb0036 bool - zb0035, zb0036, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0039 int + var zb0040 bool + zb0039, zb0040, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "AppLocalStates") return } - if zb0035 > EncodedMaxAppLocalStates { - err = msgp.ErrOverflow(uint64(zb0035), uint64(EncodedMaxAppLocalStates)) + if zb0039 > EncodedMaxAppLocalStates { + err = msgp.ErrOverflow(uint64(zb0039), uint64(EncodedMaxAppLocalStates)) err = msgp.WrapError(err, "AppLocalStates") return } - if zb0036 { + if zb0040 { (*z).AppLocalStates = nil } else if (*z).AppLocalStates == nil { - (*z).AppLocalStates = make(map[AppIndex]AppLocalState, zb0035) + (*z).AppLocalStates = make(map[AppIndex]AppLocalState, zb0039) } - for zb0035 > 0 { + for zb0039 > 0 { var zb0005 AppIndex var zb0006 AppLocalState - zb0035-- + zb0039-- bts, err = zb0005.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "AppLocalStates") @@ -1231,27 +1293,27 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (*z).AppLocalStates[zb0005] = zb0006 } case "appp": - var zb0037 int - var zb0038 bool - zb0037, zb0038, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0041 int + var zb0042 bool + zb0041, zb0042, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "AppParams") return } - if zb0037 > EncodedMaxAppParams { - err = msgp.ErrOverflow(uint64(zb0037), uint64(EncodedMaxAppParams)) + if zb0041 > EncodedMaxAppParams { + err = msgp.ErrOverflow(uint64(zb0041), uint64(EncodedMaxAppParams)) err = msgp.WrapError(err, "AppParams") return } - if zb0038 { + if zb0042 { (*z).AppParams = nil } else if (*z).AppParams == nil { - (*z).AppParams = make(map[AppIndex]AppParams, zb0037) + (*z).AppParams = make(map[AppIndex]AppParams, zb0041) } - for zb0037 > 0 { + for zb0041 > 0 { var zb0007 AppIndex var zb0008 AppParams - zb0037-- + zb0041-- bts, err = zb0007.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "AppParams") @@ -1265,33 +1327,33 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (*z).AppParams[zb0007] = zb0008 } case "tsch": - var zb0039 int - var zb0040 bool - zb0039, zb0040, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0043 int + var zb0044 bool + zb0043, zb0044, bts, err = msgp.ReadMapHeaderBytes(bts) if _, ok := err.(msgp.TypeError); ok { - zb0039, zb0040, bts, err = msgp.ReadArrayHeaderBytes(bts) + zb0043, zb0044, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "TotalAppSchema") return } - if zb0039 > 0 { - zb0039-- + if zb0043 > 0 { + zb0043-- (*z).TotalAppSchema.NumUint, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "TotalAppSchema", "struct-from-array", "NumUint") return } } - if zb0039 > 0 { - zb0039-- + if zb0043 > 0 { + zb0043-- (*z).TotalAppSchema.NumByteSlice, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "TotalAppSchema", "struct-from-array", "NumByteSlice") return } } - if zb0039 > 0 { - err = msgp.ErrTooManyArrayFields(zb0039) + if zb0043 > 0 { + err = msgp.ErrTooManyArrayFields(zb0043) if err != nil { err = msgp.WrapError(err, "TotalAppSchema", "struct-from-array") return @@ -1302,11 +1364,11 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) err = msgp.WrapError(err, "TotalAppSchema") return } - if zb0040 { + if zb0044 { (*z).TotalAppSchema = StateSchema{} } - for zb0039 > 0 { - zb0039-- + for zb0043 > 0 { + zb0043-- field, bts, err = msgp.ReadMapKeyZC(bts) if err != nil { err = msgp.WrapError(err, "TotalAppSchema") @@ -1375,7 +1437,7 @@ func (_ *AccountData) CanUnmarshalMsg(z interface{}) bool { // Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message func (z *AccountData) Msgsize() (s int) { - s = 3 + 4 + msgp.ByteSize + 5 + (*z).MicroAlgos.Msgsize() + 6 + msgp.Uint64Size + 4 + (*z).RewardedMicroAlgos.Msgsize() + 5 + (*z).VoteID.Msgsize() + 4 + (*z).SelectionID.Msgsize() + 6 + (*z).StateProofID.Msgsize() + 8 + msgp.Uint64Size + 8 + msgp.Uint64Size + 7 + msgp.Uint64Size + 5 + msgp.MapHeaderSize + s = 3 + 4 + msgp.ByteSize + 5 + (*z).MicroAlgos.Msgsize() + 6 + msgp.Uint64Size + 4 + (*z).RewardedMicroAlgos.Msgsize() + 5 + (*z).VoteID.Msgsize() + 4 + (*z).SelectionID.Msgsize() + 6 + (*z).StateProofID.Msgsize() + 8 + msgp.Uint64Size + 8 + msgp.Uint64Size + 7 + msgp.Uint64Size + 4 + msgp.Uint64Size + 4 + msgp.Uint64Size + 5 + msgp.MapHeaderSize if (*z).AssetParams != nil { for zb0001, zb0002 := range (*z).AssetParams { _ = zb0001 @@ -1413,12 +1475,12 @@ func (z *AccountData) Msgsize() (s int) { // MsgIsZero returns whether this is a zero value func (z *AccountData) MsgIsZero() bool { - return ((*z).Status == 0) && ((*z).MicroAlgos.MsgIsZero()) && ((*z).RewardsBase == 0) && ((*z).RewardedMicroAlgos.MsgIsZero()) && ((*z).VoteID.MsgIsZero()) && ((*z).SelectionID.MsgIsZero()) && ((*z).StateProofID.MsgIsZero()) && ((*z).VoteFirstValid == 0) && ((*z).VoteLastValid == 0) && ((*z).VoteKeyDilution == 0) && (len((*z).AssetParams) == 0) && (len((*z).Assets) == 0) && ((*z).AuthAddr.MsgIsZero()) && (len((*z).AppLocalStates) == 0) && (len((*z).AppParams) == 0) && (((*z).TotalAppSchema.NumUint == 0) && ((*z).TotalAppSchema.NumByteSlice == 0)) && ((*z).TotalExtraAppPages == 0) && ((*z).TotalBoxes == 0) && ((*z).TotalBoxBytes == 0) + return ((*z).Status == 0) && ((*z).MicroAlgos.MsgIsZero()) && ((*z).RewardsBase == 0) && ((*z).RewardedMicroAlgos.MsgIsZero()) && ((*z).VoteID.MsgIsZero()) && ((*z).SelectionID.MsgIsZero()) && ((*z).StateProofID.MsgIsZero()) && ((*z).VoteFirstValid == 0) && ((*z).VoteLastValid == 0) && ((*z).VoteKeyDilution == 0) && ((*z).LastProposed == 0) && ((*z).LastHeartbeat == 0) && (len((*z).AssetParams) == 0) && (len((*z).Assets) == 0) && ((*z).AuthAddr.MsgIsZero()) && (len((*z).AppLocalStates) == 0) && (len((*z).AppParams) == 0) && (((*z).TotalAppSchema.NumUint == 0) && ((*z).TotalAppSchema.NumByteSlice == 0)) && ((*z).TotalExtraAppPages == 0) && ((*z).TotalBoxes == 0) && ((*z).TotalBoxBytes == 0) } // MaxSize returns a maximum valid message size for this message type func AccountDataMaxSize() (s int) { - s = 3 + 4 + msgp.ByteSize + 5 + MicroAlgosMaxSize() + 6 + msgp.Uint64Size + 4 + MicroAlgosMaxSize() + 5 + crypto.OneTimeSignatureVerifierMaxSize() + 4 + crypto.VRFVerifierMaxSize() + 6 + merklesignature.CommitmentMaxSize() + 8 + msgp.Uint64Size + 8 + msgp.Uint64Size + 7 + msgp.Uint64Size + 5 + s = 3 + 4 + msgp.ByteSize + 5 + MicroAlgosMaxSize() + 6 + msgp.Uint64Size + 4 + MicroAlgosMaxSize() + 5 + crypto.OneTimeSignatureVerifierMaxSize() + 4 + crypto.VRFVerifierMaxSize() + 6 + merklesignature.CommitmentMaxSize() + 8 + msgp.Uint64Size + 8 + msgp.Uint64Size + 7 + msgp.Uint64Size + 4 + msgp.Uint64Size + 4 + msgp.Uint64Size + 5 s += msgp.MapHeaderSize // Adding size of map keys for z.AssetParams s += encodedMaxAssetsPerAccount * (AssetIndexMaxSize()) @@ -3199,8 +3261,8 @@ func AssetParamsMaxSize() (s int) { func (z *BalanceRecord) MarshalMsg(b []byte) (o []byte) { o = msgp.Require(b, z.Msgsize()) // omitempty: check for empty values - zb0009Len := uint32(20) - var zb0009Mask uint32 /* 22 bits */ + zb0009Len := uint32(22) + var zb0009Mask uint32 /* 24 bits */ if (*z).Addr.MsgIsZero() { zb0009Len-- zb0009Mask |= 0x4 @@ -3233,54 +3295,62 @@ func (z *BalanceRecord) MarshalMsg(b []byte) (o []byte) { zb0009Len-- zb0009Mask |= 0x200 } - if (*z).AccountData.Status == 0 { + if (*z).AccountData.LastHeartbeat == 0 { zb0009Len-- zb0009Mask |= 0x400 } - if (*z).AccountData.SelectionID.MsgIsZero() { + if (*z).AccountData.LastProposed == 0 { zb0009Len-- zb0009Mask |= 0x800 } - if (*z).AccountData.AuthAddr.MsgIsZero() { + if (*z).AccountData.Status == 0 { zb0009Len-- zb0009Mask |= 0x1000 } - if (*z).AccountData.StateProofID.MsgIsZero() { + if (*z).AccountData.SelectionID.MsgIsZero() { zb0009Len-- zb0009Mask |= 0x2000 } - if (*z).AccountData.TotalBoxes == 0 { + if (*z).AccountData.AuthAddr.MsgIsZero() { zb0009Len-- zb0009Mask |= 0x4000 } - if (*z).AccountData.TotalBoxBytes == 0 { + if (*z).AccountData.StateProofID.MsgIsZero() { zb0009Len-- zb0009Mask |= 0x8000 } - if (*z).AccountData.TotalExtraAppPages == 0 { + if (*z).AccountData.TotalBoxes == 0 { zb0009Len-- zb0009Mask |= 0x10000 } - if ((*z).AccountData.TotalAppSchema.NumUint == 0) && ((*z).AccountData.TotalAppSchema.NumByteSlice == 0) { + if (*z).AccountData.TotalBoxBytes == 0 { zb0009Len-- zb0009Mask |= 0x20000 } - if (*z).AccountData.VoteID.MsgIsZero() { + if (*z).AccountData.TotalExtraAppPages == 0 { zb0009Len-- zb0009Mask |= 0x40000 } - if (*z).AccountData.VoteFirstValid == 0 { + if ((*z).AccountData.TotalAppSchema.NumUint == 0) && ((*z).AccountData.TotalAppSchema.NumByteSlice == 0) { zb0009Len-- zb0009Mask |= 0x80000 } - if (*z).AccountData.VoteKeyDilution == 0 { + if (*z).AccountData.VoteID.MsgIsZero() { zb0009Len-- zb0009Mask |= 0x100000 } - if (*z).AccountData.VoteLastValid == 0 { + if (*z).AccountData.VoteFirstValid == 0 { zb0009Len-- zb0009Mask |= 0x200000 } + if (*z).AccountData.VoteKeyDilution == 0 { + zb0009Len-- + zb0009Mask |= 0x400000 + } + if (*z).AccountData.VoteLastValid == 0 { + zb0009Len-- + zb0009Mask |= 0x800000 + } // variable map header, size zb0009Len o = msgp.AppendMapHeader(o, zb0009Len) if zb0009Len != 0 { @@ -3409,41 +3479,51 @@ func (z *BalanceRecord) MarshalMsg(b []byte) (o []byte) { o = (*z).AccountData.RewardedMicroAlgos.MarshalMsg(o) } if (zb0009Mask & 0x400) == 0 { // if not empty + // string "lhb" + o = append(o, 0xa3, 0x6c, 0x68, 0x62) + o = msgp.AppendUint64(o, uint64((*z).AccountData.LastHeartbeat)) + } + if (zb0009Mask & 0x800) == 0 { // if not empty + // string "lpr" + o = append(o, 0xa3, 0x6c, 0x70, 0x72) + o = msgp.AppendUint64(o, uint64((*z).AccountData.LastProposed)) + } + if (zb0009Mask & 0x1000) == 0 { // if not empty // string "onl" o = append(o, 0xa3, 0x6f, 0x6e, 0x6c) o = msgp.AppendByte(o, byte((*z).AccountData.Status)) } - if (zb0009Mask & 0x800) == 0 { // if not empty + if (zb0009Mask & 0x2000) == 0 { // if not empty // string "sel" o = append(o, 0xa3, 0x73, 0x65, 0x6c) o = (*z).AccountData.SelectionID.MarshalMsg(o) } - if (zb0009Mask & 0x1000) == 0 { // if not empty + if (zb0009Mask & 0x4000) == 0 { // if not empty // string "spend" o = append(o, 0xa5, 0x73, 0x70, 0x65, 0x6e, 0x64) o = (*z).AccountData.AuthAddr.MarshalMsg(o) } - if (zb0009Mask & 0x2000) == 0 { // if not empty + if (zb0009Mask & 0x8000) == 0 { // if not empty // string "stprf" o = append(o, 0xa5, 0x73, 0x74, 0x70, 0x72, 0x66) o = (*z).AccountData.StateProofID.MarshalMsg(o) } - if (zb0009Mask & 0x4000) == 0 { // if not empty + if (zb0009Mask & 0x10000) == 0 { // if not empty // string "tbx" o = append(o, 0xa3, 0x74, 0x62, 0x78) o = msgp.AppendUint64(o, (*z).AccountData.TotalBoxes) } - if (zb0009Mask & 0x8000) == 0 { // if not empty + if (zb0009Mask & 0x20000) == 0 { // if not empty // string "tbxb" o = append(o, 0xa4, 0x74, 0x62, 0x78, 0x62) o = msgp.AppendUint64(o, (*z).AccountData.TotalBoxBytes) } - if (zb0009Mask & 0x10000) == 0 { // if not empty + if (zb0009Mask & 0x40000) == 0 { // if not empty // string "teap" o = append(o, 0xa4, 0x74, 0x65, 0x61, 0x70) o = msgp.AppendUint32(o, (*z).AccountData.TotalExtraAppPages) } - if (zb0009Mask & 0x20000) == 0 { // if not empty + if (zb0009Mask & 0x80000) == 0 { // if not empty // string "tsch" o = append(o, 0xa4, 0x74, 0x73, 0x63, 0x68) // omitempty: check for empty values @@ -3470,22 +3550,22 @@ func (z *BalanceRecord) MarshalMsg(b []byte) (o []byte) { o = msgp.AppendUint64(o, (*z).AccountData.TotalAppSchema.NumUint) } } - if (zb0009Mask & 0x40000) == 0 { // if not empty + if (zb0009Mask & 0x100000) == 0 { // if not empty // string "vote" o = append(o, 0xa4, 0x76, 0x6f, 0x74, 0x65) o = (*z).AccountData.VoteID.MarshalMsg(o) } - if (zb0009Mask & 0x80000) == 0 { // if not empty + if (zb0009Mask & 0x200000) == 0 { // if not empty // string "voteFst" o = append(o, 0xa7, 0x76, 0x6f, 0x74, 0x65, 0x46, 0x73, 0x74) o = msgp.AppendUint64(o, uint64((*z).AccountData.VoteFirstValid)) } - if (zb0009Mask & 0x100000) == 0 { // if not empty + if (zb0009Mask & 0x400000) == 0 { // if not empty // string "voteKD" o = append(o, 0xa6, 0x76, 0x6f, 0x74, 0x65, 0x4b, 0x44) o = msgp.AppendUint64(o, (*z).AccountData.VoteKeyDilution) } - if (zb0009Mask & 0x200000) == 0 { // if not empty + if (zb0009Mask & 0x800000) == 0 { // if not empty // string "voteLst" o = append(o, 0xa7, 0x76, 0x6f, 0x74, 0x65, 0x4c, 0x73, 0x74) o = msgp.AppendUint64(o, uint64((*z).AccountData.VoteLastValid)) @@ -3619,27 +3699,51 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState } if zb0009 > 0 { zb0009-- - var zb0014 int - var zb0015 bool - zb0014, zb0015, bts, err = msgp.ReadMapHeaderBytes(bts) + { + var zb0014 uint64 + zb0014, bts, err = msgp.ReadUint64Bytes(bts) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "LastProposed") + return + } + (*z).AccountData.LastProposed = Round(zb0014) + } + } + if zb0009 > 0 { + zb0009-- + { + var zb0015 uint64 + zb0015, bts, err = msgp.ReadUint64Bytes(bts) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "LastHeartbeat") + return + } + (*z).AccountData.LastHeartbeat = Round(zb0015) + } + } + if zb0009 > 0 { + zb0009-- + var zb0016 int + var zb0017 bool + zb0016, zb0017, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "AssetParams") return } - if zb0014 > encodedMaxAssetsPerAccount { - err = msgp.ErrOverflow(uint64(zb0014), uint64(encodedMaxAssetsPerAccount)) + if zb0016 > encodedMaxAssetsPerAccount { + err = msgp.ErrOverflow(uint64(zb0016), uint64(encodedMaxAssetsPerAccount)) err = msgp.WrapError(err, "struct-from-array", "AssetParams") return } - if zb0015 { + if zb0017 { (*z).AccountData.AssetParams = nil } else if (*z).AccountData.AssetParams == nil { - (*z).AccountData.AssetParams = make(map[AssetIndex]AssetParams, zb0014) + (*z).AccountData.AssetParams = make(map[AssetIndex]AssetParams, zb0016) } - for zb0014 > 0 { + for zb0016 > 0 { var zb0001 AssetIndex var zb0002 AssetParams - zb0014-- + zb0016-- bts, err = zb0001.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "AssetParams") @@ -3655,59 +3759,59 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState } if zb0009 > 0 { zb0009-- - var zb0016 int - var zb0017 bool - zb0016, zb0017, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0018 int + var zb0019 bool + zb0018, zb0019, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Assets") return } - if zb0016 > encodedMaxAssetsPerAccount { - err = msgp.ErrOverflow(uint64(zb0016), uint64(encodedMaxAssetsPerAccount)) + if zb0018 > encodedMaxAssetsPerAccount { + err = msgp.ErrOverflow(uint64(zb0018), uint64(encodedMaxAssetsPerAccount)) err = msgp.WrapError(err, "struct-from-array", "Assets") return } - if zb0017 { + if zb0019 { (*z).AccountData.Assets = nil } else if (*z).AccountData.Assets == nil { - (*z).AccountData.Assets = make(map[AssetIndex]AssetHolding, zb0016) + (*z).AccountData.Assets = make(map[AssetIndex]AssetHolding, zb0018) } - for zb0016 > 0 { + for zb0018 > 0 { var zb0003 AssetIndex var zb0004 AssetHolding - zb0016-- + zb0018-- bts, err = zb0003.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Assets") return } - var zb0018 int - var zb0019 bool - zb0018, zb0019, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0020 int + var zb0021 bool + zb0020, zb0021, bts, err = msgp.ReadMapHeaderBytes(bts) if _, ok := err.(msgp.TypeError); ok { - zb0018, zb0019, bts, err = msgp.ReadArrayHeaderBytes(bts) + zb0020, zb0021, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003) return } - if zb0018 > 0 { - zb0018-- + if zb0020 > 0 { + zb0020-- zb0004.Amount, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003, "struct-from-array", "Amount") return } } - if zb0018 > 0 { - zb0018-- + if zb0020 > 0 { + zb0020-- zb0004.Frozen, bts, err = msgp.ReadBoolBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003, "struct-from-array", "Frozen") return } } - if zb0018 > 0 { - err = msgp.ErrTooManyArrayFields(zb0018) + if zb0020 > 0 { + err = msgp.ErrTooManyArrayFields(zb0020) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003, "struct-from-array") return @@ -3718,11 +3822,11 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003) return } - if zb0019 { + if zb0021 { zb0004 = AssetHolding{} } - for zb0018 > 0 { - zb0018-- + for zb0020 > 0 { + zb0020-- field, bts, err = msgp.ReadMapKeyZC(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003) @@ -3763,27 +3867,27 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState } if zb0009 > 0 { zb0009-- - var zb0020 int - var zb0021 bool - zb0020, zb0021, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0022 int + var zb0023 bool + zb0022, zb0023, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "AppLocalStates") return } - if zb0020 > EncodedMaxAppLocalStates { - err = msgp.ErrOverflow(uint64(zb0020), uint64(EncodedMaxAppLocalStates)) + if zb0022 > EncodedMaxAppLocalStates { + err = msgp.ErrOverflow(uint64(zb0022), uint64(EncodedMaxAppLocalStates)) err = msgp.WrapError(err, "struct-from-array", "AppLocalStates") return } - if zb0021 { + if zb0023 { (*z).AccountData.AppLocalStates = nil } else if (*z).AccountData.AppLocalStates == nil { - (*z).AccountData.AppLocalStates = make(map[AppIndex]AppLocalState, zb0020) + (*z).AccountData.AppLocalStates = make(map[AppIndex]AppLocalState, zb0022) } - for zb0020 > 0 { + for zb0022 > 0 { var zb0005 AppIndex var zb0006 AppLocalState - zb0020-- + zb0022-- bts, err = zb0005.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "AppLocalStates") @@ -3799,27 +3903,27 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState } if zb0009 > 0 { zb0009-- - var zb0022 int - var zb0023 bool - zb0022, zb0023, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0024 int + var zb0025 bool + zb0024, zb0025, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "AppParams") return } - if zb0022 > EncodedMaxAppParams { - err = msgp.ErrOverflow(uint64(zb0022), uint64(EncodedMaxAppParams)) + if zb0024 > EncodedMaxAppParams { + err = msgp.ErrOverflow(uint64(zb0024), uint64(EncodedMaxAppParams)) err = msgp.WrapError(err, "struct-from-array", "AppParams") return } - if zb0023 { + if zb0025 { (*z).AccountData.AppParams = nil } else if (*z).AccountData.AppParams == nil { - (*z).AccountData.AppParams = make(map[AppIndex]AppParams, zb0022) + (*z).AccountData.AppParams = make(map[AppIndex]AppParams, zb0024) } - for zb0022 > 0 { + for zb0024 > 0 { var zb0007 AppIndex var zb0008 AppParams - zb0022-- + zb0024-- bts, err = zb0007.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "AppParams") @@ -3835,33 +3939,33 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState } if zb0009 > 0 { zb0009-- - var zb0024 int - var zb0025 bool - zb0024, zb0025, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0026 int + var zb0027 bool + zb0026, zb0027, bts, err = msgp.ReadMapHeaderBytes(bts) if _, ok := err.(msgp.TypeError); ok { - zb0024, zb0025, bts, err = msgp.ReadArrayHeaderBytes(bts) + zb0026, zb0027, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema") return } - if zb0024 > 0 { - zb0024-- + if zb0026 > 0 { + zb0026-- (*z).AccountData.TotalAppSchema.NumUint, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema", "struct-from-array", "NumUint") return } } - if zb0024 > 0 { - zb0024-- + if zb0026 > 0 { + zb0026-- (*z).AccountData.TotalAppSchema.NumByteSlice, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema", "struct-from-array", "NumByteSlice") return } } - if zb0024 > 0 { - err = msgp.ErrTooManyArrayFields(zb0024) + if zb0026 > 0 { + err = msgp.ErrTooManyArrayFields(zb0026) if err != nil { err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema", "struct-from-array") return @@ -3872,11 +3976,11 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema") return } - if zb0025 { + if zb0027 { (*z).AccountData.TotalAppSchema = StateSchema{} } - for zb0024 > 0 { - zb0024-- + for zb0026 > 0 { + zb0026-- field, bts, err = msgp.ReadMapKeyZC(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema") @@ -3960,13 +4064,13 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState } case "onl": { - var zb0026 byte - zb0026, bts, err = msgp.ReadByteBytes(bts) + var zb0028 byte + zb0028, bts, err = msgp.ReadByteBytes(bts) if err != nil { err = msgp.WrapError(err, "Status") return } - (*z).AccountData.Status = Status(zb0026) + (*z).AccountData.Status = Status(zb0028) } case "algo": bts, err = (*z).AccountData.MicroAlgos.UnmarshalMsgWithState(bts, st) @@ -4006,23 +4110,23 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState } case "voteFst": { - var zb0027 uint64 - zb0027, bts, err = msgp.ReadUint64Bytes(bts) + var zb0029 uint64 + zb0029, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "VoteFirstValid") return } - (*z).AccountData.VoteFirstValid = Round(zb0027) + (*z).AccountData.VoteFirstValid = Round(zb0029) } case "voteLst": { - var zb0028 uint64 - zb0028, bts, err = msgp.ReadUint64Bytes(bts) + var zb0030 uint64 + zb0030, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "VoteLastValid") return } - (*z).AccountData.VoteLastValid = Round(zb0028) + (*z).AccountData.VoteLastValid = Round(zb0030) } case "voteKD": (*z).AccountData.VoteKeyDilution, bts, err = msgp.ReadUint64Bytes(bts) @@ -4030,28 +4134,48 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState err = msgp.WrapError(err, "VoteKeyDilution") return } + case "lpr": + { + var zb0031 uint64 + zb0031, bts, err = msgp.ReadUint64Bytes(bts) + if err != nil { + err = msgp.WrapError(err, "LastProposed") + return + } + (*z).AccountData.LastProposed = Round(zb0031) + } + case "lhb": + { + var zb0032 uint64 + zb0032, bts, err = msgp.ReadUint64Bytes(bts) + if err != nil { + err = msgp.WrapError(err, "LastHeartbeat") + return + } + (*z).AccountData.LastHeartbeat = Round(zb0032) + } case "apar": - var zb0029 int - var zb0030 bool - zb0029, zb0030, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0033 int + var zb0034 bool + zb0033, zb0034, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "AssetParams") return } - if zb0029 > encodedMaxAssetsPerAccount { - err = msgp.ErrOverflow(uint64(zb0029), uint64(encodedMaxAssetsPerAccount)) + if zb0033 > encodedMaxAssetsPerAccount { + err = msgp.ErrOverflow(uint64(zb0033), uint64(encodedMaxAssetsPerAccount)) err = msgp.WrapError(err, "AssetParams") return } - if zb0030 { + if zb0034 { (*z).AccountData.AssetParams = nil } else if (*z).AccountData.AssetParams == nil { - (*z).AccountData.AssetParams = make(map[AssetIndex]AssetParams, zb0029) + (*z).AccountData.AssetParams = make(map[AssetIndex]AssetParams, zb0033) } - for zb0029 > 0 { + for zb0033 > 0 { var zb0001 AssetIndex var zb0002 AssetParams - zb0029-- + zb0033-- bts, err = zb0001.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "AssetParams") @@ -4065,59 +4189,59 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState (*z).AccountData.AssetParams[zb0001] = zb0002 } case "asset": - var zb0031 int - var zb0032 bool - zb0031, zb0032, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0035 int + var zb0036 bool + zb0035, zb0036, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "Assets") return } - if zb0031 > encodedMaxAssetsPerAccount { - err = msgp.ErrOverflow(uint64(zb0031), uint64(encodedMaxAssetsPerAccount)) + if zb0035 > encodedMaxAssetsPerAccount { + err = msgp.ErrOverflow(uint64(zb0035), uint64(encodedMaxAssetsPerAccount)) err = msgp.WrapError(err, "Assets") return } - if zb0032 { + if zb0036 { (*z).AccountData.Assets = nil } else if (*z).AccountData.Assets == nil { - (*z).AccountData.Assets = make(map[AssetIndex]AssetHolding, zb0031) + (*z).AccountData.Assets = make(map[AssetIndex]AssetHolding, zb0035) } - for zb0031 > 0 { + for zb0035 > 0 { var zb0003 AssetIndex var zb0004 AssetHolding - zb0031-- + zb0035-- bts, err = zb0003.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "Assets") return } - var zb0033 int - var zb0034 bool - zb0033, zb0034, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0037 int + var zb0038 bool + zb0037, zb0038, bts, err = msgp.ReadMapHeaderBytes(bts) if _, ok := err.(msgp.TypeError); ok { - zb0033, zb0034, bts, err = msgp.ReadArrayHeaderBytes(bts) + zb0037, zb0038, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "Assets", zb0003) return } - if zb0033 > 0 { - zb0033-- + if zb0037 > 0 { + zb0037-- zb0004.Amount, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "Assets", zb0003, "struct-from-array", "Amount") return } } - if zb0033 > 0 { - zb0033-- + if zb0037 > 0 { + zb0037-- zb0004.Frozen, bts, err = msgp.ReadBoolBytes(bts) if err != nil { err = msgp.WrapError(err, "Assets", zb0003, "struct-from-array", "Frozen") return } } - if zb0033 > 0 { - err = msgp.ErrTooManyArrayFields(zb0033) + if zb0037 > 0 { + err = msgp.ErrTooManyArrayFields(zb0037) if err != nil { err = msgp.WrapError(err, "Assets", zb0003, "struct-from-array") return @@ -4128,11 +4252,11 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState err = msgp.WrapError(err, "Assets", zb0003) return } - if zb0034 { + if zb0038 { zb0004 = AssetHolding{} } - for zb0033 > 0 { - zb0033-- + for zb0037 > 0 { + zb0037-- field, bts, err = msgp.ReadMapKeyZC(bts) if err != nil { err = msgp.WrapError(err, "Assets", zb0003) @@ -4169,27 +4293,27 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState return } case "appl": - var zb0035 int - var zb0036 bool - zb0035, zb0036, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0039 int + var zb0040 bool + zb0039, zb0040, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "AppLocalStates") return } - if zb0035 > EncodedMaxAppLocalStates { - err = msgp.ErrOverflow(uint64(zb0035), uint64(EncodedMaxAppLocalStates)) + if zb0039 > EncodedMaxAppLocalStates { + err = msgp.ErrOverflow(uint64(zb0039), uint64(EncodedMaxAppLocalStates)) err = msgp.WrapError(err, "AppLocalStates") return } - if zb0036 { + if zb0040 { (*z).AccountData.AppLocalStates = nil } else if (*z).AccountData.AppLocalStates == nil { - (*z).AccountData.AppLocalStates = make(map[AppIndex]AppLocalState, zb0035) + (*z).AccountData.AppLocalStates = make(map[AppIndex]AppLocalState, zb0039) } - for zb0035 > 0 { + for zb0039 > 0 { var zb0005 AppIndex var zb0006 AppLocalState - zb0035-- + zb0039-- bts, err = zb0005.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "AppLocalStates") @@ -4203,27 +4327,27 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState (*z).AccountData.AppLocalStates[zb0005] = zb0006 } case "appp": - var zb0037 int - var zb0038 bool - zb0037, zb0038, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0041 int + var zb0042 bool + zb0041, zb0042, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "AppParams") return } - if zb0037 > EncodedMaxAppParams { - err = msgp.ErrOverflow(uint64(zb0037), uint64(EncodedMaxAppParams)) + if zb0041 > EncodedMaxAppParams { + err = msgp.ErrOverflow(uint64(zb0041), uint64(EncodedMaxAppParams)) err = msgp.WrapError(err, "AppParams") return } - if zb0038 { + if zb0042 { (*z).AccountData.AppParams = nil } else if (*z).AccountData.AppParams == nil { - (*z).AccountData.AppParams = make(map[AppIndex]AppParams, zb0037) + (*z).AccountData.AppParams = make(map[AppIndex]AppParams, zb0041) } - for zb0037 > 0 { + for zb0041 > 0 { var zb0007 AppIndex var zb0008 AppParams - zb0037-- + zb0041-- bts, err = zb0007.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "AppParams") @@ -4237,33 +4361,33 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState (*z).AccountData.AppParams[zb0007] = zb0008 } case "tsch": - var zb0039 int - var zb0040 bool - zb0039, zb0040, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0043 int + var zb0044 bool + zb0043, zb0044, bts, err = msgp.ReadMapHeaderBytes(bts) if _, ok := err.(msgp.TypeError); ok { - zb0039, zb0040, bts, err = msgp.ReadArrayHeaderBytes(bts) + zb0043, zb0044, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "TotalAppSchema") return } - if zb0039 > 0 { - zb0039-- + if zb0043 > 0 { + zb0043-- (*z).AccountData.TotalAppSchema.NumUint, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "TotalAppSchema", "struct-from-array", "NumUint") return } } - if zb0039 > 0 { - zb0039-- + if zb0043 > 0 { + zb0043-- (*z).AccountData.TotalAppSchema.NumByteSlice, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "TotalAppSchema", "struct-from-array", "NumByteSlice") return } } - if zb0039 > 0 { - err = msgp.ErrTooManyArrayFields(zb0039) + if zb0043 > 0 { + err = msgp.ErrTooManyArrayFields(zb0043) if err != nil { err = msgp.WrapError(err, "TotalAppSchema", "struct-from-array") return @@ -4274,11 +4398,11 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState err = msgp.WrapError(err, "TotalAppSchema") return } - if zb0040 { + if zb0044 { (*z).AccountData.TotalAppSchema = StateSchema{} } - for zb0039 > 0 { - zb0039-- + for zb0043 > 0 { + zb0043-- field, bts, err = msgp.ReadMapKeyZC(bts) if err != nil { err = msgp.WrapError(err, "TotalAppSchema") @@ -4347,7 +4471,7 @@ func (_ *BalanceRecord) CanUnmarshalMsg(z interface{}) bool { // Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message func (z *BalanceRecord) Msgsize() (s int) { - s = 3 + 5 + (*z).Addr.Msgsize() + 4 + msgp.ByteSize + 5 + (*z).AccountData.MicroAlgos.Msgsize() + 6 + msgp.Uint64Size + 4 + (*z).AccountData.RewardedMicroAlgos.Msgsize() + 5 + (*z).AccountData.VoteID.Msgsize() + 4 + (*z).AccountData.SelectionID.Msgsize() + 6 + (*z).AccountData.StateProofID.Msgsize() + 8 + msgp.Uint64Size + 8 + msgp.Uint64Size + 7 + msgp.Uint64Size + 5 + msgp.MapHeaderSize + s = 3 + 5 + (*z).Addr.Msgsize() + 4 + msgp.ByteSize + 5 + (*z).AccountData.MicroAlgos.Msgsize() + 6 + msgp.Uint64Size + 4 + (*z).AccountData.RewardedMicroAlgos.Msgsize() + 5 + (*z).AccountData.VoteID.Msgsize() + 4 + (*z).AccountData.SelectionID.Msgsize() + 6 + (*z).AccountData.StateProofID.Msgsize() + 8 + msgp.Uint64Size + 8 + msgp.Uint64Size + 7 + msgp.Uint64Size + 4 + msgp.Uint64Size + 4 + msgp.Uint64Size + 5 + msgp.MapHeaderSize if (*z).AccountData.AssetParams != nil { for zb0001, zb0002 := range (*z).AccountData.AssetParams { _ = zb0001 @@ -4385,12 +4509,12 @@ func (z *BalanceRecord) Msgsize() (s int) { // MsgIsZero returns whether this is a zero value func (z *BalanceRecord) MsgIsZero() bool { - return ((*z).Addr.MsgIsZero()) && ((*z).AccountData.Status == 0) && ((*z).AccountData.MicroAlgos.MsgIsZero()) && ((*z).AccountData.RewardsBase == 0) && ((*z).AccountData.RewardedMicroAlgos.MsgIsZero()) && ((*z).AccountData.VoteID.MsgIsZero()) && ((*z).AccountData.SelectionID.MsgIsZero()) && ((*z).AccountData.StateProofID.MsgIsZero()) && ((*z).AccountData.VoteFirstValid == 0) && ((*z).AccountData.VoteLastValid == 0) && ((*z).AccountData.VoteKeyDilution == 0) && (len((*z).AccountData.AssetParams) == 0) && (len((*z).AccountData.Assets) == 0) && ((*z).AccountData.AuthAddr.MsgIsZero()) && (len((*z).AccountData.AppLocalStates) == 0) && (len((*z).AccountData.AppParams) == 0) && (((*z).AccountData.TotalAppSchema.NumUint == 0) && ((*z).AccountData.TotalAppSchema.NumByteSlice == 0)) && ((*z).AccountData.TotalExtraAppPages == 0) && ((*z).AccountData.TotalBoxes == 0) && ((*z).AccountData.TotalBoxBytes == 0) + return ((*z).Addr.MsgIsZero()) && ((*z).AccountData.Status == 0) && ((*z).AccountData.MicroAlgos.MsgIsZero()) && ((*z).AccountData.RewardsBase == 0) && ((*z).AccountData.RewardedMicroAlgos.MsgIsZero()) && ((*z).AccountData.VoteID.MsgIsZero()) && ((*z).AccountData.SelectionID.MsgIsZero()) && ((*z).AccountData.StateProofID.MsgIsZero()) && ((*z).AccountData.VoteFirstValid == 0) && ((*z).AccountData.VoteLastValid == 0) && ((*z).AccountData.VoteKeyDilution == 0) && ((*z).AccountData.LastProposed == 0) && ((*z).AccountData.LastHeartbeat == 0) && (len((*z).AccountData.AssetParams) == 0) && (len((*z).AccountData.Assets) == 0) && ((*z).AccountData.AuthAddr.MsgIsZero()) && (len((*z).AccountData.AppLocalStates) == 0) && (len((*z).AccountData.AppParams) == 0) && (((*z).AccountData.TotalAppSchema.NumUint == 0) && ((*z).AccountData.TotalAppSchema.NumByteSlice == 0)) && ((*z).AccountData.TotalExtraAppPages == 0) && ((*z).AccountData.TotalBoxes == 0) && ((*z).AccountData.TotalBoxBytes == 0) } // MaxSize returns a maximum valid message size for this message type func BalanceRecordMaxSize() (s int) { - s = 3 + 5 + AddressMaxSize() + 4 + msgp.ByteSize + 5 + MicroAlgosMaxSize() + 6 + msgp.Uint64Size + 4 + MicroAlgosMaxSize() + 5 + crypto.OneTimeSignatureVerifierMaxSize() + 4 + crypto.VRFVerifierMaxSize() + 6 + merklesignature.CommitmentMaxSize() + 8 + msgp.Uint64Size + 8 + msgp.Uint64Size + 7 + msgp.Uint64Size + 5 + s = 3 + 5 + AddressMaxSize() + 4 + msgp.ByteSize + 5 + MicroAlgosMaxSize() + 6 + msgp.Uint64Size + 4 + MicroAlgosMaxSize() + 5 + crypto.OneTimeSignatureVerifierMaxSize() + 4 + crypto.VRFVerifierMaxSize() + 6 + merklesignature.CommitmentMaxSize() + 8 + msgp.Uint64Size + 8 + msgp.Uint64Size + 7 + msgp.Uint64Size + 4 + msgp.Uint64Size + 4 + msgp.Uint64Size + 5 s += msgp.MapHeaderSize // Adding size of map keys for z.AccountData.AssetParams s += encodedMaxAssetsPerAccount * (AssetIndexMaxSize()) diff --git a/data/basics/userBalance.go b/data/basics/userBalance.go index e87517f28d..88caa2a0d0 100644 --- a/data/basics/userBalance.go +++ b/data/basics/userBalance.go @@ -42,6 +42,11 @@ const ( // Two special accounts that are defined as NotParticipating are the incentive pool (also know as rewards pool) and the fee sink. // These two accounts also have additional Algo transfer restrictions. NotParticipating + // Suspended indicates that an account has registered keys, intending to + // particpate, but appears to have gone dark. Their balance should no longer + // be considered online, but their voting keys should be retained so they + // can easily get back online by sending a "heartbeat". + Suspended // encodedMaxAssetsPerAccount is the decoder limit of number of assets stored per account. // it's being verified by the unit test TestEncodedAccountAllocationBounds to align @@ -75,6 +80,8 @@ func (s Status) String() string { return "Online" case NotParticipating: return "Not Participating" + case Suspended: + return "Suspended" } return "" } @@ -88,6 +95,8 @@ func UnmarshalStatus(value string) (s Status, err error) { s = Online case "Not Participating": s = NotParticipating + case "Suspended": + s = Suspended default: err = fmt.Errorf("unknown account status: %v", value) } @@ -115,8 +124,13 @@ type OnlineAccountData struct { // AccountData contains the data associated with a given address. // -// This includes the account balance, cryptographic public keys, -// consensus delegation status, asset data, and application data. +// This includes the account balance, cryptographic public keys, consensus +// status, asset params (for assets made by this account), asset holdings (for +// assets the account is opted into), and application data (globals if account +// created, locals if opted-in). This can be thought of as the fully "hydrated" +// structure and could take an arbitrary number of db queries to fill. As such, +// it is mostly used only for shuttling complete accounts into the ledger +// (genesis, catchpoints, REST API). And a lot of legacy tests. type AccountData struct { _struct struct{} `codec:",omitempty,omitemptyarray"` @@ -172,6 +186,13 @@ type AccountData struct { VoteLastValid Round `codec:"voteLst"` VoteKeyDilution uint64 `codec:"voteKD"` + // LastProposed is the last round that the account is known to have + // proposed. It is updated at the start of the _next_ round. + LastProposed Round `codec:"lpr"` + // LastHeartbeat is the last round an account has indicated it is ready to + // vote by sending a heartbeat transaction, signed by its partkey. + LastHeartbeat Round `codec:"lhb"` + // If this account created an asset, AssetParams stores // the parameters defining that asset. The params are indexed // by the Index of the AssetID; the Creator is this account's address. diff --git a/data/bookkeeping/block.go b/data/bookkeeping/block.go index c84380d86f..d26ec5b7f2 100644 --- a/data/bookkeeping/block.go +++ b/data/bookkeeping/block.go @@ -155,6 +155,10 @@ type ( // that needs to be converted to offline since their // participation key expired. ExpiredParticipationAccounts []basics.Address `codec:"partupdrmv,allocbound=config.MaxProposedExpiredOnlineAccounts"` + + // AbsentParticipationAccounts contains a list of online accounts that + // needs to be converted to offline since they are not proposing. + AbsentParticipationAccounts []basics.Address `codec:"partupdabs,allocbound=config.MaxProposedAbsentOnlineAccounts"` } // RewardsState represents the global parameters controlling the rate diff --git a/data/bookkeeping/msgp_gen.go b/data/bookkeeping/msgp_gen.go index 61630b1782..a5c8b49933 100644 --- a/data/bookkeeping/msgp_gen.go +++ b/data/bookkeeping/msgp_gen.go @@ -143,174 +143,190 @@ import ( func (z *Block) MarshalMsg(b []byte) (o []byte) { o = msgp.Require(b, z.Msgsize()) // omitempty: check for empty values - zb0004Len := uint32(28) - var zb0004Mask uint64 /* 33 bits */ + zb0005Len := uint32(29) + var zb0005Mask uint64 /* 34 bits */ if (*z).BlockHeader.RewardsState.RewardsLevel == 0 { - zb0004Len-- - zb0004Mask |= 0x20 + zb0005Len-- + zb0005Mask |= 0x20 } if (*z).BlockHeader.FeesCollected.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x40 + zb0005Len-- + zb0005Mask |= 0x40 } if (*z).BlockHeader.RewardsState.FeeSink.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x80 + zb0005Len-- + zb0005Mask |= 0x80 } if (*z).BlockHeader.RewardsState.RewardsResidue == 0 { - zb0004Len-- - zb0004Mask |= 0x100 + zb0005Len-- + zb0005Mask |= 0x100 } if (*z).BlockHeader.GenesisID == "" { - zb0004Len-- - zb0004Mask |= 0x200 + zb0005Len-- + zb0005Mask |= 0x200 } if (*z).BlockHeader.GenesisHash.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x400 + zb0005Len-- + zb0005Mask |= 0x400 } if (*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x800 + zb0005Len-- + zb0005Mask |= 0x800 } if (*z).BlockHeader.UpgradeState.NextProtocol.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x1000 + zb0005Len-- + zb0005Mask |= 0x1000 } if (*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x2000 + zb0005Len-- + zb0005Mask |= 0x2000 } if (*z).BlockHeader.UpgradeState.NextProtocolApprovals == 0 { - zb0004Len-- - zb0004Mask |= 0x4000 + zb0005Len-- + zb0005Mask |= 0x4000 + } + if len((*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) == 0 { + zb0005Len-- + zb0005Mask |= 0x8000 } if len((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 { - zb0004Len-- - zb0004Mask |= 0x8000 + zb0005Len-- + zb0005Mask |= 0x10000 } if (*z).BlockHeader.Branch.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x10000 + zb0005Len-- + zb0005Mask |= 0x20000 } if (*z).BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x20000 + zb0005Len-- + zb0005Mask |= 0x40000 } if (*z).BlockHeader.Proposer.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x40000 + zb0005Len-- + zb0005Mask |= 0x80000 } if (*z).BlockHeader.RewardsState.RewardsRate == 0 { - zb0004Len-- - zb0004Mask |= 0x80000 + zb0005Len-- + zb0005Mask |= 0x100000 } if (*z).BlockHeader.Round.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x100000 + zb0005Len-- + zb0005Mask |= 0x200000 } if (*z).BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x200000 + zb0005Len-- + zb0005Mask |= 0x400000 } if (*z).BlockHeader.RewardsState.RewardsPool.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x400000 + zb0005Len-- + zb0005Mask |= 0x800000 } if (*z).BlockHeader.Seed.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x800000 + zb0005Len-- + zb0005Mask |= 0x1000000 } if len((*z).BlockHeader.StateProofTracking) == 0 { - zb0004Len-- - zb0004Mask |= 0x1000000 + zb0005Len-- + zb0005Mask |= 0x2000000 } if (*z).BlockHeader.TxnCounter == 0 { - zb0004Len-- - zb0004Mask |= 0x2000000 + zb0005Len-- + zb0005Mask |= 0x4000000 } if (*z).BlockHeader.TimeStamp == 0 { - zb0004Len-- - zb0004Mask |= 0x4000000 + zb0005Len-- + zb0005Mask |= 0x8000000 } if (*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x8000000 + zb0005Len-- + zb0005Mask |= 0x10000000 } if (*z).BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x10000000 + zb0005Len-- + zb0005Mask |= 0x20000000 } if (*z).Payset.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x20000000 + zb0005Len-- + zb0005Mask |= 0x40000000 } if (*z).BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x40000000 + zb0005Len-- + zb0005Mask |= 0x80000000 } if (*z).BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x80000000 + zb0005Len-- + zb0005Mask |= 0x100000000 } if (*z).BlockHeader.UpgradeVote.UpgradeApprove == false { - zb0004Len-- - zb0004Mask |= 0x100000000 + zb0005Len-- + zb0005Mask |= 0x200000000 } - // variable map header, size zb0004Len - o = msgp.AppendMapHeader(o, zb0004Len) - if zb0004Len != 0 { - if (zb0004Mask & 0x20) == 0 { // if not empty + // variable map header, size zb0005Len + o = msgp.AppendMapHeader(o, zb0005Len) + if zb0005Len != 0 { + if (zb0005Mask & 0x20) == 0 { // if not empty // string "earn" o = append(o, 0xa4, 0x65, 0x61, 0x72, 0x6e) o = msgp.AppendUint64(o, (*z).BlockHeader.RewardsState.RewardsLevel) } - if (zb0004Mask & 0x40) == 0 { // if not empty + if (zb0005Mask & 0x40) == 0 { // if not empty // string "fc" o = append(o, 0xa2, 0x66, 0x63) o = (*z).BlockHeader.FeesCollected.MarshalMsg(o) } - if (zb0004Mask & 0x80) == 0 { // if not empty + if (zb0005Mask & 0x80) == 0 { // if not empty // string "fees" o = append(o, 0xa4, 0x66, 0x65, 0x65, 0x73) o = (*z).BlockHeader.RewardsState.FeeSink.MarshalMsg(o) } - if (zb0004Mask & 0x100) == 0 { // if not empty + if (zb0005Mask & 0x100) == 0 { // if not empty // string "frac" o = append(o, 0xa4, 0x66, 0x72, 0x61, 0x63) o = msgp.AppendUint64(o, (*z).BlockHeader.RewardsState.RewardsResidue) } - if (zb0004Mask & 0x200) == 0 { // if not empty + if (zb0005Mask & 0x200) == 0 { // if not empty // string "gen" o = append(o, 0xa3, 0x67, 0x65, 0x6e) o = msgp.AppendString(o, (*z).BlockHeader.GenesisID) } - if (zb0004Mask & 0x400) == 0 { // if not empty + if (zb0005Mask & 0x400) == 0 { // if not empty // string "gh" o = append(o, 0xa2, 0x67, 0x68) o = (*z).BlockHeader.GenesisHash.MarshalMsg(o) } - if (zb0004Mask & 0x800) == 0 { // if not empty + if (zb0005Mask & 0x800) == 0 { // if not empty // string "nextbefore" o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65) o = (*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.MarshalMsg(o) } - if (zb0004Mask & 0x1000) == 0 { // if not empty + if (zb0005Mask & 0x1000) == 0 { // if not empty // string "nextproto" o = append(o, 0xa9, 0x6e, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f) o = (*z).BlockHeader.UpgradeState.NextProtocol.MarshalMsg(o) } - if (zb0004Mask & 0x2000) == 0 { // if not empty + if (zb0005Mask & 0x2000) == 0 { // if not empty // string "nextswitch" o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68) o = (*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.MarshalMsg(o) } - if (zb0004Mask & 0x4000) == 0 { // if not empty + if (zb0005Mask & 0x4000) == 0 { // if not empty // string "nextyes" o = append(o, 0xa7, 0x6e, 0x65, 0x78, 0x74, 0x79, 0x65, 0x73) o = msgp.AppendUint64(o, (*z).BlockHeader.UpgradeState.NextProtocolApprovals) } - if (zb0004Mask & 0x8000) == 0 { // if not empty + if (zb0005Mask & 0x8000) == 0 { // if not empty + // string "partupdabs" + o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x61, 0x62, 0x73) + if (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts == nil { + o = msgp.AppendNil(o) + } else { + o = msgp.AppendArrayHeader(o, uint32(len((*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts))) + } + for zb0004 := range (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts { + o = (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].MarshalMsg(o) + } + } + if (zb0005Mask & 0x10000) == 0 { // if not empty // string "partupdrmv" o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76) if (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts == nil { @@ -322,47 +338,47 @@ func (z *Block) MarshalMsg(b []byte) (o []byte) { o = (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].MarshalMsg(o) } } - if (zb0004Mask & 0x10000) == 0 { // if not empty + if (zb0005Mask & 0x20000) == 0 { // if not empty // string "prev" o = append(o, 0xa4, 0x70, 0x72, 0x65, 0x76) o = (*z).BlockHeader.Branch.MarshalMsg(o) } - if (zb0004Mask & 0x20000) == 0 { // if not empty + if (zb0005Mask & 0x40000) == 0 { // if not empty // string "proto" o = append(o, 0xa5, 0x70, 0x72, 0x6f, 0x74, 0x6f) o = (*z).BlockHeader.UpgradeState.CurrentProtocol.MarshalMsg(o) } - if (zb0004Mask & 0x40000) == 0 { // if not empty + if (zb0005Mask & 0x80000) == 0 { // if not empty // string "prp" o = append(o, 0xa3, 0x70, 0x72, 0x70) o = (*z).BlockHeader.Proposer.MarshalMsg(o) } - if (zb0004Mask & 0x80000) == 0 { // if not empty + if (zb0005Mask & 0x100000) == 0 { // if not empty // string "rate" o = append(o, 0xa4, 0x72, 0x61, 0x74, 0x65) o = msgp.AppendUint64(o, (*z).BlockHeader.RewardsState.RewardsRate) } - if (zb0004Mask & 0x100000) == 0 { // if not empty + if (zb0005Mask & 0x200000) == 0 { // if not empty // string "rnd" o = append(o, 0xa3, 0x72, 0x6e, 0x64) o = (*z).BlockHeader.Round.MarshalMsg(o) } - if (zb0004Mask & 0x200000) == 0 { // if not empty + if (zb0005Mask & 0x400000) == 0 { // if not empty // string "rwcalr" o = append(o, 0xa6, 0x72, 0x77, 0x63, 0x61, 0x6c, 0x72) o = (*z).BlockHeader.RewardsState.RewardsRecalculationRound.MarshalMsg(o) } - if (zb0004Mask & 0x400000) == 0 { // if not empty + if (zb0005Mask & 0x800000) == 0 { // if not empty // string "rwd" o = append(o, 0xa3, 0x72, 0x77, 0x64) o = (*z).BlockHeader.RewardsState.RewardsPool.MarshalMsg(o) } - if (zb0004Mask & 0x800000) == 0 { // if not empty + if (zb0005Mask & 0x1000000) == 0 { // if not empty // string "seed" o = append(o, 0xa4, 0x73, 0x65, 0x65, 0x64) o = (*z).BlockHeader.Seed.MarshalMsg(o) } - if (zb0004Mask & 0x1000000) == 0 { // if not empty + if (zb0005Mask & 0x2000000) == 0 { // if not empty // string "spt" o = append(o, 0xa3, 0x73, 0x70, 0x74) if (*z).BlockHeader.StateProofTracking == nil { @@ -382,42 +398,42 @@ func (z *Block) MarshalMsg(b []byte) (o []byte) { o = zb0002.MarshalMsg(o) } } - if (zb0004Mask & 0x2000000) == 0 { // if not empty + if (zb0005Mask & 0x4000000) == 0 { // if not empty // string "tc" o = append(o, 0xa2, 0x74, 0x63) o = msgp.AppendUint64(o, (*z).BlockHeader.TxnCounter) } - if (zb0004Mask & 0x4000000) == 0 { // if not empty + if (zb0005Mask & 0x8000000) == 0 { // if not empty // string "ts" o = append(o, 0xa2, 0x74, 0x73) o = msgp.AppendInt64(o, (*z).BlockHeader.TimeStamp) } - if (zb0004Mask & 0x8000000) == 0 { // if not empty + if (zb0005Mask & 0x10000000) == 0 { // if not empty // string "txn" o = append(o, 0xa3, 0x74, 0x78, 0x6e) o = (*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.MarshalMsg(o) } - if (zb0004Mask & 0x10000000) == 0 { // if not empty + if (zb0005Mask & 0x20000000) == 0 { // if not empty // string "txn256" o = append(o, 0xa6, 0x74, 0x78, 0x6e, 0x32, 0x35, 0x36) o = (*z).BlockHeader.TxnCommitments.Sha256Commitment.MarshalMsg(o) } - if (zb0004Mask & 0x20000000) == 0 { // if not empty + if (zb0005Mask & 0x40000000) == 0 { // if not empty // string "txns" o = append(o, 0xa4, 0x74, 0x78, 0x6e, 0x73) o = (*z).Payset.MarshalMsg(o) } - if (zb0004Mask & 0x40000000) == 0 { // if not empty + if (zb0005Mask & 0x80000000) == 0 { // if not empty // string "upgradedelay" o = append(o, 0xac, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x65, 0x6c, 0x61, 0x79) o = (*z).BlockHeader.UpgradeVote.UpgradeDelay.MarshalMsg(o) } - if (zb0004Mask & 0x80000000) == 0 { // if not empty + if (zb0005Mask & 0x100000000) == 0 { // if not empty // string "upgradeprop" o = append(o, 0xab, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x70, 0x72, 0x6f, 0x70) o = (*z).BlockHeader.UpgradeVote.UpgradePropose.MarshalMsg(o) } - if (zb0004Mask & 0x100000000) == 0 { // if not empty + if (zb0005Mask & 0x200000000) == 0 { // if not empty // string "upgradeyes" o = append(o, 0xaa, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x65, 0x73) o = msgp.AppendBool(o, (*z).BlockHeader.UpgradeVote.UpgradeApprove) @@ -440,73 +456,73 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b st.AllowableDepth-- var field []byte _ = field - var zb0004 int - var zb0005 bool - zb0004, zb0005, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0005 int + var zb0006 bool + zb0005, zb0006, bts, err = msgp.ReadMapHeaderBytes(bts) if _, ok := err.(msgp.TypeError); ok { - zb0004, zb0005, bts, err = msgp.ReadArrayHeaderBytes(bts) + zb0005, zb0006, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err) return } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).BlockHeader.Round.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Round") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).BlockHeader.Branch.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Branch") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).BlockHeader.Seed.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Seed") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NativeSha512_256Commitment") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).BlockHeader.TxnCommitments.Sha256Commitment.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Sha256Commitment") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).BlockHeader.TimeStamp, bts, err = msgp.ReadInt64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "TimeStamp") return } } - if zb0004 > 0 { - zb0004-- - var zb0006 int - zb0006, err = msgp.ReadBytesBytesHeader(bts) + if zb0005 > 0 { + zb0005-- + var zb0007 int + zb0007, err = msgp.ReadBytesBytesHeader(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "GenesisID") return } - if zb0006 > config.MaxGenesisIDLen { - err = msgp.ErrOverflow(uint64(zb0006), uint64(config.MaxGenesisIDLen)) + if zb0007 > config.MaxGenesisIDLen { + err = msgp.ErrOverflow(uint64(zb0007), uint64(config.MaxGenesisIDLen)) return } (*z).BlockHeader.GenesisID, bts, err = msgp.ReadStringBytes(bts) @@ -515,173 +531,173 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).BlockHeader.GenesisHash.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "GenesisHash") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).BlockHeader.Proposer.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Proposer") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "FeesCollected") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "FeeSink") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).BlockHeader.RewardsState.RewardsPool.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsPool") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).BlockHeader.RewardsState.RewardsLevel, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsLevel") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).BlockHeader.RewardsState.RewardsRate, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsRate") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).BlockHeader.RewardsState.RewardsResidue, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsResidue") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).BlockHeader.RewardsState.RewardsRecalculationRound.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsRecalculationRound") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).BlockHeader.UpgradeState.CurrentProtocol.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "CurrentProtocol") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).BlockHeader.UpgradeState.NextProtocol.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NextProtocol") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).BlockHeader.UpgradeState.NextProtocolApprovals, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NextProtocolApprovals") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NextProtocolVoteBefore") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NextProtocolSwitchOn") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).BlockHeader.UpgradeVote.UpgradePropose.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "UpgradePropose") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).BlockHeader.UpgradeVote.UpgradeDelay.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "UpgradeDelay") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).BlockHeader.UpgradeVote.UpgradeApprove, bts, err = msgp.ReadBoolBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "UpgradeApprove") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).BlockHeader.TxnCounter, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "TxnCounter") return } } - if zb0004 > 0 { - zb0004-- - var zb0007 int - var zb0008 bool - zb0007, zb0008, bts, err = msgp.ReadMapHeaderBytes(bts) + if zb0005 > 0 { + zb0005-- + var zb0008 int + var zb0009 bool + zb0008, zb0009, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "StateProofTracking") return } - if zb0007 > protocol.NumStateProofTypes { - err = msgp.ErrOverflow(uint64(zb0007), uint64(protocol.NumStateProofTypes)) + if zb0008 > protocol.NumStateProofTypes { + err = msgp.ErrOverflow(uint64(zb0008), uint64(protocol.NumStateProofTypes)) err = msgp.WrapError(err, "struct-from-array", "StateProofTracking") return } - if zb0008 { + if zb0009 { (*z).BlockHeader.StateProofTracking = nil } else if (*z).BlockHeader.StateProofTracking == nil { - (*z).BlockHeader.StateProofTracking = make(map[protocol.StateProofType]StateProofTrackingData, zb0007) + (*z).BlockHeader.StateProofTracking = make(map[protocol.StateProofType]StateProofTrackingData, zb0008) } - for zb0007 > 0 { + for zb0008 > 0 { var zb0001 protocol.StateProofType var zb0002 StateProofTrackingData - zb0007-- + zb0008-- bts, err = zb0001.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "StateProofTracking") @@ -695,26 +711,26 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b (*z).BlockHeader.StateProofTracking[zb0001] = zb0002 } } - if zb0004 > 0 { - zb0004-- - var zb0009 int - var zb0010 bool - zb0009, zb0010, bts, err = msgp.ReadArrayHeaderBytes(bts) + if zb0005 > 0 { + zb0005-- + var zb0010 int + var zb0011 bool + zb0010, zb0011, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts") return } - if zb0009 > config.MaxProposedExpiredOnlineAccounts { - err = msgp.ErrOverflow(uint64(zb0009), uint64(config.MaxProposedExpiredOnlineAccounts)) + if zb0010 > config.MaxProposedExpiredOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0010), uint64(config.MaxProposedExpiredOnlineAccounts)) err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts") return } - if zb0010 { + if zb0011 { (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = nil - } else if (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0009 { - (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0009] + } else if (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0010 { + (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0010] } else { - (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0009) + (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0010) } for zb0003 := range (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts { bts, err = (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].UnmarshalMsgWithState(bts, st) @@ -724,16 +740,45 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b } } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- + var zb0012 int + var zb0013 bool + zb0012, zb0013, bts, err = msgp.ReadArrayHeaderBytes(bts) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts") + return + } + if zb0012 > config.MaxProposedAbsentOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0012), uint64(config.MaxProposedAbsentOnlineAccounts)) + err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts") + return + } + if zb0013 { + (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = nil + } else if (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts != nil && cap((*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) >= zb0012 { + (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = ((*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts)[:zb0012] + } else { + (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = make([]basics.Address, zb0012) + } + for zb0004 := range (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts { + bts, err = (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts", zb0004) + return + } + } + } + if zb0005 > 0 { + zb0005-- bts, err = (*z).Payset.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Payset") return } } - if zb0004 > 0 { - err = msgp.ErrTooManyArrayFields(zb0004) + if zb0005 > 0 { + err = msgp.ErrTooManyArrayFields(zb0005) if err != nil { err = msgp.WrapError(err, "struct-from-array") return @@ -744,11 +789,11 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b err = msgp.WrapError(err) return } - if zb0005 { + if zb0006 { (*z) = Block{} } - for zb0004 > 0 { - zb0004-- + for zb0005 > 0 { + zb0005-- field, bts, err = msgp.ReadMapKeyZC(bts) if err != nil { err = msgp.WrapError(err) @@ -792,14 +837,14 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b return } case "gen": - var zb0011 int - zb0011, err = msgp.ReadBytesBytesHeader(bts) + var zb0014 int + zb0014, err = msgp.ReadBytesBytesHeader(bts) if err != nil { err = msgp.WrapError(err, "GenesisID") return } - if zb0011 > config.MaxGenesisIDLen { - err = msgp.ErrOverflow(uint64(zb0011), uint64(config.MaxGenesisIDLen)) + if zb0014 > config.MaxGenesisIDLen { + err = msgp.ErrOverflow(uint64(zb0014), uint64(config.MaxGenesisIDLen)) return } (*z).BlockHeader.GenesisID, bts, err = msgp.ReadStringBytes(bts) @@ -916,27 +961,27 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b return } case "spt": - var zb0012 int - var zb0013 bool - zb0012, zb0013, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0015 int + var zb0016 bool + zb0015, zb0016, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "StateProofTracking") return } - if zb0012 > protocol.NumStateProofTypes { - err = msgp.ErrOverflow(uint64(zb0012), uint64(protocol.NumStateProofTypes)) + if zb0015 > protocol.NumStateProofTypes { + err = msgp.ErrOverflow(uint64(zb0015), uint64(protocol.NumStateProofTypes)) err = msgp.WrapError(err, "StateProofTracking") return } - if zb0013 { + if zb0016 { (*z).BlockHeader.StateProofTracking = nil } else if (*z).BlockHeader.StateProofTracking == nil { - (*z).BlockHeader.StateProofTracking = make(map[protocol.StateProofType]StateProofTrackingData, zb0012) + (*z).BlockHeader.StateProofTracking = make(map[protocol.StateProofType]StateProofTrackingData, zb0015) } - for zb0012 > 0 { + for zb0015 > 0 { var zb0001 protocol.StateProofType var zb0002 StateProofTrackingData - zb0012-- + zb0015-- bts, err = zb0001.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "StateProofTracking") @@ -950,24 +995,24 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b (*z).BlockHeader.StateProofTracking[zb0001] = zb0002 } case "partupdrmv": - var zb0014 int - var zb0015 bool - zb0014, zb0015, bts, err = msgp.ReadArrayHeaderBytes(bts) + var zb0017 int + var zb0018 bool + zb0017, zb0018, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "ExpiredParticipationAccounts") return } - if zb0014 > config.MaxProposedExpiredOnlineAccounts { - err = msgp.ErrOverflow(uint64(zb0014), uint64(config.MaxProposedExpiredOnlineAccounts)) + if zb0017 > config.MaxProposedExpiredOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0017), uint64(config.MaxProposedExpiredOnlineAccounts)) err = msgp.WrapError(err, "ExpiredParticipationAccounts") return } - if zb0015 { + if zb0018 { (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = nil - } else if (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0014 { - (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0014] + } else if (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0017 { + (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0017] } else { - (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0014) + (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0017) } for zb0003 := range (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts { bts, err = (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].UnmarshalMsgWithState(bts, st) @@ -976,6 +1021,33 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b return } } + case "partupdabs": + var zb0019 int + var zb0020 bool + zb0019, zb0020, bts, err = msgp.ReadArrayHeaderBytes(bts) + if err != nil { + err = msgp.WrapError(err, "AbsentParticipationAccounts") + return + } + if zb0019 > config.MaxProposedAbsentOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0019), uint64(config.MaxProposedAbsentOnlineAccounts)) + err = msgp.WrapError(err, "AbsentParticipationAccounts") + return + } + if zb0020 { + (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = nil + } else if (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts != nil && cap((*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) >= zb0019 { + (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = ((*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts)[:zb0019] + } else { + (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = make([]basics.Address, zb0019) + } + for zb0004 := range (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts { + bts, err = (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "AbsentParticipationAccounts", zb0004) + return + } + } case "txns": bts, err = (*z).Payset.UnmarshalMsgWithState(bts, st) if err != nil { @@ -1017,13 +1089,17 @@ func (z *Block) Msgsize() (s int) { for zb0003 := range (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts { s += (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].Msgsize() } + s += 11 + msgp.ArrayHeaderSize + for zb0004 := range (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts { + s += (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].Msgsize() + } s += 5 + (*z).Payset.Msgsize() return } // MsgIsZero returns whether this is a zero value func (z *Block) MsgIsZero() bool { - return ((*z).BlockHeader.Round.MsgIsZero()) && ((*z).BlockHeader.Branch.MsgIsZero()) && ((*z).BlockHeader.Seed.MsgIsZero()) && ((*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).BlockHeader.TimeStamp == 0) && ((*z).BlockHeader.GenesisID == "") && ((*z).BlockHeader.GenesisHash.MsgIsZero()) && ((*z).BlockHeader.Proposer.MsgIsZero()) && ((*z).BlockHeader.FeesCollected.MsgIsZero()) && ((*z).BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).BlockHeader.RewardsState.RewardsRate == 0) && ((*z).BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).BlockHeader.TxnCounter == 0) && (len((*z).BlockHeader.StateProofTracking) == 0) && (len((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).Payset.MsgIsZero()) + return ((*z).BlockHeader.Round.MsgIsZero()) && ((*z).BlockHeader.Branch.MsgIsZero()) && ((*z).BlockHeader.Seed.MsgIsZero()) && ((*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).BlockHeader.TimeStamp == 0) && ((*z).BlockHeader.GenesisID == "") && ((*z).BlockHeader.GenesisHash.MsgIsZero()) && ((*z).BlockHeader.Proposer.MsgIsZero()) && ((*z).BlockHeader.FeesCollected.MsgIsZero()) && ((*z).BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).BlockHeader.RewardsState.RewardsRate == 0) && ((*z).BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).BlockHeader.TxnCounter == 0) && (len((*z).BlockHeader.StateProofTracking) == 0) && (len((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && (len((*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) == 0) && ((*z).Payset.MsgIsZero()) } // MaxSize returns a maximum valid message size for this message type @@ -1037,6 +1113,9 @@ func BlockMaxSize() (s int) { s += 11 // Calculating size of slice: z.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts s += msgp.ArrayHeaderSize + ((config.MaxProposedExpiredOnlineAccounts) * (basics.AddressMaxSize())) + s += 11 + // Calculating size of slice: z.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts + s += msgp.ArrayHeaderSize + ((config.MaxProposedAbsentOnlineAccounts) * (basics.AddressMaxSize())) s += 5 // Using maxtotalbytes for: z.Payset s += config.MaxTxnBytesPerBlock @@ -1083,170 +1162,186 @@ func BlockHashMaxSize() int { func (z *BlockHeader) MarshalMsg(b []byte) (o []byte) { o = msgp.Require(b, z.Msgsize()) // omitempty: check for empty values - zb0004Len := uint32(27) - var zb0004Mask uint32 /* 32 bits */ + zb0005Len := uint32(28) + var zb0005Mask uint64 /* 33 bits */ if (*z).RewardsState.RewardsLevel == 0 { - zb0004Len-- - zb0004Mask |= 0x20 + zb0005Len-- + zb0005Mask |= 0x20 } if (*z).FeesCollected.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x40 + zb0005Len-- + zb0005Mask |= 0x40 } if (*z).RewardsState.FeeSink.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x80 + zb0005Len-- + zb0005Mask |= 0x80 } if (*z).RewardsState.RewardsResidue == 0 { - zb0004Len-- - zb0004Mask |= 0x100 + zb0005Len-- + zb0005Mask |= 0x100 } if (*z).GenesisID == "" { - zb0004Len-- - zb0004Mask |= 0x200 + zb0005Len-- + zb0005Mask |= 0x200 } if (*z).GenesisHash.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x400 + zb0005Len-- + zb0005Mask |= 0x400 } if (*z).UpgradeState.NextProtocolVoteBefore.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x800 + zb0005Len-- + zb0005Mask |= 0x800 } if (*z).UpgradeState.NextProtocol.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x1000 + zb0005Len-- + zb0005Mask |= 0x1000 } if (*z).UpgradeState.NextProtocolSwitchOn.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x2000 + zb0005Len-- + zb0005Mask |= 0x2000 } if (*z).UpgradeState.NextProtocolApprovals == 0 { - zb0004Len-- - zb0004Mask |= 0x4000 + zb0005Len-- + zb0005Mask |= 0x4000 + } + if len((*z).ParticipationUpdates.AbsentParticipationAccounts) == 0 { + zb0005Len-- + zb0005Mask |= 0x8000 } if len((*z).ParticipationUpdates.ExpiredParticipationAccounts) == 0 { - zb0004Len-- - zb0004Mask |= 0x8000 + zb0005Len-- + zb0005Mask |= 0x10000 } if (*z).Branch.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x10000 + zb0005Len-- + zb0005Mask |= 0x20000 } if (*z).UpgradeState.CurrentProtocol.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x20000 + zb0005Len-- + zb0005Mask |= 0x40000 } if (*z).Proposer.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x40000 + zb0005Len-- + zb0005Mask |= 0x80000 } if (*z).RewardsState.RewardsRate == 0 { - zb0004Len-- - zb0004Mask |= 0x80000 + zb0005Len-- + zb0005Mask |= 0x100000 } if (*z).Round.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x100000 + zb0005Len-- + zb0005Mask |= 0x200000 } if (*z).RewardsState.RewardsRecalculationRound.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x200000 + zb0005Len-- + zb0005Mask |= 0x400000 } if (*z).RewardsState.RewardsPool.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x400000 + zb0005Len-- + zb0005Mask |= 0x800000 } if (*z).Seed.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x800000 + zb0005Len-- + zb0005Mask |= 0x1000000 } if len((*z).StateProofTracking) == 0 { - zb0004Len-- - zb0004Mask |= 0x1000000 + zb0005Len-- + zb0005Mask |= 0x2000000 } if (*z).TxnCounter == 0 { - zb0004Len-- - zb0004Mask |= 0x2000000 + zb0005Len-- + zb0005Mask |= 0x4000000 } if (*z).TimeStamp == 0 { - zb0004Len-- - zb0004Mask |= 0x4000000 + zb0005Len-- + zb0005Mask |= 0x8000000 } if (*z).TxnCommitments.NativeSha512_256Commitment.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x8000000 + zb0005Len-- + zb0005Mask |= 0x10000000 } if (*z).TxnCommitments.Sha256Commitment.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x10000000 + zb0005Len-- + zb0005Mask |= 0x20000000 } if (*z).UpgradeVote.UpgradeDelay.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x20000000 + zb0005Len-- + zb0005Mask |= 0x40000000 } if (*z).UpgradeVote.UpgradePropose.MsgIsZero() { - zb0004Len-- - zb0004Mask |= 0x40000000 + zb0005Len-- + zb0005Mask |= 0x80000000 } if (*z).UpgradeVote.UpgradeApprove == false { - zb0004Len-- - zb0004Mask |= 0x80000000 + zb0005Len-- + zb0005Mask |= 0x100000000 } - // variable map header, size zb0004Len - o = msgp.AppendMapHeader(o, zb0004Len) - if zb0004Len != 0 { - if (zb0004Mask & 0x20) == 0 { // if not empty + // variable map header, size zb0005Len + o = msgp.AppendMapHeader(o, zb0005Len) + if zb0005Len != 0 { + if (zb0005Mask & 0x20) == 0 { // if not empty // string "earn" o = append(o, 0xa4, 0x65, 0x61, 0x72, 0x6e) o = msgp.AppendUint64(o, (*z).RewardsState.RewardsLevel) } - if (zb0004Mask & 0x40) == 0 { // if not empty + if (zb0005Mask & 0x40) == 0 { // if not empty // string "fc" o = append(o, 0xa2, 0x66, 0x63) o = (*z).FeesCollected.MarshalMsg(o) } - if (zb0004Mask & 0x80) == 0 { // if not empty + if (zb0005Mask & 0x80) == 0 { // if not empty // string "fees" o = append(o, 0xa4, 0x66, 0x65, 0x65, 0x73) o = (*z).RewardsState.FeeSink.MarshalMsg(o) } - if (zb0004Mask & 0x100) == 0 { // if not empty + if (zb0005Mask & 0x100) == 0 { // if not empty // string "frac" o = append(o, 0xa4, 0x66, 0x72, 0x61, 0x63) o = msgp.AppendUint64(o, (*z).RewardsState.RewardsResidue) } - if (zb0004Mask & 0x200) == 0 { // if not empty + if (zb0005Mask & 0x200) == 0 { // if not empty // string "gen" o = append(o, 0xa3, 0x67, 0x65, 0x6e) o = msgp.AppendString(o, (*z).GenesisID) } - if (zb0004Mask & 0x400) == 0 { // if not empty + if (zb0005Mask & 0x400) == 0 { // if not empty // string "gh" o = append(o, 0xa2, 0x67, 0x68) o = (*z).GenesisHash.MarshalMsg(o) } - if (zb0004Mask & 0x800) == 0 { // if not empty + if (zb0005Mask & 0x800) == 0 { // if not empty // string "nextbefore" o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65) o = (*z).UpgradeState.NextProtocolVoteBefore.MarshalMsg(o) } - if (zb0004Mask & 0x1000) == 0 { // if not empty + if (zb0005Mask & 0x1000) == 0 { // if not empty // string "nextproto" o = append(o, 0xa9, 0x6e, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f) o = (*z).UpgradeState.NextProtocol.MarshalMsg(o) } - if (zb0004Mask & 0x2000) == 0 { // if not empty + if (zb0005Mask & 0x2000) == 0 { // if not empty // string "nextswitch" o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68) o = (*z).UpgradeState.NextProtocolSwitchOn.MarshalMsg(o) } - if (zb0004Mask & 0x4000) == 0 { // if not empty + if (zb0005Mask & 0x4000) == 0 { // if not empty // string "nextyes" o = append(o, 0xa7, 0x6e, 0x65, 0x78, 0x74, 0x79, 0x65, 0x73) o = msgp.AppendUint64(o, (*z).UpgradeState.NextProtocolApprovals) } - if (zb0004Mask & 0x8000) == 0 { // if not empty + if (zb0005Mask & 0x8000) == 0 { // if not empty + // string "partupdabs" + o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x61, 0x62, 0x73) + if (*z).ParticipationUpdates.AbsentParticipationAccounts == nil { + o = msgp.AppendNil(o) + } else { + o = msgp.AppendArrayHeader(o, uint32(len((*z).ParticipationUpdates.AbsentParticipationAccounts))) + } + for zb0004 := range (*z).ParticipationUpdates.AbsentParticipationAccounts { + o = (*z).ParticipationUpdates.AbsentParticipationAccounts[zb0004].MarshalMsg(o) + } + } + if (zb0005Mask & 0x10000) == 0 { // if not empty // string "partupdrmv" o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76) if (*z).ParticipationUpdates.ExpiredParticipationAccounts == nil { @@ -1258,47 +1353,47 @@ func (z *BlockHeader) MarshalMsg(b []byte) (o []byte) { o = (*z).ParticipationUpdates.ExpiredParticipationAccounts[zb0003].MarshalMsg(o) } } - if (zb0004Mask & 0x10000) == 0 { // if not empty + if (zb0005Mask & 0x20000) == 0 { // if not empty // string "prev" o = append(o, 0xa4, 0x70, 0x72, 0x65, 0x76) o = (*z).Branch.MarshalMsg(o) } - if (zb0004Mask & 0x20000) == 0 { // if not empty + if (zb0005Mask & 0x40000) == 0 { // if not empty // string "proto" o = append(o, 0xa5, 0x70, 0x72, 0x6f, 0x74, 0x6f) o = (*z).UpgradeState.CurrentProtocol.MarshalMsg(o) } - if (zb0004Mask & 0x40000) == 0 { // if not empty + if (zb0005Mask & 0x80000) == 0 { // if not empty // string "prp" o = append(o, 0xa3, 0x70, 0x72, 0x70) o = (*z).Proposer.MarshalMsg(o) } - if (zb0004Mask & 0x80000) == 0 { // if not empty + if (zb0005Mask & 0x100000) == 0 { // if not empty // string "rate" o = append(o, 0xa4, 0x72, 0x61, 0x74, 0x65) o = msgp.AppendUint64(o, (*z).RewardsState.RewardsRate) } - if (zb0004Mask & 0x100000) == 0 { // if not empty + if (zb0005Mask & 0x200000) == 0 { // if not empty // string "rnd" o = append(o, 0xa3, 0x72, 0x6e, 0x64) o = (*z).Round.MarshalMsg(o) } - if (zb0004Mask & 0x200000) == 0 { // if not empty + if (zb0005Mask & 0x400000) == 0 { // if not empty // string "rwcalr" o = append(o, 0xa6, 0x72, 0x77, 0x63, 0x61, 0x6c, 0x72) o = (*z).RewardsState.RewardsRecalculationRound.MarshalMsg(o) } - if (zb0004Mask & 0x400000) == 0 { // if not empty + if (zb0005Mask & 0x800000) == 0 { // if not empty // string "rwd" o = append(o, 0xa3, 0x72, 0x77, 0x64) o = (*z).RewardsState.RewardsPool.MarshalMsg(o) } - if (zb0004Mask & 0x800000) == 0 { // if not empty + if (zb0005Mask & 0x1000000) == 0 { // if not empty // string "seed" o = append(o, 0xa4, 0x73, 0x65, 0x65, 0x64) o = (*z).Seed.MarshalMsg(o) } - if (zb0004Mask & 0x1000000) == 0 { // if not empty + if (zb0005Mask & 0x2000000) == 0 { // if not empty // string "spt" o = append(o, 0xa3, 0x73, 0x70, 0x74) if (*z).StateProofTracking == nil { @@ -1318,37 +1413,37 @@ func (z *BlockHeader) MarshalMsg(b []byte) (o []byte) { o = zb0002.MarshalMsg(o) } } - if (zb0004Mask & 0x2000000) == 0 { // if not empty + if (zb0005Mask & 0x4000000) == 0 { // if not empty // string "tc" o = append(o, 0xa2, 0x74, 0x63) o = msgp.AppendUint64(o, (*z).TxnCounter) } - if (zb0004Mask & 0x4000000) == 0 { // if not empty + if (zb0005Mask & 0x8000000) == 0 { // if not empty // string "ts" o = append(o, 0xa2, 0x74, 0x73) o = msgp.AppendInt64(o, (*z).TimeStamp) } - if (zb0004Mask & 0x8000000) == 0 { // if not empty + if (zb0005Mask & 0x10000000) == 0 { // if not empty // string "txn" o = append(o, 0xa3, 0x74, 0x78, 0x6e) o = (*z).TxnCommitments.NativeSha512_256Commitment.MarshalMsg(o) } - if (zb0004Mask & 0x10000000) == 0 { // if not empty + if (zb0005Mask & 0x20000000) == 0 { // if not empty // string "txn256" o = append(o, 0xa6, 0x74, 0x78, 0x6e, 0x32, 0x35, 0x36) o = (*z).TxnCommitments.Sha256Commitment.MarshalMsg(o) } - if (zb0004Mask & 0x20000000) == 0 { // if not empty + if (zb0005Mask & 0x40000000) == 0 { // if not empty // string "upgradedelay" o = append(o, 0xac, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x65, 0x6c, 0x61, 0x79) o = (*z).UpgradeVote.UpgradeDelay.MarshalMsg(o) } - if (zb0004Mask & 0x40000000) == 0 { // if not empty + if (zb0005Mask & 0x80000000) == 0 { // if not empty // string "upgradeprop" o = append(o, 0xab, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x70, 0x72, 0x6f, 0x70) o = (*z).UpgradeVote.UpgradePropose.MarshalMsg(o) } - if (zb0004Mask & 0x80000000) == 0 { // if not empty + if (zb0005Mask & 0x100000000) == 0 { // if not empty // string "upgradeyes" o = append(o, 0xaa, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x65, 0x73) o = msgp.AppendBool(o, (*z).UpgradeVote.UpgradeApprove) @@ -1371,73 +1466,73 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) st.AllowableDepth-- var field []byte _ = field - var zb0004 int - var zb0005 bool - zb0004, zb0005, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0005 int + var zb0006 bool + zb0005, zb0006, bts, err = msgp.ReadMapHeaderBytes(bts) if _, ok := err.(msgp.TypeError); ok { - zb0004, zb0005, bts, err = msgp.ReadArrayHeaderBytes(bts) + zb0005, zb0006, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err) return } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Round.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Round") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Branch.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Branch") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Seed.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Seed") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).TxnCommitments.NativeSha512_256Commitment.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NativeSha512_256Commitment") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).TxnCommitments.Sha256Commitment.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Sha256Commitment") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).TimeStamp, bts, err = msgp.ReadInt64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "TimeStamp") return } } - if zb0004 > 0 { - zb0004-- - var zb0006 int - zb0006, err = msgp.ReadBytesBytesHeader(bts) + if zb0005 > 0 { + zb0005-- + var zb0007 int + zb0007, err = msgp.ReadBytesBytesHeader(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "GenesisID") return } - if zb0006 > config.MaxGenesisIDLen { - err = msgp.ErrOverflow(uint64(zb0006), uint64(config.MaxGenesisIDLen)) + if zb0007 > config.MaxGenesisIDLen { + err = msgp.ErrOverflow(uint64(zb0007), uint64(config.MaxGenesisIDLen)) return } (*z).GenesisID, bts, err = msgp.ReadStringBytes(bts) @@ -1446,173 +1541,173 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).GenesisHash.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "GenesisHash") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).Proposer.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "Proposer") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).FeesCollected.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "FeesCollected") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).RewardsState.FeeSink.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "FeeSink") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).RewardsState.RewardsPool.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsPool") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).RewardsState.RewardsLevel, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsLevel") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).RewardsState.RewardsRate, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsRate") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).RewardsState.RewardsResidue, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsResidue") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).RewardsState.RewardsRecalculationRound.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "RewardsRecalculationRound") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).UpgradeState.CurrentProtocol.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "CurrentProtocol") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).UpgradeState.NextProtocol.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NextProtocol") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).UpgradeState.NextProtocolApprovals, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NextProtocolApprovals") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).UpgradeState.NextProtocolVoteBefore.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NextProtocolVoteBefore") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).UpgradeState.NextProtocolSwitchOn.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "NextProtocolSwitchOn") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).UpgradeVote.UpgradePropose.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "UpgradePropose") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- bts, err = (*z).UpgradeVote.UpgradeDelay.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "UpgradeDelay") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).UpgradeVote.UpgradeApprove, bts, err = msgp.ReadBoolBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "UpgradeApprove") return } } - if zb0004 > 0 { - zb0004-- + if zb0005 > 0 { + zb0005-- (*z).TxnCounter, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "TxnCounter") return } } - if zb0004 > 0 { - zb0004-- - var zb0007 int - var zb0008 bool - zb0007, zb0008, bts, err = msgp.ReadMapHeaderBytes(bts) + if zb0005 > 0 { + zb0005-- + var zb0008 int + var zb0009 bool + zb0008, zb0009, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "StateProofTracking") return } - if zb0007 > protocol.NumStateProofTypes { - err = msgp.ErrOverflow(uint64(zb0007), uint64(protocol.NumStateProofTypes)) + if zb0008 > protocol.NumStateProofTypes { + err = msgp.ErrOverflow(uint64(zb0008), uint64(protocol.NumStateProofTypes)) err = msgp.WrapError(err, "struct-from-array", "StateProofTracking") return } - if zb0008 { + if zb0009 { (*z).StateProofTracking = nil } else if (*z).StateProofTracking == nil { - (*z).StateProofTracking = make(map[protocol.StateProofType]StateProofTrackingData, zb0007) + (*z).StateProofTracking = make(map[protocol.StateProofType]StateProofTrackingData, zb0008) } - for zb0007 > 0 { + for zb0008 > 0 { var zb0001 protocol.StateProofType var zb0002 StateProofTrackingData - zb0007-- + zb0008-- bts, err = zb0001.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "struct-from-array", "StateProofTracking") @@ -1626,26 +1721,26 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (*z).StateProofTracking[zb0001] = zb0002 } } - if zb0004 > 0 { - zb0004-- - var zb0009 int - var zb0010 bool - zb0009, zb0010, bts, err = msgp.ReadArrayHeaderBytes(bts) + if zb0005 > 0 { + zb0005-- + var zb0010 int + var zb0011 bool + zb0010, zb0011, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts") return } - if zb0009 > config.MaxProposedExpiredOnlineAccounts { - err = msgp.ErrOverflow(uint64(zb0009), uint64(config.MaxProposedExpiredOnlineAccounts)) + if zb0010 > config.MaxProposedExpiredOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0010), uint64(config.MaxProposedExpiredOnlineAccounts)) err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts") return } - if zb0010 { + if zb0011 { (*z).ParticipationUpdates.ExpiredParticipationAccounts = nil - } else if (*z).ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).ParticipationUpdates.ExpiredParticipationAccounts) >= zb0009 { - (*z).ParticipationUpdates.ExpiredParticipationAccounts = ((*z).ParticipationUpdates.ExpiredParticipationAccounts)[:zb0009] + } else if (*z).ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).ParticipationUpdates.ExpiredParticipationAccounts) >= zb0010 { + (*z).ParticipationUpdates.ExpiredParticipationAccounts = ((*z).ParticipationUpdates.ExpiredParticipationAccounts)[:zb0010] } else { - (*z).ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0009) + (*z).ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0010) } for zb0003 := range (*z).ParticipationUpdates.ExpiredParticipationAccounts { bts, err = (*z).ParticipationUpdates.ExpiredParticipationAccounts[zb0003].UnmarshalMsgWithState(bts, st) @@ -1655,8 +1750,37 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) } } } - if zb0004 > 0 { - err = msgp.ErrTooManyArrayFields(zb0004) + if zb0005 > 0 { + zb0005-- + var zb0012 int + var zb0013 bool + zb0012, zb0013, bts, err = msgp.ReadArrayHeaderBytes(bts) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts") + return + } + if zb0012 > config.MaxProposedAbsentOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0012), uint64(config.MaxProposedAbsentOnlineAccounts)) + err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts") + return + } + if zb0013 { + (*z).ParticipationUpdates.AbsentParticipationAccounts = nil + } else if (*z).ParticipationUpdates.AbsentParticipationAccounts != nil && cap((*z).ParticipationUpdates.AbsentParticipationAccounts) >= zb0012 { + (*z).ParticipationUpdates.AbsentParticipationAccounts = ((*z).ParticipationUpdates.AbsentParticipationAccounts)[:zb0012] + } else { + (*z).ParticipationUpdates.AbsentParticipationAccounts = make([]basics.Address, zb0012) + } + for zb0004 := range (*z).ParticipationUpdates.AbsentParticipationAccounts { + bts, err = (*z).ParticipationUpdates.AbsentParticipationAccounts[zb0004].UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts", zb0004) + return + } + } + } + if zb0005 > 0 { + err = msgp.ErrTooManyArrayFields(zb0005) if err != nil { err = msgp.WrapError(err, "struct-from-array") return @@ -1667,11 +1791,11 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) err = msgp.WrapError(err) return } - if zb0005 { + if zb0006 { (*z) = BlockHeader{} } - for zb0004 > 0 { - zb0004-- + for zb0005 > 0 { + zb0005-- field, bts, err = msgp.ReadMapKeyZC(bts) if err != nil { err = msgp.WrapError(err) @@ -1715,14 +1839,14 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) return } case "gen": - var zb0011 int - zb0011, err = msgp.ReadBytesBytesHeader(bts) + var zb0014 int + zb0014, err = msgp.ReadBytesBytesHeader(bts) if err != nil { err = msgp.WrapError(err, "GenesisID") return } - if zb0011 > config.MaxGenesisIDLen { - err = msgp.ErrOverflow(uint64(zb0011), uint64(config.MaxGenesisIDLen)) + if zb0014 > config.MaxGenesisIDLen { + err = msgp.ErrOverflow(uint64(zb0014), uint64(config.MaxGenesisIDLen)) return } (*z).GenesisID, bts, err = msgp.ReadStringBytes(bts) @@ -1839,27 +1963,27 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) return } case "spt": - var zb0012 int - var zb0013 bool - zb0012, zb0013, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0015 int + var zb0016 bool + zb0015, zb0016, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "StateProofTracking") return } - if zb0012 > protocol.NumStateProofTypes { - err = msgp.ErrOverflow(uint64(zb0012), uint64(protocol.NumStateProofTypes)) + if zb0015 > protocol.NumStateProofTypes { + err = msgp.ErrOverflow(uint64(zb0015), uint64(protocol.NumStateProofTypes)) err = msgp.WrapError(err, "StateProofTracking") return } - if zb0013 { + if zb0016 { (*z).StateProofTracking = nil } else if (*z).StateProofTracking == nil { - (*z).StateProofTracking = make(map[protocol.StateProofType]StateProofTrackingData, zb0012) + (*z).StateProofTracking = make(map[protocol.StateProofType]StateProofTrackingData, zb0015) } - for zb0012 > 0 { + for zb0015 > 0 { var zb0001 protocol.StateProofType var zb0002 StateProofTrackingData - zb0012-- + zb0015-- bts, err = zb0001.UnmarshalMsgWithState(bts, st) if err != nil { err = msgp.WrapError(err, "StateProofTracking") @@ -1873,24 +1997,24 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (*z).StateProofTracking[zb0001] = zb0002 } case "partupdrmv": - var zb0014 int - var zb0015 bool - zb0014, zb0015, bts, err = msgp.ReadArrayHeaderBytes(bts) + var zb0017 int + var zb0018 bool + zb0017, zb0018, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "ExpiredParticipationAccounts") return } - if zb0014 > config.MaxProposedExpiredOnlineAccounts { - err = msgp.ErrOverflow(uint64(zb0014), uint64(config.MaxProposedExpiredOnlineAccounts)) + if zb0017 > config.MaxProposedExpiredOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0017), uint64(config.MaxProposedExpiredOnlineAccounts)) err = msgp.WrapError(err, "ExpiredParticipationAccounts") return } - if zb0015 { + if zb0018 { (*z).ParticipationUpdates.ExpiredParticipationAccounts = nil - } else if (*z).ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).ParticipationUpdates.ExpiredParticipationAccounts) >= zb0014 { - (*z).ParticipationUpdates.ExpiredParticipationAccounts = ((*z).ParticipationUpdates.ExpiredParticipationAccounts)[:zb0014] + } else if (*z).ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).ParticipationUpdates.ExpiredParticipationAccounts) >= zb0017 { + (*z).ParticipationUpdates.ExpiredParticipationAccounts = ((*z).ParticipationUpdates.ExpiredParticipationAccounts)[:zb0017] } else { - (*z).ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0014) + (*z).ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0017) } for zb0003 := range (*z).ParticipationUpdates.ExpiredParticipationAccounts { bts, err = (*z).ParticipationUpdates.ExpiredParticipationAccounts[zb0003].UnmarshalMsgWithState(bts, st) @@ -1899,6 +2023,33 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) return } } + case "partupdabs": + var zb0019 int + var zb0020 bool + zb0019, zb0020, bts, err = msgp.ReadArrayHeaderBytes(bts) + if err != nil { + err = msgp.WrapError(err, "AbsentParticipationAccounts") + return + } + if zb0019 > config.MaxProposedAbsentOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0019), uint64(config.MaxProposedAbsentOnlineAccounts)) + err = msgp.WrapError(err, "AbsentParticipationAccounts") + return + } + if zb0020 { + (*z).ParticipationUpdates.AbsentParticipationAccounts = nil + } else if (*z).ParticipationUpdates.AbsentParticipationAccounts != nil && cap((*z).ParticipationUpdates.AbsentParticipationAccounts) >= zb0019 { + (*z).ParticipationUpdates.AbsentParticipationAccounts = ((*z).ParticipationUpdates.AbsentParticipationAccounts)[:zb0019] + } else { + (*z).ParticipationUpdates.AbsentParticipationAccounts = make([]basics.Address, zb0019) + } + for zb0004 := range (*z).ParticipationUpdates.AbsentParticipationAccounts { + bts, err = (*z).ParticipationUpdates.AbsentParticipationAccounts[zb0004].UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "AbsentParticipationAccounts", zb0004) + return + } + } default: err = msgp.ErrNoField(string(field)) if err != nil { @@ -1934,12 +2085,16 @@ func (z *BlockHeader) Msgsize() (s int) { for zb0003 := range (*z).ParticipationUpdates.ExpiredParticipationAccounts { s += (*z).ParticipationUpdates.ExpiredParticipationAccounts[zb0003].Msgsize() } + s += 11 + msgp.ArrayHeaderSize + for zb0004 := range (*z).ParticipationUpdates.AbsentParticipationAccounts { + s += (*z).ParticipationUpdates.AbsentParticipationAccounts[zb0004].Msgsize() + } return } // MsgIsZero returns whether this is a zero value func (z *BlockHeader) MsgIsZero() bool { - return ((*z).Round.MsgIsZero()) && ((*z).Branch.MsgIsZero()) && ((*z).Seed.MsgIsZero()) && ((*z).TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).TimeStamp == 0) && ((*z).GenesisID == "") && ((*z).GenesisHash.MsgIsZero()) && ((*z).Proposer.MsgIsZero()) && ((*z).FeesCollected.MsgIsZero()) && ((*z).RewardsState.FeeSink.MsgIsZero()) && ((*z).RewardsState.RewardsPool.MsgIsZero()) && ((*z).RewardsState.RewardsLevel == 0) && ((*z).RewardsState.RewardsRate == 0) && ((*z).RewardsState.RewardsResidue == 0) && ((*z).RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).UpgradeState.NextProtocol.MsgIsZero()) && ((*z).UpgradeState.NextProtocolApprovals == 0) && ((*z).UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).UpgradeVote.UpgradeApprove == false) && ((*z).TxnCounter == 0) && (len((*z).StateProofTracking) == 0) && (len((*z).ParticipationUpdates.ExpiredParticipationAccounts) == 0) + return ((*z).Round.MsgIsZero()) && ((*z).Branch.MsgIsZero()) && ((*z).Seed.MsgIsZero()) && ((*z).TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).TimeStamp == 0) && ((*z).GenesisID == "") && ((*z).GenesisHash.MsgIsZero()) && ((*z).Proposer.MsgIsZero()) && ((*z).FeesCollected.MsgIsZero()) && ((*z).RewardsState.FeeSink.MsgIsZero()) && ((*z).RewardsState.RewardsPool.MsgIsZero()) && ((*z).RewardsState.RewardsLevel == 0) && ((*z).RewardsState.RewardsRate == 0) && ((*z).RewardsState.RewardsResidue == 0) && ((*z).RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).UpgradeState.NextProtocol.MsgIsZero()) && ((*z).UpgradeState.NextProtocolApprovals == 0) && ((*z).UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).UpgradeVote.UpgradeApprove == false) && ((*z).TxnCounter == 0) && (len((*z).StateProofTracking) == 0) && (len((*z).ParticipationUpdates.ExpiredParticipationAccounts) == 0) && (len((*z).ParticipationUpdates.AbsentParticipationAccounts) == 0) } // MaxSize returns a maximum valid message size for this message type @@ -1953,6 +2108,9 @@ func BlockHeaderMaxSize() (s int) { s += 11 // Calculating size of slice: z.ParticipationUpdates.ExpiredParticipationAccounts s += msgp.ArrayHeaderSize + ((config.MaxProposedExpiredOnlineAccounts) * (basics.AddressMaxSize())) + s += 11 + // Calculating size of slice: z.ParticipationUpdates.AbsentParticipationAccounts + s += msgp.ArrayHeaderSize + ((config.MaxProposedAbsentOnlineAccounts) * (basics.AddressMaxSize())) return } @@ -2944,16 +3102,32 @@ func LightBlockHeaderMaxSize() (s int) { func (z *ParticipationUpdates) MarshalMsg(b []byte) (o []byte) { o = msgp.Require(b, z.Msgsize()) // omitempty: check for empty values - zb0002Len := uint32(1) - var zb0002Mask uint8 /* 2 bits */ - if len((*z).ExpiredParticipationAccounts) == 0 { - zb0002Len-- - zb0002Mask |= 0x2 + zb0003Len := uint32(2) + var zb0003Mask uint8 /* 3 bits */ + if len((*z).AbsentParticipationAccounts) == 0 { + zb0003Len-- + zb0003Mask |= 0x2 } - // variable map header, size zb0002Len - o = append(o, 0x80|uint8(zb0002Len)) - if zb0002Len != 0 { - if (zb0002Mask & 0x2) == 0 { // if not empty + if len((*z).ExpiredParticipationAccounts) == 0 { + zb0003Len-- + zb0003Mask |= 0x4 + } + // variable map header, size zb0003Len + o = append(o, 0x80|uint8(zb0003Len)) + if zb0003Len != 0 { + if (zb0003Mask & 0x2) == 0 { // if not empty + // string "partupdabs" + o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x61, 0x62, 0x73) + if (*z).AbsentParticipationAccounts == nil { + o = msgp.AppendNil(o) + } else { + o = msgp.AppendArrayHeader(o, uint32(len((*z).AbsentParticipationAccounts))) + } + for zb0002 := range (*z).AbsentParticipationAccounts { + o = (*z).AbsentParticipationAccounts[zb0002].MarshalMsg(o) + } + } + if (zb0003Mask & 0x4) == 0 { // if not empty // string "partupdrmv" o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76) if (*z).ExpiredParticipationAccounts == nil { @@ -2983,35 +3157,35 @@ func (z *ParticipationUpdates) UnmarshalMsgWithState(bts []byte, st msgp.Unmarsh st.AllowableDepth-- var field []byte _ = field - var zb0002 int - var zb0003 bool - zb0002, zb0003, bts, err = msgp.ReadMapHeaderBytes(bts) + var zb0003 int + var zb0004 bool + zb0003, zb0004, bts, err = msgp.ReadMapHeaderBytes(bts) if _, ok := err.(msgp.TypeError); ok { - zb0002, zb0003, bts, err = msgp.ReadArrayHeaderBytes(bts) + zb0003, zb0004, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err) return } - if zb0002 > 0 { - zb0002-- - var zb0004 int - var zb0005 bool - zb0004, zb0005, bts, err = msgp.ReadArrayHeaderBytes(bts) + if zb0003 > 0 { + zb0003-- + var zb0005 int + var zb0006 bool + zb0005, zb0006, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts") return } - if zb0004 > config.MaxProposedExpiredOnlineAccounts { - err = msgp.ErrOverflow(uint64(zb0004), uint64(config.MaxProposedExpiredOnlineAccounts)) + if zb0005 > config.MaxProposedExpiredOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0005), uint64(config.MaxProposedExpiredOnlineAccounts)) err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts") return } - if zb0005 { + if zb0006 { (*z).ExpiredParticipationAccounts = nil - } else if (*z).ExpiredParticipationAccounts != nil && cap((*z).ExpiredParticipationAccounts) >= zb0004 { - (*z).ExpiredParticipationAccounts = ((*z).ExpiredParticipationAccounts)[:zb0004] + } else if (*z).ExpiredParticipationAccounts != nil && cap((*z).ExpiredParticipationAccounts) >= zb0005 { + (*z).ExpiredParticipationAccounts = ((*z).ExpiredParticipationAccounts)[:zb0005] } else { - (*z).ExpiredParticipationAccounts = make([]basics.Address, zb0004) + (*z).ExpiredParticipationAccounts = make([]basics.Address, zb0005) } for zb0001 := range (*z).ExpiredParticipationAccounts { bts, err = (*z).ExpiredParticipationAccounts[zb0001].UnmarshalMsgWithState(bts, st) @@ -3021,8 +3195,37 @@ func (z *ParticipationUpdates) UnmarshalMsgWithState(bts []byte, st msgp.Unmarsh } } } - if zb0002 > 0 { - err = msgp.ErrTooManyArrayFields(zb0002) + if zb0003 > 0 { + zb0003-- + var zb0007 int + var zb0008 bool + zb0007, zb0008, bts, err = msgp.ReadArrayHeaderBytes(bts) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts") + return + } + if zb0007 > config.MaxProposedAbsentOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0007), uint64(config.MaxProposedAbsentOnlineAccounts)) + err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts") + return + } + if zb0008 { + (*z).AbsentParticipationAccounts = nil + } else if (*z).AbsentParticipationAccounts != nil && cap((*z).AbsentParticipationAccounts) >= zb0007 { + (*z).AbsentParticipationAccounts = ((*z).AbsentParticipationAccounts)[:zb0007] + } else { + (*z).AbsentParticipationAccounts = make([]basics.Address, zb0007) + } + for zb0002 := range (*z).AbsentParticipationAccounts { + bts, err = (*z).AbsentParticipationAccounts[zb0002].UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts", zb0002) + return + } + } + } + if zb0003 > 0 { + err = msgp.ErrTooManyArrayFields(zb0003) if err != nil { err = msgp.WrapError(err, "struct-from-array") return @@ -3033,11 +3236,11 @@ func (z *ParticipationUpdates) UnmarshalMsgWithState(bts []byte, st msgp.Unmarsh err = msgp.WrapError(err) return } - if zb0003 { + if zb0004 { (*z) = ParticipationUpdates{} } - for zb0002 > 0 { - zb0002-- + for zb0003 > 0 { + zb0003-- field, bts, err = msgp.ReadMapKeyZC(bts) if err != nil { err = msgp.WrapError(err) @@ -3045,24 +3248,24 @@ func (z *ParticipationUpdates) UnmarshalMsgWithState(bts []byte, st msgp.Unmarsh } switch string(field) { case "partupdrmv": - var zb0006 int - var zb0007 bool - zb0006, zb0007, bts, err = msgp.ReadArrayHeaderBytes(bts) + var zb0009 int + var zb0010 bool + zb0009, zb0010, bts, err = msgp.ReadArrayHeaderBytes(bts) if err != nil { err = msgp.WrapError(err, "ExpiredParticipationAccounts") return } - if zb0006 > config.MaxProposedExpiredOnlineAccounts { - err = msgp.ErrOverflow(uint64(zb0006), uint64(config.MaxProposedExpiredOnlineAccounts)) + if zb0009 > config.MaxProposedExpiredOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0009), uint64(config.MaxProposedExpiredOnlineAccounts)) err = msgp.WrapError(err, "ExpiredParticipationAccounts") return } - if zb0007 { + if zb0010 { (*z).ExpiredParticipationAccounts = nil - } else if (*z).ExpiredParticipationAccounts != nil && cap((*z).ExpiredParticipationAccounts) >= zb0006 { - (*z).ExpiredParticipationAccounts = ((*z).ExpiredParticipationAccounts)[:zb0006] + } else if (*z).ExpiredParticipationAccounts != nil && cap((*z).ExpiredParticipationAccounts) >= zb0009 { + (*z).ExpiredParticipationAccounts = ((*z).ExpiredParticipationAccounts)[:zb0009] } else { - (*z).ExpiredParticipationAccounts = make([]basics.Address, zb0006) + (*z).ExpiredParticipationAccounts = make([]basics.Address, zb0009) } for zb0001 := range (*z).ExpiredParticipationAccounts { bts, err = (*z).ExpiredParticipationAccounts[zb0001].UnmarshalMsgWithState(bts, st) @@ -3071,6 +3274,33 @@ func (z *ParticipationUpdates) UnmarshalMsgWithState(bts []byte, st msgp.Unmarsh return } } + case "partupdabs": + var zb0011 int + var zb0012 bool + zb0011, zb0012, bts, err = msgp.ReadArrayHeaderBytes(bts) + if err != nil { + err = msgp.WrapError(err, "AbsentParticipationAccounts") + return + } + if zb0011 > config.MaxProposedAbsentOnlineAccounts { + err = msgp.ErrOverflow(uint64(zb0011), uint64(config.MaxProposedAbsentOnlineAccounts)) + err = msgp.WrapError(err, "AbsentParticipationAccounts") + return + } + if zb0012 { + (*z).AbsentParticipationAccounts = nil + } else if (*z).AbsentParticipationAccounts != nil && cap((*z).AbsentParticipationAccounts) >= zb0011 { + (*z).AbsentParticipationAccounts = ((*z).AbsentParticipationAccounts)[:zb0011] + } else { + (*z).AbsentParticipationAccounts = make([]basics.Address, zb0011) + } + for zb0002 := range (*z).AbsentParticipationAccounts { + bts, err = (*z).AbsentParticipationAccounts[zb0002].UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "AbsentParticipationAccounts", zb0002) + return + } + } default: err = msgp.ErrNoField(string(field)) if err != nil { @@ -3098,12 +3328,16 @@ func (z *ParticipationUpdates) Msgsize() (s int) { for zb0001 := range (*z).ExpiredParticipationAccounts { s += (*z).ExpiredParticipationAccounts[zb0001].Msgsize() } + s += 11 + msgp.ArrayHeaderSize + for zb0002 := range (*z).AbsentParticipationAccounts { + s += (*z).AbsentParticipationAccounts[zb0002].Msgsize() + } return } // MsgIsZero returns whether this is a zero value func (z *ParticipationUpdates) MsgIsZero() bool { - return (len((*z).ExpiredParticipationAccounts) == 0) + return (len((*z).ExpiredParticipationAccounts) == 0) && (len((*z).AbsentParticipationAccounts) == 0) } // MaxSize returns a maximum valid message size for this message type @@ -3111,6 +3345,9 @@ func ParticipationUpdatesMaxSize() (s int) { s = 1 + 11 // Calculating size of slice: z.ExpiredParticipationAccounts s += msgp.ArrayHeaderSize + ((config.MaxProposedExpiredOnlineAccounts) * (basics.AddressMaxSize())) + s += 11 + // Calculating size of slice: z.AbsentParticipationAccounts + s += msgp.ArrayHeaderSize + ((config.MaxProposedAbsentOnlineAccounts) * (basics.AddressMaxSize())) return } diff --git a/data/txntest/txn.go b/data/txntest/txn.go index 5815aacc60..dfda6cdd33 100644 --- a/data/txntest/txn.go +++ b/data/txntest/txn.go @@ -147,30 +147,39 @@ func (tx *Txn) FillDefaults(params config.ConsensusParams) { tx.LastValid = tx.FirstValid + basics.Round(params.MaxTxnLife) } - if tx.Type == protocol.ApplicationCallTx && - (tx.ApplicationID == 0 || tx.OnCompletion == transactions.UpdateApplicationOC) { - - switch program := tx.ApprovalProgram.(type) { - case nil: - tx.ApprovalProgram = fmt.Sprintf("#pragma version %d\nint 1", params.LogicSigVersion) - case string: - if program != "" && !strings.Contains(program, "#pragma version") { - pragma := fmt.Sprintf("#pragma version %d\n", params.LogicSigVersion) - tx.ApprovalProgram = pragma + program + switch tx.Type { + case protocol.KeyRegistrationTx: + if !tx.VotePK.MsgIsZero() && !tx.SelectionPK.MsgIsZero() { + if tx.VoteLast == 0 { + tx.VoteLast = tx.VoteFirst + 1_000_000 } - case []byte: } + case protocol.ApplicationCallTx: + // fill in empty programs + if tx.ApplicationID == 0 || tx.OnCompletion == transactions.UpdateApplicationOC { + switch program := tx.ApprovalProgram.(type) { + case nil: + tx.ApprovalProgram = fmt.Sprintf("#pragma version %d\nint 1", params.LogicSigVersion) + case string: + if program != "" && !strings.Contains(program, "#pragma version") { + pragma := fmt.Sprintf("#pragma version %d\n", params.LogicSigVersion) + tx.ApprovalProgram = pragma + program + } + case []byte: + } - switch program := tx.ClearStateProgram.(type) { - case nil: - tx.ClearStateProgram = tx.ApprovalProgram - case string: - if program != "" && !strings.Contains(program, "#pragma version") { - pragma := fmt.Sprintf("#pragma version %d\n", params.LogicSigVersion) - tx.ClearStateProgram = pragma + program + switch program := tx.ClearStateProgram.(type) { + case nil: + tx.ClearStateProgram = tx.ApprovalProgram + case string: + if program != "" && !strings.Contains(program, "#pragma version") { + pragma := fmt.Sprintf("#pragma version %d\n", params.LogicSigVersion) + tx.ClearStateProgram = pragma + program + } + case []byte: } - case []byte: } + } } diff --git a/ledger/acctdeltas.go b/ledger/acctdeltas.go index 42d5d93b2f..9071b4009b 100644 --- a/ledger/acctdeltas.go +++ b/ledger/acctdeltas.go @@ -1013,15 +1013,15 @@ func onlineAccountsNewRoundImpl( } updatedAccounts = append(updatedAccounts, updated) prevAcct = updated - } else if !newAcct.IsVotingEmpty() { + } else if !newAcct.IsVotingEmpty() && newStatus != basics.Suspended { err = fmt.Errorf("non-empty voting data for non-online account %s: %v", data.address.String(), newAcct) return nil, err } } } else { // non-zero rowid means we had a previous value. - if newAcct.IsVotingEmpty() { - // new value is zero then go offline + if newAcct.IsVotingEmpty() || newStatus == basics.Suspended { + // new value is zero, or the account is suspended then go offline if newStatus == basics.Online { err = fmt.Errorf("empty voting data but online account %s: %v", data.address.String(), newAcct) return nil, err diff --git a/ledger/acctdeltas_test.go b/ledger/acctdeltas_test.go index bf4bd6e399..57da3c4983 100644 --- a/ledger/acctdeltas_test.go +++ b/ledger/acctdeltas_test.go @@ -74,7 +74,7 @@ func checkAccounts(t *testing.T, tx trackerdb.TransactionScope, rnd basics.Round switch d.Status { case basics.Online: totalOnline += d.MicroAlgos.Raw - case basics.Offline: + case basics.Offline, basics.Suspended: totalOffline += d.MicroAlgos.Raw case basics.NotParticipating: totalNotPart += d.MicroAlgos.Raw diff --git a/ledger/acctupdates_test.go b/ledger/acctupdates_test.go index 1f3ca086a2..2e5df4e0ee 100644 --- a/ledger/acctupdates_test.go +++ b/ledger/acctupdates_test.go @@ -396,7 +396,7 @@ func checkAcctUpdates(t *testing.T, au *accountUpdates, ao *onlineAccounts, base case basics.Online: totalOnline += d.MicroAlgos.Raw totalOnline += (d.MicroAlgos.Raw / proto.RewardUnit) * rewardsDelta - case basics.Offline: + case basics.Offline, basics.Suspended: totalOffline += d.MicroAlgos.Raw totalOffline += (d.MicroAlgos.Raw / proto.RewardUnit) * rewardsDelta case basics.NotParticipating: diff --git a/ledger/apply/keyreg.go b/ledger/apply/keyreg.go index 206ff31bf3..81a33d4bb5 100644 --- a/ledger/apply/keyreg.go +++ b/ledger/apply/keyreg.go @@ -77,6 +77,9 @@ func Keyreg(keyreg transactions.KeyregTxnFields, header transactions.Header, bal } } record.Status = basics.Online + if params.EnableAbsenteeTracking() { + record.LastHeartbeat = header.FirstValid + } record.VoteFirstValid = keyreg.VoteFirst record.VoteLastValid = keyreg.VoteLast record.VoteKeyDilution = keyreg.VoteKeyDilution diff --git a/ledger/eval/eval.go b/ledger/eval/eval.go index c8450886f0..e99a7c7987 100644 --- a/ledger/eval/eval.go +++ b/ledger/eval/eval.go @@ -783,6 +783,7 @@ func StartEvaluator(l LedgerForEvaluator, hdr bookkeeping.BlockHeader, evalOpts return nil, fmt.Errorf("overflowed subtracting rewards for block %v", hdr.Round) } + // Pay the previous proposer miningIncentive, _ := basics.NewPercent(proto.MiningPercent).DivvyAlgos(prevHeader.FeesCollected) err = eval.state.Move(prevHeader.FeeSink, prevHeader.Proposer, miningIncentive, nil, nil) if err != nil { @@ -790,6 +791,17 @@ func StartEvaluator(l LedgerForEvaluator, hdr bookkeeping.BlockHeader, evalOpts return nil, fmt.Errorf("unable to Move mining incentive") } + // Note their proposal + prp, err := eval.state.Get(prevHeader.Proposer, false) + if err != nil { + return nil, err + } + prp.LastProposed = hdr.Round - 1 + err = eval.state.Put(prevHeader.Proposer, prp) + if err != nil { + return nil, err + } + if eval.Tracer != nil { eval.Tracer.BeforeBlock(&eval.block.BlockHeader) } @@ -1293,7 +1305,7 @@ func (eval *BlockEvaluator) endOfBlock() error { eval.block.FeesCollected = eval.state.feesCollected } - eval.generateExpiredOnlineAccountsList() + eval.generateKnockOfflineAccountsList() if eval.proto.StateProofInterval > 0 { var basicStateProof bookkeeping.StateProofTrackingData @@ -1392,9 +1404,10 @@ func (eval *BlockEvaluator) endOfBlock() error { return nil } -// generateExpiredOnlineAccountsList creates the list of the expired participation accounts by traversing over the -// modified accounts in the state deltas and testing if any of them needs to be reset. -func (eval *BlockEvaluator) generateExpiredOnlineAccountsList() { +// generateKnockOfflineAccountsList creates the lists of expired or absent +// participation accounts by traversing over the modified accounts in the state +// deltas and testing if any of them needs to be reset/suspended. +func (eval *BlockEvaluator) generateKnockOfflineAccountsList() { if !eval.generate { return } @@ -1403,28 +1416,47 @@ func (eval *BlockEvaluator) generateExpiredOnlineAccountsList() { // Then we are going to go through each modified account and // see if it meets the criteria for adding it to the expired // participation accounts list. - modifiedAccounts := eval.state.modifiedAccounts() currentRound := eval.Round() expectedMaxNumberOfExpiredAccounts := eval.proto.MaxProposedExpiredOnlineAccounts + expectedMaxNumberOfAbsentAccounts := eval.proto.MaxProposedAbsentOnlineAccounts - for i := 0; i < len(modifiedAccounts) && len(eval.block.ParticipationUpdates.ExpiredParticipationAccounts) < expectedMaxNumberOfExpiredAccounts; i++ { - accountAddr := modifiedAccounts[i] + updates := &eval.block.ParticipationUpdates + + for _, accountAddr := range eval.state.modifiedAccounts() { acctDelta, found := eval.state.mods.Accts.GetData(accountAddr) if !found { continue } - // true if the account is online - isOnline := acctDelta.Status == basics.Online - // true if the accounts last valid round has passed - pastCurrentRound := acctDelta.VoteLastValid < currentRound + if acctDelta.Status == basics.Online || acctDelta.Status == basics.Suspended { + expiresBeforeCurrent := acctDelta.VoteLastValid < currentRound + if expiresBeforeCurrent && + len(updates.ExpiredParticipationAccounts) < expectedMaxNumberOfExpiredAccounts { + updates.ExpiredParticipationAccounts = append( + updates.ExpiredParticipationAccounts, + accountAddr, + ) + continue // if marking expired, do not also suspend + } + } - if isOnline && pastCurrentRound { - eval.block.ParticipationUpdates.ExpiredParticipationAccounts = append( - eval.block.ParticipationUpdates.ExpiredParticipationAccounts, - accountAddr, - ) + if acctDelta.Status == basics.Online { + // TODO: 1000 rounds is obviously a placeholder. Probably needs to + // be something like 10x the "expected" interval. Further + // complications: (1) At keyreg, LastProposed=0 (or is old). (2) + // Accounts should be allowed to "heartbeat" to stay online. (3) + // "Expected" interval varies with balance and onlinestake. + allowableLag := basics.Round(1000) + absent := acctDelta.LastProposed+allowableLag < currentRound && + acctDelta.LastHeartbeat+allowableLag < currentRound + if absent && + len(updates.AbsentParticipationAccounts) < expectedMaxNumberOfAbsentAccounts { + updates.AbsentParticipationAccounts = append( + updates.AbsentParticipationAccounts, + accountAddr, + ) + } } } } @@ -1449,7 +1481,7 @@ func (eval *BlockEvaluator) validateExpiredOnlineAccounts() error { // are unique. We make this map to keep track of previously seen address addressSet := make(map[basics.Address]bool, lengthOfExpiredParticipationAccounts) - // Validate that all expired accounts meet the current criteria + // Validate that all proposed accounts have expired keys currentRound := eval.Round() for _, accountAddr := range eval.block.ParticipationUpdates.ExpiredParticipationAccounts { @@ -1466,22 +1498,68 @@ func (eval *BlockEvaluator) validateExpiredOnlineAccounts() error { return fmt.Errorf("endOfBlock was unable to retrieve account %v : %w", accountAddr, err) } - // true if the account is online - isOnline := acctData.Status == basics.Online - // true if the accounts last valid round has passed - pastCurrentRound := acctData.VoteLastValid < currentRound - - if !isOnline { + if acctData.Status != basics.Online && acctData.Status != basics.Suspended { return fmt.Errorf("endOfBlock found %v was not online but %v", accountAddr, acctData.Status) } - if !pastCurrentRound { + if acctData.VoteLastValid >= currentRound { return fmt.Errorf("endOfBlock found %v round (%d) was not less than current round (%d)", accountAddr, acctData.VoteLastValid, currentRound) } } return nil } +// validateAbsentOnlineAccounts tests the accounts specified in +// AbsentParticipationAccounts, and verifies that they need to be reset. +func (eval *BlockEvaluator) validateAbsentOnlineAccounts() error { + if !eval.validate { + return nil + } + expectedMaxNumberOfAbsentAccounts := eval.proto.MaxProposedAbsentOnlineAccounts + lengthOfAbsentParticipationAccounts := len(eval.block.ParticipationUpdates.AbsentParticipationAccounts) + + // If the length of the array is strictly greater than our max then we have an error. + // This works when the expected number of accounts is zero (i.e. it is disabled) as well + if lengthOfAbsentParticipationAccounts > expectedMaxNumberOfAbsentAccounts { + return fmt.Errorf("length of absent accounts (%d) was greater than expected (%d)", + lengthOfAbsentParticipationAccounts, expectedMaxNumberOfAbsentAccounts) + } + + // For consistency with expired account handling, we preclude duplicates + addressSet := make(map[basics.Address]bool, lengthOfAbsentParticipationAccounts) + + // Validate that all accounts have been absent + currentRound := eval.Round() + for _, accountAddr := range eval.block.ParticipationUpdates.AbsentParticipationAccounts { + + if _, exists := addressSet[accountAddr]; exists { + return fmt.Errorf("duplicate address found: %v", accountAddr) + } + addressSet[accountAddr] = true + + acctData, err := eval.state.lookup(accountAddr) + if err != nil { + return fmt.Errorf("unable to retrieve proposed absent account %v : %w", accountAddr, err) + } + + if acctData.Status != basics.Online { + return fmt.Errorf("proposed absent acct %v was not online but %v", accountAddr, acctData.Status) + } + + // TODO: 1000 rounds is obviously a placeholder. Probably needs to be + // something like 10x the "expected" interval. Further complications: + // (1) At first keyreg, LastProposed=0. (2) Accounts should be allowed + // to "heartbeat" to stay online. + allowableLag := basics.Round(1000) + if acctData.LastProposed+allowableLag >= currentRound || + acctData.LastHeartbeat+allowableLag >= currentRound { + return fmt.Errorf("proposed absent account %v is not absent in %d, %d", + accountAddr, acctData.LastProposed, acctData.LastHeartbeat) + } + } + return nil +} + // resetExpiredOnlineAccountsParticipationKeys after all transactions and rewards are processed, modify the accounts so that their status is offline func (eval *BlockEvaluator) resetExpiredOnlineAccountsParticipationKeys() error { expectedMaxNumberOfExpiredAccounts := eval.proto.MaxProposedExpiredOnlineAccounts @@ -1512,6 +1590,24 @@ func (eval *BlockEvaluator) resetExpiredOnlineAccountsParticipationKeys() error return nil } +// suspendAbsentAccounts suspends the proposed list of absent accounts. +func (eval *BlockEvaluator) suspendAbsentAccounts() error { + for _, addr := range eval.block.ParticipationUpdates.AbsentParticipationAccounts { + acct, err := eval.state.lookup(addr) + if err != nil { + return err + } + + acct.Suspend() + + err = eval.state.putAccount(addr, acct) + if err != nil { + return err + } + } + return nil +} + // GenerateBlock produces a complete block from the BlockEvaluator. This is // used during proposal to get an actual block that will be proposed, after // feeding in tentative transactions into this block evaluator. diff --git a/ledger/eval_simple_test.go b/ledger/eval_simple_test.go index 86269cabd5..4f929df2c3 100644 --- a/ledger/eval_simple_test.go +++ b/ledger/eval_simple_test.go @@ -272,6 +272,73 @@ func TestMiningFees(t *testing.T) { }) } +// TestAbsentTracking checks that LastProposed and LastHeartbeat are updated +// properly. +func TestAbsentTracking(t *testing.T) { + partitiontest.PartitionTest(t) + t.Parallel() + + genBalances, addrs, _ := ledgertesting.NewTestGenesis() + // Absentee checking begins in v39. Start checking in v38 to test that is unchanged. + ledgertesting.TestConsensusRange(t, 38, 0, func(t *testing.T, ver int, cv protocol.ConsensusVersion, cfg config.Local) { + dl := NewDoubleLedger(t, genBalances, cv, cfg) + defer dl.Close() + + dl.fullBlock() + + pay := txntest.Txn{ + Type: "pay", + Sender: addrs[1], + Receiver: addrs[2], + Amount: 100000, + } + + proposer := addrs[7] + dl.beginBlock() + dl.txns(&pay) + dl.endBlock(proposer) + + dl.fullBlock() + + prp := lookup(t, dl.validator, proposer) + + if ver >= 39 { + // version sanity check + require.True(t, dl.generator.GenesisProto().EnableAbsenteeTracking()) + require.NotZero(t, prp.LastProposed) + require.Zero(t, prp.LastHeartbeat) // genesis participants have never hb + } else { + require.False(t, dl.generator.GenesisProto().EnableAbsenteeTracking()) + require.Zero(t, prp.LastProposed) + require.Zero(t, prp.LastHeartbeat) + } + + dl.txns(&txntest.Txn{Type: "keyreg", Sender: addrs[1]}) // OFFLINE keyreg + regger := lookup(t, dl.validator, addrs[1]) + + // offline transaction records nothing + require.Zero(t, regger.LastProposed) + require.Zero(t, regger.LastHeartbeat) + + // ONLINE keyreg + dl.txns(&txntest.Txn{ + Type: "keyreg", + Sender: addrs[1], + VotePK: [32]byte{1}, + SelectionPK: [32]byte{1}, + }) + regger = lookup(t, dl.validator, addrs[1]) + + if ver >= 39 { + require.Zero(t, regger.LastProposed) + require.NotZero(t, regger.LastHeartbeat) // online keyreg caused update + } else { + require.Zero(t, regger.LastProposed) + require.Zero(t, regger.LastHeartbeat) + } + }) +} + // TestHoldingGet tests some of the corner cases for the asset_holding_get // opcode: the asset doesn't exist, the account doesn't exist, account not opted // in, vs it has none of the asset. This is tested here, even though it should diff --git a/ledger/ledgercore/accountdata.go b/ledger/ledgercore/accountdata.go index 69e2c543eb..4efe905563 100644 --- a/ledger/ledgercore/accountdata.go +++ b/ledger/ledgercore/accountdata.go @@ -48,6 +48,9 @@ type AccountBaseData struct { TotalAssets uint64 // Total of asset creations and optins (i.e. number of holdings) TotalBoxes uint64 // Total number of boxes associated to this account TotalBoxBytes uint64 // Total bytes for this account's boxes. keys _and_ values count + + LastProposed basics.Round // The last round that this account proposed the winning block. + LastHeartbeat basics.Round // The last round that this account sent a heartbeat to show it was online. } // VotingData holds participation information @@ -86,6 +89,9 @@ func ToAccountData(acct basics.AccountData) AccountData { TotalAppLocalStates: uint64(len(acct.AppLocalStates)), TotalBoxes: acct.TotalBoxes, TotalBoxBytes: acct.TotalBoxBytes, + + LastProposed: acct.LastProposed, + LastHeartbeat: acct.LastHeartbeat, }, VotingData: VotingData{ VoteID: acct.VoteID, @@ -118,6 +124,9 @@ func AssignAccountData(a *basics.AccountData, acct AccountData) { a.TotalExtraAppPages = acct.TotalExtraAppPages a.TotalBoxes = acct.TotalBoxes a.TotalBoxBytes = acct.TotalBoxBytes + + a.LastProposed = acct.LastProposed + a.LastHeartbeat = acct.LastHeartbeat } // WithUpdatedRewards calls basics account data WithUpdatedRewards @@ -134,6 +143,12 @@ func (u *AccountData) ClearOnlineState() { u.VotingData = VotingData{} } +// Suspend sets the status to Suspended, but does _not_ clear voting keys, so +// that a heartbeat can bring the account back Online +func (u *AccountData) Suspend() { + u.Status = basics.Suspended +} + // MinBalance computes the minimum balance requirements for an account based on // some consensus parameters. MinBalance should correspond roughly to how much // storage the account is allowed to store on disk. diff --git a/ledger/ledgercore/totals.go b/ledger/ledgercore/totals.go index 904cac9114..a38393ab03 100644 --- a/ledger/ledgercore/totals.go +++ b/ledger/ledgercore/totals.go @@ -66,7 +66,7 @@ func (at *AccountTotals) statusField(status basics.Status) *AlgoCount { switch status { case basics.Online: return &at.Online - case basics.Offline: + case basics.Offline, basics.Suspended: return &at.Offline case basics.NotParticipating: return &at.NotParticipating diff --git a/ledger/simple_test.go b/ledger/simple_test.go index efe81bfc87..3d9f1ad0aa 100644 --- a/ledger/simple_test.go +++ b/ledger/simple_test.go @@ -101,6 +101,9 @@ func fillDefaults(t testing.TB, ledger *Ledger, eval *eval.BlockEvaluator, txn * if txn.FirstValid == 0 { txn.FirstValid = eval.Round() } + if txn.Type == protocol.KeyRegistrationTx && txn.VoteFirst == 0 { + txn.VoteFirst = eval.Round() + } txn.FillDefaults(ledger.GenesisProto()) } diff --git a/ledger/store/trackerdb/data.go b/ledger/store/trackerdb/data.go index 264c055821..3823864ddc 100644 --- a/ledger/store/trackerdb/data.go +++ b/ledger/store/trackerdb/data.go @@ -48,6 +48,9 @@ type BaseAccountData struct { TotalBoxes uint64 `codec:"m"` TotalBoxBytes uint64 `codec:"n"` + LastProposed basics.Round `codec:"o"` + LastHeartbeat basics.Round `codec:"p"` + BaseVotingData // UpdateRound is the round that modified this account data last. Since we want all the nodes to have the exact same @@ -287,6 +290,9 @@ func (ba *BaseAccountData) SetCoreAccountData(ad *ledgercore.AccountData) { ba.TotalBoxes = ad.TotalBoxes ba.TotalBoxBytes = ad.TotalBoxBytes + ba.LastProposed = ad.LastProposed + ba.LastHeartbeat = ad.LastHeartbeat + ba.BaseVotingData.SetCoreAccountData(ad) } @@ -307,6 +313,9 @@ func (ba *BaseAccountData) SetAccountData(ad *basics.AccountData) { ba.TotalBoxes = ad.TotalBoxes ba.TotalBoxBytes = ad.TotalBoxBytes + ba.LastProposed = ad.LastProposed + ba.LastHeartbeat = ad.LastHeartbeat + ba.BaseVotingData.VoteID = ad.VoteID ba.BaseVotingData.SelectionID = ad.SelectionID ba.BaseVotingData.StateProofID = ad.StateProofID @@ -342,6 +351,9 @@ func (ba *BaseAccountData) GetLedgerCoreAccountBaseData() ledgercore.AccountBase TotalAssets: ba.TotalAssets, TotalBoxes: ba.TotalBoxes, TotalBoxBytes: ba.TotalBoxBytes, + + LastProposed: ba.LastProposed, + LastHeartbeat: ba.LastHeartbeat, } } @@ -379,6 +391,9 @@ func (ba *BaseAccountData) GetAccountData() basics.AccountData { VoteFirstValid: ba.VoteFirstValid, VoteLastValid: ba.VoteLastValid, VoteKeyDilution: ba.VoteKeyDilution, + + LastProposed: ba.LastProposed, + LastHeartbeat: ba.LastHeartbeat, } } @@ -398,6 +413,8 @@ func (ba *BaseAccountData) IsEmpty() bool { ba.TotalAppLocalStates == 0 && ba.TotalBoxes == 0 && ba.TotalBoxBytes == 0 && + ba.LastProposed == 0 && + ba.LastHeartbeat == 0 && ba.BaseVotingData.IsEmpty() } @@ -421,7 +438,7 @@ func (bo *BaseOnlineAccountData) IsVotingEmpty() bool { return bo.BaseVotingData.IsEmpty() } -// IsEmpty return true if any of the fields are non-zero. +// IsEmpty return true if all of the fields are zero. func (bo *BaseOnlineAccountData) IsEmpty() bool { return bo.IsVotingEmpty() && bo.MicroAlgos.Raw == 0 && diff --git a/ledger/store/trackerdb/data_test.go b/ledger/store/trackerdb/data_test.go index fe253304fd..f6adeec983 100644 --- a/ledger/store/trackerdb/data_test.go +++ b/ledger/store/trackerdb/data_test.go @@ -1105,7 +1105,7 @@ func TestBaseAccountDataIsEmpty(t *testing.T) { structureTesting := func(t *testing.T) { encoding, err := json.Marshal(&empty) zeros32 := "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" - expectedEncoding := `{"Status":0,"MicroAlgos":{"Raw":0},"RewardsBase":0,"RewardedMicroAlgos":{"Raw":0},"AuthAddr":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ","TotalAppSchemaNumUint":0,"TotalAppSchemaNumByteSlice":0,"TotalExtraAppPages":0,"TotalAssetParams":0,"TotalAssets":0,"TotalAppParams":0,"TotalAppLocalStates":0,"TotalBoxes":0,"TotalBoxBytes":0,"VoteID":[` + zeros32 + `],"SelectionID":[` + zeros32 + `],"VoteFirstValid":0,"VoteLastValid":0,"VoteKeyDilution":0,"StateProofID":[` + zeros32 + `,` + zeros32 + `],"UpdateRound":0}` + expectedEncoding := `{"Status":0,"MicroAlgos":{"Raw":0},"RewardsBase":0,"RewardedMicroAlgos":{"Raw":0},"AuthAddr":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ","TotalAppSchemaNumUint":0,"TotalAppSchemaNumByteSlice":0,"TotalExtraAppPages":0,"TotalAssetParams":0,"TotalAssets":0,"TotalAppParams":0,"TotalAppLocalStates":0,"TotalBoxes":0,"TotalBoxBytes":0,"LastProposed":0,"LastHeartbeat":0,"VoteID":[` + zeros32 + `],"SelectionID":[` + zeros32 + `],"VoteFirstValid":0,"VoteLastValid":0,"VoteKeyDilution":0,"StateProofID":[` + zeros32 + `,` + zeros32 + `],"UpdateRound":0}` require.NoError(t, err) require.Equal(t, expectedEncoding, string(encoding)) } diff --git a/ledger/store/trackerdb/msgp_gen.go b/ledger/store/trackerdb/msgp_gen.go index a13469c0ab..576f9ff0d6 100644 --- a/ledger/store/trackerdb/msgp_gen.go +++ b/ledger/store/trackerdb/msgp_gen.go @@ -100,8 +100,8 @@ import ( func (z *BaseAccountData) MarshalMsg(b []byte) (o []byte) { o = msgp.Require(b, z.Msgsize()) // omitempty: check for empty values - zb0001Len := uint32(21) - var zb0001Mask uint32 /* 23 bits */ + zb0001Len := uint32(23) + var zb0001Mask uint32 /* 25 bits */ if (*z).BaseVotingData.VoteID.MsgIsZero() { zb0001Len-- zb0001Mask |= 0x1 @@ -182,10 +182,18 @@ func (z *BaseAccountData) MarshalMsg(b []byte) (o []byte) { zb0001Len-- zb0001Mask |= 0x200000 } - if (*z).UpdateRound == 0 { + if (*z).LastProposed.MsgIsZero() { zb0001Len-- zb0001Mask |= 0x400000 } + if (*z).LastHeartbeat.MsgIsZero() { + zb0001Len-- + zb0001Mask |= 0x800000 + } + if (*z).UpdateRound == 0 { + zb0001Len-- + zb0001Mask |= 0x1000000 + } // variable map header, size zb0001Len o = msgp.AppendMapHeader(o, zb0001Len) if zb0001Len != 0 { @@ -290,6 +298,16 @@ func (z *BaseAccountData) MarshalMsg(b []byte) (o []byte) { o = msgp.AppendUint64(o, (*z).TotalBoxBytes) } if (zb0001Mask & 0x400000) == 0 { // if not empty + // string "o" + o = append(o, 0xa1, 0x6f) + o = (*z).LastProposed.MarshalMsg(o) + } + if (zb0001Mask & 0x800000) == 0 { // if not empty + // string "p" + o = append(o, 0xa1, 0x70) + o = (*z).LastHeartbeat.MarshalMsg(o) + } + if (zb0001Mask & 0x1000000) == 0 { // if not empty // string "z" o = append(o, 0xa1, 0x7a) o = msgp.AppendUint64(o, (*z).UpdateRound) @@ -433,6 +451,22 @@ func (z *BaseAccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalSta return } } + if zb0001 > 0 { + zb0001-- + bts, err = (*z).LastProposed.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "LastProposed") + return + } + } + if zb0001 > 0 { + zb0001-- + bts, err = (*z).LastHeartbeat.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "LastHeartbeat") + return + } + } if zb0001 > 0 { zb0001-- bts, err = (*z).BaseVotingData.VoteID.UnmarshalMsgWithState(bts, st) @@ -596,6 +630,18 @@ func (z *BaseAccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalSta err = msgp.WrapError(err, "TotalBoxBytes") return } + case "o": + bts, err = (*z).LastProposed.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "LastProposed") + return + } + case "p": + bts, err = (*z).LastHeartbeat.UnmarshalMsgWithState(bts, st) + if err != nil { + err = msgp.WrapError(err, "LastHeartbeat") + return + } case "A": bts, err = (*z).BaseVotingData.VoteID.UnmarshalMsgWithState(bts, st) if err != nil { @@ -661,18 +707,18 @@ func (_ *BaseAccountData) CanUnmarshalMsg(z interface{}) bool { // Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message func (z *BaseAccountData) Msgsize() (s int) { - s = 3 + 2 + (*z).Status.Msgsize() + 2 + (*z).MicroAlgos.Msgsize() + 2 + msgp.Uint64Size + 2 + (*z).RewardedMicroAlgos.Msgsize() + 2 + (*z).AuthAddr.Msgsize() + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint32Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + (*z).BaseVotingData.VoteID.Msgsize() + 2 + (*z).BaseVotingData.SelectionID.Msgsize() + 2 + (*z).BaseVotingData.VoteFirstValid.Msgsize() + 2 + (*z).BaseVotingData.VoteLastValid.Msgsize() + 2 + msgp.Uint64Size + 2 + (*z).BaseVotingData.StateProofID.Msgsize() + 2 + msgp.Uint64Size + s = 3 + 2 + (*z).Status.Msgsize() + 2 + (*z).MicroAlgos.Msgsize() + 2 + msgp.Uint64Size + 2 + (*z).RewardedMicroAlgos.Msgsize() + 2 + (*z).AuthAddr.Msgsize() + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint32Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + (*z).LastProposed.Msgsize() + 2 + (*z).LastHeartbeat.Msgsize() + 2 + (*z).BaseVotingData.VoteID.Msgsize() + 2 + (*z).BaseVotingData.SelectionID.Msgsize() + 2 + (*z).BaseVotingData.VoteFirstValid.Msgsize() + 2 + (*z).BaseVotingData.VoteLastValid.Msgsize() + 2 + msgp.Uint64Size + 2 + (*z).BaseVotingData.StateProofID.Msgsize() + 2 + msgp.Uint64Size return } // MsgIsZero returns whether this is a zero value func (z *BaseAccountData) MsgIsZero() bool { - return ((*z).Status.MsgIsZero()) && ((*z).MicroAlgos.MsgIsZero()) && ((*z).RewardsBase == 0) && ((*z).RewardedMicroAlgos.MsgIsZero()) && ((*z).AuthAddr.MsgIsZero()) && ((*z).TotalAppSchemaNumUint == 0) && ((*z).TotalAppSchemaNumByteSlice == 0) && ((*z).TotalExtraAppPages == 0) && ((*z).TotalAssetParams == 0) && ((*z).TotalAssets == 0) && ((*z).TotalAppParams == 0) && ((*z).TotalAppLocalStates == 0) && ((*z).TotalBoxes == 0) && ((*z).TotalBoxBytes == 0) && ((*z).BaseVotingData.VoteID.MsgIsZero()) && ((*z).BaseVotingData.SelectionID.MsgIsZero()) && ((*z).BaseVotingData.VoteFirstValid.MsgIsZero()) && ((*z).BaseVotingData.VoteLastValid.MsgIsZero()) && ((*z).BaseVotingData.VoteKeyDilution == 0) && ((*z).BaseVotingData.StateProofID.MsgIsZero()) && ((*z).UpdateRound == 0) + return ((*z).Status.MsgIsZero()) && ((*z).MicroAlgos.MsgIsZero()) && ((*z).RewardsBase == 0) && ((*z).RewardedMicroAlgos.MsgIsZero()) && ((*z).AuthAddr.MsgIsZero()) && ((*z).TotalAppSchemaNumUint == 0) && ((*z).TotalAppSchemaNumByteSlice == 0) && ((*z).TotalExtraAppPages == 0) && ((*z).TotalAssetParams == 0) && ((*z).TotalAssets == 0) && ((*z).TotalAppParams == 0) && ((*z).TotalAppLocalStates == 0) && ((*z).TotalBoxes == 0) && ((*z).TotalBoxBytes == 0) && ((*z).LastProposed.MsgIsZero()) && ((*z).LastHeartbeat.MsgIsZero()) && ((*z).BaseVotingData.VoteID.MsgIsZero()) && ((*z).BaseVotingData.SelectionID.MsgIsZero()) && ((*z).BaseVotingData.VoteFirstValid.MsgIsZero()) && ((*z).BaseVotingData.VoteLastValid.MsgIsZero()) && ((*z).BaseVotingData.VoteKeyDilution == 0) && ((*z).BaseVotingData.StateProofID.MsgIsZero()) && ((*z).UpdateRound == 0) } // MaxSize returns a maximum valid message size for this message type func BaseAccountDataMaxSize() (s int) { - s = 3 + 2 + basics.StatusMaxSize() + 2 + basics.MicroAlgosMaxSize() + 2 + msgp.Uint64Size + 2 + basics.MicroAlgosMaxSize() + 2 + basics.AddressMaxSize() + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint32Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + crypto.OneTimeSignatureVerifierMaxSize() + 2 + crypto.VRFVerifierMaxSize() + 2 + basics.RoundMaxSize() + 2 + basics.RoundMaxSize() + 2 + msgp.Uint64Size + 2 + merklesignature.CommitmentMaxSize() + 2 + msgp.Uint64Size + s = 3 + 2 + basics.StatusMaxSize() + 2 + basics.MicroAlgosMaxSize() + 2 + msgp.Uint64Size + 2 + basics.MicroAlgosMaxSize() + 2 + basics.AddressMaxSize() + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint32Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + basics.RoundMaxSize() + 2 + basics.RoundMaxSize() + 2 + crypto.OneTimeSignatureVerifierMaxSize() + 2 + crypto.VRFVerifierMaxSize() + 2 + basics.RoundMaxSize() + 2 + basics.RoundMaxSize() + 2 + msgp.Uint64Size + 2 + merklesignature.CommitmentMaxSize() + 2 + msgp.Uint64Size return } diff --git a/ledger/testing/randomAccounts.go b/ledger/testing/randomAccounts.go index fd4f3b4158..b3571c3885 100644 --- a/ledger/testing/randomAccounts.go +++ b/ledger/testing/randomAccounts.go @@ -64,16 +64,23 @@ func RandomAccountData(rewardsBase uint64) basics.AccountData { // Avoid overflowing totals data.MicroAlgos.Raw = crypto.RandUint64() % (1 << 32) + // 0 is an invalid round, but would be right if never proposed + data.LastProposed = basics.Round(crypto.RandUint64() % 100) + // 0 is an invalid round, but would be right if never needed a heartbeat + data.LastHeartbeat = basics.Round(crypto.RandUint64() % 100) - switch crypto.RandUint64() % 3 { + switch crypto.RandUint64() % 4 { case 0: data.Status = basics.Online data.VoteLastValid = 10000 case 1: data.Status = basics.Offline data.VoteLastValid = 0 - default: + case 2: data.Status = basics.NotParticipating + case 3: + data.Status = basics.Suspended + data.VoteLastValid = basics.Round(crypto.RandUint64() % 10000) } data.VoteFirstValid = 0 @@ -268,14 +275,15 @@ func RandomAppLocalState() basics.AppLocalState { func RandomFullAccountData(rewardsLevel uint64, lastCreatableID *basics.CreatableIndex, assets map[basics.AssetIndex]struct{}, apps map[basics.AppIndex]struct{}) basics.AccountData { data := RandomAccountData(rewardsLevel) - if data.Status == basics.Online { + switch data.Status { + case basics.Online, basics.Suspended: crypto.RandBytes(data.VoteID[:]) crypto.RandBytes(data.SelectionID[:]) crypto.RandBytes(data.StateProofID[:]) data.VoteFirstValid = basics.Round(crypto.RandUint64()) data.VoteLastValid = basics.Round(crypto.RandUint64() % uint64(math.MaxInt64)) // int64 is the max sqlite can store data.VoteKeyDilution = crypto.RandUint64() - } else { + case basics.Offline, basics.NotParticipating: data.VoteID = crypto.OneTimeSignatureVerifier{} data.SelectionID = crypto.VRFVerifier{} data.StateProofID = merklesignature.Commitment{} diff --git a/test/scripts/e2e_subs/absentee.py b/test/scripts/e2e_subs/absentee.py new file mode 100755 index 0000000000..f889a4ff35 --- /dev/null +++ b/test/scripts/e2e_subs/absentee.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python + +import base64 +import os +import sys +from goal import Goal +import algosdk.encoding as enc + +from datetime import datetime + +stamp = datetime.now().strftime("%Y%m%d_%H%M%S") +print(f"{os.path.basename(sys.argv[0])} start {stamp}") + +goal = Goal(sys.argv[1], autosend=True) + +joe = goal.new_account() + +txinfo, err = goal.pay(goal.account, joe, amt=500_000) +assert not err, err + +# Joe is a brand new account, it has neither proposed nor heartbeat +joe_info = goal.algod.account_info(joe) +assert "last-proposed" not in joe_info, joe_info +assert "last-heartbeat" not in joe_info, joe_info + +# Find info on the proposer of the pay block +pblock = goal.algod.block_info(txinfo['confirmed-round'])['block'] +assert pblock["prp"] != "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ" +prp_info = goal.algod.account_info(pblock["prp"]) +assert "last-proposed" in prp_info, prp_info # they just did! +assert prp_info["last-proposed"] > 0 +assert "last-heartbeat" not in prp_info, prp_info # was a genesis account + +stamp = datetime.now().strftime("%Y%m%d_%H%M%S") +print(f"{os.path.basename(sys.argv[0])} OK {stamp}") From 0ddfec4004131f76f6be671e48602e1c32c9a6e0 Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Tue, 3 Oct 2023 11:36:20 -0400 Subject: [PATCH 5/9] Make migrate use VoteID.IsEmpty() instead of basics.Offline Also changes to use IsEmpty() as much as possible --- config/consensus.go | 2 ++ crypto/onetimesig.go | 5 +++++ crypto/vrf.go | 5 +++++ daemon/algod/api/server/v2/account.go | 2 +- daemon/algod/api/server/v2/handlers.go | 2 +- data/transactions/transaction.go | 8 ++++---- ledger/apply/keyreg.go | 3 +-- ledger/store/trackerdb/sqlitedriver/schema.go | 5 +++-- 8 files changed, 22 insertions(+), 10 deletions(-) diff --git a/config/consensus.go b/config/consensus.go index b9cb9df3ac..db526c34e5 100644 --- a/config/consensus.go +++ b/config/consensus.go @@ -535,6 +535,8 @@ type ConsensusParams struct { MiningPercent uint64 } +// EnableAbsenteeTracking returns true if the suspension mechanism of absentee +// accounts is enabled. func (cp ConsensusParams) EnableAbsenteeTracking() bool { return cp.MaxProposedAbsentOnlineAccounts > 0 } diff --git a/crypto/onetimesig.go b/crypto/onetimesig.go index 1de4854967..f85f8cca1a 100644 --- a/crypto/onetimesig.go +++ b/crypto/onetimesig.go @@ -304,6 +304,11 @@ func (s *OneTimeSignatureSecrets) Sign(id OneTimeSignatureIdentifier, message Ha return OneTimeSignature{} } +// IsEmpty returns true is the verifier is empty/zero'd. +func (v OneTimeSignatureVerifier) IsEmpty() bool { + return v == OneTimeSignatureVerifier{} +} + // Verify verifies that some Hashable signature was signed under some // OneTimeSignatureVerifier and some OneTimeSignatureIdentifier. // diff --git a/crypto/vrf.go b/crypto/vrf.go index 948a84ddc5..a9a8af68d5 100644 --- a/crypto/vrf.go +++ b/crypto/vrf.go @@ -134,6 +134,11 @@ func (pk VrfPubkey) verifyBytes(proof VrfProof, msg []byte) (bool, VrfOutput) { return ret == 0, out } +// IsEmpty returns true is the key is empty/zero'd. +func (pk VrfPubkey) IsEmpty() bool { + return pk == VrfPubkey{} +} + // Verify checks a VRF proof of a given Hashable. If the proof is valid the pseudorandom VrfOutput will be returned. // For a given public key and message, there are potentially multiple valid proofs. // However, given a public key and message, all valid proofs will yield the same output. diff --git a/daemon/algod/api/server/v2/account.go b/daemon/algod/api/server/v2/account.go index 875d9ed3f5..84045439a8 100644 --- a/daemon/algod/api/server/v2/account.go +++ b/daemon/algod/api/server/v2/account.go @@ -67,7 +67,7 @@ func AccountDataToAccount( }) var apiParticipation *model.AccountParticipation - if record.VoteID != (crypto.OneTimeSignatureVerifier{}) { + if !record.VoteID.IsEmpty() { apiParticipation = &model.AccountParticipation{ VoteParticipationKey: record.VoteID[:], SelectionParticipationKey: record.SelectionID[:], diff --git a/daemon/algod/api/server/v2/handlers.go b/daemon/algod/api/server/v2/handlers.go index f65ffe4995..c3e58c007a 100644 --- a/daemon/algod/api/server/v2/handlers.go +++ b/daemon/algod/api/server/v2/handlers.go @@ -494,7 +494,7 @@ func (v2 *Handlers) basicAccountInformation(ctx echo.Context, addr basics.Addres } var apiParticipation *model.AccountParticipation - if record.VoteID != (crypto.OneTimeSignatureVerifier{}) { + if !record.VoteID.IsEmpty() { apiParticipation = &model.AccountParticipation{ VoteParticipationKey: record.VoteID[:], SelectionParticipationKey: record.SelectionID[:], diff --git a/data/transactions/transaction.go b/data/transactions/transaction.go index 725f9d7ec2..17af770f12 100644 --- a/data/transactions/transaction.go +++ b/data/transactions/transaction.go @@ -365,8 +365,8 @@ func (tx Transaction) WellFormed(spec SpecialAddresses, proto config.ConsensusPa } // The trio of [VotePK, SelectionPK, VoteKeyDilution] needs to be all zeros or all non-zero for the transaction to be valid. - if !((tx.KeyregTxnFields.VotePK == crypto.OneTimeSignatureVerifier{} && tx.KeyregTxnFields.SelectionPK == crypto.VRFVerifier{} && tx.KeyregTxnFields.VoteKeyDilution == 0) || - (tx.KeyregTxnFields.VotePK != crypto.OneTimeSignatureVerifier{} && tx.KeyregTxnFields.SelectionPK != crypto.VRFVerifier{} && tx.KeyregTxnFields.VoteKeyDilution != 0)) { + if !((tx.KeyregTxnFields.VotePK.IsEmpty() && tx.KeyregTxnFields.SelectionPK.IsEmpty() && tx.KeyregTxnFields.VoteKeyDilution == 0) || + (!tx.KeyregTxnFields.VotePK.IsEmpty() && !tx.KeyregTxnFields.SelectionPK.IsEmpty() && tx.KeyregTxnFields.VoteKeyDilution != 0)) { return errKeyregTxnNonCoherentVotingKeys } @@ -395,7 +395,7 @@ func (tx Transaction) WellFormed(spec SpecialAddresses, proto config.ConsensusPa // that type of transaction, it is invalid. return errKeyregTxnUnsupportedSwitchToNonParticipating } - suppliesNullKeys := tx.KeyregTxnFields.VotePK == crypto.OneTimeSignatureVerifier{} || tx.KeyregTxnFields.SelectionPK == crypto.VRFVerifier{} + suppliesNullKeys := tx.KeyregTxnFields.VotePK.IsEmpty() || tx.KeyregTxnFields.SelectionPK.IsEmpty() if !suppliesNullKeys { return errKeyregTxnGoingOnlineWithNonParticipating } @@ -673,7 +673,7 @@ func (tx Transaction) stateProofPKWellFormed(proto config.ConsensusParams) error return nil } - if tx.VotePK == (crypto.OneTimeSignatureVerifier{}) || tx.SelectionPK == (crypto.VRFVerifier{}) { + if tx.VotePK.IsEmpty() || tx.SelectionPK.IsEmpty() { if !isEmpty { return errKeyregTxnOfflineShouldBeEmptyStateProofPK } diff --git a/ledger/apply/keyreg.go b/ledger/apply/keyreg.go index 81a33d4bb5..207fd440f0 100644 --- a/ledger/apply/keyreg.go +++ b/ledger/apply/keyreg.go @@ -20,7 +20,6 @@ import ( "errors" "fmt" - "github.com/algorand/go-algorand/crypto" "github.com/algorand/go-algorand/data/basics" "github.com/algorand/go-algorand/data/transactions" ) @@ -54,7 +53,7 @@ func Keyreg(keyreg transactions.KeyregTxnFields, header transactions.Header, bal if params.EnableStateProofKeyregCheck { record.StateProofID = keyreg.StateProofPK } - if (keyreg.VotePK == crypto.OneTimeSignatureVerifier{} || keyreg.SelectionPK == crypto.VRFVerifier{}) { + if keyreg.VotePK.IsEmpty() || keyreg.SelectionPK.IsEmpty() { if keyreg.Nonparticipation { if params.SupportBecomeNonParticipatingTransactions { record.Status = basics.NotParticipating diff --git a/ledger/store/trackerdb/sqlitedriver/schema.go b/ledger/store/trackerdb/sqlitedriver/schema.go index ea6f577868..66e4d9f220 100644 --- a/ledger/store/trackerdb/sqlitedriver/schema.go +++ b/ledger/store/trackerdb/sqlitedriver/schema.go @@ -734,8 +734,9 @@ func performOnlineAccountsTableMigration(ctx context.Context, e db.Executable, p } } - // remove stateproofID field for offline accounts - if ba.Status != basics.Online && !ba.StateProofID.IsEmpty() { + // We had a bug that didn't remove StateProofIDs when going offline. + // Tidy up such accounts. + if ba.VoteID.IsEmpty() && !ba.StateProofID.IsEmpty() { // store old data for account hash update state := acctState{old: ba, oldEnc: encodedAcctData} ba.StateProofID = merklesignature.Commitment{} From 5c0444a517dae3fe293b1521923963ef01211375 Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Tue, 3 Oct 2023 11:38:52 -0400 Subject: [PATCH 6/9] Improve random accounts, especially for basics.Suspended --- ledger/acctupdates_test.go | 19 ++++-- .../trackerdb/sqlitedriver/schema_test.go | 8 +-- ledger/testing/randomAccounts.go | 59 +++++++++---------- 3 files changed, 46 insertions(+), 40 deletions(-) diff --git a/ledger/acctupdates_test.go b/ledger/acctupdates_test.go index 2e5df4e0ee..f31d4fcae5 100644 --- a/ledger/acctupdates_test.go +++ b/ledger/acctupdates_test.go @@ -385,11 +385,16 @@ func checkAcctUpdates(t *testing.T, au *accountUpdates, ao *onlineAccounts, base // TODO: make lookupOnlineAccountData returning extended version of ledgercore.VotingData ? od, err := ao.lookupOnlineAccountData(rnd, addr) require.NoError(t, err) - require.Equal(t, od.VoteID, data.VoteID) - require.Equal(t, od.SelectionID, data.SelectionID) - require.Equal(t, od.VoteFirstValid, data.VoteFirstValid) - require.Equal(t, od.VoteLastValid, data.VoteLastValid) - require.Equal(t, od.VoteKeyDilution, data.VoteKeyDilution) + // Unless suspended an account's voting data should agree with + // the online account tracker. (Vaccuously true, when account is + // offline or non-part). + if data.Status != basics.Suspended { + require.Equal(t, od.VoteID, data.VoteID) + require.Equal(t, od.SelectionID, data.SelectionID) + require.Equal(t, od.VoteFirstValid, data.VoteFirstValid) + require.Equal(t, od.VoteLastValid, data.VoteLastValid) + require.Equal(t, od.VoteKeyDilution, data.VoteKeyDilution) + } rewardsDelta := rewards[rnd] - d.RewardsBase switch d.Status { @@ -504,6 +509,10 @@ func checkOnlineAcctUpdatesConsistency(t *testing.T, ao *onlineAccounts, rnd bas for i := 0; i < latest.Len(); i++ { addr, acct := latest.GetByIdx(i) od, err := ao.lookupOnlineAccountData(rnd, addr) + if acct.Status == basics.Suspended { + // suspended accounts will not match, since they have vote info but not in online accounts + continue + } require.NoError(t, err) require.Equal(t, acct.VoteID, od.VoteID) require.Equal(t, acct.SelectionID, od.SelectionID) diff --git a/ledger/store/trackerdb/sqlitedriver/schema_test.go b/ledger/store/trackerdb/sqlitedriver/schema_test.go index 581082447b..df5a9b02bd 100644 --- a/ledger/store/trackerdb/sqlitedriver/schema_test.go +++ b/ledger/store/trackerdb/sqlitedriver/schema_test.go @@ -176,7 +176,7 @@ func TestRemoveOfflineStateProofID(t *testing.T) { accts[addr] = acct expectedAcct := acct - if acct.Status != basics.Online { + if acct.Status != basics.Online && acct.Status != basics.Suspended { expectedAcct.StateProofID = merklesignature.Commitment{} } expectedAccts[addr] = expectedAcct @@ -211,7 +211,7 @@ func TestRemoveOfflineStateProofID(t *testing.T) { defer dbs.Close() defer tx.Rollback() - // make second copy of DB to prepare exepected/fixed merkle trie + // make second copy of DB to prepare expected/fixed merkle trie expectedDBs, expectedTx := buildDB(expectedAccts) defer expectedDBs.Close() defer expectedTx.Rollback() @@ -237,7 +237,7 @@ func TestRemoveOfflineStateProofID(t *testing.T) { var ba trackerdb.BaseAccountData err = protocol.Decode(encodedAcctData, &ba) require.NoError(t, err) - if expected && ba.Status != basics.Online { + if expected && (ba.Status != basics.Online && ba.Status != basics.Suspended) { require.Equal(t, merklesignature.Commitment{}, ba.StateProofID) } addHash := trackerdb.AccountHashBuilderV6(addr, &ba, encodedAcctData) @@ -287,7 +287,7 @@ func TestRemoveOfflineStateProofID(t *testing.T) { var ba trackerdb.BaseAccountData err = protocol.Decode(encodedAcctData, &ba) require.NoError(t, err) - if ba.Status != basics.Online { + if ba.Status != basics.Online && ba.Status != basics.Suspended { require.True(t, ba.StateProofID.IsEmpty()) } } diff --git a/ledger/testing/randomAccounts.go b/ledger/testing/randomAccounts.go index b3571c3885..e9ef1b2da4 100644 --- a/ledger/testing/randomAccounts.go +++ b/ledger/testing/randomAccounts.go @@ -58,48 +58,60 @@ func RandomNote() []byte { return note[:] } -// RandomAccountData generates a random AccountData +// RandomAccountData generates a random AccountData with no associated resources. func RandomAccountData(rewardsBase uint64) basics.AccountData { var data basics.AccountData // Avoid overflowing totals data.MicroAlgos.Raw = crypto.RandUint64() % (1 << 32) // 0 is an invalid round, but would be right if never proposed - data.LastProposed = basics.Round(crypto.RandUint64() % 100) + data.LastProposed = basics.Round(crypto.RandUint64() % 10) // 0 is an invalid round, but would be right if never needed a heartbeat - data.LastHeartbeat = basics.Round(crypto.RandUint64() % 100) + data.LastHeartbeat = basics.Round(crypto.RandUint64() % 10) switch crypto.RandUint64() % 4 { case 0: data.Status = basics.Online - data.VoteLastValid = 10000 case 1: data.Status = basics.Offline - data.VoteLastValid = 0 case 2: data.Status = basics.NotParticipating case 3: data.Status = basics.Suspended - data.VoteLastValid = basics.Round(crypto.RandUint64() % 10000) } - data.VoteFirstValid = 0 + switch data.Status { + case basics.Online, basics.Suspended: + crypto.RandBytes(data.VoteID[:]) + crypto.RandBytes(data.SelectionID[:]) + crypto.RandBytes(data.StateProofID[:]) + data.VoteFirstValid = basics.Round(crypto.RandUint64()) + data.VoteLastValid = basics.Round(crypto.RandUint64() % uint64(math.MaxInt64)) // int64 is the max sqlite can store + data.VoteKeyDilution = crypto.RandUint64() + case basics.Offline, basics.NotParticipating: + data.VoteID = crypto.OneTimeSignatureVerifier{} + data.SelectionID = crypto.VRFVerifier{} + data.StateProofID = merklesignature.Commitment{} + data.VoteFirstValid = 0 + data.VoteLastValid = 0 + data.VoteKeyDilution = 0 + } + data.RewardsBase = rewardsBase return data } // RandomOnlineAccountData is similar to RandomAccountData but always creates online account func RandomOnlineAccountData(rewardsBase uint64) basics.AccountData { - var data basics.AccountData - data.MicroAlgos.Raw = crypto.RandUint64() % (1 << 32) - data.Status = basics.Online - data.VoteLastValid = 1000 - data.VoteFirstValid = 0 - data.RewardsBase = rewardsBase - return data + for { + data := RandomAccountData(rewardsBase) + if data.Status == basics.Online { + return data + } + } } -// RandomAssetParams creates a randim basics.AssetParams +// RandomAssetParams creates a random basics.AssetParams func RandomAssetParams() basics.AssetParams { ap := basics.AssetParams{ Total: crypto.RandUint64(), @@ -221,6 +233,7 @@ func RandomAppParams() basics.AppParams { if len(ap.GlobalState) == 0 { ap.GlobalState = nil } + ap.ExtraProgramPages = uint32(crypto.RandUint64() % 4) return ap } @@ -275,22 +288,6 @@ func RandomAppLocalState() basics.AppLocalState { func RandomFullAccountData(rewardsLevel uint64, lastCreatableID *basics.CreatableIndex, assets map[basics.AssetIndex]struct{}, apps map[basics.AppIndex]struct{}) basics.AccountData { data := RandomAccountData(rewardsLevel) - switch data.Status { - case basics.Online, basics.Suspended: - crypto.RandBytes(data.VoteID[:]) - crypto.RandBytes(data.SelectionID[:]) - crypto.RandBytes(data.StateProofID[:]) - data.VoteFirstValid = basics.Round(crypto.RandUint64()) - data.VoteLastValid = basics.Round(crypto.RandUint64() % uint64(math.MaxInt64)) // int64 is the max sqlite can store - data.VoteKeyDilution = crypto.RandUint64() - case basics.Offline, basics.NotParticipating: - data.VoteID = crypto.OneTimeSignatureVerifier{} - data.SelectionID = crypto.VRFVerifier{} - data.StateProofID = merklesignature.Commitment{} - data.VoteFirstValid = 0 - data.VoteLastValid = 0 - data.VoteKeyDilution = 0 - } if (crypto.RandUint64() % 2) == 1 { // if account has created assets, have these defined. createdAssetsCount := crypto.RandUint64()%20 + 1 From 2fe9d79b0ee5df3a277f477415bcf14b2efe944b Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Tue, 10 Oct 2023 12:04:57 -0400 Subject: [PATCH 7/9] Correct block proposal max size for suspensions --- protocol/tags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/tags.go b/protocol/tags.go index 11dbb55d4e..c6d694c93d 100644 --- a/protocol/tags.go +++ b/protocol/tags.go @@ -73,7 +73,7 @@ const PingReplyTagMaxSize = 8 // ProposalPayloadTagMaxSize is the maximum size of a ProposalPayloadTag message // This value is dominated by the MaxTxnBytesPerBlock -const ProposalPayloadTagMaxSize = 5248065 +const ProposalPayloadTagMaxSize = 5250289 // StateProofSigTagMaxSize is the maximum size of a StateProofSigTag message const StateProofSigTagMaxSize = 6378 From 6dd7d1c3809b423836f90c4aa35d6f990b5e6806 Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Tue, 10 Oct 2023 15:45:13 -0400 Subject: [PATCH 8/9] Validate proposed absents, and suspend them. First cut at computing the expected interval. Uses 10x the expected interval, but calculating the interval is currently wonky. Uses the last round's total online stake, but this round's acct stake. Also ignores rewards. --- ledger/eval/eval.go | 50 +++++++++++--------- ledger/eval_simple_test.go | 88 +++++++++++++++++++++++++++++------ ledger/testing/testGenesis.go | 20 ++++++-- 3 files changed, 117 insertions(+), 41 deletions(-) diff --git a/ledger/eval/eval.go b/ledger/eval/eval.go index e99a7c7987..e9f1eb6573 100644 --- a/ledger/eval/eval.go +++ b/ledger/eval/eval.go @@ -1321,13 +1321,17 @@ func (eval *BlockEvaluator) endOfBlock() error { } } - err := eval.validateExpiredOnlineAccounts() - if err != nil { + if err := eval.validateExpiredOnlineAccounts(); err != nil { + return err + } + if err := eval.resetExpiredOnlineAccountsParticipationKeys(); err != nil { return err } - err = eval.resetExpiredOnlineAccountsParticipationKeys() - if err != nil { + if err := eval.validateAbsentOnlineAccounts(); err != nil { + return err + } + if err := eval.suspendAbsentAccounts(); err != nil { return err } @@ -1392,8 +1396,7 @@ func (eval *BlockEvaluator) endOfBlock() error { } } - err = eval.state.CalculateTotals() - if err != nil { + if err := eval.state.CalculateTotals(); err != nil { return err } @@ -1442,15 +1445,8 @@ func (eval *BlockEvaluator) generateKnockOfflineAccountsList() { } if acctDelta.Status == basics.Online { - // TODO: 1000 rounds is obviously a placeholder. Probably needs to - // be something like 10x the "expected" interval. Further - // complications: (1) At keyreg, LastProposed=0 (or is old). (2) - // Accounts should be allowed to "heartbeat" to stay online. (3) - // "Expected" interval varies with balance and onlinestake. - allowableLag := basics.Round(1000) - absent := acctDelta.LastProposed+allowableLag < currentRound && - acctDelta.LastHeartbeat+allowableLag < currentRound - if absent && + lastSeen := max(acctDelta.LastHeartbeat, acctDelta.LastHeartbeat) + if isAbsent(eval.state.prevTotals.Online.Money, acctDelta.MicroAlgos, lastSeen, currentRound) && len(updates.AbsentParticipationAccounts) < expectedMaxNumberOfAbsentAccounts { updates.AbsentParticipationAccounts = append( updates.AbsentParticipationAccounts, @@ -1461,6 +1457,21 @@ func (eval *BlockEvaluator) generateKnockOfflineAccountsList() { } } +// delete me in Go 1.21 +func max(a, b basics.Round) basics.Round { + if a > b { + return a + } + return b +} + +func isAbsent(totalOnlineStake basics.MicroAlgos, acctStake basics.MicroAlgos, lastSeen basics.Round, current basics.Round) bool { + // See if the account has exceeded 10x their expected observation interval. + allowableLag := basics.Round(10 * totalOnlineStake.Raw / acctStake.Raw) + fmt.Printf("%d / %d -> %d \n", acctStake, totalOnlineStake, allowableLag) + return lastSeen+allowableLag < current +} + // validateExpiredOnlineAccounts tests the expired online accounts specified in ExpiredParticipationAccounts, and verify // that they have all expired and need to be reset. func (eval *BlockEvaluator) validateExpiredOnlineAccounts() error { @@ -1546,13 +1557,8 @@ func (eval *BlockEvaluator) validateAbsentOnlineAccounts() error { return fmt.Errorf("proposed absent acct %v was not online but %v", accountAddr, acctData.Status) } - // TODO: 1000 rounds is obviously a placeholder. Probably needs to be - // something like 10x the "expected" interval. Further complications: - // (1) At first keyreg, LastProposed=0. (2) Accounts should be allowed - // to "heartbeat" to stay online. - allowableLag := basics.Round(1000) - if acctData.LastProposed+allowableLag >= currentRound || - acctData.LastHeartbeat+allowableLag >= currentRound { + lastSeen := max(acctData.LastHeartbeat, acctData.LastHeartbeat) + if !isAbsent(eval.state.prevTotals.Online.Money, acctData.MicroAlgos, lastSeen, currentRound) { return fmt.Errorf("proposed absent account %v is not absent in %d, %d", accountAddr, acctData.LastProposed, acctData.LastHeartbeat) } diff --git a/ledger/eval_simple_test.go b/ledger/eval_simple_test.go index 4f929df2c3..a45241dbad 100644 --- a/ledger/eval_simple_test.go +++ b/ledger/eval_simple_test.go @@ -278,26 +278,42 @@ func TestAbsentTracking(t *testing.T) { partitiontest.PartitionTest(t) t.Parallel() - genBalances, addrs, _ := ledgertesting.NewTestGenesis() + genBalances, addrs, _ := ledgertesting.NewTestGenesis(func(cfg *ledgertesting.GenesisCfg) { + cfg.OnlineCount = 2 // So we know proposer should propose every 2 rounds, on average + }) // Absentee checking begins in v39. Start checking in v38 to test that is unchanged. ledgertesting.TestConsensusRange(t, 38, 0, func(t *testing.T, ver int, cv protocol.ConsensusVersion, cfg config.Local) { dl := NewDoubleLedger(t, genBalances, cv, cfg) defer dl.Close() + totals, err := dl.generator.Totals(0) + require.NoError(t, err) + require.NotZero(t, totals.Online.Money.Raw) + for i, addr := range addrs { + fmt.Printf("addrs[%d] == %v\n", i, addr) + } + require.True(t, lookup(t, dl.generator, addrs[0]).Status == basics.Online) + require.True(t, lookup(t, dl.generator, addrs[1]).Status == basics.Online) + require.False(t, lookup(t, dl.generator, addrs[2]).Status == basics.Online) + dl.fullBlock() - pay := txntest.Txn{ + proposer := addrs[7] + dl.beginBlock() + dl.txns(&txntest.Txn{ Type: "pay", Sender: addrs[1], Receiver: addrs[2], - Amount: 100000, - } - - proposer := addrs[7] - dl.beginBlock() - dl.txns(&pay) + Amount: 100_000, + }) dl.endBlock(proposer) + newtotals, err := dl.generator.Totals(dl.generator.Latest()) + require.NoError(t, err) + // payment and fee left the online account + require.Equal(t, totals.Online.Money.Raw-100_000-1000, newtotals.Online.Money.Raw) + totals = newtotals + dl.fullBlock() prp := lookup(t, dl.validator, proposer) @@ -313,8 +329,13 @@ func TestAbsentTracking(t *testing.T) { require.Zero(t, prp.LastHeartbeat) } - dl.txns(&txntest.Txn{Type: "keyreg", Sender: addrs[1]}) // OFFLINE keyreg - regger := lookup(t, dl.validator, addrs[1]) + // addrs[2] was already offline + dl.txns(&txntest.Txn{Type: "keyreg", Sender: addrs[2]}) // OFFLINE keyreg + regger := lookup(t, dl.validator, addrs[2]) + + newtotals, err = dl.generator.Totals(dl.generator.Latest()) + require.NoError(t, err) + require.Equal(t, totals.Online.Money.Raw, newtotals.Online.Money.Raw) // offline transaction records nothing require.Zero(t, regger.LastProposed) @@ -323,19 +344,58 @@ func TestAbsentTracking(t *testing.T) { // ONLINE keyreg dl.txns(&txntest.Txn{ Type: "keyreg", - Sender: addrs[1], + Sender: addrs[2], VotePK: [32]byte{1}, SelectionPK: [32]byte{1}, }) - regger = lookup(t, dl.validator, addrs[1]) + newtotals, err = dl.generator.Totals(dl.generator.Latest()) + require.NoError(t, err) + require.Greater(t, newtotals.Online.Money.Raw, totals.Online.Money.Raw) + + regger = lookup(t, dl.validator, addrs[2]) + require.Zero(t, regger.LastProposed) + require.True(t, regger.Status == basics.Online) if ver >= 39 { - require.Zero(t, regger.LastProposed) require.NotZero(t, regger.LastHeartbeat) // online keyreg caused update } else { - require.Zero(t, regger.LastProposed) require.Zero(t, regger.LastHeartbeat) } + + for i := 0; i < 5; i++ { + dl.fullBlock() + require.True(t, lookup(t, dl.generator, addrs[0]).Status == basics.Online) + require.True(t, lookup(t, dl.generator, addrs[1]).Status == basics.Online) + require.True(t, lookup(t, dl.generator, addrs[2]).Status == basics.Online) + } + + // all are still online after a few blocks + require.True(t, lookup(t, dl.generator, addrs[0]).Status == basics.Online) + require.True(t, lookup(t, dl.generator, addrs[1]).Status == basics.Online) + require.True(t, lookup(t, dl.generator, addrs[2]).Status == basics.Online) + + for i := 0; i < 30; i++ { + dl.fullBlock() + } + + // addrs 0-2 all have about 1/3 of stake, so become eligible for + // suspension after 30 rounds. We're at about 35. But, since blocks are + // empty, nobody's susspendible account is noticed. + require.True(t, lookup(t, dl.generator, addrs[0]).Status == basics.Online) + require.True(t, lookup(t, dl.generator, addrs[1]).Status == basics.Online) + require.True(t, lookup(t, dl.generator, addrs[2]).Status == basics.Online) + + // when 2 pays 0, they both get noticed and get suspended + dl.txns(&txntest.Txn{ + Type: "pay", + Sender: addrs[2], + Receiver: addrs[0], + Amount: 0, + }) + require.Equal(t, ver < 39, lookup(t, dl.generator, addrs[0]).Status == basics.Online) + require.True(t, lookup(t, dl.generator, addrs[1]).Status == basics.Online) + require.Equal(t, ver < 39, lookup(t, dl.generator, addrs[2]).Status == basics.Online) + }) } diff --git a/ledger/testing/testGenesis.go b/ledger/testing/testGenesis.go index 98a41d06d5..9911af343a 100644 --- a/ledger/testing/testGenesis.go +++ b/ledger/testing/testGenesis.go @@ -25,17 +25,18 @@ import ( "github.com/algorand/go-algorand/protocol" ) -// testGenesisCfg provides a configuration object for NewTestGenesis. -type testGenesisCfg struct { +// GenesisCfg provides a configuration object for NewTestGenesis. +type GenesisCfg struct { rewardsPoolAmount basics.MicroAlgos + OnlineCount int } // TestGenesisOption provides functional options for testGenesisCfg. -type TestGenesisOption func(*testGenesisCfg) +type TestGenesisOption func(*GenesisCfg) // TestGenesisRewardsPoolSize configures the rewards pool size in the genesis block. func TestGenesisRewardsPoolSize(amount basics.MicroAlgos) TestGenesisOption { - return func(cfg *testGenesisCfg) { cfg.rewardsPoolAmount = amount } + return func(cfg *GenesisCfg) { cfg.rewardsPoolAmount = amount } } // NewTestGenesis creates a bunch of accounts, splits up 10B algos @@ -43,7 +44,7 @@ func TestGenesisRewardsPoolSize(amount basics.MicroAlgos) TestGenesisOption { // addresses and secrets it creates to enable tests. For special // scenarios, manipulate these return values before using newTestLedger. func NewTestGenesis(opts ...TestGenesisOption) (bookkeeping.GenesisBalances, []basics.Address, []*crypto.SignatureSecrets) { - var cfg testGenesisCfg + var cfg GenesisCfg for _, opt := range opts { opt(&cfg) } @@ -75,6 +76,15 @@ func NewTestGenesis(opts ...TestGenesisOption) (bookkeeping.GenesisBalances, []b adata := basics.AccountData{ MicroAlgos: basics.MicroAlgos{Raw: amount}, + Status: basics.Offline, + } + if i < cfg.OnlineCount { + adata.Status = basics.Online + adata.VoteFirstValid = 0 + adata.VoteLastValid = 1_000_000 + crypto.RandBytes(adata.VoteID[:]) + crypto.RandBytes(adata.SelectionID[:]) + crypto.RandBytes(adata.StateProofID[:]) } accts[addrs[i]] = adata } From 2dc578d8ad87aa7be56fefec2866407be80040a5 Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Mon, 23 Oct 2023 19:07:49 -0400 Subject: [PATCH 9/9] An opcode `heartbeat` that keeps an unlucky node online. If, by chance, a node does not propose for a long time, they can issue a transaction to explicitly indicate that they are still online, so they won't be suspended. They must sign a block seed of recent block using their particpation key and execute the `heartbeat` opcode on it. --- data/transactions/logic/README.md | 3 + data/transactions/logic/TEAL_opcodes_v10.md | 11 +++ data/transactions/logic/assembler.go | 4 +- data/transactions/logic/assembler_test.go | 97 ++++++++++---------- data/transactions/logic/crypto.go | 57 ++++++++++++ data/transactions/logic/crypto_test.go | 92 ++++++++++++++++--- data/transactions/logic/doc.go | 3 +- data/transactions/logic/eval.go | 75 +++++++++++++-- data/transactions/logic/evalStateful_test.go | 19 ++-- data/transactions/logic/eval_test.go | 4 +- data/transactions/logic/fields.go | 9 ++ data/transactions/logic/fields_string.go | 8 +- data/transactions/logic/langspec_v10.json | 25 ++++- data/transactions/logic/ledger_test.go | 38 +++++++- data/transactions/logic/opcodes.go | 8 +- data/transactions/logic/teal.tmLanguage.json | 4 +- ledger/eval/applications.go | 9 ++ ledger/ledger.go | 2 +- 18 files changed, 373 insertions(+), 95 deletions(-) diff --git a/data/transactions/logic/README.md b/data/transactions/logic/README.md index 1ec45b6e2c..9bb080bc98 100644 --- a/data/transactions/logic/README.md +++ b/data/transactions/logic/README.md @@ -469,6 +469,7 @@ these results may contain leading zero bytes. | `ed25519verify` | for (data A, signature B, pubkey C) verify the signature of ("ProgData" \|\| program_hash \|\| data) against the pubkey => {0 or 1} | | `ed25519verify_bare` | for (data A, signature B, pubkey C) verify the signature of the data against the pubkey => {0 or 1} | | `ecdsa_verify v` | for (data A, signature B, C and pubkey D, E) verify the signature of the data against the pubkey => {0 or 1} | +| `heartbeat` | for (signature components A, B, C, D, E, and account F) verify the signature of the block seed from round txn.FirstValid-1 using F's partkey for txn.LastValid | | `ecdsa_pk_recover v` | for (data A, recovery id B, signature C, D) recover a public key | | `ecdsa_pk_decompress v` | decompress pubkey A into components X, Y | | `vrf_verify s` | Verify the proof B of message A against pubkey C. Returns vrf output and verification flag. | @@ -696,6 +697,8 @@ Account fields used in the `acct_params_get` opcode. | 9 | AcctTotalAssets | uint64 | v8 | The numbers of ASAs held by this account (including ASAs this account created). | | 10 | AcctTotalBoxes | uint64 | v8 | The number of existing boxes created by this account's app. | | 11 | AcctTotalBoxBytes | uint64 | v8 | The total number of bytes used by this account's app's box keys and values. | +| 12 | AcctLastProposed | uint64 | v10 | The round in which this account last proposed. | +| 13 | AcctLastHeartbeat | uint64 | v10 | The round in which the account went online or executed `heartbeat`. | ### Flow Control diff --git a/data/transactions/logic/TEAL_opcodes_v10.md b/data/transactions/logic/TEAL_opcodes_v10.md index 0ae3f35ca6..16c99c0261 100644 --- a/data/transactions/logic/TEAL_opcodes_v10.md +++ b/data/transactions/logic/TEAL_opcodes_v10.md @@ -1081,6 +1081,8 @@ Fields | 9 | AcctTotalAssets | uint64 | v8 | The numbers of ASAs held by this account (including ASAs this account created). | | 10 | AcctTotalBoxes | uint64 | v8 | The number of existing boxes created by this account's app. | | 11 | AcctTotalBoxBytes | uint64 | v8 | The total number of bytes used by this account's app's box keys and values. | +| 12 | AcctLastProposed | uint64 | v10 | The round in which this account last proposed. | +| 13 | AcctLastHeartbeat | uint64 | v10 | The round in which the account went online or executed `heartbeat`. | ## min_balance @@ -1141,6 +1143,15 @@ pushints args are not added to the intcblock during assembly processes - **Cost**: 1900 - Availability: v7 +## heartbeat + +- Bytecode: 0x87 +- Stack: ..., A: [64]byte, B: [32]byte, C: [64]byte, D: [32]byte, E: [64]byte, F → ... +- for (signature components A, B, C, D, E, and account F) verify the signature of the block seed from round txn.FirstValid-1 using F's partkey for txn.LastValid +- **Cost**: 5700 +- Availability: v10 +- Mode: Application + ## callsub - Syntax: `callsub TARGET` ∋ TARGET: branch offset diff --git a/data/transactions/logic/assembler.go b/data/transactions/logic/assembler.go index aa32c51eba..d9f839cbb7 100644 --- a/data/transactions/logic/assembler.go +++ b/data/transactions/logic/assembler.go @@ -1992,8 +1992,8 @@ func (ops *OpStream) trackStack(args StackTypes, returns StackTypes, instruction ops.trace(", %s", argType) } if !stype.overlaps(argType) { - ops.typeErrorf(tokens[0], "%s arg %d wanted type %s got %s", - reJoin(instruction, tokens[1:]), i, argType, stype) + ops.typeErrorf(tokens[0], "%s arg %c wanted type %s got %s", + reJoin(instruction, tokens[1:]), argName(i), argType, stype) } } if !firstPop { diff --git a/data/transactions/logic/assembler_test.go b/data/transactions/logic/assembler_test.go index 0a6a0c1f89..08cdb3d69c 100644 --- a/data/transactions/logic/assembler_test.go +++ b/data/transactions/logic/assembler_test.go @@ -430,7 +430,8 @@ pushbytess "1" "2" "1" const v8Nonsense = v7Nonsense + switchNonsense + frameNonsense + matchNonsense + boxNonsense const v9Nonsense = v8Nonsense -const v10Nonsense = v9Nonsense + pairingNonsense + +const v10Nonsense = v9Nonsense + pairingNonsense + incentiveNonsense const v6Compiled = "2004010002b7a60c26050242420c68656c6c6f20776f726c6421070123456789abcd208dae2087fbba51304eb02b91f656948397a7946390e8cb70fc9ea4d95f92251d047465737400320032013202320380021234292929292b0431003101310231043105310731083109310a310b310c310d310e310f3111311231133114311533000033000133000233000433000533000733000833000933000a33000b33000c33000d33000e33000f3300113300123300133300143300152d2e01022581f8acd19181cf959a1281f8acd19181cf951a81f8acd19181cf1581f8acd191810f082209240a220b230c240d250e230f2310231123122313231418191a1b1c28171615400003290349483403350222231d4a484848482b50512a632223524100034200004322602261222704634848222862482864286548482228246628226723286828692322700048482371004848361c0037001a0031183119311b311d311e311f312023221e312131223123312431253126312731283129312a312b312c312d312e312f447825225314225427042455220824564c4d4b0222382124391c0081e80780046a6f686e2281d00f23241f880003420001892224902291922494249593a0a1a2a3a4a5a6a7a8a9aaabacadae24af3a00003b003c003d816472064e014f012a57000823810858235b235a2359b03139330039b1b200b322c01a23c1001a2323c21a23c3233e233f8120af06002a494905002a49490700b400b53a03b6b7043cb8033a0c2349c42a9631007300810881088120978101c53a8101c6003a" @@ -447,7 +448,7 @@ const matchCompiled = "83030102018e02fff500008203013101320131" const v8Compiled = v7Compiled + switchCompiled + frameCompiled + matchCompiled + boxCompiled const v9Compiled = v8Compiled -const v10Compiled = v9Compiled + pairingCompiled +const v10Compiled = v9Compiled + pairingCompiled + incentiveCompiled var nonsense = map[uint64]string{ 1: v1Nonsense, @@ -797,9 +798,9 @@ func TestAssembleGlobal(t *testing.T) { testProg(t, "global MinTxnFee; int 2; +", AssemblerMaxVersion) testProg(t, "global ZeroAddress; byte 0x12; concat; len", AssemblerMaxVersion) testProg(t, "global MinTxnFee; byte 0x12; concat", AssemblerMaxVersion, - exp(1, "concat arg 0 wanted type []byte...", 29)) + exp(1, "concat arg A wanted type []byte...", 29)) testProg(t, "int 2; global ZeroAddress; +", AssemblerMaxVersion, - exp(1, "+ arg 1 wanted type uint64...", 27)) + exp(1, "+ arg B wanted type uint64...", 27)) } func TestAssembleDefault(t *testing.T) { @@ -811,7 +812,7 @@ int 1 + // comment ` - testProg(t, source, AssemblerMaxVersion, exp(3, "+ arg 0 wanted type uint64 got [5]byte", 1)) + testProg(t, source, AssemblerMaxVersion, exp(3, "+ arg A wanted type uint64 got [5]byte", 1)) } // mutateProgVersion replaces version (first two symbols) in hex-encoded program @@ -1945,7 +1946,7 @@ balance int 1 ==` for v := uint64(2); v < directRefEnabledVersion; v++ { - testProg(t, source, v, exp(2, "balance arg 0 wanted type uint64 got [1]byte")) + testProg(t, source, v, exp(2, "balance arg A wanted type uint64 got [1]byte")) } for v := uint64(directRefEnabledVersion); v <= AssemblerMaxVersion; v++ { testProg(t, source, v) @@ -1961,7 +1962,7 @@ min_balance int 1 ==` for v := uint64(3); v < directRefEnabledVersion; v++ { - testProg(t, source, v, exp(2, "min_balance arg 0 wanted type uint64 got [1]byte")) + testProg(t, source, v, exp(2, "min_balance arg A wanted type uint64 got [1]byte")) } for v := uint64(directRefEnabledVersion); v <= AssemblerMaxVersion; v++ { testProg(t, source, v) @@ -1985,15 +1986,15 @@ func TestAssembleAsset(t *testing.T) { exp(1, "asset_holding_get unknown field: \"ABC\"")) testProg(t, "byte 0x1234; asset_params_get ABC 1", v, - exp(1, "asset_params_get ABC 1 arg 0 wanted type uint64...")) + exp(1, "asset_params_get ABC 1 arg A wanted type uint64...")) // Test that AssetUnitName is known to return bytes testProg(t, "int 1; asset_params_get AssetUnitName; pop; int 1; +", v, - exp(1, "+ arg 0 wanted type uint64...")) + exp(1, "+ arg A wanted type uint64...")) // Test that AssetTotal is known to return uint64 testProg(t, "int 1; asset_params_get AssetTotal; pop; byte 0x12; concat", v, - exp(1, "concat arg 0 wanted type []byte...")) + exp(1, "concat arg A wanted type []byte...")) testLine(t, "asset_params_get ABC 1", v, "asset_params_get expects 1 immediate argument") testLine(t, "asset_params_get ABC", v, "asset_params_get unknown field: \"ABC\"") @@ -2620,10 +2621,10 @@ func TestSwapTypeCheck(t *testing.T) { t.Parallel() /* reconfirm that we detect this type error */ - testProg(t, "int 1; byte 0x1234; +", AssemblerMaxVersion, exp(1, "+ arg 1...")) + testProg(t, "int 1; byte 0x1234; +", AssemblerMaxVersion, exp(1, "+ arg B...")) /* despite swap, we track types */ - testProg(t, "int 1; byte 0x1234; swap; +", AssemblerMaxVersion, exp(1, "+ arg 0...")) - testProg(t, "byte 0x1234; int 1; swap; +", AssemblerMaxVersion, exp(1, "+ arg 1...")) + testProg(t, "int 1; byte 0x1234; swap; +", AssemblerMaxVersion, exp(1, "+ arg A...")) + testProg(t, "byte 0x1234; int 1; swap; +", AssemblerMaxVersion, exp(1, "+ arg B...")) } func TestDigAsm(t *testing.T) { @@ -2634,7 +2635,7 @@ func TestDigAsm(t *testing.T) { testProg(t, "int 1; byte 0x1234; int 2; dig 2; +", AssemblerMaxVersion) testProg(t, "byte 0x32; byte 0x1234; int 2; dig 2; +", AssemblerMaxVersion, - exp(1, "+ arg 1...")) + exp(1, "+ arg B...")) testProg(t, "byte 0x32; byte 0x1234; int 2; dig 3; +", AssemblerMaxVersion, exp(1, "dig 3 expects 4...")) testProg(t, "int 1; byte 0x1234; int 2; dig 12; +", AssemblerMaxVersion, @@ -2642,7 +2643,7 @@ func TestDigAsm(t *testing.T) { // Confirm that digging something out does not ruin our knowledge about the types in the middle testProg(t, "int 1; byte 0x1234; byte 0x1234; dig 2; dig 3; +; pop; +", AssemblerMaxVersion, - exp(1, "+ arg 1...")) + exp(1, "+ arg B...")) testProg(t, "int 3; pushbytes \"123456\"; int 1; dig 2; substring3", AssemblerMaxVersion) } @@ -2655,7 +2656,7 @@ func TestBuryAsm(t *testing.T) { testProg(t, "int 1; byte 0x1234; int 2; bury 1; +", AssemblerMaxVersion) // the 2 replaces the byte string testProg(t, "int 2; int 2; byte 0x1234; bury 1; +", AssemblerMaxVersion, - exp(1, "+ arg 1...")) + exp(1, "+ arg B...")) testProg(t, "byte 0x32; byte 0x1234; int 2; bury 3; +", AssemblerMaxVersion, exp(1, "bury 3 expects 4...")) testProg(t, "int 1; byte 0x1234; int 2; bury 12; +", AssemblerMaxVersion, @@ -2663,11 +2664,11 @@ func TestBuryAsm(t *testing.T) { // We do not lose track of the ints between ToS and bury index testProg(t, "int 0; int 1; int 2; int 4; bury 3; concat", AssemblerMaxVersion, - exp(1, "concat arg 1 wanted type []byte...")) + exp(1, "concat arg B wanted type []byte...")) // Even when we are burying into unknown (seems repetitive, but is an easy bug) testProg(t, "int 0; int 0; b LABEL; LABEL: int 1; int 2; int 4; bury 4; concat", AssemblerMaxVersion, - exp(1, "concat arg 1 wanted type []byte...")) + exp(1, "concat arg B wanted type []byte...")) testProg(t, "intcblock 55; bury 1; int 1", AssemblerMaxVersion, exp(1, "bury 1 expects 2 stack arguments...", 14)) testProg(t, "intcblock 55; int 2; bury 1; int 1", AssemblerMaxVersion, exp(1, "bury 1 expects 2 stack arguments...", 21)) @@ -2677,39 +2678,39 @@ func TestBuryAsm(t *testing.T) { func TestEqualsTypeCheck(t *testing.T) { partitiontest.PartitionTest(t) t.Parallel() - testProg(t, "int 1; byte 0x1234; ==", AssemblerMaxVersion, exp(1, "== arg 0...")) - testProg(t, "int 1; byte 0x1234; !=", AssemblerMaxVersion, exp(1, "!= arg 0...")) - testProg(t, "byte 0x1234; int 1; ==", AssemblerMaxVersion, exp(1, "== arg 0...")) - testProg(t, "byte 0x1234; int 1; !=", AssemblerMaxVersion, exp(1, "!= arg 0...")) + testProg(t, "int 1; byte 0x1234; ==", AssemblerMaxVersion, exp(1, "== arg A...")) + testProg(t, "int 1; byte 0x1234; !=", AssemblerMaxVersion, exp(1, "!= arg A...")) + testProg(t, "byte 0x1234; int 1; ==", AssemblerMaxVersion, exp(1, "== arg A...")) + testProg(t, "byte 0x1234; int 1; !=", AssemblerMaxVersion, exp(1, "!= arg A...")) } func TestDupTypeCheck(t *testing.T) { partitiontest.PartitionTest(t) t.Parallel() - testProg(t, "byte 0x1234; dup; int 1; +", AssemblerMaxVersion, exp(1, "+ arg 0...")) + testProg(t, "byte 0x1234; dup; int 1; +", AssemblerMaxVersion, exp(1, "+ arg A...")) testProg(t, "byte 0x1234; int 1; dup; +", AssemblerMaxVersion) - testProg(t, "byte 0x1234; int 1; dup2; +", AssemblerMaxVersion, exp(1, "+ arg 0...")) - testProg(t, "int 1; byte 0x1234; dup2; +", AssemblerMaxVersion, exp(1, "+ arg 1...")) + testProg(t, "byte 0x1234; int 1; dup2; +", AssemblerMaxVersion, exp(1, "+ arg A...")) + testProg(t, "int 1; byte 0x1234; dup2; +", AssemblerMaxVersion, exp(1, "+ arg B...")) - testProg(t, "byte 0x1234; int 1; dup; dig 1; len", AssemblerMaxVersion, exp(1, "len arg 0...")) - testProg(t, "int 1; byte 0x1234; dup; dig 1; !", AssemblerMaxVersion, exp(1, "! arg 0...")) + testProg(t, "byte 0x1234; int 1; dup; dig 1; len", AssemblerMaxVersion, exp(1, "len arg A...")) + testProg(t, "int 1; byte 0x1234; dup; dig 1; !", AssemblerMaxVersion, exp(1, "! arg A...")) - testProg(t, "byte 0x1234; int 1; dup2; dig 2; len", AssemblerMaxVersion, exp(1, "len arg 0...")) - testProg(t, "int 1; byte 0x1234; dup2; dig 2; !", AssemblerMaxVersion, exp(1, "! arg 0...")) + testProg(t, "byte 0x1234; int 1; dup2; dig 2; len", AssemblerMaxVersion, exp(1, "len arg A...")) + testProg(t, "int 1; byte 0x1234; dup2; dig 2; !", AssemblerMaxVersion, exp(1, "! arg A...")) } func TestSelectTypeCheck(t *testing.T) { partitiontest.PartitionTest(t) t.Parallel() - testProg(t, "int 1; int 2; int 3; select; len", AssemblerMaxVersion, exp(1, "len arg 0...")) - testProg(t, "byte 0x1234; byte 0x5678; int 3; select; !", AssemblerMaxVersion, exp(1, "! arg 0...")) + testProg(t, "int 1; int 2; int 3; select; len", AssemblerMaxVersion, exp(1, "len arg A...")) + testProg(t, "byte 0x1234; byte 0x5678; int 3; select; !", AssemblerMaxVersion, exp(1, "! arg A...")) } func TestSetBitTypeCheck(t *testing.T) { partitiontest.PartitionTest(t) t.Parallel() - testProg(t, "int 1; int 2; int 3; setbit; len", AssemblerMaxVersion, exp(1, "len arg 0...")) - testProg(t, "byte 0x1234; int 2; int 3; setbit; !", AssemblerMaxVersion, exp(1, "! arg 0...")) + testProg(t, "int 1; int 2; int 3; setbit; len", AssemblerMaxVersion, exp(1, "len arg A...")) + testProg(t, "byte 0x1234; int 2; int 3; setbit; !", AssemblerMaxVersion, exp(1, "! arg A...")) } func TestScratchTypeCheck(t *testing.T) { @@ -2718,15 +2719,15 @@ func TestScratchTypeCheck(t *testing.T) { // All scratch slots should start as uint64 testProg(t, "load 0; int 1; +", AssemblerMaxVersion) // Check load and store accurately using the scratch space - testProg(t, "byte 0x01; store 0; load 0; int 1; +", AssemblerMaxVersion, exp(1, "+ arg 0...")) + testProg(t, "byte 0x01; store 0; load 0; int 1; +", AssemblerMaxVersion, exp(1, "+ arg A...")) // Loads should know the type it's loading if all the slots are the same type - testProg(t, "int 0; loads; btoi", AssemblerMaxVersion, exp(1, "btoi arg 0...")) + testProg(t, "int 0; loads; btoi", AssemblerMaxVersion, exp(1, "btoi arg A...")) // Loads only knows the type when slot is a const - testProg(t, "byte 0x01; store 0; int 1; loads; btoi", AssemblerMaxVersion, exp(1, "btoi arg 0...")) + testProg(t, "byte 0x01; store 0; int 1; loads; btoi", AssemblerMaxVersion, exp(1, "btoi arg A...")) // Loads doesnt know the type if its the result of some other expression where we lose information testProg(t, "byte 0x01; store 0; load 0; btoi; loads; btoi", AssemblerMaxVersion) // Stores should only set slots to StackAny if they are not the same type as what is being stored - testProg(t, "byte 0x01; store 0; int 3; byte 0x01; stores; load 0; int 1; +", AssemblerMaxVersion, exp(1, "+ arg 0...")) + testProg(t, "byte 0x01; store 0; int 3; byte 0x01; stores; load 0; int 1; +", AssemblerMaxVersion, exp(1, "+ arg A...")) // ScratchSpace should reset after hitting label in deadcode testProg(t, "byte 0x01; store 0; b label1; label1:; load 0; int 1; +", AssemblerMaxVersion) // But it should reset to StackAny not uint64 @@ -2734,7 +2735,7 @@ func TestScratchTypeCheck(t *testing.T) { // Callsubs should also reset the scratch space testProg(t, "callsub A; load 0; btoi; return; A: byte 0x01; store 0; retsub", AssemblerMaxVersion) // But the scratchspace should still be tracked after the callsub - testProg(t, "callsub A; int 1; store 0; load 0; btoi; return; A: retsub", AssemblerMaxVersion, exp(1, "btoi arg 0...")) + testProg(t, "callsub A; int 1; store 0; load 0; btoi; return; A: retsub", AssemblerMaxVersion, exp(1, "btoi arg A...")) } @@ -2773,7 +2774,7 @@ func TestScratchBounds(t *testing.T) { require.Equal(t, osv.AVMType, avmAny) require.ElementsMatch(t, osv.Bound, static(0)) - testProg(t, "byte 0xff; store 1; load 1; return", AssemblerMaxVersion, exp(1, "return arg 0 wanted type uint64 ...")) + testProg(t, "byte 0xff; store 1; load 1; return", AssemblerMaxVersion, exp(1, "return arg A wanted type uint64 ...")) } // TestProtoAsm confirms that the assembler will yell at you if you are @@ -2806,7 +2807,7 @@ func TestCoverAsm(t *testing.T) { t.Parallel() testProg(t, `int 4; byte "john"; int 5; cover 2; pop; +`, AssemblerMaxVersion) testProg(t, `int 4; byte "ayush"; int 5; cover 1; pop; +`, AssemblerMaxVersion) - testProg(t, `int 4; byte "john"; int 5; cover 2; +`, AssemblerMaxVersion, exp(1, "+ arg 1...")) + testProg(t, `int 4; byte "john"; int 5; cover 2; +`, AssemblerMaxVersion, exp(1, "+ arg B...")) testProg(t, `int 4; cover junk`, AssemblerMaxVersion, exp(1, "cover unable to parse n ...")) testProg(t, notrack(`int 4; int 5; cover 0`), AssemblerMaxVersion) @@ -2818,7 +2819,7 @@ func TestUncoverAsm(t *testing.T) { testProg(t, `int 4; byte "john"; int 5; uncover 2; +`, AssemblerMaxVersion) testProg(t, `int 4; byte "ayush"; int 5; uncover 1; pop; +`, AssemblerMaxVersion) testProg(t, `int 1; byte "jj"; byte "ayush"; byte "john"; int 5; uncover 4; +`, AssemblerMaxVersion) - testProg(t, `int 4; byte "ayush"; int 5; uncover 1; +`, AssemblerMaxVersion, exp(1, "+ arg 1...")) + testProg(t, `int 4; byte "ayush"; int 5; uncover 1; +`, AssemblerMaxVersion, exp(1, "+ arg B...")) } func TestTxTypes(t *testing.T) { @@ -2866,7 +2867,7 @@ func TestTypeTracking(t *testing.T) { // but we do want to ensure we're not just treating the code after callsub as dead testProg(t, "callsub A; int 1; concat; return; A: int 1; int 2; retsub", LogicVersion, - exp(1, "concat arg 1 wanted...")) + exp(1, "concat arg B wanted...")) // retsub deadens code, like any unconditional branch testProg(t, "callsub A; +; return; A: int 1; int 2; retsub; concat", LogicVersion) @@ -2882,7 +2883,7 @@ label: + confusion: b label -`, LogicVersion, exp(7, "+ arg 0 wanted type uint64...")) +`, LogicVersion, exp(7, "+ arg A wanted type uint64...")) // Unless that same error is in dead code. testProg(t, ` @@ -2936,7 +2937,7 @@ done: concat #pragma typetrack true concat -`, LogicVersion, exp(5, "concat arg 1 wanted type []byte...")) +`, LogicVersion, exp(5, "concat arg B wanted type []byte...")) } func TestMergeProtos(t *testing.T) { @@ -2994,7 +2995,7 @@ func TestReplacePseudo(t *testing.T) { testProg(t, "byte 0x0000; byte 0x1234; replace 0", v) testProg(t, "byte 0x0000; int 0; byte 0x1234; replace", v) testProg(t, "byte 0x0000; byte 0x1234; replace", v, exp(1, "replace without immediates expects 3 stack arguments but stack height is 2")) - testProg(t, "byte 0x0000; int 0; byte 0x1234; replace 0", v, exp(1, "replace 0 arg 0 wanted type []byte got 0")) + testProg(t, "byte 0x0000; int 0; byte 0x1234; replace 0", v, exp(1, "replace 0 arg A wanted type []byte got 0")) } } @@ -3055,7 +3056,7 @@ func TestAssembleSwitch(t *testing.T) { byte "fail" switch label1 labe11: - `, AssemblerMaxVersion, exp(3, "switch label1 arg 0 wanted type uint64...")) + `, AssemblerMaxVersion, exp(3, "switch label1 arg A wanted type uint64...")) // No labels is pretty degenerate, but ok, I suppose. It's just a no-op testProg(t, ` @@ -3569,9 +3570,9 @@ func TestAssemblePushConsts(t *testing.T) { source = `pushbytess 1 2 3` testProg(t, source, AssemblerMaxVersion, exp(1, "pushbytess arg did not parse: 1")) source = `pushints 6 4; concat` - testProg(t, source, AssemblerMaxVersion, exp(1, "concat arg 1 wanted type []byte got uint64")) + testProg(t, source, AssemblerMaxVersion, exp(1, "concat arg B wanted type []byte got uint64")) source = `pushbytess "x" "y"; +` - testProg(t, source, AssemblerMaxVersion, exp(1, "+ arg 1 wanted type uint64 got []byte")) + testProg(t, source, AssemblerMaxVersion, exp(1, "+ arg B wanted type uint64 got []byte")) } func TestAssembleEmpty(t *testing.T) { diff --git a/data/transactions/logic/crypto.go b/data/transactions/logic/crypto.go index 43fe4d50d5..f0c5552f4e 100644 --- a/data/transactions/logic/crypto.go +++ b/data/transactions/logic/crypto.go @@ -27,6 +27,7 @@ import ( "github.com/algorand/go-algorand/crypto" "github.com/algorand/go-algorand/crypto/secp256k1" + "github.com/algorand/go-algorand/data/basics" "github.com/algorand/go-algorand/protocol" "golang.org/x/crypto/sha3" ) @@ -136,6 +137,62 @@ func opEd25519VerifyBare(cx *EvalContext) error { return nil } +func opHeartbeat(cx *EvalContext) error { + last := len(cx.Stack) - 1 + pk2sig := last - 1 + pk2 := last - 2 + pk1sig := last - 3 + pk := last - 4 + sig := last - 5 + + addr, _, err := cx.accountReference(cx.Stack[last]) + if err != nil { + return err + } + + account, err := cx.Ledger.AccountData(addr) + if err != nil { + return err + } + + sv := account.VoteID + if sv.IsEmpty() { + return fmt.Errorf("Account %s has has no voting keys\n", addr) + } + id := basics.OneTimeIDForRound(cx.txn.Txn.LastValid, account.VoteKeyDilution) + + err = cx.checkStackArgBounds() + if err != nil { + return err + } + + ots := crypto.OneTimeSignature{ + Sig: [64]byte(cx.Stack[sig].Bytes), // the sig for the message, by PK + PK: [32]byte(cx.Stack[pk].Bytes), // the actual key that signed the message + PK1Sig: [64]byte(cx.Stack[pk1sig].Bytes), // the sig that proves PK is valid + PK2: [32]byte(cx.Stack[pk2].Bytes), // the key that signed to create PK1Sig + PK2Sig: [64]byte(cx.Stack[pk2sig].Bytes), // the sig that proves PK2 is valid, signed by VoteID + } + + rnd, err := cx.availableRound(uint64(cx.txn.Txn.FirstValid) - 1) + if err != nil { + return err + } + hdr, err := cx.SigLedger.BlockHdr(rnd) + if err != nil { + return err + } + + if !sv.Verify(id, hdr.Seed, ots) { + return errors.New("Improper heartbeat") + } + + cx.Ledger.Heartbeat(addr) + + cx.Stack = cx.Stack[:sig] + return nil +} + func leadingZeros(size int, b *big.Int) ([]byte, error) { byteLength := (b.BitLen() + 7) / 8 if size < byteLength { diff --git a/data/transactions/logic/crypto_test.go b/data/transactions/logic/crypto_test.go index 7c0dc5f582..22e6fd8d68 100644 --- a/data/transactions/logic/crypto_test.go +++ b/data/transactions/logic/crypto_test.go @@ -112,9 +112,9 @@ func TestVrfVerify(t *testing.T) { t.Parallel() ep := defaultAppParams() - testApp(t, notrack("int 1; int 2; int 3; vrf_verify VrfAlgorand"), ep, "arg 0 wanted") - testApp(t, notrack("byte 0x1122; int 2; int 3; vrf_verify VrfAlgorand"), ep, "arg 1 wanted") - testApp(t, notrack("byte 0x1122; byte 0x2233; int 3; vrf_verify VrfAlgorand"), ep, "arg 2 wanted") + testApp(t, notrack("int 1; int 2; int 3; vrf_verify VrfAlgorand"), ep, "arg A wanted") + testApp(t, notrack("byte 0x1122; int 2; int 3; vrf_verify VrfAlgorand"), ep, "arg B wanted") + testApp(t, notrack("byte 0x1122; byte 0x2233; int 3; vrf_verify VrfAlgorand"), ep, "arg C wanted") ep = defaultSigParams() testLogic(t, notrack("byte 0x1122; byte 0x2233; byte 0x3344; vrf_verify VrfAlgorand"), LogicVersion, ep, "vrf proof wrong size") @@ -184,13 +184,17 @@ pop // output`, "int 1"}, } } +func randSeed() crypto.Seed { + var s crypto.Seed + crypto.RandBytes(s[:]) + return s +} + func TestEd25519verify(t *testing.T) { partitiontest.PartitionTest(t) t.Parallel() - var s crypto.Seed - crypto.RandBytes(s[:]) - c := crypto.GenerateSignatureSecrets(s) + c := crypto.GenerateSignatureSecrets(randSeed()) msg := "62fdfc072182654f163f5f0f9a621d729566c74d0aa413bf009c9800418c19cd" data, err := hex.DecodeString(msg) require.NoError(t, err) @@ -229,9 +233,7 @@ func TestEd25519VerifyBare(t *testing.T) { partitiontest.PartitionTest(t) t.Parallel() - var s crypto.Seed - crypto.RandBytes(s[:]) - c := crypto.GenerateSignatureSecrets(s) + c := crypto.GenerateSignatureSecrets(randSeed()) msg := "62fdfc072182654f163f5f0f9a621d729566c74d0aa413bf009c9800418c19cd" data, err := hex.DecodeString(msg) require.NoError(t, err) @@ -264,6 +266,64 @@ func TestEd25519VerifyBare(t *testing.T) { } } +func TestPartkeyVerify(t *testing.T) { + partitiontest.PartitionTest(t) + t.Parallel() + + for v := uint64(10); v <= AssemblerMaxVersion; v++ { + t.Run(fmt.Sprintf("v=%d", v), func(t *testing.T) { + ops := testProg(t, ` + // OneTimeSignature in 5 parts + txn ApplicationArgs 0; + txn ApplicationArgs 1; + txn ApplicationArgs 2; + txn ApplicationArgs 3; + txn ApplicationArgs 4; + + txn Sender; + heartbeat; + + txn Sender + acct_params_get AcctLastHeartbeat + assert + global Round + == +`, v) + ep, tx, ledger := makeSampleEnv() + ep.Proto.MaxAppProgramCost = 6000 // ugly. real heartbeats would need a lot of opup + + id := basics.OneTimeIDForRound(tx.LastValid, 10_000) + otss := crypto.GenerateOneTimeSignatureSecrets(id.Batch, 1) + + hdr, err := ledger.BlockHdr(tx.FirstValid - 1) + require.NoError(t, err) + ots := otss.Sign(id, hdr.Seed) + + tx.ApplicationArgs = [][]byte{ + ots.Sig[:], + ots.PK[:], + ots.PK1Sig[:], + ots.PK2[:], + ots.PK2Sig[:], + } + testLogicBytes(t, ops.Program, defaultSigParams(transactions.SignedTxn{Txn: *tx}), + "not allowed in current mode", "not allowed in current mode") + ledger.NewAccount(tx.Sender, 1_000_000) + ledger.NewVoting(tx.Sender, otss.OneTimeSignatureVerifier) + testAppBytes(t, ops.Program, ep) + + // change a byte in any arg, fail + for i := range tx.ApplicationArgs { + tx.ApplicationArgs[i][0]++ + testAppBytes(t, ops.Program, ep, "REJECT") + tx.ApplicationArgs[i][0]-- + } + // confirm back to passing + testAppBytes(t, ops.Program, ep) + }) + } +} + func keyToByte(tb testing.TB, b *big.Int) []byte { k := make([]byte, 32) require.NotPanics(tb, func() { @@ -680,9 +740,7 @@ func BenchmarkEd25519Verifyx1(b *testing.B) { crypto.RandBytes(buffer[:]) data = append(data, buffer) - var s crypto.Seed //generate programs and signatures - crypto.RandBytes(s[:]) - secret := crypto.GenerateSignatureSecrets(s) + secret := crypto.GenerateSignatureSecrets(randSeed()) //generate programs and signatures pk := basics.Address(secret.SignatureVerifier) pkStr := pk.String() ops, err := AssembleStringWithVersion(fmt.Sprintf(`arg 0 @@ -864,3 +922,13 @@ int 1` benchmarkEcdsa(b, source, Secp256k1) }) } + +const incentiveNonsense = ` +pushbytes "X" +pushbytes "sig" +int 1 +heartbeat +` + +// ------------------------pb 1 X pb 3 S I G 1 pv +const incentiveCompiled = "80 01 58 80 03 73 69 67 22 87" diff --git a/data/transactions/logic/doc.go b/data/transactions/logic/doc.go index c060d82623..1e3f48de86 100644 --- a/data/transactions/logic/doc.go +++ b/data/transactions/logic/doc.go @@ -41,6 +41,7 @@ var opDescByName = map[string]OpDesc{ "ed25519verify": {"for (data A, signature B, pubkey C) verify the signature of (\"ProgData\" || program_hash || data) against the pubkey => {0 or 1}", "The 32 byte public key is the last element on the stack, preceded by the 64 byte signature at the second-to-last element on the stack, preceded by the data which was signed at the third-to-last element on the stack.", nil}, "ed25519verify_bare": {"for (data A, signature B, pubkey C) verify the signature of the data against the pubkey => {0 or 1}", "", nil}, "ecdsa_verify": {"for (data A, signature B, C and pubkey D, E) verify the signature of the data against the pubkey => {0 or 1}", "The 32 byte Y-component of a public key is the last element on the stack, preceded by X-component of a pubkey, preceded by S and R components of a signature, preceded by the data that is fifth element on the stack. All values are big-endian encoded. The signed data must be 32 bytes long, and signatures in lower-S form are only accepted.", []string{"curve index"}}, + "heartbeat": {"for (signature components A, B, C, D, E, and account F) verify the signature of the block seed from round txn.FirstValid-1 using F's partkey for txn.LastValid", "", nil}, "ecdsa_pk_decompress": {"decompress pubkey A into components X, Y", "The 33 byte public key in a compressed form to be decompressed into X and Y (top) components. All values are big-endian encoded.", []string{"curve index"}}, "ecdsa_pk_recover": {"for (data A, recovery id B, signature C, D) recover a public key", "S (top) and R elements of a signature, recovery id and data (bottom) are expected on the stack and used to deriver a public key. All values are big-endian encoded. The signed data must be 32 bytes long.", []string{"curve index"}}, @@ -347,7 +348,7 @@ var OpGroups = map[string][]string{ "Byte Array Manipulation": {"getbit", "setbit", "getbyte", "setbyte", "concat", "len", "substring", "substring3", "extract", "extract3", "extract_uint16", "extract_uint32", "extract_uint64", "replace2", "replace3", "base64_decode", "json_ref"}, "Byte Array Arithmetic": {"b+", "b-", "b/", "b*", "b<", "b>", "b<=", "b>=", "b==", "b!=", "b%", "bsqrt"}, "Byte Array Logic": {"b|", "b&", "b^", "b~"}, - "Cryptography": {"sha256", "keccak256", "sha512_256", "sha3_256", "ed25519verify", "ed25519verify_bare", "ecdsa_verify", "ecdsa_pk_recover", "ecdsa_pk_decompress", "vrf_verify", "ec_add", "ec_scalar_mul", "ec_pairing_check", "ec_multi_scalar_mul", "ec_subgroup_check", "ec_map_to"}, + "Cryptography": {"sha256", "keccak256", "sha512_256", "sha3_256", "ed25519verify", "ed25519verify_bare", "ecdsa_verify", "heartbeat", "ecdsa_pk_recover", "ecdsa_pk_decompress", "vrf_verify", "ec_add", "ec_scalar_mul", "ec_pairing_check", "ec_multi_scalar_mul", "ec_subgroup_check", "ec_map_to"}, "Loading Values": {"intcblock", "intc", "intc_0", "intc_1", "intc_2", "intc_3", "pushint", "pushints", "bytecblock", "bytec", "bytec_0", "bytec_1", "bytec_2", "bytec_3", "pushbytes", "pushbytess", "bzero", "arg", "arg_0", "arg_1", "arg_2", "arg_3", "args", "txn", "gtxn", "txna", "txnas", "gtxna", "gtxnas", "gtxns", "gtxnsa", "gtxnsas", "global", "load", "loads", "store", "stores", "gload", "gloads", "gloadss", "gaid", "gaids"}, "Flow Control": {"err", "bnz", "bz", "b", "return", "pop", "popn", "dup", "dup2", "dupn", "dig", "bury", "cover", "uncover", "frame_dig", "frame_bury", "swap", "select", "assert", "callsub", "proto", "retsub", "switch", "match"}, "State Access": {"balance", "min_balance", "app_opted_in", "app_local_get", "app_local_get_ex", "app_global_get", "app_global_get_ex", "app_local_put", "app_global_put", "app_local_del", "app_global_del", "asset_holding_get", "asset_params_get", "app_params_get", "acct_params_get", "log", "block"}, diff --git a/data/transactions/logic/eval.go b/data/transactions/logic/eval.go index 08cc62feef..62caf20356 100644 --- a/data/transactions/logic/eval.go +++ b/data/transactions/logic/eval.go @@ -239,6 +239,8 @@ type LedgerForLogic interface { Perform(gi int, ep *EvalParams) error Counter() uint64 + + Heartbeat(addr basics.Address) error } // BoxRef is the "hydrated" form of a transactions.BoxRef - it has the actual app id, not an index @@ -900,6 +902,32 @@ func (st StackType) overlaps(expected StackType) bool { return smin <= emax && smax >= emin } +func (st StackType) checkBounds(value stackValue) error { + switch st.AVMType { + case avmAny: + return nil + case avmUint64: + if value.Uint < st.Bound[0] { + return fmt.Errorf("value is too small (%d < %d)", value.Uint, st.Bound[0]) + } + if value.Uint > st.Bound[1] { + return fmt.Errorf("value is too large (%d > %d)", value.Uint, st.Bound[1]) + } + return nil + case avmBytes: + l := uint64(len(value.Bytes)) + if l < st.Bound[0] { + return fmt.Errorf("length is too small (%d < %d)", l, st.Bound[0]) + } + if l > st.Bound[1] { + return fmt.Errorf("length is too large (%d > %d)", l, st.Bound[1]) + } + return nil + default: + panic(st) + } +} + func (st StackType) String() string { return st.Name } @@ -1383,6 +1411,29 @@ func (cx *EvalContext) remainingInners() int { return cx.Proto.MaxInnerTransactions - len(cx.txn.EvalDelta.InnerTxns) } +// checkStackArgBounds confirms that all arguments obey StackType bounds. It +// plows along without check the AVMType because that will already have been +// checked. It is only invoked explicitly by specific opcodes, rather than in +// step() to avoid pointless overhead, as most opcodes have no specific bounds. + +func argName(i int) rune { + return rune(int('A') + i) +} + +func (cx *EvalContext) checkStackArgBounds() error { + opcode := cx.program[cx.pc] + spec := &opsByOpcode[cx.version][opcode] + + first := len(cx.Stack) - len(spec.Arg.Types) + for i, argType := range spec.Arg.Types { + value := cx.Stack[first+i] + if err := argType.checkBounds(value); err != nil { + return fmt.Errorf("%s arg %c's %w", spec.Name, argName(i), err) + } + } + return nil +} + func (cx *EvalContext) step() error { opcode := cx.program[cx.pc] spec := &opsByOpcode[cx.version][opcode] @@ -1402,7 +1453,7 @@ func (cx *EvalContext) step() error { first := len(cx.Stack) - len(spec.Arg.Types) for i, argType := range spec.Arg.Types { if !opCompat(argType.AVMType, cx.Stack[first+i].avmType()) { - return fmt.Errorf("%s arg %d wanted %s but got %s", spec.Name, i, argType, cx.Stack[first+i].typeName()) + return fmt.Errorf("%s arg %c wanted %s but got %s", spec.Name, argName(i), argType, cx.Stack[first+i].typeName()) } } @@ -1443,17 +1494,17 @@ func (cx *EvalContext) step() error { if err == nil && !spec.trusted { postheight := len(cx.Stack) if postheight-preheight != len(spec.Return.Types)-len(spec.Arg.Types) && !spec.AlwaysExits() { - return fmt.Errorf("%s changed stack height improperly %d != %d", - spec.Name, postheight-preheight, len(spec.Return.Types)-len(spec.Arg.Types)) + return fmt.Errorf("%s changed stack height improperly. Expected %d, Actual %d", + spec.Name, len(spec.Return.Types)-len(spec.Arg.Types), postheight-preheight) } first = postheight - len(spec.Return.Types) - for i, argType := range spec.Return.Types { + for i, retType := range spec.Return.Types { stackType := cx.Stack[first+i].avmType() - if !opCompat(argType.AVMType, stackType) { - if spec.AlwaysExits() { // We test in the loop because it's the uncommon case. + if !opCompat(retType.AVMType, stackType) { + if spec.AlwaysExits() { // We check "late", because it's the uncommon case. break } - return fmt.Errorf("%s produced %s but intended %s", spec.Name, cx.Stack[first+i].typeName(), argType) + return fmt.Errorf("%s produced %s but intended %s", spec.Name, cx.Stack[first+i].typeName(), retType) } if stackType == avmBytes && len(cx.Stack[first+i].Bytes) > maxStringSize { return fmt.Errorf("%s produced a too big (%d) byte-array", spec.Name, len(cx.Stack[first+i].Bytes)) @@ -1530,7 +1581,7 @@ func (cx *EvalContext) step() error { // because the static cost would be wrong. But then again, a static cost model // wouldn't work before backBranchEnabledVersion, so such an opcode is already // unacceptable. TestLinearOpcodes ensures. -var blankStack = make([]stackValue, 5) +var blankStack = make([]stackValue, 6) func (cx *EvalContext) checkStep() (int, error) { cx.instructionStarts[cx.pc] = true @@ -4897,6 +4948,14 @@ func opAcctParamsGet(cx *EvalContext) error { value.Uint = account.TotalBoxes case AcctTotalBoxBytes: value.Uint = account.TotalBoxBytes + + case AcctLastProposed: + value.Uint = uint64(account.LastProposed) + case AcctLastHeartbeat: + value.Uint = uint64(account.LastHeartbeat) + + default: + return fmt.Errorf("invalid acct_params_get field %s", paramField) } cx.Stack[last] = value cx.Stack = append(cx.Stack, boolToSV(account.MicroAlgos.Raw > 0)) diff --git a/data/transactions/logic/evalStateful_test.go b/data/transactions/logic/evalStateful_test.go index 436643e4c2..3c6a7dc00a 100644 --- a/data/transactions/logic/evalStateful_test.go +++ b/data/transactions/logic/evalStateful_test.go @@ -406,7 +406,7 @@ func TestBalance(t *testing.T) { // won't assemble in old version teal if v < directRefEnabledVersion { testProg(t, source, ep.Proto.LogicSigVersion, - exp(1, "balance arg 0 wanted type uint64...")) + exp(1, "balance arg A wanted type uint64...")) return } @@ -655,7 +655,7 @@ func TestAppCheckOptedIn(t *testing.T) { testApp(t, "int 1; int 2; app_opted_in; int 0; ==", pre) // in pre, int 2 is an actual app id testApp(t, "byte \"aoeuiaoeuiaoeuiaoeuiaoeuiaoeui01\"; int 2; app_opted_in; int 1; ==", now) testProg(t, "byte \"aoeuiaoeuiaoeuiaoeuiaoeuiaoeui01\"; int 2; app_opted_in; int 1; ==", directRefEnabledVersion-1, - exp(1, "app_opted_in arg 0 wanted type uint64...")) + exp(1, "app_opted_in arg A wanted type uint64...")) // Receiver opts into 888, the current app in testApp ledger.NewLocals(txn.Txn.Receiver, 888) @@ -730,7 +730,7 @@ byte "ALGO" testApp(t, text, now) testApp(t, strings.Replace(text, "int 1 // account idx", "byte \"aoeuiaoeuiaoeuiaoeuiaoeuiaoeui01\"", -1), now) testProg(t, strings.Replace(text, "int 1 // account idx", "byte \"aoeuiaoeuiaoeuiaoeuiaoeuiaoeui01\"", -1), directRefEnabledVersion-1, - exp(4, "app_local_get_ex arg 0 wanted type uint64...")) + exp(4, "app_local_get_ex arg A wanted type uint64...")) testApp(t, strings.Replace(text, "int 100 // app id", "int 2", -1), now) // Next we're testing if the use of the current app's id works // as a direct reference. The error is because the receiver @@ -803,7 +803,7 @@ byte "ALGO" testApp(t, text, now) testApp(t, strings.Replace(text, "int 0 // account idx", "byte \"aoeuiaoeuiaoeuiaoeuiaoeuiaoeui00\"", -1), now) testProg(t, strings.Replace(text, "int 0 // account idx", "byte \"aoeuiaoeuiaoeuiaoeuiaoeuiaoeui00\"", -1), directRefEnabledVersion-1, - exp(3, "app_local_get arg 0 wanted type uint64...")) + exp(3, "app_local_get arg A wanted type uint64...")) testApp(t, strings.Replace(text, "int 0 // account idx", "byte \"aoeuiaoeuiaoeuiaoeuiaoeuiaoeui01\"", -1), now) testApp(t, strings.Replace(text, "int 0 // account idx", "byte \"aoeuiaoeuiaoeuiaoeuiaoeuiaoeui02\"", -1), now, "invalid Account reference") @@ -1065,7 +1065,7 @@ func testAssetsByVersion(t *testing.T, assetsTestProgram string, version uint64) // it wasn't legal to use a direct ref for account testProg(t, `byte "aoeuiaoeuiaoeuiaoeuiaoeuiaoeui00"; int 54; asset_holding_get AssetBalance`, - directRefEnabledVersion-1, exp(1, "asset_holding_get AssetBalance arg 0 wanted type uint64...")) + directRefEnabledVersion-1, exp(1, "asset_holding_get AssetBalance arg A wanted type uint64...")) // but it is now (empty asset yields 0,0 on stack) testApp(t, `byte "aoeuiaoeuiaoeuiaoeuiaoeuiaoeui00"; int 55; asset_holding_get AssetBalance; ==`, now) // This is receiver, who is in Assets array @@ -1108,7 +1108,7 @@ func testAssetsByVersion(t *testing.T, assetsTestProgram string, version uint64) testApp(t, strings.Replace(assetsTestProgram, "int 55", "int 0", -1), now) // but old code cannot - testProg(t, strings.Replace(assetsTestProgram, "int 0//account", "byte \"aoeuiaoeuiaoeuiaoeuiaoeuiaoeui00\"", -1), directRefEnabledVersion-1, exp(3, "asset_holding_get AssetBalance arg 0 wanted type uint64...")) + testProg(t, strings.Replace(assetsTestProgram, "int 0//account", "byte \"aoeuiaoeuiaoeuiaoeuiaoeuiaoeui00\"", -1), directRefEnabledVersion-1, exp(3, "asset_holding_get AssetBalance arg A wanted type uint64...")) if version < 5 { // Can't run these with AppCreator anyway @@ -2445,7 +2445,7 @@ int 1 delta := testApp(t, withBytes, ep) // But won't even compile in old teal testProg(t, withBytes, directRefEnabledVersion-1, - exp(4, "app_local_put arg 0 wanted..."), exp(11, "app_local_del arg 0 wanted...")) + exp(4, "app_local_put arg A wanted..."), exp(11, "app_local_del arg A wanted...")) require.Equal(t, 0, len(delta.GlobalDelta)) require.Equal(t, 2, len(delta.LocalDeltas)) ledger.Reset() @@ -3098,7 +3098,8 @@ func TestReturnTypes(t *testing.T) { "err": true, "return": true, - "ecdsa_pk_decompress": true, + "ecdsa_pk_decompress": true, // requires a [33]byte arg + "heartbeat": true, // panics unless it verifies "frame_dig": true, // would need a "proto" subroutine "frame_bury": true, // would need a "proto" subroutine @@ -3366,7 +3367,7 @@ func TestLog(t *testing.T) { }, { source: `load 0; log`, - errContains: "log arg 0 wanted []byte but got uint64", + errContains: "log arg A wanted []byte but got uint64", assembledBytes: []byte{byte(ep.Proto.LogicSigVersion), 0x34, 0x00, 0xb0}, }, } diff --git a/data/transactions/logic/eval_test.go b/data/transactions/logic/eval_test.go index fd8b9ff806..06f2efbed9 100644 --- a/data/transactions/logic/eval_test.go +++ b/data/transactions/logic/eval_test.go @@ -3083,7 +3083,7 @@ func TestWrongStackTypeRuntime(t *testing.T) { t.Run(fmt.Sprintf("v=%d", v), func(t *testing.T) { ops := testProg(t, `int 1`, v) ops.Program = append(ops.Program, 0x01, 0x15) // sha256, len - testLogicBytes(t, ops.Program, nil, "sha256 arg 0 wanted") + testLogicBytes(t, ops.Program, nil, "sha256 arg A wanted") }) } } @@ -3123,7 +3123,7 @@ func TestWrongStackTypeRuntime2(t *testing.T) { t.Run(fmt.Sprintf("v=%d", v), func(t *testing.T) { ops := testProg(t, `byte 0x1234; int 1`, v) ops.Program = append(ops.Program, 0x08) // + - testLogicBytes(t, ops.Program, nil, "+ arg 0 wanted") + testLogicBytes(t, ops.Program, nil, "+ arg A wanted") }) } } diff --git a/data/transactions/logic/fields.go b/data/transactions/logic/fields.go index 77e3de23e0..a6b01a500a 100644 --- a/data/transactions/logic/fields.go +++ b/data/transactions/logic/fields.go @@ -1313,6 +1313,12 @@ const ( // AcctTotalAppSchema - consider how to expose + // AcctLastProposed is the last round that this account was the propser + AcctLastProposed + // AcctLastHeartbeat is the last round in which this account went online, + // or the `heartbeat` opcode executed in a valid transaction for it. + AcctLastHeartbeat + invalidAcctParamsField // compile-time constant for number of fields ) @@ -1355,6 +1361,9 @@ var acctParamsFieldSpecs = [...]acctParamsFieldSpec{ {AcctTotalAssets, StackUint64, 8, "The numbers of ASAs held by this account (including ASAs this account created)."}, {AcctTotalBoxes, StackUint64, boxVersion, "The number of existing boxes created by this account's app."}, {AcctTotalBoxBytes, StackUint64, boxVersion, "The total number of bytes used by this account's app's box keys and values."}, + + {AcctLastProposed, StackUint64, incentiveVersion, "The round in which this account last proposed."}, + {AcctLastHeartbeat, StackUint64, incentiveVersion, "The round in which the account went online or executed `heartbeat`."}, } func acctParamsFieldSpecByField(f AcctParamsField) (acctParamsFieldSpec, bool) { diff --git a/data/transactions/logic/fields_string.go b/data/transactions/logic/fields_string.go index 2bf79d7a82..17d17cb844 100644 --- a/data/transactions/logic/fields_string.go +++ b/data/transactions/logic/fields_string.go @@ -194,12 +194,14 @@ func _() { _ = x[AcctTotalAssets-9] _ = x[AcctTotalBoxes-10] _ = x[AcctTotalBoxBytes-11] - _ = x[invalidAcctParamsField-12] + _ = x[AcctLastProposed-12] + _ = x[AcctLastHeartbeat-13] + _ = x[invalidAcctParamsField-14] } -const _AcctParamsField_name = "AcctBalanceAcctMinBalanceAcctAuthAddrAcctTotalNumUintAcctTotalNumByteSliceAcctTotalExtraAppPagesAcctTotalAppsCreatedAcctTotalAppsOptedInAcctTotalAssetsCreatedAcctTotalAssetsAcctTotalBoxesAcctTotalBoxBytesinvalidAcctParamsField" +const _AcctParamsField_name = "AcctBalanceAcctMinBalanceAcctAuthAddrAcctTotalNumUintAcctTotalNumByteSliceAcctTotalExtraAppPagesAcctTotalAppsCreatedAcctTotalAppsOptedInAcctTotalAssetsCreatedAcctTotalAssetsAcctTotalBoxesAcctTotalBoxBytesAcctLastProposedAcctLastHeartbeatinvalidAcctParamsField" -var _AcctParamsField_index = [...]uint8{0, 11, 25, 37, 53, 74, 96, 116, 136, 158, 173, 187, 204, 226} +var _AcctParamsField_index = [...]uint16{0, 11, 25, 37, 53, 74, 96, 116, 136, 158, 173, 187, 204, 220, 237, 259} func (i AcctParamsField) String() string { if i < 0 || i >= AcctParamsField(len(_AcctParamsField_index)-1) { diff --git a/data/transactions/logic/langspec_v10.json b/data/transactions/logic/langspec_v10.json index daaa484a73..192b10a149 100644 --- a/data/transactions/logic/langspec_v10.json +++ b/data/transactions/logic/langspec_v10.json @@ -2891,7 +2891,9 @@ "AcctTotalAssetsCreated", "AcctTotalAssets", "AcctTotalBoxes", - "AcctTotalBoxBytes" + "AcctTotalBoxBytes", + "AcctLastProposed", + "AcctLastHeartbeat" ], "ArgEnumTypes": [ "uint64", @@ -2905,6 +2907,8 @@ "uint64", "uint64", "uint64", + "uint64", + "uint64", "uint64" ], "DocCost": "1", @@ -3041,6 +3045,25 @@ "Cryptography" ] }, + { + "Opcode": 135, + "Name": "heartbeat", + "Args": [ + "[64]byte", + "[32]byte", + "[64]byte", + "[32]byte", + "[64]byte", + "any" + ], + "Size": 1, + "DocCost": "5700", + "Doc": "for (signature components A, B, C, D, E, and account F) verify the signature of the block seed from round txn.FirstValid-1 using F's partkey for txn.LastValid", + "IntroducedVersion": 10, + "Groups": [ + "Cryptography" + ] + }, { "Opcode": 136, "Name": "callsub", diff --git a/data/transactions/logic/ledger_test.go b/data/transactions/logic/ledger_test.go index a111eec131..6b490b0981 100644 --- a/data/transactions/logic/ledger_test.go +++ b/data/transactions/logic/ledger_test.go @@ -36,6 +36,7 @@ import ( "math" "math/rand" + "github.com/algorand/go-algorand/crypto" "github.com/algorand/go-algorand/data/basics" "github.com/algorand/go-algorand/data/bookkeeping" "github.com/algorand/go-algorand/data/committee" @@ -45,9 +46,12 @@ import ( ) type balanceRecord struct { - addr basics.Address - auth basics.Address - balance uint64 + addr basics.Address + auth basics.Address + balance uint64 + voting ledgercore.VotingData + heartbeat basics.Round // The last round that this account sent a heartbeat to show it was online. + locals map[basics.AppIndex]basics.TealKeyValue holdings map[basics.AssetIndex]basics.AssetHolding mods map[basics.AppIndex]map[string]basics.ValueDelta @@ -118,6 +122,18 @@ func (l *Ledger) NewAccount(addr basics.Address, balance uint64) { l.balances[addr] = newBalanceRecord(addr, balance) } +// NewVoting sets VoteID on the account. Could expand to set other voting data +// if that became useful in tests. +func (l *Ledger) NewVoting(addr basics.Address, voteID crypto.OneTimeSignatureVerifier) { + br, ok := l.balances[addr] + if !ok { + br = newBalanceRecord(addr, 0) + } + br.voting.VoteID = voteID + br.voting.VoteKeyDilution = 10_000 + l.balances[addr] = br +} + // NewApp add a new AVM app to the Ledger. In most uses, it only sets up the id // and schema but no code, as testing will want to try many different code // sequences. @@ -305,7 +321,10 @@ func (l *Ledger) AccountData(addr basics.Address) (ledgercore.AccountData, error TotalBoxes: uint64(boxesTotal), TotalBoxBytes: uint64(boxBytesTotal), + + LastHeartbeat: br.heartbeat, }, + VotingData: br.voting, }, nil } @@ -900,6 +919,18 @@ func (l *Ledger) Perform(gi int, ep *EvalParams) error { } } +// Heartbeat increments the given addr's LastHeartbeat +func (l *Ledger) Heartbeat(addr basics.Address) error { + br, ok := l.balances[addr] + if !ok { + return fmt.Errorf("no account %s", addr) + } + br.heartbeat = l.Round() + fmt.Printf("%+v\n", br) + l.balances[addr] = br + return nil +} + // Get returns the AccountData of an address. This test ledger does // not handle rewards, so the pening rewards flag is ignored. func (l *Ledger) Get(addr basics.Address, withPendingRewards bool) (basics.AccountData, error) { @@ -913,6 +944,7 @@ func (l *Ledger) Get(addr basics.Address, withPendingRewards bool) (basics.Accou Assets: map[basics.AssetIndex]basics.AssetHolding{}, AppLocalStates: map[basics.AppIndex]basics.AppLocalState{}, AppParams: map[basics.AppIndex]basics.AppParams{}, + LastHeartbeat: br.heartbeat, }, nil } diff --git a/data/transactions/logic/opcodes.go b/data/transactions/logic/opcodes.go index 1f98bfaf61..0bd22668b0 100644 --- a/data/transactions/logic/opcodes.go +++ b/data/transactions/logic/opcodes.go @@ -118,11 +118,10 @@ func (lc *linearCost) docCost(argLen int) string { return strconv.Itoa(lc.baseCost) } idxFromStart := argLen - lc.depth - 1 - stackArg := rune(int('A') + idxFromStart) if lc.chunkSize == 1 { - return fmt.Sprintf("%d + %d per byte of %c", lc.baseCost, lc.chunkCost, stackArg) + return fmt.Sprintf("%d + %d per byte of %c", lc.baseCost, lc.chunkCost, argName(idxFromStart)) } - return fmt.Sprintf("%d + %d per %d bytes of %c", lc.baseCost, lc.chunkCost, lc.chunkSize, stackArg) + return fmt.Sprintf("%d + %d per %d bytes of %c", lc.baseCost, lc.chunkCost, lc.chunkSize, argName(idxFromStart)) } // OpDetails records details such as non-standard costs, immediate arguments, or @@ -647,6 +646,9 @@ var OpSpecs = []OpSpec{ {0x83, "pushints", opPushInts, proto(":", "", "[N items]").stackExplain(opPushIntsStackChange), 8, constants(asmPushInts, checkIntImmArgs, "uint ...", immInts).typed(typePushInts).trust()}, {0x84, "ed25519verify_bare", opEd25519VerifyBare, proto("b63:T"), 7, costly(1900)}, + {0x84, "ed25519verify_bare", opEd25519VerifyBare, proto("b63:T"), 7, costly(1900)}, + // leaving room for falcon_verify and sumhash512 + {0x87, "heartbeat", opHeartbeat, proto("63636a:"), incentiveVersion, only(ModeApp).costs(3 * 1900)}, // "Function oriented" {0x88, "callsub", opCallSub, proto(":"), 4, detBranch()}, diff --git a/data/transactions/logic/teal.tmLanguage.json b/data/transactions/logic/teal.tmLanguage.json index a8f72ea280..1691070cab 100644 --- a/data/transactions/logic/teal.tmLanguage.json +++ b/data/transactions/logic/teal.tmLanguage.json @@ -76,7 +76,7 @@ }, { "name": "keyword.operator.teal", - "match": "^(\\!|\\!\\=|%|\u0026|\u0026\u0026|\\*|\\+|\\-|/|\\\u003c|\\\u003c\\=|\\=\\=|\\\u003e|\\\u003e\\=|\\^|addw|bitlen|btoi|divmodw|divw|exp|expw|itob|mulw|shl|shr|sqrt|\\||\\|\\||\\~|b\\!\\=|b%|b\\*|b\\+|b\\-|b/|b\\\u003c|b\\\u003c\\=|b\\=\\=|b\\\u003e|b\\\u003e\\=|bsqrt|b\u0026|b\\^|b\\||b\\~|base64_decode|concat|extract|extract3|extract_uint16|extract_uint32|extract_uint64|getbit|getbyte|json_ref|len|replace2|replace3|setbit|setbyte|substring|substring3|ec_add|ec_map_to|ec_multi_scalar_mul|ec_pairing_check|ec_scalar_mul|ec_subgroup_check|ecdsa_pk_decompress|ecdsa_pk_recover|ecdsa_verify|ed25519verify|ed25519verify_bare|keccak256|sha256|sha3_256|sha512_256|vrf_verify|gitxn|gitxna|gitxnas|itxn|itxn_begin|itxn_field|itxn_next|itxn_submit|itxna|itxnas)\\b" + "match": "^(\\!|\\!\\=|%|\u0026|\u0026\u0026|\\*|\\+|\\-|/|\\\u003c|\\\u003c\\=|\\=\\=|\\\u003e|\\\u003e\\=|\\^|addw|bitlen|btoi|divmodw|divw|exp|expw|itob|mulw|shl|shr|sqrt|\\||\\|\\||\\~|b\\!\\=|b%|b\\*|b\\+|b\\-|b/|b\\\u003c|b\\\u003c\\=|b\\=\\=|b\\\u003e|b\\\u003e\\=|bsqrt|b\u0026|b\\^|b\\||b\\~|base64_decode|concat|extract|extract3|extract_uint16|extract_uint32|extract_uint64|getbit|getbyte|json_ref|len|replace2|replace3|setbit|setbyte|substring|substring3|ec_add|ec_map_to|ec_multi_scalar_mul|ec_pairing_check|ec_scalar_mul|ec_subgroup_check|ecdsa_pk_decompress|ecdsa_pk_recover|ecdsa_verify|ed25519verify|ed25519verify_bare|heartbeat|keccak256|sha256|sha3_256|sha512_256|vrf_verify|gitxn|gitxna|gitxnas|itxn|itxn_begin|itxn_field|itxn_next|itxn_submit|itxna|itxnas)\\b" } ] }, @@ -112,7 +112,7 @@ }, { "name": "variable.parameter.teal", - "match": "\\b(unknown|pay|keyreg|acfg|axfer|afrz|appl|NoOp|OptIn|CloseOut|ClearState|UpdateApplication|DeleteApplication|Secp256k1|Secp256r1|Sender|Fee|FirstValid|FirstValidTime|LastValid|Note|Lease|Receiver|Amount|CloseRemainderTo|VotePK|SelectionPK|VoteFirst|VoteLast|VoteKeyDilution|Type|TypeEnum|XferAsset|AssetAmount|AssetSender|AssetReceiver|AssetCloseTo|GroupIndex|TxID|ApplicationID|OnCompletion|NumAppArgs|NumAccounts|ApprovalProgram|ClearStateProgram|RekeyTo|ConfigAsset|ConfigAssetTotal|ConfigAssetDecimals|ConfigAssetDefaultFrozen|ConfigAssetUnitName|ConfigAssetName|ConfigAssetURL|ConfigAssetMetadataHash|ConfigAssetManager|ConfigAssetReserve|ConfigAssetFreeze|ConfigAssetClawback|FreezeAsset|FreezeAssetAccount|FreezeAssetFrozen|NumAssets|NumApplications|GlobalNumUint|GlobalNumByteSlice|LocalNumUint|LocalNumByteSlice|ExtraProgramPages|Nonparticipation|NumLogs|CreatedAssetID|CreatedApplicationID|LastLog|StateProofPK|NumApprovalProgramPages|NumClearStateProgramPages|MinTxnFee|MinBalance|MaxTxnLife|ZeroAddress|GroupSize|LogicSigVersion|Round|LatestTimestamp|CurrentApplicationID|CreatorAddress|CurrentApplicationAddress|GroupID|OpcodeBudget|CallerApplicationID|CallerApplicationAddress|AssetCreateMinBalance|AssetOptInMinBalance|ApplicationArgs|Accounts|Assets|Applications|Logs|ApprovalProgramPages|ClearStateProgramPages|URLEncoding|StdEncoding|JSONString|JSONUint64|JSONObject|AssetBalance|AssetFrozen|AssetTotal|AssetDecimals|AssetDefaultFrozen|AssetUnitName|AssetName|AssetURL|AssetMetadataHash|AssetManager|AssetReserve|AssetFreeze|AssetClawback|AssetCreator|AppApprovalProgram|AppClearStateProgram|AppGlobalNumUint|AppGlobalNumByteSlice|AppLocalNumUint|AppLocalNumByteSlice|AppExtraProgramPages|AppCreator|AppAddress|AcctBalance|AcctMinBalance|AcctAuthAddr|AcctTotalNumUint|AcctTotalNumByteSlice|AcctTotalExtraAppPages|AcctTotalAppsCreated|AcctTotalAppsOptedIn|AcctTotalAssetsCreated|AcctTotalAssets|AcctTotalBoxes|AcctTotalBoxBytes|VrfAlgorand|BlkSeed|BlkTimestamp|BlkProposer|BlkFeesCollected|BN254g1|BN254g2|BLS12_381g1|BLS12_381g2)\\b" + "match": "\\b(unknown|pay|keyreg|acfg|axfer|afrz|appl|NoOp|OptIn|CloseOut|ClearState|UpdateApplication|DeleteApplication|Secp256k1|Secp256r1|Sender|Fee|FirstValid|FirstValidTime|LastValid|Note|Lease|Receiver|Amount|CloseRemainderTo|VotePK|SelectionPK|VoteFirst|VoteLast|VoteKeyDilution|Type|TypeEnum|XferAsset|AssetAmount|AssetSender|AssetReceiver|AssetCloseTo|GroupIndex|TxID|ApplicationID|OnCompletion|NumAppArgs|NumAccounts|ApprovalProgram|ClearStateProgram|RekeyTo|ConfigAsset|ConfigAssetTotal|ConfigAssetDecimals|ConfigAssetDefaultFrozen|ConfigAssetUnitName|ConfigAssetName|ConfigAssetURL|ConfigAssetMetadataHash|ConfigAssetManager|ConfigAssetReserve|ConfigAssetFreeze|ConfigAssetClawback|FreezeAsset|FreezeAssetAccount|FreezeAssetFrozen|NumAssets|NumApplications|GlobalNumUint|GlobalNumByteSlice|LocalNumUint|LocalNumByteSlice|ExtraProgramPages|Nonparticipation|NumLogs|CreatedAssetID|CreatedApplicationID|LastLog|StateProofPK|NumApprovalProgramPages|NumClearStateProgramPages|MinTxnFee|MinBalance|MaxTxnLife|ZeroAddress|GroupSize|LogicSigVersion|Round|LatestTimestamp|CurrentApplicationID|CreatorAddress|CurrentApplicationAddress|GroupID|OpcodeBudget|CallerApplicationID|CallerApplicationAddress|AssetCreateMinBalance|AssetOptInMinBalance|ApplicationArgs|Accounts|Assets|Applications|Logs|ApprovalProgramPages|ClearStateProgramPages|URLEncoding|StdEncoding|JSONString|JSONUint64|JSONObject|AssetBalance|AssetFrozen|AssetTotal|AssetDecimals|AssetDefaultFrozen|AssetUnitName|AssetName|AssetURL|AssetMetadataHash|AssetManager|AssetReserve|AssetFreeze|AssetClawback|AssetCreator|AppApprovalProgram|AppClearStateProgram|AppGlobalNumUint|AppGlobalNumByteSlice|AppLocalNumUint|AppLocalNumByteSlice|AppExtraProgramPages|AppCreator|AppAddress|AcctBalance|AcctMinBalance|AcctAuthAddr|AcctTotalNumUint|AcctTotalNumByteSlice|AcctTotalExtraAppPages|AcctTotalAppsCreated|AcctTotalAppsOptedIn|AcctTotalAssetsCreated|AcctTotalAssets|AcctTotalBoxes|AcctTotalBoxBytes|AcctLastProposed|AcctLastHeartbeat|VrfAlgorand|BlkSeed|BlkTimestamp|BlkProposer|BlkFeesCollected|BN254g1|BN254g2|BLS12_381g1|BLS12_381g2)\\b" } ] }, diff --git a/ledger/eval/applications.go b/ledger/eval/applications.go index 36d0734ec2..06cc467187 100644 --- a/ledger/eval/applications.go +++ b/ledger/eval/applications.go @@ -348,3 +348,12 @@ func (cs *roundCowState) Perform(gi int, ep *logic.EvalParams) error { return nil } + +func (cs *roundCowState) Heartbeat(addr basics.Address) error { + acct, err := cs.lookup(addr) + if err != nil { + return err + } + acct.LastHeartbeat = cs.Round() + return cs.Put(addr, acct) +} diff --git a/ledger/ledger.go b/ledger/ledger.go index dc3baaf766..cf90649db0 100644 --- a/ledger/ledger.go +++ b/ledger/ledger.go @@ -680,7 +680,7 @@ func (l *Ledger) Block(rnd basics.Round) (blk bookkeeping.Block, err error) { func (l *Ledger) BlockHdr(rnd basics.Round) (blk bookkeeping.BlockHeader, err error) { // Expected availability range in txTail.blockHeader is [Latest - MaxTxnLife, Latest] - // allowing (MaxTxnLife + 1) = 1001 rounds back loopback. + // allowing (MaxTxnLife + 1) = 1001 rounds lookback. // The depth besides the MaxTxnLife is controlled by DeeperBlockHeaderHistory parameter // and currently set to 1. // Explanation: