From 41c7e6066fe84a1aab76941763e95f4e25346b9c Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Fri, 15 Sep 2023 11:15:27 -0400 Subject: [PATCH 1/8] 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 | 8 +- config/consensus.go | 10 + daemon/algod/api/server/v2/handlers.go | 5 +- 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/eval.go | 7 +- data/transactions/logic/fields.go | 6 + data/transactions/logic/fields_string.go | 8 +- data/transactions/logic/opcodes.go | 6 +- 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_subs/goal/goal.py | 18 +- test/scripts/e2e_subs/mining.py | 98 ++++ 37 files changed, 1085 insertions(+), 388 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 a22a3a0526..ca640260c7 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 a0afca4d46..fa1e4c1c5c 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 9ec85618e8..11d6f5f90e 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 00ba132294..91d261c6e7 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 ac29970b16..852006952c 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 { @@ -251,7 +257,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 fc08e2990e..81c6afc84a 100644 --- a/config/consensus.go +++ b/config/consensus.go @@ -529,6 +529,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 @@ -1412,6 +1419,9 @@ func initConsensusProtocols() { vFuture.LogicSigVersion = 11 // When moving this to a release, put a new higher LogicSigVersion here + 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 69201ca848..3eb65154b7 100644 --- a/daemon/algod/api/server/v2/handlers.go +++ b/daemon/algod/api/server/v2/handlers.go @@ -1401,10 +1401,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/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 d67621b343..987b44e867 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 cb3a63ad2e..e020a7c7bf 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 7c9462d40d..67bdefbb8c 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/eval.go b/data/transactions/logic/eval.go index fe102086aa..a93407c40a 100644 --- a/data/transactions/logic/eval.go +++ b/data/transactions/logic/eval.go @@ -5593,17 +5593,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 %s", 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 a2f971f7b7..7f962125b5 100644 --- a/data/transactions/logic/fields.go +++ b/data/transactions/logic/fields.go @@ -965,6 +965,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 ) @@ -980,6 +984,8 @@ type blockFieldSpec struct { var blockFieldSpecs = [...]blockFieldSpec{ {BlkSeed, StackBytes, randomnessVersion}, {BlkTimestamp, StackUint64, randomnessVersion}, + {BlkProposer, StackAddress, incentiveVersion}, + {BlkFeesCollected, StackUint64, incentiveVersion}, } func blockFieldSpecByField(r BlockField) (blockFieldSpec, bool) { diff --git a/data/transactions/logic/fields_string.go b/data/transactions/logic/fields_string.go index 37bfeb9bcc..70f74fe11e 100644 --- a/data/transactions/logic/fields_string.go +++ b/data/transactions/logic/fields_string.go @@ -352,12 +352,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/opcodes.go b/data/transactions/logic/opcodes.go index 18af2af1b2..134d146aa4 100644 --- a/data/transactions/logic/opcodes.go +++ b/data/transactions/logic/opcodes.go @@ -71,11 +71,13 @@ const fpVersion = 8 // changes for frame pointers and simpler function d const sharedResourcesVersion = 9 // apps can access resources from other transactions. +const pairingVersion = 10 // bn256 opcodes. will add bls12-381, and unify the available opcodes. +const spliceVersion = 10 // box splicing/resizing + // 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 spliceVersion = 10 // box splicing/resizing +const incentiveVersion = 11 // block fields, heartbeat const spOpcodesVersion = 11 // falcon_verify, sumhash512 diff --git a/data/transactions/payment.go b/data/transactions/payment.go index 62eafdb1e9..d3c1432e7c 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 e3a25619bb..dfec67c558 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 eddc15757e..0280ecdb60 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 e64beea4b4..41976257ea 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 d377211a17..a0b5976d70 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 167d22f2dc..d94d78d63d 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 c08212e373..00ae863399 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 8be898e05c..3aa7bd3905 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 269ce570ff..1e8f3c1a50 100644 --- a/ledger/eval/cow.go +++ b/ledger/eval/cow.go @@ -95,6 +95,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{ @@ -299,6 +301,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) @@ -342,6 +346,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 06d600d58a..81224a8d0b 100644 --- a/ledger/eval/cow_test.go +++ b/ledger/eval/cow_test.go @@ -282,6 +282,7 @@ func TestCowChildReflect(t *testing.T) { "compatibilityMode": {}, "compatibilityGetKeyCache": {}, "prevTotals": {}, + "feesCollected": {}, } cow := roundCowState{} @@ -289,7 +290,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 de1304988a..90baff553c 100644 --- a/ledger/eval/eval.go +++ b/ledger/eval/eval.go @@ -788,6 +788,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) } @@ -1165,12 +1172,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 } @@ -1272,6 +1294,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 { @@ -1316,6 +1342,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 57f4c5d92b..2f79cd45d4 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 7354b4a567..1b10cf5352 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 79ae16284d..9edbdfa42d 100644 --- a/ledger/ledger_test.go +++ b/ledger/ledger_test.go @@ -173,6 +173,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 541a3a54f8..3bfef32649 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 10b87f9378..b42d3a53f2 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 75d9bcfa27..abcb195951 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 e980454674..1e2ef3b148 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_subs/goal/goal.py b/test/scripts/e2e_subs/goal/goal.py index 812afe8976..a366f1b69e 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..5a52b4482c --- /dev/null +++ b/test/scripts/e2e_subs/mining.py @@ -0,0 +1,98 @@ +#!/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 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 +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 a3408552e74660c98596aa8eb8eb3748d5d404fe Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Tue, 28 Nov 2023 16:05:29 -0500 Subject: [PATCH 2/8] Add min and max to receive block incentives --- ledger/acctonline_expired_test.go | 5 +- ledger/apptxn_test.go | 12 ++-- ledger/eval/eval.go | 52 ++++++++++++-- ledger/eval_simple_test.go | 111 ++++++++++++++++++------------ ledger/testing/testGenesis.go | 7 +- 5 files changed, 126 insertions(+), 61 deletions(-) diff --git a/ledger/acctonline_expired_test.go b/ledger/acctonline_expired_test.go index ac7986a78b..e51494d184 100644 --- a/ledger/acctonline_expired_test.go +++ b/ledger/acctonline_expired_test.go @@ -244,9 +244,8 @@ type doubleLedgerAcctModel struct { } func newDoubleLedgerAcctModel(t testing.TB, proto protocol.ConsensusVersion, inMem bool) *doubleLedgerAcctModel { - // set 1 Algo for rewards pool size -- rewards math not supported by newMapOnlineAcctModel - genesisOpt := ledgertesting.TestGenesisRewardsPoolSize(basics.MicroAlgos{Raw: 1_000_000}) - genBalances, genAddrs, genSecrets := ledgertesting.NewTestGenesis(genesisOpt) + // rewards math not supported by newMapOnlineAcctModel + genBalances, genAddrs, genSecrets := ledgertesting.NewTestGenesis(ledgertesting.TurnOffRewards) cfg := config.GetDefaultLocal() opts := []simpleLedgerOption{simpleLedgerNotArchival()} if !inMem { diff --git a/ledger/apptxn_test.go b/ledger/apptxn_test.go index d94d78d63d..8126322875 100644 --- a/ledger/apptxn_test.go +++ b/ledger/apptxn_test.go @@ -35,7 +35,7 @@ import ( "github.com/algorand/go-algorand/test/partitiontest" ) -// TestPayAction ensures a pay in teal affects balances +// TestPayAction ensures a inner pay transaction affects balances func TestPayAction(t *testing.T) { partitiontest.PartitionTest(t) t.Parallel() @@ -59,8 +59,13 @@ func TestPayAction(t *testing.T) { `)) // 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() + proposer := basics.Address{0x01, 0x02, 0x03} + dl.txn(&txntest.Txn{ + Type: "pay", + Sender: addrs[7], + Receiver: proposer, + Amount: 1_000_000 * 1_000_000, // 1 million algos is surely an eligible amount + }) payout1 := txntest.Txn{ Type: "appl", @@ -69,7 +74,6 @@ func TestPayAction(t *testing.T) { Accounts: []basics.Address{addrs[1]}, // pay self } - proposer := addrs[7] presink := micros(dl.t, dl.generator, genBalances.FeeSink) preprop := micros(dl.t, dl.generator, proposer) dl.beginBlock() diff --git a/ledger/eval/eval.go b/ledger/eval/eval.go index 90baff553c..bdf351c953 100644 --- a/ledger/eval/eval.go +++ b/ledger/eval/eval.go @@ -788,11 +788,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.eligibleForIncentives(prevHeader.Proposer) { + 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 { @@ -802,6 +804,46 @@ func StartEvaluator(l LedgerForEvaluator, hdr bookkeeping.BlockHeader, evalOpts return eval, nil } +const ( + // these would become ConsensusParameters if we ever wanted to change them + + // incentiveMinBalance is the minimum balance an account must have to be + // eligible for incentives. It serves a couple purposes. First, it sets a + // manageable upper bound on the total number of incentivized participating + // accounts. This means it is possible to track these accounts in memory, + // which is required to ensure absenteeism checking time is bounded. Second, + // it ensures that smaller accounts continue to operate for the same + // motivations they had before block incentives were introduced. Without + // that assurance, it is difficult to model their behaviour - might many + // participants join for the hope of easy financial rewards, but without + // caring enough to run a high-quality node? + incentiveMinBalance = 100_000 * 1_000_000 // 100K algos + + // incentiveMaxBalance is the maximum balance an account might have to be + // eligible for incentives. It encourages large accounts to split their + // stake to add resilience to consensus in the case of outages. Of course, + // nothing in protocol can prevent such accounts from running nodes that + // share fate (same machine, same data center, etc), but this serves as a + // gentle reminder. + incentiveMaxBalance = 100_000_000 * 1_000_000 // 100M algos +) + +func (eval *BlockEvaluator) eligibleForIncentives(proposer basics.Address) bool { + proposerState, err := eval.state.Get(proposer, true) + if err != nil { + return false + } + if proposerState.MicroAlgos.Raw < incentiveMinBalance { + return false + } + if proposerState.MicroAlgos.Raw > incentiveMaxBalance { + return false + } + // We'll also need a flag on the account, set to true if the account + // properly key-regged for incentives by including the "entry fee". + return true +} + // hotfix for testnet stall 08/26/2019; move some algos from testnet bank to rewards pool to give it enough time until protocol upgrade occur. // hotfix for testnet stall 11/07/2019; do the same thing func (eval *BlockEvaluator) workaroundOverspentRewards(rewardPoolBalance ledgercore.AccountData, headerRound basics.Round) (poolOld ledgercore.AccountData, err error) { diff --git a/ledger/eval_simple_test.go b/ledger/eval_simple_test.go index 1b10cf5352..9f9e15912f 100644 --- a/ledger/eval_simple_test.go +++ b/ledger/eval_simple_test.go @@ -217,57 +217,78 @@ func TestMiningFees(t *testing.T) { partitiontest.PartitionTest(t) t.Parallel() - genBalances, addrs, _ := ledgertesting.NewTestGenesis() + // Lots of balance checks that would be messed up by rewards + genBalances, addrs, _ := ledgertesting.NewTestGenesis(ledgertesting.TurnOffRewards) // 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) + tooBig := basics.Address{0x01, 0x011} + tooSmall := basics.Address{0x01, 0x022} + smallest := basics.Address{0x01, 0x033} + biggest := basics.Address{0x01, 0x044} + + dl.txns(&txntest.Txn{Type: "pay", Sender: addrs[1], Receiver: tooBig, Amount: 100_000_000*1_000_000 + 1}, + &txntest.Txn{Type: "pay", Sender: addrs[1], Receiver: tooSmall, Amount: 100_000*1_000_000 - 1}, + &txntest.Txn{Type: "pay", Sender: addrs[1], Receiver: smallest, Amount: 100_000 * 1_000_000}, + &txntest.Txn{Type: "pay", Sender: addrs[1], Receiver: biggest, Amount: 100_000_000 * 1_000_000}, + ) + + for _, proposer := range []basics.Address{tooBig, tooSmall, smallest, biggest} { + t.Log(proposer) + dl.fullBlock() // start with an empty block, so no mining fees are paid at start of next one + + presink := micros(dl.t, dl.generator, genBalances.FeeSink) + preprop := micros(dl.t, dl.generator, proposer) + t.Log(" presink", presink) + t.Log(" preprop", preprop) + dl.beginBlock() + pay := txntest.Txn{ + Type: "pay", + Sender: addrs[1], + Receiver: addrs[2], + Amount: 100000, + } + dl.txns(&pay, pay.Args("again")) + vb := dl.endBlock(proposer) + + if ver >= 39 { + require.True(t, dl.generator.GenesisProto().EnableMining) // version sanity check + require.NotZero(t, dl.generator.GenesisProto().MiningPercent) // 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) + require.Zero(t, dl.generator.GenesisProto().MiningPercent) // version sanity check + // new fields are not in the header + require.Zero(t, vb.Block().BlockHeader.Proposer) + require.Zero(t, vb.Block().BlockHeader.FeesCollected) + } - 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 + postsink := micros(dl.t, dl.generator, genBalances.FeeSink) + postprop := micros(dl.t, dl.generator, proposer) + t.Log(" postsink", postsink) + t.Log(" postprop", postprop) + + // 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 && (proposer == smallest || proposer == biggest) { + require.EqualValues(t, 500, postsink-presink) // based on 75% in config/consensus.go + require.EqualValues(t, 1500, postprop-preprop) + } else { + // stayed in the feesink + require.EqualValues(t, 0, postprop-preprop, "%v", proposer) + require.EqualValues(t, 2000, postsink-presink) + } } }) } diff --git a/ledger/testing/testGenesis.go b/ledger/testing/testGenesis.go index a2d469dcf0..06b50be977 100644 --- a/ledger/testing/testGenesis.go +++ b/ledger/testing/testGenesis.go @@ -33,10 +33,9 @@ type testGenesisCfg struct { // TestGenesisOption provides functional options for testGenesisCfg. type TestGenesisOption func(*testGenesisCfg) -// TestGenesisRewardsPoolSize configures the rewards pool size in the genesis block. -func TestGenesisRewardsPoolSize(amount basics.MicroAlgos) TestGenesisOption { - return func(cfg *testGenesisCfg) { cfg.rewardsPoolAmount = amount } -} +// TurnOffRewards turns off the rewards pool for tests that are sensistive to +// "surprise" balance changes. +var TurnOffRewards = func(cfg *testGenesisCfg) { cfg.rewardsPoolAmount = basics.MicroAlgos{Raw: 100_000} } // NewTestGenesis creates a bunch of accounts, splits up 10B algos // between them and the rewardspool and feesink, and gives out the From 96de6e4240f9648217b040fd2b0a776b2bbb1487 Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Wed, 29 Nov 2023 15:27:52 -0500 Subject: [PATCH 3/8] Stop checking for incentive payouts in e2e subs. --- test/scripts/e2e_subs/mining.py | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/test/scripts/e2e_subs/mining.py b/test/scripts/e2e_subs/mining.py index 5a52b4482c..04f10e4b7f 100755 --- a/test/scripts/e2e_subs/mining.py +++ b/test/scripts/e2e_subs/mining.py @@ -76,23 +76,10 @@ 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 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 -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 +# We can not do checks on whether the proposer actually gets paid here +# because in our e2e tests, the proposers _won't_ get paid. Their +# accounts have too many algos. + stamp = datetime.now().strftime("%Y%m%d_%H%M%S") print(f"{os.path.basename(sys.argv[0])} OK {stamp}") + From 3bc618b41f871140ab6a50f068bc13c2c4cba1c1 Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Thu, 30 Nov 2023 12:13:00 -0500 Subject: [PATCH 4/8] Add IncentiveEligible field to accounts. --- daemon/algod/api/algod.oas2.json | 4 + daemon/algod/api/algod.oas3.yml | 4 + daemon/algod/api/server/v2/account.go | 1 + .../api/server/v2/generated/data/routes.go | 257 +++++------ .../v2/generated/experimental/routes.go | 257 +++++------ .../api/server/v2/generated/model/types.go | 3 + .../nonparticipating/private/routes.go | 419 +++++++++--------- .../nonparticipating/public/routes.go | 411 ++++++++--------- .../generated/participating/private/routes.go | 269 +++++------ .../generated/participating/public/routes.go | 280 ++++++------ daemon/algod/api/server/v2/handlers.go | 1 + data/basics/msgp_gen.go | 158 ++++--- data/basics/userBalance.go | 2 + ledger/ledgercore/accountdata.go | 8 +- ledger/store/trackerdb/data.go | 6 + ledger/store/trackerdb/data_test.go | 2 +- ledger/store/trackerdb/msgp_gen.go | 35 +- ledger/testing/randomAccounts.go | 5 + ledger/testing/randomAccounts_test.go | 1 - 19 files changed, 1112 insertions(+), 1011 deletions(-) diff --git a/daemon/algod/api/algod.oas2.json b/daemon/algod/api/algod.oas2.json index e327e0e3be..23f835e908 100644 --- a/daemon/algod/api/algod.oas2.json +++ b/daemon/algod/api/algod.oas2.json @@ -2983,6 +2983,10 @@ "participation": { "$ref": "#/definitions/AccountParticipation" }, + "incentive-eligible": { + "description": "Whether or not the account can receive block incentives if its balance is in range at proposal time.", + "type": "boolean" + }, "pending-rewards": { "description": "amount of MicroAlgos of pending rewards in this account.", "type": "integer" diff --git a/daemon/algod/api/algod.oas3.yml b/daemon/algod/api/algod.oas3.yml index be9237b90e..96e4a670d9 100644 --- a/daemon/algod/api/algod.oas3.yml +++ b/daemon/algod/api/algod.oas3.yml @@ -1067,6 +1067,10 @@ }, "type": "array" }, + "incentive-eligible": { + "description": "Whether or not the account can receive block incentives if its balance is in range at proposal time.", + "type": "boolean" + }, "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 addb81b432..0d659320bf 100644 --- a/daemon/algod/api/server/v2/account.go +++ b/daemon/algod/api/server/v2/account.go @@ -123,6 +123,7 @@ func AccountDataToAccount( Status: record.Status.String(), RewardBase: &record.RewardsBase, Participation: apiParticipation, + IncentiveEligible: omitEmpty(record.IncentiveEligible), CreatedAssets: &createdAssets, TotalCreatedAssets: uint64(len(createdAssets)), CreatedApps: &createdApps, diff --git a/daemon/algod/api/server/v2/generated/data/routes.go b/daemon/algod/api/server/v2/generated/data/routes.go index 4a3438b8ff..0507c856e2 100644 --- a/daemon/algod/api/server/v2/generated/data/routes.go +++ b/daemon/algod/api/server/v2/generated/data/routes.go @@ -192,134 +192,135 @@ var swaggerSpec = []string{ "FwmLLwEf4RbiO0bcaB3/t92vILf31tvVyw8e7FKtl5k529FVKUPifmea2kELI2T5aAzFFqitujJLMyD5", "EvJrV/8GVpXeTjuf+4AfJ2h61sGUrYxkM/OwNgc6KGZA6qqgThSnfNsvkqBAax9W/BauYXsp2tIeh1RF", "6Cbpq9RBRUoNpEtDrOGxdWP0N99FlaFiX1U+1x2THj1ZPG/own+TPshW5D3CIY4RRSeJPIUIKiOIsMSf", - "QMEtFmrGuxPpx5ZntIyZvfkiVZI87yfulVZ5cgFg4WrQ6m6frwDLrIkbRWbUyO3CVQiziegBF6sVXUBC", - "Qg59RCPTvTt+JRxk370XvenEvH+hDe6bKMj25cysOUopYJ4YUkFlphf252eybkjnmcDCnw5hsxLFpCY+", - "0jIdKju+OlvJMAVanIBB8lbg8GB0MRJKNkuqfPEyrPHmz/IoGeB3LKywq5zOeRCxFhRya4rleJ7bP6cD", - "7dIV1fGVdHz5nFC1HFEKx0j4GCQf2w7BUQAqoISFXbh92RNKW+Sh3SADx4/zeck4kCwW/BaYQYNrxs0B", - "Rj5+SIi1wJPRI8TIOAAb3es4MPlBhGeTLw4BkrsiFdSPjY754G+Ip4/ZcHAj8ojKsHCW8GrlngNQFzHZ", - "3F+9uF0chjA+JYbNrWlp2JzT+NpBBlVdUGzt1XBxAR4PUuLsDgeIvVgOWpO9im6zmlBm8kDHBbodEM/E", - "JrP5o1GJd7aZGXqPRshjNmvsYNr6OfcUmYkNBg3h1WIjsvfAkobDgxFo+BumkF7xu9RtboHZNe1uaSpG", - "hQpJxpnzGnJJiRNjpk5IMClyuR+UxLkVAD1jR1tf2im/e5XUrngyvMzbW23alnrzyUex4586QtFdSuBv", - "aIVpiti86UssUTtFN/alW78nECFjRG/YxNBJM3QFKSgBlYKsI0Rl1zHPqdFtAG+cC/9ZYLzAKkGUbx8E", - "AVUSFkxpaI3oPk7ic5gnKRYnFGKeXp2u5Nys760QzTVl3Yj4YWeZn3wFGJE8Z1LpDD0Q0SWYl75VqFR/", - "a16Ny0rdkC1bypcVcd6A017DNitYWcfp1c37/Usz7Q8NS1T1DPkt4zZgZYalp6OBnDumtrG+Oxf8yi74", - "FT3aesedBvOqmVgacunO8U9yLnqcdxc7iBBgjDiGu5ZE6Q4GGSTgDrljIDcFPv6TXdbXwWEq/Nh7o3Z8", - "GnDqjrIjRdcSGAx2roKhm8iIJUwHlZuHmbGJM0CrihWbni3UjprUmOlBBg9f766HBdxdN9geDHTj8qJh", - "zp1agS76z9l8TlFAPjUinA0HdLFuIFHLsTmhRS3RqNYJthsWpmwEu5Fr//7nCy0kXYAzjGYWpDsNgcs5", - "BA1B2UdFNLMezoLN5xAaBNVtjFkd4Ppmn2hzhxFEFrca1ozrL5/FyGgP9bQw7kdZnGIitJByE10ODa9e", - "rAr0zqZzSbA1t7CeRjNIv4dt9rPRUEhFmVRtxJizhHb53wG7vl59D1sceW8glgFsz66gmvoWkAZjZsHm", - "kU2caFSgsIYpFn3obOEBO3UW36UjbY2rOpsm/jYsu1OVtbuUuxyM1m9nYBmzGxdxd5k5PdBFfJ+U920C", - "SxjjQnIMRK5wKqZ8j57hVdSkR++j3UugpSdeXM7k43RyN+dU7DZzI+7B9ZvmAo3iGYOfrLOi42s+EOW0", - "qqRY0zJzLrzU5S/F2l3++Lr3+H1iYTJO2ZffnL1648D/OJ3kJVCZNcpYclX4XvVPsypbp3b3VYISi7eK", - "WGU92PymuGbo9rtZgmumEOj7g6rPrUs3OIrODTiPx2Du5X3O+2yXuMMLDVXjhG4dJNYH3fU70zVlpfdM", - "eGgT8ZK4uHGlw6NcIRzgzv7rIAwhOyq7GZzu+OloqWsPT8K5fsRqaXGNg7taasiKnD+aHl16+lbIDvN3", - "yTJRf/bvJ1YZIdviMRE+6Bv09IWpE2IFr18Xv5rT+PBheNQePpySX0v3IAAQf5+531G/ePgw6mqIWhIM", - "k0BDAacreNAE/iY34tOanTjcjLugz9arRrIUaTJsKNQ6pj26bxz2biRz+CzcLwWUYH7an1vX23SL7hCY", - "MSfoIpUc08Q9rWxPIEUE74f5YV6WIS1k9iuKVc+t52Z4hHi9Qm9HpkqWx/3AfKYMe+U2vse8TPDlhMHM", - "jFizRLgYr1kwlnltTBm/HpDBHFFkqmglwRZ3M+GOd83ZP2ogrDBazZyBxHutd9V55QBHHQikRvUczuUG", - "tlEE7fB3sYOEFf/7MiMCsdsIEkYTDcB92Zj1/UIbr1mrMx0alBjOOGDcOwIKHX04arYJFstuVNA4PWZM", - "b0jP6FzrgcQc0V6PTGVzKX6DuC0aTfiR3Gzf44BhJO5vEKpnYYezDktpPFBty8p29n3bPV43Tm38nXVh", - "v+imrcJtLtP4qT5sI2+j9Kp4BVGH5JQSFroju9GqCdaCxyuIz8KK9j5UgXJ7nmxicifpIX4qw/SiUzt+", - "eyodzIOUrJLezGis3L/RhQxMwfZ2giq0IP5jvwGqSbu1s5MgqLB5l9niRhXItjbFsFDiLfUaO+1ojaZV", - "YJCiQtVlagPBSiUiw9T8hnLbJtF8Z/mV+1qB9YKar26ExNJkKh7/UUDOVlFz7NXVuyIf+voLtmC2A2Ct", - "IGgx5way3VUtFbk2fU0yuUPN+Zw8mgZ9Lt1uFGzNFJuVgG88tm/MqMLrsvFINp+Y5QHXS4WvPxnx+rLm", - "hYRCL5VFrBKk0T1RyGuimGagbwA4eYTvPf6K3Mf4LcXW8MBg0QlBk+ePv0Lvu/3jUeyWdR0cd7HsAnn2", - "3xzPjtMxBrDZMQyTdKOeRKs42RbO6dthx2myn445S/imu1D2n6UV5XQB8ZDh1R6Y7Le4m+hR7eGFW28A", - "KC3FljAdnx80NfwpkYZo2J8Fg+RitWJ65aJ8lFgZemr7x9lJ/XC2malr/eHh8g8xWK7ysUI9W9cnVmPo", - "KpFGgCGNP9AVdNE6JdTWoytZG8bqGxKRc1/uEnuhNC1QLG7MXGbpKEtiVOucVJJxjfaPWs+zPxu1WNLc", - "sL+TFLjZ7MtnkZ4i3bL7/DDAPzneJSiQ6zjqZYLsvcziviX3ueDZynCU4kGb9hucymRUXzx+KxVEtnvo", - "sZKvGSVLklvdITcacOo7ER7fMeAdSbFZz0H0ePDKPjll1jJOHrQ2O/TT21dOylgJGath3R53J3FI0JLB", - "GpM44ptkxrzjXshy1C7cBfrPG4LiRc5ALPNnOaoIBB7NXfmbRor/+XVbjBcdqzY5pmcDFDJi7XR2u08c", - "8HWY1a3vv7UxO/gsgbnRaLOd3gdYSYTq2ljc5ptPnM4bNffaPe8YHB//SqTRwVGOf/gQgX74cOrE4F+f", - "dB9b9v7wYbwmZtTkZn5tsXAXjRi/je3h1yJiAPMNqJqAIpeyGzFApi4p88AwwZkbakq6zX4+vRRxnGSQ", - "eMBf/BRcXb3DJx4P+EcfEZ+ZWeIGtiHN6cPebXYWJZmieR6EGlPytdiMJZzeHeSJ5w+AogRKRprncCWD", - "Zm5Rd/3eeJGARs2oMyiFUTLDPhWhPf+fB89m8dMd2K5ZWfzclhvqXSSS8nwZDdScmQ9/aZuuN0u0rDJa", - "+n5JOYcyOpzVbX/xOnBES/+7GDvPivGR7/abCdrl9hbXAt4F0wPlJzToZbo0E4RY7VZyaTKFy4UoCM7T", - "1llvmeOwK2fQKuwfNSgdOxr4wGYrobPLMF/bqYoAL9D6dUK+w5oKBpZOEV20OvnyhN1SXXVVClpMsWzi", - "5Tdnr4id1X5jWwfbTlkLNLp0VxG1ko8vXdZ0AY7n5I8fZ3eSsFm10lnT2CpW9ci80bbeYr3QCTTHhNg5", - "IS+tJUx5O4udhGDxTbmCIuijZXUxpAnzH61pvkQTU+ciS5P8+BZvnipbA3zQL7rpq4DnzsDturzZJm9T", - "IvQS5A1TgFmYsIZuoaWm6pgzcfrCS93lyZpzSyknB8gUTReFQ9HugbMCifcNRyHrIf5AA4PtkHhox7sL", - "/Cpa5rnfPq/nvPVle5o+wK+djTinXHCWY5HlmECERWHGeZtG1KOOu4nUxJ3QyOGKNu1r8r8cFpNt/Dwj", - "dIgbem6Dp2ZTLXXYPzVsXDOXBWjlOBsUU9970vk1GFfg+mQYIgr5pJCR2JRoPHvjBz+QjLDeQ8JQ9a15", - "9oMzY2Ii9DXjaLBwaHNitvU8lIqhg5ETpslCgHLr6Ra9Uu/MNydY/6mAzfuTV2LB8gu2wDFsNJRZtg39", - "Gw515gMBXeCdefeFeddV5W1+7kT12EnPqspNmu5MGm/HvOFJBMfCT3w8QIDcZvxwtB3ktjOCF+9TQ2iw", - "xuAjqPAeHhBG06Wz1xLbqAiWovANYnOToqX5GI+A8Ypx7wmLXxB59ErAjcHzmvhO5ZJqKwKO4mmXQMtE", - "HDvm+llX6l2H6tckNijBNfo50tvYNhhNMI7mhVZwo3xL/KEw1B0IEy9o2UTARtqFolTlhKgCc0R6DURj", - "jMMwbt+iuHsB7OlKPm0/xzrfh95EqepHs7pYgM5oUcTalnyNTwk+9bk+sIG8btpbVBXJsdhnt/rpkNrc", - "RLngql7tmMu/cMfpgo68EWoIuwL7HcbqCrMt/ntIv/gm9vXg/DYf6FocVvJ3mK8Xk3oNTWeKLbLxmMA7", - "5e7oaKe+HaG33x+V0kux6ALyOYykCS4X7lGMv31jLo6wJOAgzNheLU3FPgzpFfjcF7loak11uRJeZYMO", - "Jui8bvq07zZDpDuuT/HyS+SUhiZve79aM3AqszRPJkJT7UqyaEp2sqBkmQsb8tkzog89QakwTxvleTzj", - "s1vrToSmXTDfdxwuNtSnZRZJR8vtfCHtBh/qDPl+nUo29hXA8Xm/I/M1uDptlYQ1E7UPovGhrF4ltL92", - "+hs36d7R9UcDxD+38TlpKr90nfHsMp1O/v3P1plGgGu5/QMYzgebPuj1PJR2rXmqfYU0TZVGNVnq3Ipj", - "quPHCrE72bDTbXpPr+wBWb0cIw4Me19PJ+fFQRdmrJj/xI4SO3bxTtbpWsdtfWM8YpVQrO1tFmtxPTJm", - "/BK7VAe1modj+VjCNeQaG9q1MVIS4JDKzWYyb7v/V83jtDrdhNa7Use76hsPu9jtueMHJUiCMjq2A9jJ", - "+Gq+Z00krE3kuaEKa99LtHF3U19HJ+DN55Brtt5T8uVvS+BBOZGpt8sgLPOgAgxr0lGwYujhVscWoF0V", - "WXbCE1TuvzM4qXTka9jeU6RDDdGWZE0u1m2KRSIGkDtkhkSEikWaWUOyC/5hqqEMxIKP7LSfQ1t2O9nN", - "OChgdMu5PEmai6MtarRjyng71VFzmU8PKvWFmRWpqjDDboxp/eMlNr9ULs6JNsUmQy2dnA9L8t+4YpVY", - "oKfxnfiylaD8b74al52lZNcQ9ltGT9UNlYV/I2p68VadbMd9NCjl4jsJ9oGeNzOzNg5/6KuOFHnGlJa8", - "FEaMyFJ5Qd3Q9yZu7J6yAX5tHRaEaw7S9aVH+bcUCjItfNz+Ljh2ocJGMd4KCSrZWMEClyx3+rat54oN", - "ZiiWN6UueDFcIJGwogY6GVRdTc+5C9kv7HOfS+0bjOy1MDX0ur/Tnc/AYGqAxJDq58TdlvtztG9jbGKc", - "g8y856lfgpWD7HpDKimKOrcXdHgwGoPc6BIoO1hJ1E6TD1fZ0xGCXOdr2J5aJci3CPQ7GAJtJScLelC6", - "r7fJRzW/qRjci6OA9zktV9NJJUSZJZwd58O6sX2Kv2b5NRTE3BQ+UjnR/ZXcRxt7482+WW59ndSqAg7F", - "gxNCzrjNDfGO7W7jot7k/J7eNf8GZy1qW8rZGdVOrng8yB6LLMs7cjM/zG4epsCwujtOZQfZU5V0k6hZ", - "K+lNpBfyyVitfOhq7venbYnKQhGTSS6sx+oFHvSY4Qgz2YOSC+jIpMR5uogqRSwk8zbZ9maoOKbCyRAg", - "DXxM0ncDhRs8ioBox9XIKbQVzFztMjEnElon8m2LuA2bw8Y0+v7MzSxdfjcXEjptXs3XQhZe5GGq7cdM", - "5YxpSeX2NqXWBs1pB9aTJJb3hmM1kVjtQtporCEOy1LcZMissqa2eUy1Ne+p7mXs27m035lTPYMgrosq", - "J6htyZIWJBdSQh5+EU/bs1CthISsFBjmFfNAz7WRu1eYq8NJKRZEVLkowPYIiFNQaq6ac4piEwRRNVEU", - "WNrBpE/7TUDHI6c8VmdkW5zHLjqzvsxE4CkoV4zHYci+PIR3R1fhg6rzn8/RIsQw1qWbe22lz7C3MhzY", - "WpmVpTcYpLork59UjeFImHhjpnhGVkJpp9nZkVQzVBvidT8XXEtRll0jkBWJF86y/ZpuzvJcvxLiekbz", - "6weoR3Khm5UWU5+W2g/Ga2eSvYpMI9tAXy4jdl6cxZ+6g3s9O85xcIvWAMz3+znWfhv3WayVdXdd/d7s", - "PFE7U4sVy+M0/M8V3ZaMSYuxhGipJ9slySbn42vIqMPLoQlmQJY0RDNwQ7Cx/XI8zTl1kXmY/6LE2x+X", - "zMFdEomLacgnndSS5UnZqgcAQmozRnUtbWulUPJpuIpY2AxzdEn3AR3JxTHy526wmRGODpSGOwE1iDZs", - "ALxvlf2pLcllIxdnYuOfP2hrdt0K+I+7qTzWjj5yihvSct3yfX2PBEeIVwbeGX+EjcP9Dbo/Cqlpgzfy", - "Rg0ASMcldWAYFZ10KBhzykooMqoTlzvahKaBZusyWvrNTZlynDyn9sJeAjFj1xJcvQkrUveaoVfUkJJo", - "Xh9abnkBG1BYDMJ2dKbK+hm8vwNK21aqp3yLKithDZ1wLVcEo0bRjq3Bf6uaj0kBUKH3r2+TisUhhXd5", - "z1Dh1p4FkSxjsBu1XFjE2p0ie8wSUSPKhmf2mKixR8lAtGZFTTv4U4eKHF2zmznKEVQNZPLM621jp/nJ", - "jvDWD3Dmv4+JMh4T78fxoYNZUBx1uxjQ3rjEWqVOPY+HJYYVXhqHBs5WNI5PS+It31AVveFpA+CQ5Fv1", - "ZuQ+McEDxH6zgRylmm7c3d1xQnAwonrVm5IiuGx2+PaG5M9CwztJODleTNVQgAx2p6XG04UT2PEFbGfJ", - "jdhrpGZsIeX4v+N/U+zAbwcyerXtaBVqcC/Be+ywoHTjrHACLWsuNB9fOHX1BPtKOQsiq1d0S4TEf4y+", - "9o+almy+xRNqwfefEbWkhoSci9D6rl28opl4t2Ay9YB5u4DwU9l1s7FjBsNtzSgB0OYKdMYprAx0DeE2", - "oFvecp5cG5aj6tmKKYWXXW87h1hwi/c1IVa0CHVkrEzXbSXqa5War/9nm7UVTuULSlUlzX3/MiCKrnoG", - "cduj0BOXXsJqd1rfUD32JND0PWyJVvp03uIWxr0DIzdisfKpfg8dsAf94AatLu60jEMaFLeZ0TsSIkct", - "5di7MDY+ZAA0Opl9Va894NtqjL4C2KfAf7RoZGoZY8D/o+A90UYvhNd2zPsEWO6k/EdgtXbVmdhkEuZq", - "XyiENawaRVi2xQK8cZLxXAJVNjbk/EensrU1ERk3KqSNXmy8b80oBcwZb5kl41WtIxoAlkbk2wBhoXka", - "0Zpw9qSkBCOGrWn54xqkZEVq48zpsG28wpr03iTvvo0o/82dOhyAqVb7wUxCaDPVgtfMBW673tjAQqUp", - "L6gswtcZJzlIc++TG7pVt/d9GGhlbeSLPd4PGkgz3fz2wA+CpG0BKbfOfXlHz0QDID2ii2KEawEjWCNu", - "BWsU0SLhSRjCEC+rQDdZKRaYX5YgQFd8En0/VlkRHA22Vh46bB7FfoPd02DdbXfwtcBZx0yx+5z9iKhD", - "hecnzvTOk2ataf2EPxuRaQ+Cp3++aMPC7eYM6T+Wo3mJSQydPM1+03m/1zY8xM4HCU9G14Kb2EV0kLsE", - "39BcO76fUdcHH8sEtTpshrqt2hH4DaoNcqa5C9wZGn0GSrFFytTl0R5oE7KWZH8PJMCznWrd2epO2wRT", - "mHEOaQK1O3M2q0SV5WOiAW1p/sIZtB2kXRgT9BGYqxPrbgInVNOsolPYpNO14tA+WMmuGfv8MlW+S8lO", - "GTQSHLRrLBdz5GV4hK0ZB3M8GuPFtJ991DXYNEyCUCIhryUaNG/odn9foURJ2Iu/nn3x+MkvT774kpgX", - "SMEWoNqywr2+PG3EGON9O8unjREbLE/HN8HnpVvEeU+ZT7dpNsWdNcttVVszcNCV6BBLaOQCiBzHSD+Y", - "W+0VjtMGff+xtiu2yKPvWAwFv/+eSVGW8bLujegWMfXHdisw9huJvwKpmNKGEXZ9dUy3sbJqieY4LO65", - "tnVGBM9d9fWGCphOBOPEFpIKtUR+hlm/zr9BYFOVjldZn8SudTm9yFrEMDgD4zdmQCpROVGazUkMIswt", - "kUHOpTM0YnhnED3ZMFsbRxkjRBeTHCe9M+40TzEnu7l9t1ujjnN6s4kR8cIfyluQZsqSns5ovw0naU3p", - "fxj+EUnRPxrXaJb7e/CKqH5wu8bHo0AbpmtHyAMBSORhdjLowr7obaVRaa3yaL/3rs6++PG6dYHuTRhA", - "SPwHe8ALEyvb95oYdwfOZy7Z+bpBSrCU9ylK6Cx/X66mZ73NRRJskTNSaA3KsiUxFAuDRFz1oslvTWgl", - "gzRYbIJuNNOyjKTPWrsJnqmQcIxKINe0/PRcA7vjnyE+oHibTpoJcyhDJFtUqttVcHtFR80d5Eseb2r+", - "BlN2/wZmj6L3nBvKuYsHtxlavbAl9cLfCjYLmNzgmDYc6PGXZOaq6VcScqb6bugbL5w0KYMg2dyFXsJG", - "78lR3LfOn4W+AxnPfcwI+SFwJwk027UQtkf0MzOVxMmNUnmM+gZkEcFfjEeF3Tf3XBd3rLx+u4IgQWmv", - "AwuCDPuKjl2eLXphLp1awXCdo2/rDm4jF3W7trHVbEYXcL+6eqdnY4rQxIutm8+xCs5Rqq4fVHP9d6h/", - "Y3HkxnDzxijm51RFVFv1M1F8t7cfNSv3Boh0Sil/nE4WwEExhcWCf3HNIT7tXeohsDn5w6NqYb1LIRGL", - "mMhaO5MHUwVFkkfUR3afRaohY75bXkumt9gY1BvQ2C/RSj3fNVUfXNWQxnfl7j4trqFpztzWiKiVv12/", - "E7TE+8i61Li5hUR5Qr7Z0FVVOnMw+cu92Z/g6Z+fFY+ePv7T7M+PvniUw7Mvvnr0iH71jD7+6uljePLn", - "L549gsfzL7+aPSmePHsye/bk2ZdffJU/ffZ49uzLr/50z/AhA7IF1Nfufj75P9lZuRDZ2Zvz7NIA2+KE", - "Vux7MHuDuvJcYOM6g9QcTyKsKCsnz/1P/8ufsJNcrNrh/a8T14BlstS6Us9PT29ubk7CT04XmBSeaVHn", - "y1M/D7YT68grb86baHIb94I72lqPcVMdKZzhs7ffXFySszfnJy3BTJ5PHp08OnnsetdyWrHJ88lT/AlP", - "zxL3/dQR2+T5h4/TyekSaIk1VMwfK9CS5f6RBFps3f/VDV0sQJ5gwoD9af3k1IsVpx9ccvzHXc9Ow5CK", - "0w+dGgLFni8xHOD0g+9gufvtTvdCF4kVfDASil2vnc6wa8XYV0EFL6eXgsqGOv2A4nLy91Nn84g/RLXF", - "nodTX2gj/mYHSx/0xsC654sNK4KV5FTny7o6/YD/QeoNgLZFGE/1hp+i5/T0Q2et7vFgrd3f28/DN9Yr", - "UYAHTszntrPnrsenH+y/wUSwqUAyIxZi4RP3qy1QdYoNnrbDn7fc+R1LiJUV+YkrsGqrLwq/5XmbLdUc", - "6PPCv3yx5bmXX30wIB7TJ48e2emf4X8mrgFKr/jGqTuPk3Fd3btlD5EJ9gxnDbw2Jwz0yQRhePzpYDjn", - "NgDQcEXLvT9OJ198SiycG42e05Lgm3b6p59wE0CuWQ7kElaVkFSyckt+4k0MY9COMkaB11zccA+5ufrr", - "1YrKLYrUK7EGRVyny4A4iQQjxNg4B/TFtzSMdw9dKPQc1rOS5ZOpLXL5HsUmHZMgvDVnOJO3ZLWDd0/F", - "d3vPxPhd6AqmO6qKjIJzT765HX4oVQ/31+993xdqp7oX26DJvxjBvxjBERmBriVPHtHg/sLSWFC5rMic", - "5kvYxQ+Gt2VwwU8qEcv9v9jBLFwDihSvuOjyijbGbvL83bg2W879YC3LBShzmE+8VmFE5lbolw1H8mce", - "nZ/BXu/qIPzx/R/ifn9BuT/PnR23/kUqSwayoQLKhz1B/sUF/ttwAdvciNp9nRINZanCs68Fnn3rinEV", - "D7l1kY3kA50Cla0w3fn51BsQYjpk980PnT+7qpNa1roQN8EsaHq3fqOhlmEe1qr/9+kNZTqbC+nqImJX", - "9OHHGmh56pqg9H5t644PnmAx9eDHMAMx+uspdepG7Flle/AnHvZV3thTp/IlXvLhv/5xa/4KzUnIZxtD", - "0rv3hsthu2PHglvryPPTU8wHWQqlTycfpx96lpPw4fuGsHyXvkkl2RrL0L+fTjaZkGzBOC0zZ5VoOzlN", - "npw8mnz8/wEAAP//6aRdnSH5AAA=", + "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", + "r0Zkc775AAA=", } // 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 e7e56520a4..760f86cc7a 100644 --- a/daemon/algod/api/server/v2/generated/experimental/routes.go +++ b/daemon/algod/api/server/v2/generated/experimental/routes.go @@ -168,134 +168,135 @@ 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/generated/model/types.go b/daemon/algod/api/server/v2/generated/model/types.go index b9fc3b1baa..2565f762a9 100644 --- a/daemon/algod/api/server/v2/generated/model/types.go +++ b/daemon/algod/api/server/v2/generated/model/types.go @@ -185,6 +185,9 @@ type Account struct { // Note: the raw account uses `map[int] -> Asset` for this type. CreatedAssets *[]Asset `json:"created-assets,omitempty"` + // IncentiveEligible Whether or not the account can receive block incentives if its balance is in range at proposal time. + IncentiveEligible *bool `json:"incentive-eligible,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 b866cc9f42..697e544f8d 100644 --- a/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go +++ b/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go @@ -139,215 +139,216 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", - "nUw+/v8AAAD//31f+lNw+wAA", + "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", + "6a4N/AAA", } // GetSwagger returns the content of the embedded swagger specification file 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 713e5cd7b0..49eb954d27 100644 --- a/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go +++ b/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go @@ -802,211 +802,212 @@ var swaggerSpec = []string{ "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", - "bwAAAP//bsB3VeaoAQA=", + "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", + "AQA=", } // 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 c0e0c71fe2..84000d35dd 100644 --- a/daemon/algod/api/server/v2/generated/participating/private/routes.go +++ b/daemon/algod/api/server/v2/generated/participating/private/routes.go @@ -281,140 +281,141 @@ var swaggerSpec = []string{ "7Fe+SFh8CfgItxDfMeJG6/i/6X4Fub033q5efvBgl2q9zMzZjq5KGRL3O9PUDloYIctHYyi2QG3VlVma", "AcmXkF+7+jewqvRu2vncB/w4QdOzDqZsZSSbmYe1OdBBMQNSVwV1ojjlu36RBAVa+7Dit3ANu0vRlvY4", "pipCN0lfpQ4qUmogXRpiDY+tG6O/+S6qDBX7qvK57pj06MniRUMX/pv0QbYi7x0c4hhRdJLIU4igMoII", - "S/wJFNxgoWa8W5F+bHlGy5jZmy9SJcnzfuJeaZUnFwAWrgat7vb5CrDMmtgoMqNGbheuQphNRA+4WK3o", - "AhIScugjGpnu3fEr4SCH7r3oTSfm/QttcN9EQbYvZ2bNUUoB88SQCiozvbA/P5N1QzrPBBb+dAiblSgm", - "NfGRlulQ2fHV2UqGKdDiBAyStwKHB6OLkVCyWVLli5dhjTd/lkfJAH9gYYV95XTOg4i1oJBbUyzH89z+", - "OR1ol66ojq+k48vnhKrliFI4RsLHIPnYdgiOAlABJSzswu3LnlDaIg/tBhk4fpzPS8aBZLHgt8AMGlwz", - "bg4w8vFDQqwFnoweIUbGAdjoXseByQ8iPJt8cQyQ3BWpoH5sdMwHf0M8fcyGgxuRR1SGhbOEVyv3HIC6", - "iMnm/urF7eIwhPEpMWxuTUvD5pzG1w4yqOqCYmuvhosL8HiQEmf3OEDsxXLUmuxVdJPVhDKTBzou0O2B", - "eCa2mc0fjUq8s+3M0Hs0Qh6zWWMH09bPuafITGwxaAivFhuRfQCWNBwejEDD3zKF9IrfpW5zC8y+afdL", - "UzEqVEgyzpzXkEtKnBgzdUKCSZHL/aAkzo0A6Bk72vrSTvk9qKR2xZPhZd7eatO21JtPPood/9QRiu5S", - "An9DK0xTxOZNX2KJ2im6sS/d+j2BCBkjesMmhk6aoStIQQmoFGQdISq7jnlOjW4DeONc+M8C4wVWCaJ8", - "9yAIqJKwYEpDa0T3cRKfwzxJsTihEPP06nQl52Z9b4VorinrRsQPO8v85CvAiOQ5k0pn6IGILsG89I1C", - "pfob82pcVuqGbNlSvqyI8wac9hp2WcHKOk6vbt7vXplpf2hYoqpnyG8ZtwErMyw9HQ3k3DO1jfXdu+DX", - "dsGv6Z2td9xpMK+aiaUhl+4c/yLnosd597GDCAHGiGO4a0mU7mGQQQLukDsGclPg4z/ZZ30dHKbCj30w", - "asenAafuKDtSdC2BwWDvKhi6iYxYwnRQuXmYGZs4A7SqWLHt2ULtqEmNmR5l8PD17npYwN11gx3AQDcu", - "Lxrm3KkV6KL/nM3nFAXkUyPC2XBAF+sGErUcmxNa1BKNap1gu2FhykawG7n2736+0ELSBTjDaGZButUQ", - "uJxj0BCUfVREM+vhLNh8DqFBUN3EmNUBrm/2iTZ3GEFkcathzbj+4lmMjA5QTwvjYZTFKSZCCyk30eXQ", - "8OrFqkDvbDqXBFtzA+tpNIP0O9hlPxsNhVSUSdVGjDlLaJf/HbHr69V3sMORDwZiGcAO7AqqqW8BaTBm", - "Fmwe2cSJRgUKa5hi0YfOFh6xU2fxXbqjrXFVZ9PE34Zld6qydpdym4PR+u0MLGN24yLuLjOnB7qI75Py", - "oU1gCWNcSI6ByBVOxZTv0TO8ipr06EO0ewm09MSLy5l8nE5u55yK3WZuxAO4ftNcoFE8Y/CTdVZ0fM1H", - "opxWlRRrWmbOhZe6/KVYu8sfX/cev08sTMYp+/Lrs9dvHPgfp5O8BCqzRhlLrgrfq/5lVmXr1O6/SlBi", - "8VYRq6wHm98U1wzdfpsluGYKgb4/qPrcunSDo+jcgPN4DOZB3ue8z3aJe7zQUDVO6NZBYn3QXb8zXVNW", - "es+EhzYRL4mLG1c6PMoVwgFu7b8OwhCyO2U3g9MdPx0tdR3gSTjXj1gtLa5xcFdLDVmR80fTO5eevhGy", - "w/xdskzUn/3HiVVGyLZ4TIQP+gY9fWHqhFjB69fFr+Y0PnwYHrWHD6fk19I9CADE32fud9QvHj6Muhqi", - "lgTDJNBQwOkKHjSBv8mN+LRmJw6bcRf02XrVSJYiTYYNhVrHtEf3xmFvI5nDZ+F+KaAE89Ph3Lreplt0", - "h8CMOUEXqeSYJu5pZXsCKSJ4P8wP87IMaSGzX1Gsem49N8MjxOsVejsyVbI87gfmM2XYK7fxPeZlgi8n", - "DGZmxJolwsV4zYKxzGtjyvj1gAzmiCJTRSsJtribCXe8a85+q4Gwwmg1cwYS77XeVeeVAxx1IJAa1XM4", - "lxvYRhG0w9/GDhJW/O/LjAjEfiNIGE00APdVY9b3C228Zq3OdGxQYjjjgHHvCSh09OGo2SZYLLtRQeP0", - "mDG9IT2jc60HEnNEez0ylc2l+B3itmg04Udys32PA4aRuL9DqJ6FHc46LKXxQLUtK9vZD233eN04tfG3", - "1oX9opu2Cje5TOOn+riNvInSq+IVRB2SU0pY6I7sRqsmWAseryA+Cyva+1AFyu15sonJnaSH+KkM04tO", - "7fjtqXQwD1KySrqZ0Vi5f6MLGZiC7e0EVWhB/Md+A1STdmtnJ0FQYfMus8WNKpBtbYphocQb6jV22tEa", - "TavAIEWFqsvUBoKVSkSGqfmGctsm0Xxn+ZX7WoH1gpqvNkJiaTIVj/8oIGerqDn26updkQ99/QVbMNsB", - "sFYQtJhzA9nuqpaKXJu+JpncoeZ8Th5Ngz6XbjcKtmaKzUrANx7bN2ZU4XXZeCSbT8zygOulwtefjHh9", - "WfNCQqGXyiJWCdLonijkNVFMM9AbAE4e4XuPvyT3MX5LsTU8MFh0QtDkxeMv0ftu/3gUu2VdB8d9LLtA", - "nv13x7PjdIwBbHYMwyTdqCfRKk62hXP6dthzmuynY84SvukulMNnaUU5XUA8ZHh1ACb7Le4melR7eOHW", - "GwBKS7EjTMfnB00Nf0qkIRr2Z8EguVitmF65KB8lVoae2v5xdlI/nG1m6lp/eLj8QwyWq3ysUM/W9YnV", - "GLpKpBFgSOMPdAVdtE4JtfXoStaGsfqGROTcl7vEXihNCxSLGzOXWTrKkhjVOieVZFyj/aPW8+wvRi2W", - "NDfs7yQFbjb74lmkp0i37D4/DvBPjncJCuQ6jnqZIHsvs7hvyX0ueLYyHKV40Kb9BqcyGdUXj99KBZHt", - "H3qs5GtGyZLkVnfIjQac+laEx/cMeEtSbNZzFD0evbJPTpm1jJMHrc0O/fT2tZMyVkLGali3x91JHBK0", - "ZLDGJI74Jpkxb7kXshy1C7eB/vOGoHiRMxDL/FmOKgKBR3Nf/qaR4n/+vi3Gi45VmxzTswEKGbF2Orvd", - "Jw74Os7q1vff2pgdfJbA3Gi02U7vA6wkQnVtLG7zzSdO542ae+2edwyOj38l0ujgKMc/fIhAP3w4dWLw", - "r0+6jy17f/gwXhMzanIzv7ZYuI1GjN/G9vArETGA+QZUTUCRS9mNGCBTl5R5YJjgzA01Jd1mP59eirib", - "ZJB4wF/8FFxdvcMnHg/4Rx8Rn5lZ4ga2Ic3pw95tdhYlmaJ5HoQaU/KV2I4lnN4d5InnnwBFCZSMNM/h", - "SgbN3KLu+oPxIgGNmlFnUAqjZIZ9KkJ7/r8Ons3ip3uwXbOy+LktN9S7SCTl+TIaqDkzH/7SNl1vlmhZ", - "ZbT0/ZJyDmV0OKvb/uJ14IiW/g8xdp4V4yPf7TcTtMvtLa4FvAumB8pPaNDLdGkmCLHareTSZAqXC1EQ", - "nKets94yx2FXzqBV2G81KB07GvjAZiuhs8swX9upigAv0Pp1Qr7FmgoGlk4RXbQ6+fKE3VJddVUKWkyx", - "bOLl12eviZ3VfmNbB9tOWQs0unRXEbWSjy9d1nQBjufkjx9nf5KwWbXSWdPYKlb1yLzRtt5ivdAJNMeE", - "2Dkhr6wlTHk7i52EYPFNuYIi6KNldTGkCfMfrWm+RBNT5yJLk/z4Fm+eKlsDfNAvuumrgOfOwO26vNkm", - "b1Mi9BLkhinALExYQ7fQUlN1zJk4feGl7vJkzbmllJMjZIqmi8KxaPfAWYHE+4ajkPUQf6SBwXZIPLbj", - "3QV+FS3z3G+f13Pe+rI9TR/g752NOKdccJZjkeWYQIRFYcZ5m0bUo467idTEndDI4Yo27WvyvxwWk238", - "PCN0iBt6boOnZlMtddg/NWxdM5cFaOU4GxRT33vS+TUYV+D6ZBgiCvmkkJHYlGg8e+MHP5KMsN5DwlD1", - "jXn2gzNjYiL0NeNosHBoc2K29TyUiqGDkROmyUKAcuvpFr1S78w3J1j/qYDt+5PXYsHyC7bAMWw0lFm2", - "Df0bDnXmAwFd4J1596V511XlbX7uRPXYSc+qyk2a7kwab8e85UkEx8JPfDxAgNxm/HC0PeS2N4IX71ND", - "aLDG4COo8B4eEEbTpbPXEtuoCJai8A1ic5OipfkYj4DxmnHvCYtfEHn0SsCNwfOa+E7lkmorAo7iaZdA", - "y0QcO+b6WVfqbYfq1yQ2KME1+jnS29g2GE0wjuaFVnCjfEf8oTDUHQgTL2nZRMBG2oWiVOWEqAJzRHoN", - "RGOMwzBu36K4ewEc6Eo+bT/HOt/H3kSp6kezuliAzmhRxNqWfIVPCT71uT6whbxu2ltUFcmx2Ge3+umQ", - "2txEueCqXu2Zy79wy+mCjrwRagi7AvsdxuoKsx3+e0y/+Cb29ej8Nh/oWhxX8neYrxeTeg1NZ4otsvGY", - "wDvl9uhop74Zobff3ymll2LRBeRzGEkTXC7coxh/+9pcHGFJwEGYsb1amop9GNIr8LkvctHUmupyJbzK", - "Bh1M0Hnd9Gnfb4ZId1yf4uWXyCkNTd72frVm4FRmaZ5MhKbalWTRlOxlQckyFzbks2dEH3qCUmGeNsrz", - "7ozPbq17EZp2wXzXcbjYUJ+WWSQdLTfzhbQbfKwz5Lt1KtnYVwDH5/2OzNfg6rRVEtZM1D6IxoeyepXQ", - "/trpb9yke0fXHw0Q/9zG56Sp/NJ1xrPLdDr5dz9bZxoBruXun8BwPtj0Qa/nobRrzVPtK6RpqjSqyVLn", - "VhxTHT9WiN3Jhp1u0wd6ZQ/I6tUYcWDY+3o6OS+OujBjxfwndpTYsYt3sk7XOm7rG+MRq4RibW+zWIvr", - "kTHjl9ilOqjVPBzLxxKuIdfY0K6NkZIAx1RuNpN52/2fNY/T6nQTWu9KHe+rbzzsYnfgjh+UIAnK6NgO", - "YCfjq/meNZGwNpFnQxXWvpdo4+6mvo5OwJvPIddsfaDky9+XwINyIlNvl0FY5kEFGNako2DF0OOtji1A", - "+yqy7IUnqNx/a3BS6cjXsLunSIcaoi3JmlysmxSLRAwgd8gMiQgVizSzhmQX/MNUQxmIBR/ZaT+Htux2", - "sptxUMDohnN5kjQXR1vUaM+U8Xaqo+Yynx5V6gszK1JVYYbdGNP6xytsfqlcnBNtik2GWjo5H5bk37hi", - "lVigp/Gd+LKVoPxvvhqXnaVk1xD2W0ZP1YbKwr8RNb14q0625z4alHLxnQT7QM+bmVkbhz/0VUeKPGNK", - "S14KI0Zkqbygbuh7Ezd2T9kAv7YOC8I1B+n60qP8WwoFmRY+bn8fHPtQYaMYb4QElWysYIFLljt929Zz", - "xQYzFMubUhe8GC6QSFhRA50Mqq6m59yH7Jf2uc+l9g1GDlqYGno93OnOZ2AwNUBiSPVz4m7LwznaNzE2", - "Mc5BZt7z1C/BykF2vSGVFEWd2ws6PBiNQW50CZQ9rCRqp8mHq+zpCEGu8zXsTq0S5FsE+h0MgbaSkwU9", - "KN3X2+Q7Nb+pGNyLOwHvc1quppNKiDJLODvOh3Vj+xR/zfJrKIi5KXykcqL7K7mPNvbGm71Z7nyd1KoC", - "DsWDE0LOuM0N8Y7tbuOi3uT8nt43/xZnLWpbytkZ1U6ueDzIHossy1tyMz/Mfh6mwLC6W05lBzlQlXSb", - "qFkr6SbSC/lkrFY+dDX3+9O2RGWhiMkkF9Zj9RIPesxwhJnsQckFdGRS4jxdRJUiFpJ5k2x7M1QcU+Fk", - "CJAGPibpu4HCDR5FQLTjauQU2gpmrnaZmBMJrRP5pkXchs1hYxp9f+Zmli6/mwsJnTav5mshCy/yMNX2", - "Y6ZyxrSkcneTUmuD5rQD60kSywfDsZpIrHYhbTTWEIdlKTYZMqusqW0eU23Ne6p7Gft2Lu135lTPIIjr", - "osoJajuypAXJhZSQh1/E0/YsVCshISsFhnnFPNBzbeTuFebqcFKKBRFVLgqwPQLiFJSaq+acotgEQVRN", - "FAWWdjDp034T0PHIKe+qM7ItzmMXnVlfZiLwFJQrxuMwZF8ewrunq/BR1fnP52gRYhjr0s29ttJn2FsZ", - "jmytzMrSGwxS3ZXJT6rGcCRMvDFTPCMrobTT7OxIqhmqDfG6nwuupSjLrhHIisQLZ9n+nm7P8ly/FuJ6", - "RvPrB6hHcqGblRZTn5baD8ZrZ5K9ikwj20BfLiN2XpzFn7qjez07znF0i9YAzPeHOdZhG/dZrJV1d139", - "3uw8UTtTixXL4zT8rxXdloxJi7GEaKkn2yXJJufja8iow8uhCWZAljREM3BDsLH9cjzNOXWReZj/osTb", - "H5fMwV0SiYtpyCed1JLlSdmqBwBCajNGdS1ta6VQ8mm4iljYDHN0SfcBHcnFMfLndrCZEe4cKA23AmoQ", - "bdgAeN8q+1NbkstGLs7E1j9/0NbsuhHwH/dTeawdfeQUN6TluuX7+h4JjhCvDLw3/ggbh/sb9HAUUtMG", - "b+SNGgCQjkvqwDAqOulYMOaUlVBkVCcud7QJTQPN1mW09JubMuU4eU7thb0EYsauJbh6E1ak7jVDr6gh", - "JdG8PrTc8gK2oLAYhO3oTJX1M3h/B5S2rVRP+RZVVsIaOuFarghGjaIdW4P/VjUfkwKgQu9f3yYVi0MK", - "7/KeocKtPQsiWcZgN2q5sIi1O0UOmCWiRpQtz+wxUWOPkoFozYqadvCnjhU5umY3c5QjqBrI5JnX28ZO", - "85Md4a0f4Mx/HxNlPCbej+NDR7OgOOr2MaCDcYm1Sp16Hg9LDCu8NA4NnK1oHJ+WxFu+oSq64WkD4JDk", - "W/Vm5D4xwQPEfr2FHKWabtzd7XFCcDCietWbkiK4bHb45obkz0LDe0k4OV5M1VCADHavpcbThRPY8QVs", - "Z8mN2GukZmwh5fi/439T7MBvBzJ6te1oFWpwr8B77LCgdOOscAItay40H184dfUE+0o5CyKrV3RHhMR/", - "jL72W01LNt/hCbXg+8+IWlJDQs5FaH3XLl7RTLxfMJl6wLxdQPip7LrZ2DGD4XZmlABocwU64xRWBrqG", - "cBvQLW85T64Ny1H1bMWUwsuut51DLLjF+5oQK1qEOjJWpuu2EvW1Ss3X/3+btRVO5QtKVSXNff8yIIqu", - "egZx26PQE5dewmp/Wt9QPfYk0PQ9bIlW+nTe4gbGvSMjN2Kx8ql+Dx2wB/3gBq0ubrWMYxoUt5nRexIi", - "Ry3lrndhbHzIAGh0MvuqXgfAt9UYfQWwT4H/aNHI1DLGgP/PgvdEG70QXtsx7xNguZPyH4HV2lVnYptJ", - "mKtDoRDWsGoUYdkWC/DGScZzCVTZ2JDzH53K1tZEZNyokDZ6sfG+NaMUMGe8ZZaMV7WOaABYGpHvAoSF", - "5mlEa8LZk5ISjBi2puWPa5CSFamNM6fDtvEKa9J7k7z7NqL8N3fqcACmWu0HMwmhzVQLXjMXuO16YwML", - "laa8oLIIX2ec5CDNvU82dKdu7vsw0MrayBcHvB80kGa6+e2BHwRJ2wJS7pz78paeiQZAeocuihGuBYxg", - "jbgVrFFEi4QnYQhDvKwC3WalWGB+WYIAXfFJ9P1YZUVwNNhaeei4eRT7HfZPg3W33cHXAmcdM8X+c/Yj", - "og4Vnp8403tPmrWm9RP+bESmPQie/vmiDQu3mzOk/1iO5iUmMXTyNPtN5/1e2/AQOx8kPBldC25iF9FB", - "7hJ8Q3Pt+H5GXR98LBPU6rAZ6rZqT+A3qDbImeYucGdo9BkoxRYpU5dHe6RNyFqS/T2QAM92qnVnqztt", - "E0xhxjmmCdT+zNmsElWWj4kGtKX5C2fQdpB2YUzQR2CuTqy7CZxQTbOKTmGTTteKY/tgJbtmHPLLVPk+", - "JTtl0Ehw0K6xXMyRl+ERtmYczPFojBfTfvZR12DTMAlCiYS8lmjQ3NDd4b5CiZKwF387e/74yS9Pnn9B", - "zAukYAtQbVnhXl+eNmKM8b6d5dPGiA2Wp+Ob4PPSLeK8p8yn2zSb4s6a5baqrRk46Ep0jCU0cgFEjmOk", - "H8yN9grHaYO+/7m2K7bIO9+xGAr++D2ToizjZd0b0S1i6o/tVmDsNxJ/BVIxpQ0j7PrqmG5jZdUSzXFY", - "3HNt64wInrvq6w0VMJ0IxoktJBVqifwMs36df4PAtiodr7I+iX3rcnqRtYhhcAbGb8yAVKJyojSbkxhE", - "mFsig5xLZ2jE8M4gerJhtjaOMkaILiY5Tnpn3GmeYk72c/tut0Yd5/RmEyPihT+UNyDNlCU9ndF+E07S", - "mtL/afhHJEX/zrhGs9w/gldE9YObNT4eBdowXTtCHghAIg+zk0EX9kVvK41Ka5VH+713dfbFj+9bF+jB", - "hAGExH9wALwwsbJ9r4lxd+B85pKd3zdICZbyPkUJneUfytX0rLe5SIItckYKrUFZtiSGYmGQiKteNvmt", - "Ca1kkAaLTdCNZlqWkfRZazfBMxUSjlEJ5JqWn55rYHf8M8QHFG/TSTNhDmWIZItKdbMKbq/pqLmDfMm7", - "m5q/wZTdv4PZo+g954Zy7uLBbYZWL2xJvfC3gs0CJhsc04YDPf6CzFw1/UpCzlTfDb3xwkmTMgiSzV3o", - "JWz1gRzFQ+v8WehbkPHcx4yQHwJ3kkCzXQthe0Q/M1NJnNwolceob0AWEfzFeFTYffPAdXHLyus3KwgS", - "lPY6siDIsK/o2OXZohfm0qkVDNc5+rbu4DZyUbdrG1vNZnQB96urd3o2pghNvNi6+Ryr4NxJ1fWjaq7/", - "AfVvLI7cGG7eGMX8nKqIaqt+Jorv9vajZuXBAJFOKeWP08kCOCimsFjwL645xKe9Sz0ENid/eFQtrLcp", - "JGIRE1lrZ/JgqqBI8oj6yO6zSDVkzHfLa8n0DhuDegMa+yVaqefbpuqDqxrS+K7c3afFNTTNmdsaEbXy", - "t+u3gpZ4H1mXGje3kChPyNdbuqpKZw4mf703+w94+pdnxaOnj/9j9pdHzx/l8Oz5l48e0S+f0cdfPn0M", - "T/7y/NkjeDz/4svZk+LJsyezZ0+effH8y/zps8ezZ198+R/3DB8yIFtAfe3uF5P/nZ2VC5GdvTnPLg2w", - "LU5oxb4DszeoK88FNq4zSM3xJMKKsnLywv/0v/wJO8nFqh3e/zpxDVgmS60r9eL0dLPZnISfnC4wKTzT", - "os6Xp34ebCfWkVfenDfR5DbuBXe0tR7jpjpSOMNnb7++uCRnb85PWoKZvJg8Onl08tj1ruW0YpMXk6f4", - "E56eJe77qSO2yYsPH6eT0yXQEmuomD9WoCXL/SMJtNi5/6sNXSxAnmDCgP1p/eTUixWnH1xy/Md9z07D", - "kIrTD50aAsWBLzEc4PSD72C5/+1O90IXiRV8MBKKfa+dzrBrxdhXQQUvp5eCyoY6/YDicvL3U2fziD9E", - "tcWeh1NfaCP+ZgdLH/TWwHrgiy0rgpXkVOfLujr9gP9B6g2AtkUYT/WWn6Ln9PRDZ63u8WCt3d/bz8M3", - "1itRgAdOzOe2s+e+x6cf7L/BRLCtQDIjFmLhE/erLVB1ig2edsOfdzyP/jhcR6c4jzl3US/0W1sRnpKS", - "KR9O0K3po8Lmz+cF8mfdLxRkXvKhhHjInzx65Dmb0xsCqjx1h3jStoIfV3agX55oeOMNWdu+lX2cTp4d", - "Cehe21CnqGMEmK9oQXwOKs79+NPNfc5tWKPh9fZOQgiefToIOttHvoMd+UFo8g0qTx+nk+efcifOuRHl", - "aEnwzaDB5vCI/MSvudhw/6YRZurVisrd6OOj6UKh31OyNXWiZPMaX0zeYw0Gm5fcPWpnRTEgeivUgdJf", - "CbwdUxhbqUXl3CYt0lqZlnGzhKFSPEDVpe0z26v0ZevReOc5FwVMQmlTyxo+3pIn9AIuqNTnERsPGisx", - "0nnuW+IGoEbLVvXd0XbkoT5yiITbrs1tgPCfPOVPntLwlOePnn666S9ArlkO5BJWlZBUsnJHfuJN5PmN", - "edxZUURr/XWP/kEeN51ss1wUsACeOQaWzUSx853pOxNcg1VfB4LMqVf3OhJ/gnt6RTImrbTxkJMX72J+", - "StdGtapnJcuJNXWhrmcUmUAVa4qvdZnfNNjWAfuJFPglBSvrJhFYb4RLtBteKOR+mB6vfrMd1vEgMr0j", - "G8YLscH20gjubzUgn3fw+mkmEQCDoLthL4vWgm8AHICVmg9N/2Ows2fy1/Rmc5f02Knf3/LKOniZNsWN", - "/uvixx+CdBybQmw99JgMYkkXI3elwIjUDcUQLamhOCEvreml3BEu0Mhfq067nZM/76E/ef/tef+3TbVL", - "22hHYweNIUsK7oKTUQJvlLd/6PzpTBMTGx8Zq1FpfieULLBJ2vCCmu3I+auB9mo/618JX+3w1d6tEOH3", - "fRCPYvwJ9rJPpDELWQjdRInaRf0pZP4pZN5KcR19eMborlHLkm1dSAf62NR3IYz106Z6CMoY+9NnPb53", - "svFD21bMlmXr4UJBggc2PbuP5j9ZxJ8s4nYs4luIHEY8tY5pRIjuOFvXWIaBVTiKTsyTlzr863VJZZAR", - "d8iEfYYjxlXBP4RrfGqDXRRX1l6HgbzMRrBFNvBubXh/srw/Wd6/Dss7O8xouoLJra1e17Bb0aqxdall", - "rQuxCTzcCIuNPh36+Kzi3//7dEOZzuZCuu4KdK5BDj/WQMtT10q192vbvWzwBFuyBT+GdYyiv57SrtOy", - "6xs3rDf14cBxHnvqHMeJl3wSsX/cBtGEQSnI9ptwlHfvDctWINf+RmhjLF6cnmJViaVQ+nTycfqhF38R", - "PnzfkMeH5h5xZPIR6UJItmCclpmLbWj7QU+enDyafPx/AQAA//+o0sPPZwkBAA==", + "S/wJFNxgoWa8W5F+bHmM58A1W0MGJVuwWayo49+H/jAPq6FKV8fKRSE3AyrC5sSo8jN7sTr1XlK+AHM9", + "mytVKFraGn3RoA2jArmvIyWc/MXUTNBodi46LUQ1ugTs8xVgDTixMaAZpUK48mU2Sz5gsbWiC0iI76ED", + "a2QuesfphYMcupSj17CY92/bwWUYBdm+nJk1R8kYzBNDx6hp9WIS/UzWR+rcJliV1CFsVqIM1wRvWo5I", + "ZceRaMsspkCLny6QvJWGPBhdjIQUuaTKUyQWoPOMZpSA8gdWfdhX6+c8CKcLqsw1lXz8hdBnIgPV11X8", + "8WV+fG2fUO8dUafHqB8YwR/bDsFROiughIVduH3ZE0pbgaLdIAPHj/N5yTiQLBaZF9hogzvQzQFGeH9I", + "iHUPkNEjxMg4ABt9/zgw+UGEZ5MvjgGSuwoa1I+NXDL4G+K5bTZW3chjojL3C0u43HLPAagL52wu115Q", + "MQ5DGJ8Sw+bWtDRszqmj7SCDkjMoU/cKzLjokwcpWXuPd8beeketyd6TN1lNKNB5oOPS5h6IZ2Kb2eTW", + "qDg+284MvUfD9zHVNnYwbXGfe4rMxBYjmvBqseHiB2BJw+HBCMwPW6aQXvG7lKhhgdk37X5RL0aFCknG", + "2RobcknJOmOmTohXKXK5H9TruREAPUtMW/zaaeYHNeiueDK8zNtbbdrWofOZUbHjnzpC0V1K4G9oImoq", + "7LzpSyxRI0o3MKdbXCiQb2NEb9jE0IM09FMpKAE1lqwjRGXXMbeuUbwAb5wL/1lgWcESRpTvHgTRXhIW", + "TGloLfw+iONz2E4pVk4UYp5ena7k3KzvrRDNNWV9nPhhZ5mffAUYLj1nUukM3SPRJZiXvlGo8X9jXo3L", + "St14MltnmBVx3oDTXsMuK1hZx+nVzfvdKzPtDw1LVPUM+S3jNppmhnWxo1Gme6a2gch7F/zaLvg1vbP1", + "jjsN5lUzsTTk0p3jX+Rc9DjvPnYQIcAYcQx3LYnSPQwyyA4ecsdAbgoCEE72mYYHh6nwYx8MKfI5yqk7", + "yo4UXUtgzdi7CoY+LCOWGB096JfRX1HiDNCqYsW2Z6i1oyY1ZnqUNcYX4+thAXfXDXYAA92gwWgMdqeQ", + "oQtNdAapUxSQT40IZ2MVXSAeSNRybMJqUUu0+HUiAYdVMxvBbuTav/v5QgtJF+CstpkF6VZD4HKOQUNQ", + "k1IRzaz7tWDzOYTWSnUTS1sHuIFNqhhBuhEii5s0a8b1F89iZHSAeloYD6MsTjERWkj5sC6HVmEvVgV6", + "Z9NWJdiaG5h2o+mt38Eu+9loKKSiTKo2nM2Zabv874hdX6++gx2OfDBKzAB2YFdQTX0LSIMxs2DzyGZ1", + "NCpQWGAVK1J0tvCInTqL79IdbY0riZsm/jZmvFMytruU2xyM1qloYBmzGxdxX545PdBFfJ+UD20CSxjj", + "QnIMRK5wKqZ8A6HhVdTkbh+i3UugpSdeXM7k43RyO89Z7DZzIx7A9ZvmAo3iGSOzrCel4wg/EuW0qqRY", + "0zJz/sXU5S/F2l3++Lp3R35iYTJO2Zdfn71+48D/OJ3kJVCZNcpYclX4XvUvsypbRHf/VYISi7eKWGU9", + "2Pym8mfok9wswXV6CPT9QUnq1t8cHEXno5zHA0QP8j7nGrdL3OMih6rxkLcOEusg7zrF6Zqy0nsmPLSJ", + "YE5c3Li65lGuEA5wa+d6ECOR3Sm7GZzu+OloqesAT8K5fsRSbnGNg7tCb8iKnLOc3rn09I2QHebvMnmi", + "zvY/TqwyQrbFYyK20XcP6gtTJ8QKXr8ufjWn8eHD8Kg9fDglv5buQQAg/j5zv6N+8fBh1NUQtSQYJoGG", + "Ak5X8KCJSk5uxKc1O3HYjLugz9arRrIUaTJsKNR6zT26Nw57G8kcPgv3SwElmJ8OJ/71Nt2iOwRmzAm6", + "SGXuNEFZK9uwSBHB+zGImDRmSAuZ/YpiSXbruRkeIV6v0NuRqZLlcT8wnynDXrkNPjIvE3w5YTAzI9Ys", + "EcvGaxaMZV4bU2OwB2QwRxSZKlrmsMXdTLjjXXP2Ww2EFUarmTOQeK/1rjqvHOCoA4HUqJ7DudzANoqg", + "Hf42dpCwHUFfZkQg9htBwlCnAbivGrO+X2jjNWt1pmMjJsMZB4x7T7Sjow9HzTb7Y9kNWRqnx4xpXOkZ", + "neuLkJgj2oiSqWwuxe8Qt0WjCT+SOO4bMDAME/4deCzSpc9SGg9U20+znf3Qdo/XjVMbf2td2C+66flw", + "k8s0fqqP28ibKL0qXt7UITmlhIXuyG4obYK14PEKgsew3L4PVaDcniebNd3JyIifyjD36dSO355KB/Mg", + "X6ykmxmN9SIwupCBKdjeTlCFFsR/7DdANTnBdnYSRDw27zJbeakC2RbOGFZxvKFeY6cdrdG0CgxSVKi6", + "TG0gWKlEZJiabyi3PRzNd5Zfua8VWC+o+WojJNZNU/H4jwJytoqaY6+u3hX50NdfsAWz7QlrBUH/OzeQ", + "bf1qqcj1EGwy3R1qzufk0TRowul2o2BrptisBHzjsX1jRhVel41HsvnELA+4Xip8/cmI15c1LyQUeqks", + "YpUgje6JQl4TxTQDvQHg5BG+9/hLch/jtxRbwwODRScETV48/hK97/aPR7Fb1rWX3MeyC+TZPrgxTscY", + "wGbHMEzSjRqPVrT9pdO3w57TZD8dc5bwTXehHD5LK8rpAuLxzKsDMNlvcTfRo9rDC7feAFBaih1hOj4/", + "aGr4UyJH0rA/CwbJxWrF9MpF+SixMvTUNrezk/rhbKdV15fEw+UfYrBc5WOFerauT6zG0FUixwFDGn+g", + "K+iidUqoLZZXsjaM1XdLIue+Fic2amn6s1jcmLnM0lGWxKjWOakk4xrtH7WeZ38xarGkuWF/Jylws9kX", + "zyINT7o9AfhxgH9yvEtQINdx1MsE2XuZxX1L7nPBs5XhKMWDNic5OJXJqL54/FYqiGz/0GMlXzNKliS3", + "ukNuNODUtyI8vmfAW5Jis56j6PHolX1yyqxlnDxobXbop7evnZSxEjJWYLs97k7ikKAlgzVmmMQ3yYx5", + "y72Q5ahduA30nzcExYucgVjmz3JUEQg8mvuSS40U//P3baVgdKzazJ2eDVDIiLXT2e0+ccDXcVa3vv/W", + "xuzgswTmRqPNtqEfYCURqmtjcZtvPnGucdTca/e8Y3B8/CuRRgdHOf7hQwT64cOpE4N/fdJ9bNn7w4fx", + "gp1Rk5v5tcXCbTRi/Da2h1+JiAHMd8dqAopcPnHEAJm6pMwDwwRnbqgp6XYi+vRSxN0kg8QD/uKn4Orq", + "HT7xeMA/+oj4zMwSN7ANaU4f9m4ntijJFM3zINSYkq/Edizh9O4gTzz/BChKoGSkeQ5XMug0F3XXH4wX", + "CWjUjDqDUhglM2yiEdrz/3XwbBY/3YPtmpXFz20tpN5FIinPl9FAzZn58Je2I3yzRMsqo3X5l5RzKKPD", + "Wd32F68DR7T0f4ix86wYH/luv9OhXW5vcS3gXTA9UH5Cg16mSzNBiNVumZkmjblciILgPG0R+JY5DluG", + "Bn3MfqtB6djRwAc2WwmdXYb52jZaBHiB1q8T8i0WfDCwdCr8otXJ107s1hGrq1LQYoo1HS+/PntN7Kz2", + "G9vX2LbxWqDRpbuKqJV8fF21pkVxvGDA+HH2ZzCbVSudNV23YiWZzBttXzDWC51Ac0yInRPyylrClLez", + "2EkIVgaVKyiCJl9WF0OaMP/RmuZLNDF1LrI0yY/vP+epsjXAB82sm6YPeO4M3K4Fne1ANyVCL0FumALM", + "woQ1dKtANSXRnInTV4XqLk/WnFtKOTlCpmhaPByLdg+cFUi8bzgKWQ/xRxoYbPvGY9vxXeBX0RrU/d5+", + "PeetrynUNCn+3tmIc8oFZzlWgI4JRFixZpy3aUSx7LibSE3cCY0crmhHwSb/y2Ex2WPQM0KHuKHnNnhq", + "NtVSh/1Tw9Z1mlmAVo6zQTH1jTGdX4NxBa6JhyGikE8KGYlNicazN37wI8kIi1EkDFXfmGc/ODMmJkJf", + "M44GC4c2J2Zbz0OpGDoYOWGaLAQot55uRS71znxzgsWpCti+P3ktFiy/YAscw0ZDmWXb0L/hUGc+ENAF", + "3pl3X5p3Xcng5udOVI+d9Kyq3KTptqnxXtFbnkRwLPzExwMEyG3GD0fbQ257I3jxPjWEBmsMPoIK7+EB", + "YTQtRHv9uo2KYCkK3yA2NylaN5DxCBivGfeesPgFkUevBNwYPK+J71QuqbYi4Ciedgm0TMSxY66fdaXe", + "dqh+wWSDElyjnyO9jW330wTjaF5oBTfKd8QfCkPdgTDxkpZNBGyklylKVU6IKjBHpNfdNMY4DOP2/ZO7", + "F8CBlunT9nMsQn7sTZQqzTSriwXojBZFrKfKV/iU4FOf6wNbyOum90ZVkRwrkXZLsw6pzU2UC67q1Z65", + "/Au3nC5oFxyhhrBlsd9hrK4w2+G/xzSzb2Jfj85v84GuxXH1iIf5ejGp19B0ptgiG48JvFNuj4526psR", + "evv9nVJ6KRZdQD6HkTTB5cI9ivG3r83FEdYrHIQZ26ulKSeIIb0Cn/siF00hrC5Xwqts0F4FnddNE/n9", + "Zoh0O/gpXn6JnNLQ5G3vV2sGTmWW5slEaKpdSRZNyV4WlCxzYUM+e0b0oScoFeZpozzvzvjs1roXoWkX", + "zHcdh4sN9WmZRdLRcjNfSLvBxzpDvlunko19eXJ83m8XfQ2uiFwlYc1E7YNofCirVwntr53my026d3T9", + "0QDxz218TprKL13bPrtMp5N/97N1phHgWu7+CQzng00fNKIeSrvWPNW+QpqOT6M6QHVuxTGl+2NV4p1s", + "2GmFfaCR94CsXo0RB4aNuaeT8+KoCzPWaWBiR4kdu3ib7XQh5rb4Mh6xSijWNl6L9d8eGTN+iS20g0LS", + "w7F8LOEaco3d9toYKQlwTFlpM5m33f9ZkDmtTjeh9a4O877iy8MWewfu+EEJkqCMjm1PdjK+1PBZEwlr", + "E3k2VGFhfok27m7q6+gEvPkcciwGubfky9+XwINyIlNvl0FY5kEFGNako2A50+Otji1A+yqy7IUnaCtw", + "a3BS6cjXsLunSIcaov3SmlysmxSLRAwgd8h86cyUIdkF/zDVUAZiwUd22s+hrQmebLUcFDC64VyeJM3F", + "0RY12jNlvNfrqLnMp0eV+sLMilRVmGGryLT+8Qo7cyoX50SbYpOhlk7Oh/0CNq5YJRboaXwnvmwlKP+b", + "r8ZlZynZNYTNoNFTtaGy8G9ETS/eqpPtuY8GpVx8m8M+0PNmZtbG4Q991ZEK1JjSkpfCiBFZKi+oG/re", + "xI3dUzbAr63DgnDNQbqm+Sj/lkJBpoWP298Hxz5U2CjGGyFBJbs+WOCS5U7ftvVcsfsNxfKm1AUvhgsk", + "ElbUQCeDqqvpOfch+6V97nOpffeTgxamhl4Pt+HzGRhMDZAYUv2cuNvycI72TYxNjHOQmfc89UuwcpBd", + "b0glRVHn9oIOD0ZjkBtdAmUPK4naafLhKns6QpDrfA27U6sE+f6FfgdDoK3kZEEPSvf1NvlOzW8qBvfi", + "TsD7nJar6aQSoswSzo7zYd3YPsVfs/waCmJuCh+pnGhNS+6jjb3xZm+WO18ntaqAQ/HghJAzbnNDvGO7", + "21WpNzm/p/fNv8VZi9qWcnZGtZMrHg+yxyLL8pbczA+zn4cpMKzullPZQQ5UJd0matZKuok0aj4Zq5UP", + "Xc395rktUVkoYjLJhfVYvcSDHjMcYSZ7UHIBHZmUOE8XUaWIhWTeJNveDBXHVDgZAqSBj0n6bqBwg0cR", + "EG0HGzmFtoKZq10m5kRC60S+aRG3YefamEbfn7mZpcvv5kJCpwet+VrIwos8TLXNoqmcMS2p3N2k1Nqg", + "c+7AepLE8sFwrCYSq11IG401xGFZik2GzCprapvHVFvznupexr7XTPudOdUzCOK6qHKC2o4saUFyISXk", + "4RfxtD0L1UpIyEqBYV4xD/RcG7l7hbk6nJRiQUSViwJsj4A4BaXmqjmnKDZBEFUTRYGlHUz6tN8EdDxy", + "yrtq22yL89hFZ9aXmQg8BeWK8TgM2ZeH8O5peXxUdf7zOVqEGMa6dHOvrfQZNn6GI/s+s7L0BoNU62fy", + "k6oxHAkTb8wUz8hKKO00OzuSaoZqQ7zu54JrKcqyawSyIvHCWba/p9uzPNevhbie0fz6AeqRXOhmpcXU", + "p6X2g/HamWSvItPIHtWXy4idF2fxp+7oRtSOcxzdPzYA8/1hjnXYxn0W67PdXVe/cTxP1M7UYsXyOA3/", + "a0W3JWPSYiwhWurJtnCyyfn4GjLq8HJoghmQJQ3RDJxGe9CcEcfTnFMXmYf5L0q8/XHJHNwlkbiYhnzS", + "SS1ZnpStegAgpDZjVNfS9n0KJZ+Gq4iFzTBHl3Qf0JFcHCN/bgebGeHOgdJwK6AG0YYNgPetsj+1Jbls", + "5OJMbP3zB23NrhsB/3E/lcd65UdOcUNarpW/r++R4AjxysB744+wq7m/QQ9HITU9+kbeqAEA6bikDgyj", + "opOOBWNOWQlFRnXickeb0DTQbF1GS7/zKlOOk+fUXthLIGbsWoKrN2FF6l6n9ooaUhLN60PLLS9gCwqL", + "Qdh201RZP4P3d0Bp20r1lG9RZSWsoROu5Ypg1CjasTX4b1XzMSkAKvT+9W1SsTik8C7vGSrc2rMgkmUM", + "dqOWC4tYu1PkgFkiakTZ8sweEzX2KBmI1qyoaQd/6liRo2t2M0c5gqqBTJ55vW3sND/ZEd76Ac789zFR", + "xmPi/Tg+dDQLiqNuHwM6GJdYq9Sp5/GwxLDCS+PQwNmKxvFpSbzlG6qiG542AA5JvlVvRu4TEzxA7Ndb", + "yFGq6cbd3R4nBAcjqle9KSmCy2aHb25I/iw0vJeEk+PFVA0FyGD3Wmo8XTiBHV/AXpvciL1GasYWUo7/", + "O/43JbPaD2T0atvRKtTgXoH32GFB6cZZ4QRa1lxoPr5w6uoJ9pVyFkRWr+iOCIn/GH3tt5qWbL7DE2rB", + "958RtaSGhJyL0PquXbyimXi/YDL1gHm7gPBT2XWzsWMGw+3MKAHQ5gp0ximsDHQN4TagW95ynlwblqPq", + "2YophZddbzuHWHCL9zUhVrQIdWSsTNftc+prlZqv//82ayucyheUqkqa+/5lQBRd9QzitkehJy69hNX+", + "tL6heuxJoOl72BKt9Om8xQ2Me0dGbsRi5VP9HjpgD/rBDVpd3GoZx3RPbjOj9yREjlrKXe/C2PiQAdDo", + "ZPZVvQ6Ab6sx+gpgnwL/0aKRqWWMAf+fBe+JNnohvLZj3ifAciflPwKrtavOxDaTMFeHQiGsYdUowrIt", + "FuCNk4znEqiysSHnPzqVra2JyLhRIW30YuN9a0YpYM54yywZr2od0QCwNCLfBQgLzdOI1oSzJyUlGDFs", + "Tcsf1yAlK1IbZ06HbeMV1qT3Jnn3bUT5b+7U4QBMtdoPZhJCm6kWvGYucNv1xgYWKk15QWURvs44yUGa", + "e59s6E7d3PdhoJW1kS8OeD9oIM1089sDPwiStgWk3Dn35S09Ew2A9A5dFCNcCxjBGnErWKOIFglPwhCG", + "eFkFus1KscD8sgQBuuKT6PuxyorgaLC18tBx8yj2O+yfButuu4OvBc46Zor95+xHRB0qPD9xpveeNGtN", + "6yf82YhMexA8/fNFGxZuN2dI/7EczUtMYujkafY74vu9tuEhdj5IeDK6FtzELqKD3CX4huba8f2Muj74", + "WCao1WEz1G3VnsBvUG2QM81d4M7Q6DNQii1Spi6P9kibkLUk+3sgAZ7tVOvOVnfaJpjCjHNME6j9mbNZ", + "JaosHxMNaEvzF86g7SDtwpigj8BcnVh3EzihmmYVncImna4Vx/bBSnbNOOSXqfJ9SnbKoJHgoF1juZgj", + "L8MjbM04mOPRGC+m/eyjrsGmYRKEEgl5LdGguaG7w32FEiVhL/529vzxk1+ePP+CmBdIwRag2rLCvb48", + "bcQY4307y6eNERssT8c3weelW8R5T5lPt2k2xZ01y21VWzNw0JXoGEto5AKIHMdIP5gb7RWO0wZ9/3Nt", + "V2yRd75jMRT88XsmRVnGy7o3olvE1B/brcDYbyT+CqRiShtG2PXVMd3GyqolmuOwuOfa1hkRPHfV1xsq", + "YDoRjBNbSCrUEvkZZv06/waBbVU6XmV9EvvW5fQiaxHD4AyM35gBqUTlRGk2JzGIMLdEBjmXztCI4Z1B", + "9GTDbG0cZYwQXUxynPTOuNM8xZzs5/bdbo06zunNJkbEC38ob0CaKUt6OqP9JpykNaX/0/CPSIr+nXGN", + "Zrl/BK+I6gc3a3w8CrRhunaEPBCARB5mJ4Mu7IveVhqV1iqP9nvv6uyLH9+3LtCDCQMIif/gAHhhYmX7", + "XhPj7sD5zCU7v2+QEizlfYoSOss/lKvpWW9zkQRb5IwUWoOybEkMxcIgEVe9bPJbE1rJIA0Wm6AbzbQs", + "I+mz1m6CZyokHKMSyDUtPz3XwO74Z4gPKN6mk2bCHMoQyRaV6mYV3F7TUXMH+ZJ3NzV/gym7fwezR9F7", + "zg3l3MWD2wytXtiSeuFvBZsFTDY4pg0HevwFmblq+pWEnKm+G3rjhZMmZRAkm7vQS9jqAzmKh9b5s9C3", + "IOO5jxkhPwTuJIFmuxbC9oh+ZqaSOLlRKo9R34AsIviL8aiw++aB6+KWlddvVhAkKO11ZEGQYV/Rscuz", + "RS/MpVMrGK5z9G3dwW3kom7XNraazegC7ldX7/RsTBGaeLF18zlWwbmTqutH1Vz/A+rfWBy5Mdy8MYr5", + "OVUR1Vb9TBTf7e1HzcqDASKdUsofp5MFcFBMYbHgX1xziE97l3oIbE7+8KhaWG9TSMQiJrLWzuTBVEGR", + "5BH1kd1nkWrImO+W15LpHTYG9QY09ku0Us+3TdUHVzWk8V25u0+La2iaM7c1Imrlb9dvBS3xPrIuNW5u", + "IVGekK+3dFWVzhxM/npv9h/w9C/PikdPH//H7C+Pnj/K4dnzLx89ol8+o4+/fPoYnvzl+bNH8Hj+xZez", + "J8WTZ09mz548++L5l/nTZ49nz7748j/uGT5kQLaA+trdLyb/OzsrFyI7e3OeXRpgW5zQin0HZm9QV54L", + "bFxnkJrjSYQVZeXkhf/pf/kTdpKLVTu8/3XiGrBMllpX6sXp6WazOQk/OV1gUnimRZ0vT/082E6sI6+8", + "OW+iyW3cC+5oaz3GTXWkcIbP3n59cUnO3pyftAQzeTF5dPLo5LHrXctpxSYvJk/xJzw9S9z3U0dskxcf", + "Pk4np0ugJdZQMX+sQEuW+0cSaLFz/1cbuliAPMGEAfvT+smpFytOP7jk+I/7np2GIRWnHzo1BIoDX2I4", + "wOkH38Fy/9ud7oUuEiv4YCQU+147nWHXirGvggpeTi8FlQ11+gHF5eTvp87mEX+Iaos9D6e+0Eb8zQ6W", + "PuitgfXAF1tWBCvJqc6XdXX6Af+D1BsAbYswnuotP0XP6emHzlrd48Fau7+3n4dvrFeiAA+cmM9tZ899", + "j08/2H+DiWBbgWRGLMTCJ+5XW6DqFBs87YY/73ge/XG4jk5xHnPuol7ot7YiPCUlUz6coFvTR4XNn88L", + "5M+6XyjIvORDCfGQP3n0yHM2pzcEVHnqDvGkbQU/ruxAvzzR8MYbsrZ9K/s4nTw7EtC9tqFOUccIMF/R", + "gvgcVJz78aeb+5zbsEbD6+2dhBA8+3QQdLaPfAc78oPQ5BtUnj5OJ88/5U6ccyPK0ZLgm0GDzeER+Ylf", + "c7Hh/k0jzNSrFZW70cdH04VCv6dka+pEyeY1vpi8xxoMNi+5e9TOimJA9FaoA6W/Eng7pjC2UovKuU1a", + "pLUyLeNmCUOleICqS9tntlfpy9aj8c5zLgqYhNKmljV8vCVP6AVcUKnPIzYeNFZipPPct8QNQI2Wreq7", + "o+3IQ33kEAm3XZvbAOE/ecqfPKXhKc8fPf1001+AXLMcyCWsKiGpZOWO/MSbyPMb87izoojW+use/YM8", + "bjrZZrkoYAE8cwwsm4li5zvTdya4Bqu+DgSZU6/udST+BPf0imRMWmnjIScv3sX8lK6NalXPSpYTa+pC", + "Xc8oMoEq1hRf6zK/abCtA/YTKfBLClbWTSKw3giXaDe8UMj9MD1e/WY7rONBZHpHNowXYoPtpRHc32pA", + "Pu/g9dNMIgAGQXfDXhatBd8AOAArNR+a/sdgZ8/kr+nN5i7psVO/v+WVdfAybYob/dfFjz8E6Tg2hdh6", + "6DEZxJIuRu5KgRGpG4ohWlJDcUJeWtNLuSNcoJG/Vp12Oyd/3kN/8v7b8/5vm2qXttGOxg4aQ5YU3AUn", + "owTeKG//0PnTmSYmNj4yVqPS/E4oWWCTtOEFNduR81cD7dV+1r8Svtrhq71bIcLv+yAexfgT7GWfSGMW", + "shC6iRK1i/pTyPxTyLyV4jr68IzRXaOWJdu6kA70sanvQhjrp031EJQx9qfPenzvZOOHtq2YLcvWw4WC", + "BA9senYfzX+yiD9ZxO1YxLcQOYx4ah3TiBDdcbausQwDq3AUnZgnL3X41+uSyiAj7pAJ+wxHjKuCfwjX", + "+NQGuyiurL0OA3mZjWCLbODd2vD+ZHl/srx/HZZ3dpjRdAWTW1u9rmG3olVj61LLWhdiE3i4ERYbfTr0", + "8VnFv//36YYync2FdN0V6FyDHH6sgZanrpVq79e2e9ngCbZkC34M6xhFfz2lXadl1zduWG/qw4HjPPbU", + "OY4TL/kkYv+4DaIJg1KQ7TfhKO/eG5atQK79jdDGWLw4PcWqEkuh9Onk4/RDL/4ifPi+IY8PzT3iyOQj", + "0oWQbME4LTMX29D2g548OXk0+fj/AgAA//88dqWvBAoBAA==", } // 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 0938833520..c4e4a8de10 100644 --- a/daemon/algod/api/server/v2/generated/participating/public/routes.go +++ b/daemon/algod/api/server/v2/generated/participating/public/routes.go @@ -255,146 +255,146 @@ var swaggerSpec = []string{ "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", - "/G1EEgEA", + "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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 3eb65154b7..5663f429ba 100644 --- a/daemon/algod/api/server/v2/handlers.go +++ b/daemon/algod/api/server/v2/handlers.go @@ -525,6 +525,7 @@ func (v2 *Handlers) basicAccountInformation(ctx echo.Context, addr basics.Addres Status: record.Status.String(), RewardBase: &record.RewardsBase, Participation: apiParticipation, + IncentiveEligible: omitEmpty(record.IncentiveEligible), TotalCreatedAssets: record.TotalAssetParams, TotalCreatedApps: record.TotalAppParams, TotalAssetsOptedIn: record.TotalAssets, diff --git a/data/basics/msgp_gen.go b/data/basics/msgp_gen.go index 06190153d6..f51e6e503b 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(20) + var zb0009Mask uint32 /* 21 bits */ if (*z).MicroAlgos.MsgIsZero() { zb0009Len-- zb0009Mask |= 0x2 @@ -280,54 +280,58 @@ func (z *AccountData) MarshalMsg(b []byte) (o []byte) { zb0009Len-- zb0009Mask |= 0x80 } - if (*z).Status == 0 { + if (*z).IncentiveEligible == false { zb0009Len-- zb0009Mask |= 0x100 } - if (*z).SelectionID.MsgIsZero() { + if (*z).Status == 0 { zb0009Len-- zb0009Mask |= 0x200 } - if (*z).AuthAddr.MsgIsZero() { + if (*z).SelectionID.MsgIsZero() { zb0009Len-- zb0009Mask |= 0x400 } - if (*z).StateProofID.MsgIsZero() { + if (*z).AuthAddr.MsgIsZero() { zb0009Len-- zb0009Mask |= 0x800 } - if (*z).TotalBoxes == 0 { + if (*z).StateProofID.MsgIsZero() { zb0009Len-- zb0009Mask |= 0x1000 } - if (*z).TotalBoxBytes == 0 { + if (*z).TotalBoxes == 0 { zb0009Len-- zb0009Mask |= 0x2000 } - if (*z).TotalExtraAppPages == 0 { + if (*z).TotalBoxBytes == 0 { zb0009Len-- zb0009Mask |= 0x4000 } - if ((*z).TotalAppSchema.NumUint == 0) && ((*z).TotalAppSchema.NumByteSlice == 0) { + if (*z).TotalExtraAppPages == 0 { zb0009Len-- zb0009Mask |= 0x8000 } - if (*z).VoteID.MsgIsZero() { + if ((*z).TotalAppSchema.NumUint == 0) && ((*z).TotalAppSchema.NumByteSlice == 0) { zb0009Len-- zb0009Mask |= 0x10000 } - if (*z).VoteFirstValid == 0 { + if (*z).VoteID.MsgIsZero() { zb0009Len-- zb0009Mask |= 0x20000 } - if (*z).VoteKeyDilution == 0 { + if (*z).VoteFirstValid == 0 { zb0009Len-- zb0009Mask |= 0x40000 } - if (*z).VoteLastValid == 0 { + if (*z).VoteKeyDilution == 0 { zb0009Len-- zb0009Mask |= 0x80000 } + if (*z).VoteLastValid == 0 { + zb0009Len-- + zb0009Mask |= 0x100000 + } // variable map header, size zb0009Len o = msgp.AppendMapHeader(o, zb0009Len) if zb0009Len != 0 { @@ -451,41 +455,46 @@ func (z *AccountData) MarshalMsg(b []byte) (o []byte) { o = (*z).RewardedMicroAlgos.MarshalMsg(o) } if (zb0009Mask & 0x100) == 0 { // if not empty + // string "ie" + o = append(o, 0xa2, 0x69, 0x65) + o = msgp.AppendBool(o, (*z).IncentiveEligible) + } + if (zb0009Mask & 0x200) == 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 & 0x400) == 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 & 0x800) == 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 & 0x1000) == 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 & 0x2000) == 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 & 0x4000) == 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 & 0x8000) == 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 & 0x10000) == 0 { // if not empty // string "tsch" o = append(o, 0xa4, 0x74, 0x73, 0x63, 0x68) // omitempty: check for empty values @@ -512,22 +521,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 & 0x20000) == 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 & 0x40000) == 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 & 0x80000) == 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 & 0x100000) == 0 { // if not empty // string "voteLst" o = append(o, 0xa7, 0x76, 0x6f, 0x74, 0x65, 0x4c, 0x73, 0x74) o = msgp.AppendUint64(o, uint64((*z).VoteLastValid)) @@ -795,6 +804,14 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) return } } + if zb0009 > 0 { + zb0009-- + (*z).IncentiveEligible, bts, err = msgp.ReadBoolBytes(bts) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "IncentiveEligible") + return + } + } if zb0009 > 0 { zb0009-- var zb0020 int @@ -1196,6 +1213,12 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) err = msgp.WrapError(err, "AuthAddr") return } + case "ie": + (*z).IncentiveEligible, bts, err = msgp.ReadBoolBytes(bts) + if err != nil { + err = msgp.WrapError(err, "IncentiveEligible") + return + } case "appl": var zb0035 int var zb0036 bool @@ -1391,7 +1414,7 @@ func (z *AccountData) Msgsize() (s int) { s += 0 + zb0003.Msgsize() + 1 + 2 + msgp.Uint64Size + 2 + msgp.BoolSize } } - s += 6 + (*z).AuthAddr.Msgsize() + 5 + msgp.MapHeaderSize + s += 6 + (*z).AuthAddr.Msgsize() + 3 + msgp.BoolSize + 5 + msgp.MapHeaderSize if (*z).AppLocalStates != nil { for zb0005, zb0006 := range (*z).AppLocalStates { _ = zb0005 @@ -1413,7 +1436,7 @@ 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) && (len((*z).AssetParams) == 0) && (len((*z).Assets) == 0) && ((*z).AuthAddr.MsgIsZero()) && ((*z).IncentiveEligible == false) && (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 @@ -1431,7 +1454,7 @@ func AccountDataMaxSize() (s int) { // Adding size of map values for z.Assets s += encodedMaxAssetsPerAccount * (1) s += 2 + msgp.Uint64Size + 2 + msgp.BoolSize - s += 6 + AddressMaxSize() + 5 + s += 6 + AddressMaxSize() + 3 + msgp.BoolSize + 5 s += msgp.MapHeaderSize // Adding size of map keys for z.AppLocalStates s += EncodedMaxAppLocalStates * (AppIndexMaxSize()) @@ -3199,8 +3222,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(21) + var zb0009Mask uint32 /* 23 bits */ if (*z).Addr.MsgIsZero() { zb0009Len-- zb0009Mask |= 0x4 @@ -3233,54 +3256,58 @@ func (z *BalanceRecord) MarshalMsg(b []byte) (o []byte) { zb0009Len-- zb0009Mask |= 0x200 } - if (*z).AccountData.Status == 0 { + if (*z).AccountData.IncentiveEligible == false { zb0009Len-- zb0009Mask |= 0x400 } - if (*z).AccountData.SelectionID.MsgIsZero() { + if (*z).AccountData.Status == 0 { zb0009Len-- zb0009Mask |= 0x800 } - if (*z).AccountData.AuthAddr.MsgIsZero() { + if (*z).AccountData.SelectionID.MsgIsZero() { zb0009Len-- zb0009Mask |= 0x1000 } - if (*z).AccountData.StateProofID.MsgIsZero() { + if (*z).AccountData.AuthAddr.MsgIsZero() { zb0009Len-- zb0009Mask |= 0x2000 } - if (*z).AccountData.TotalBoxes == 0 { + if (*z).AccountData.StateProofID.MsgIsZero() { zb0009Len-- zb0009Mask |= 0x4000 } - if (*z).AccountData.TotalBoxBytes == 0 { + if (*z).AccountData.TotalBoxes == 0 { zb0009Len-- zb0009Mask |= 0x8000 } - if (*z).AccountData.TotalExtraAppPages == 0 { + if (*z).AccountData.TotalBoxBytes == 0 { zb0009Len-- zb0009Mask |= 0x10000 } - if ((*z).AccountData.TotalAppSchema.NumUint == 0) && ((*z).AccountData.TotalAppSchema.NumByteSlice == 0) { + if (*z).AccountData.TotalExtraAppPages == 0 { zb0009Len-- zb0009Mask |= 0x20000 } - if (*z).AccountData.VoteID.MsgIsZero() { + if ((*z).AccountData.TotalAppSchema.NumUint == 0) && ((*z).AccountData.TotalAppSchema.NumByteSlice == 0) { zb0009Len-- zb0009Mask |= 0x40000 } - if (*z).AccountData.VoteFirstValid == 0 { + if (*z).AccountData.VoteID.MsgIsZero() { zb0009Len-- zb0009Mask |= 0x80000 } - if (*z).AccountData.VoteKeyDilution == 0 { + if (*z).AccountData.VoteFirstValid == 0 { zb0009Len-- zb0009Mask |= 0x100000 } - if (*z).AccountData.VoteLastValid == 0 { + if (*z).AccountData.VoteKeyDilution == 0 { zb0009Len-- zb0009Mask |= 0x200000 } + if (*z).AccountData.VoteLastValid == 0 { + zb0009Len-- + zb0009Mask |= 0x400000 + } // variable map header, size zb0009Len o = msgp.AppendMapHeader(o, zb0009Len) if zb0009Len != 0 { @@ -3409,41 +3436,46 @@ func (z *BalanceRecord) MarshalMsg(b []byte) (o []byte) { o = (*z).AccountData.RewardedMicroAlgos.MarshalMsg(o) } if (zb0009Mask & 0x400) == 0 { // if not empty + // string "ie" + o = append(o, 0xa2, 0x69, 0x65) + o = msgp.AppendBool(o, (*z).AccountData.IncentiveEligible) + } + if (zb0009Mask & 0x800) == 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 & 0x1000) == 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 & 0x2000) == 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 & 0x4000) == 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 & 0x8000) == 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 & 0x10000) == 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 & 0x20000) == 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 & 0x40000) == 0 { // if not empty // string "tsch" o = append(o, 0xa4, 0x74, 0x73, 0x63, 0x68) // omitempty: check for empty values @@ -3470,22 +3502,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 & 0x80000) == 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 & 0x100000) == 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 & 0x200000) == 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 & 0x400000) == 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)) @@ -3761,6 +3793,14 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState return } } + if zb0009 > 0 { + zb0009-- + (*z).AccountData.IncentiveEligible, bts, err = msgp.ReadBoolBytes(bts) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "IncentiveEligible") + return + } + } if zb0009 > 0 { zb0009-- var zb0020 int @@ -4168,6 +4208,12 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState err = msgp.WrapError(err, "AuthAddr") return } + case "ie": + (*z).AccountData.IncentiveEligible, bts, err = msgp.ReadBoolBytes(bts) + if err != nil { + err = msgp.WrapError(err, "IncentiveEligible") + return + } case "appl": var zb0035 int var zb0036 bool @@ -4363,7 +4409,7 @@ func (z *BalanceRecord) Msgsize() (s int) { s += 0 + zb0003.Msgsize() + 1 + 2 + msgp.Uint64Size + 2 + msgp.BoolSize } } - s += 6 + (*z).AccountData.AuthAddr.Msgsize() + 5 + msgp.MapHeaderSize + s += 6 + (*z).AccountData.AuthAddr.Msgsize() + 3 + msgp.BoolSize + 5 + msgp.MapHeaderSize if (*z).AccountData.AppLocalStates != nil { for zb0005, zb0006 := range (*z).AccountData.AppLocalStates { _ = zb0005 @@ -4385,7 +4431,7 @@ 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) && (len((*z).AccountData.AssetParams) == 0) && (len((*z).AccountData.Assets) == 0) && ((*z).AccountData.AuthAddr.MsgIsZero()) && ((*z).AccountData.IncentiveEligible == false) && (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 @@ -4403,7 +4449,7 @@ func BalanceRecordMaxSize() (s int) { // Adding size of map values for z.AccountData.Assets s += encodedMaxAssetsPerAccount * (1) s += 2 + msgp.Uint64Size + 2 + msgp.BoolSize - s += 6 + AddressMaxSize() + 5 + s += 6 + AddressMaxSize() + 3 + msgp.BoolSize + 5 s += msgp.MapHeaderSize // Adding size of map keys for z.AccountData.AppLocalStates s += EncodedMaxAppLocalStates * (AppIndexMaxSize()) diff --git a/data/basics/userBalance.go b/data/basics/userBalance.go index 398147bb6d..cea8a9bc2c 100644 --- a/data/basics/userBalance.go +++ b/data/basics/userBalance.go @@ -209,6 +209,8 @@ type AccountData struct { // This allows key rotation, changing the members in a multisig, etc. AuthAddr Address `codec:"spend"` + IncentiveEligible bool `codec:"ie"` + // AppLocalStates stores the local states associated with any applications // that this account has opted in to. AppLocalStates map[AppIndex]AppLocalState `codec:"appl,allocbound=EncodedMaxAppLocalStates"` diff --git a/ledger/ledgercore/accountdata.go b/ledger/ledgercore/accountdata.go index 3685d16909..7fde54c0aa 100644 --- a/ledger/ledgercore/accountdata.go +++ b/ledger/ledgercore/accountdata.go @@ -39,6 +39,7 @@ type AccountBaseData struct { RewardsBase uint64 RewardedMicroAlgos basics.MicroAlgos AuthAddr basics.Address + IncentiveEligible bool TotalAppSchema basics.StateSchema // Totals across created globals, and opted in locals. TotalExtraAppPages uint32 // Total number of extra pages across all created apps @@ -75,8 +76,8 @@ func ToAccountData(acct basics.AccountData) AccountData { MicroAlgos: acct.MicroAlgos, RewardsBase: acct.RewardsBase, RewardedMicroAlgos: acct.RewardedMicroAlgos, - - AuthAddr: acct.AuthAddr, + AuthAddr: acct.AuthAddr, + IncentiveEligible: acct.IncentiveEligible, TotalAppSchema: acct.TotalAppSchema, TotalExtraAppPages: acct.TotalExtraAppPages, @@ -105,6 +106,8 @@ func AssignAccountData(a *basics.AccountData, acct AccountData) { a.MicroAlgos = acct.MicroAlgos a.RewardsBase = acct.RewardsBase a.RewardedMicroAlgos = acct.RewardedMicroAlgos + a.AuthAddr = acct.AuthAddr + a.IncentiveEligible = acct.IncentiveEligible a.VoteID = acct.VoteID a.SelectionID = acct.SelectionID @@ -113,7 +116,6 @@ func AssignAccountData(a *basics.AccountData, acct AccountData) { a.VoteLastValid = acct.VoteLastValid a.VoteKeyDilution = acct.VoteKeyDilution - a.AuthAddr = acct.AuthAddr a.TotalAppSchema = acct.TotalAppSchema a.TotalExtraAppPages = acct.TotalExtraAppPages a.TotalBoxes = acct.TotalBoxes diff --git a/ledger/store/trackerdb/data.go b/ledger/store/trackerdb/data.go index fc243b2b92..2e9ee4778e 100644 --- a/ledger/store/trackerdb/data.go +++ b/ledger/store/trackerdb/data.go @@ -47,6 +47,7 @@ type BaseAccountData struct { TotalAppLocalStates uint64 `codec:"l"` TotalBoxes uint64 `codec:"m"` TotalBoxBytes uint64 `codec:"n"` + IncentiveEligible bool `codec:"o"` BaseVotingData @@ -286,6 +287,7 @@ func (ba *BaseAccountData) SetCoreAccountData(ad *ledgercore.AccountData) { ba.TotalAppLocalStates = ad.TotalAppLocalStates ba.TotalBoxes = ad.TotalBoxes ba.TotalBoxBytes = ad.TotalBoxBytes + ba.IncentiveEligible = ad.IncentiveEligible ba.BaseVotingData.SetCoreAccountData(ad) } @@ -306,6 +308,7 @@ func (ba *BaseAccountData) SetAccountData(ad *basics.AccountData) { ba.TotalAppLocalStates = uint64(len(ad.AppLocalStates)) ba.TotalBoxes = ad.TotalBoxes ba.TotalBoxBytes = ad.TotalBoxBytes + ba.IncentiveEligible = ad.IncentiveEligible ba.BaseVotingData.VoteID = ad.VoteID ba.BaseVotingData.SelectionID = ad.SelectionID @@ -342,6 +345,7 @@ func (ba *BaseAccountData) GetLedgerCoreAccountBaseData() ledgercore.AccountBase TotalAssets: ba.TotalAssets, TotalBoxes: ba.TotalBoxes, TotalBoxBytes: ba.TotalBoxBytes, + IncentiveEligible: ba.IncentiveEligible, } } @@ -365,6 +369,7 @@ func (ba *BaseAccountData) GetAccountData() basics.AccountData { RewardsBase: ba.RewardsBase, RewardedMicroAlgos: ba.RewardedMicroAlgos, AuthAddr: ba.AuthAddr, + IncentiveEligible: ba.IncentiveEligible, TotalAppSchema: basics.StateSchema{ NumUint: ba.TotalAppSchemaNumUint, NumByteSlice: ba.TotalAppSchemaNumByteSlice, @@ -389,6 +394,7 @@ func (ba *BaseAccountData) IsEmpty() bool { ba.RewardsBase == 0 && ba.RewardedMicroAlgos.Raw == 0 && ba.AuthAddr.IsZero() && + !ba.IncentiveEligible && ba.TotalAppSchemaNumUint == 0 && ba.TotalAppSchemaNumByteSlice == 0 && ba.TotalExtraAppPages == 0 && diff --git a/ledger/store/trackerdb/data_test.go b/ledger/store/trackerdb/data_test.go index e329a84e74..8c91b028de 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,"IncentiveEligible":false,"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..8b0092f4c1 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(22) + var zb0001Mask uint32 /* 24 bits */ if (*z).BaseVotingData.VoteID.MsgIsZero() { zb0001Len-- zb0001Mask |= 0x1 @@ -182,10 +182,14 @@ func (z *BaseAccountData) MarshalMsg(b []byte) (o []byte) { zb0001Len-- zb0001Mask |= 0x200000 } - if (*z).UpdateRound == 0 { + if (*z).IncentiveEligible == false { zb0001Len-- zb0001Mask |= 0x400000 } + if (*z).UpdateRound == 0 { + zb0001Len-- + zb0001Mask |= 0x800000 + } // variable map header, size zb0001Len o = msgp.AppendMapHeader(o, zb0001Len) if zb0001Len != 0 { @@ -290,6 +294,11 @@ 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 = msgp.AppendBool(o, (*z).IncentiveEligible) + } + if (zb0001Mask & 0x800000) == 0 { // if not empty // string "z" o = append(o, 0xa1, 0x7a) o = msgp.AppendUint64(o, (*z).UpdateRound) @@ -433,6 +442,14 @@ func (z *BaseAccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalSta return } } + if zb0001 > 0 { + zb0001-- + (*z).IncentiveEligible, bts, err = msgp.ReadBoolBytes(bts) + if err != nil { + err = msgp.WrapError(err, "struct-from-array", "IncentiveEligible") + return + } + } if zb0001 > 0 { zb0001-- bts, err = (*z).BaseVotingData.VoteID.UnmarshalMsgWithState(bts, st) @@ -596,6 +613,12 @@ func (z *BaseAccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalSta err = msgp.WrapError(err, "TotalBoxBytes") return } + case "o": + (*z).IncentiveEligible, bts, err = msgp.ReadBoolBytes(bts) + if err != nil { + err = msgp.WrapError(err, "IncentiveEligible") + return + } case "A": bts, err = (*z).BaseVotingData.VoteID.UnmarshalMsgWithState(bts, st) if err != nil { @@ -661,18 +684,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 + msgp.BoolSize + 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).IncentiveEligible == false) && ((*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 + msgp.BoolSize + 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 2d5f79c82a..99a5879301 100644 --- a/ledger/testing/randomAccounts.go +++ b/ledger/testing/randomAccounts.go @@ -78,6 +78,7 @@ func RandomAccountData(rewardsBase uint64) basics.AccountData { data.VoteFirstValid = 0 data.RewardsBase = rewardsBase + data.IncentiveEligible = crypto.RandUint64()%5 == 0 return data } @@ -99,6 +100,10 @@ func RandomAssetParams() basics.AssetParams { Decimals: uint32(crypto.RandUint64() % 20), DefaultFrozen: crypto.RandUint64()%2 == 0, } + // Since 0 and 1 Total assets seem extra interesting, make them more often. + if crypto.RandUint64()%5 != 0 { + ap.Total = crypto.RandUint64() % 2 + } if crypto.RandUint64()%5 != 0 { ap.UnitName = fmt.Sprintf("un%x", uint32(crypto.RandUint64()%0x7fffff)) } diff --git a/ledger/testing/randomAccounts_test.go b/ledger/testing/randomAccounts_test.go index 9f69321aaa..f59f704129 100644 --- a/ledger/testing/randomAccounts_test.go +++ b/ledger/testing/randomAccounts_test.go @@ -87,7 +87,6 @@ func TestAccounts(t *testing.T) { zeroValueExceptions := []reflectionhelpers.TypePath{ reflectionhelpers.TypePath{}.AddField("MicroAlgos").AddField("Raw"), reflectionhelpers.TypePath{}.AddField("AssetParams").AddMapKey(), - reflectionhelpers.TypePath{}.AddField("AssetParams").AddValue().AddField("Total"), reflectionhelpers.TypePath{}.AddField("Assets").AddMapKey(), reflectionhelpers.TypePath{}.AddField("AppLocalStates").AddMapKey(), reflectionhelpers.TypePath{}.AddField("AppLocalStates").AddValue().AddField("KeyValue").AddValue().AddField("Type"), From fe32dae82bffa37263f8c2946063f13dd5a5776f Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Thu, 30 Nov 2023 15:18:19 -0500 Subject: [PATCH 5/8] Maintain and use the acct.Incentiveligible flag --- daemon/algod/api/server/v2/account.go | 7 ++ daemon/algod/api/server/v2/account_test.go | 21 ++++++ data/basics/units.go | 18 +++++ data/basics/userBalance.go | 3 + data/txntest/txn.go | 3 + ledger/apply/keyreg.go | 12 ++- ledger/apptxn_test.go | 11 ++- ledger/eval/eval.go | 14 ++-- ledger/eval_simple_test.go | 88 +++++++++++++++++++++- ledger/testing/randomAccounts.go | 6 +- test/scripts/e2e_subs/eligible.py | 51 +++++++++++++ test/scripts/e2e_subs/goal/goal.py | 24 +++--- test/scripts/e2e_subs/mining.py | 3 +- 13 files changed, 232 insertions(+), 29 deletions(-) create mode 100755 test/scripts/e2e_subs/eligible.py diff --git a/daemon/algod/api/server/v2/account.go b/daemon/algod/api/server/v2/account.go index 0d659320bf..732d85133c 100644 --- a/daemon/algod/api/server/v2/account.go +++ b/daemon/algod/api/server/v2/account.go @@ -24,6 +24,7 @@ import ( "github.com/algorand/go-algorand/config" "github.com/algorand/go-algorand/crypto" + "github.com/algorand/go-algorand/crypto/merklesignature" "github.com/algorand/go-algorand/daemon/algod/api/server/v2/generated/model" "github.com/algorand/go-algorand/data/basics" "golang.org/x/exp/slices" @@ -200,12 +201,16 @@ func AccountToAccountData(a *model.Account) (basics.AccountData, error) { var voteFirstValid basics.Round var voteLastValid basics.Round var voteKeyDilution uint64 + var stateProofID merklesignature.Commitment if a.Participation != nil { copy(voteID[:], a.Participation.VoteParticipationKey) copy(selID[:], a.Participation.SelectionParticipationKey) voteFirstValid = basics.Round(a.Participation.VoteFirstValid) voteLastValid = basics.Round(a.Participation.VoteLastValid) voteKeyDilution = a.Participation.VoteKeyDilution + if a.Participation.StateProofKey != nil { + copy(stateProofID[:], *a.Participation.StateProofKey) + } } var rewardsBase uint64 @@ -351,11 +356,13 @@ func AccountToAccountData(a *model.Account) (basics.AccountData, error) { MicroAlgos: basics.MicroAlgos{Raw: a.Amount}, RewardsBase: rewardsBase, RewardedMicroAlgos: basics.MicroAlgos{Raw: a.Rewards}, + IncentiveEligible: nilToZero(a.IncentiveEligible), VoteID: voteID, SelectionID: selID, VoteFirstValid: voteFirstValid, VoteLastValid: voteLastValid, VoteKeyDilution: voteKeyDilution, + StateProofID: stateProofID, Assets: assets, AppLocalStates: appLocalStates, AppParams: appParams, diff --git a/daemon/algod/api/server/v2/account_test.go b/daemon/algod/api/server/v2/account_test.go index cd3c67499a..29d668f6e2 100644 --- a/daemon/algod/api/server/v2/account_test.go +++ b/daemon/algod/api/server/v2/account_test.go @@ -25,12 +25,15 @@ import ( "github.com/algorand/go-algorand/config" "github.com/algorand/go-algorand/daemon/algod/api/server/v2/generated/model" "github.com/algorand/go-algorand/data/basics" + ledgertesting "github.com/algorand/go-algorand/ledger/testing" "github.com/algorand/go-algorand/protocol" "github.com/algorand/go-algorand/test/partitiontest" ) func TestAccount(t *testing.T) { partitiontest.PartitionTest(t) + t.Parallel() + proto := config.Consensus[protocol.ConsensusFuture] appIdx1 := basics.AppIndex(1) appIdx2 := basics.AppIndex(2) @@ -203,3 +206,21 @@ func TestAccount(t *testing.T) { } }) } + +func TestAccountRandomRoundTrip(t *testing.T) { + partitiontest.PartitionTest(t) + t.Parallel() + + for _, simple := range []bool{true, false} { + accts := ledgertesting.RandomAccounts(20, simple) + for addr, acct := range accts { + round := basics.Round(2) + proto := config.Consensus[protocol.ConsensusFuture] + conv, err := AccountDataToAccount(addr.String(), &acct, round, &proto, acct.MicroAlgos) + require.NoError(t, err) + c, err := AccountToAccountData(&conv) + require.NoError(t, err) + require.Equal(t, acct, c) + } + } +} diff --git a/data/basics/units.go b/data/basics/units.go index af8743ee40..09bee7b8a8 100644 --- a/data/basics/units.go +++ b/data/basics/units.go @@ -17,6 +17,8 @@ package basics import ( + "math" + "github.com/algorand/go-codec/codec" "github.com/algorand/msgp/msgp" @@ -43,6 +45,11 @@ func (a MicroAlgos) GreaterThan(b MicroAlgos) bool { return a.Raw > b.Raw } +// GTE implements arithmetic comparison for MicroAlgos +func (a MicroAlgos) GTE(b MicroAlgos) bool { + return a.Raw >= b.Raw +} + // IsZero implements arithmetic comparison for MicroAlgos func (a MicroAlgos) IsZero() bool { return a.Raw == 0 @@ -122,6 +129,17 @@ func MicroAlgosMaxSize() (s int) { return msgp.Uint64Size } +// Algos is a convenience function so that whole Algos can be written easily. It +// panics on overflow because it should only be used constants - things that are +// best human-readable in source code - not used on arbitrary values from, say, +// transactions. +func Algos(algos uint64) MicroAlgos { + if algos > math.MaxUint64/1_000_000 { + panic(algos) + } + return MicroAlgos{Raw: algos * 1_000_000} +} + // Round represents a protocol round index type Round uint64 diff --git a/data/basics/userBalance.go b/data/basics/userBalance.go index cea8a9bc2c..48af4348e2 100644 --- a/data/basics/userBalance.go +++ b/data/basics/userBalance.go @@ -209,6 +209,9 @@ type AccountData struct { // This allows key rotation, changing the members in a multisig, etc. AuthAddr Address `codec:"spend"` + // IncentiveEligible indicates whether the account came online with the + // extra fee required to be eligible for block incentives. At proposal time, + // balance limits must also be met to receive incentives. IncentiveEligible bool `codec:"ie"` // AppLocalStates stores the local states associated with any applications diff --git a/data/txntest/txn.go b/data/txntest/txn.go index 515c9df458..26553d6b97 100644 --- a/data/txntest/txn.go +++ b/data/txntest/txn.go @@ -23,6 +23,7 @@ import ( "github.com/algorand/go-algorand/config" "github.com/algorand/go-algorand/crypto" + "github.com/algorand/go-algorand/crypto/merklesignature" "github.com/algorand/go-algorand/crypto/stateproof" "github.com/algorand/go-algorand/data/basics" "github.com/algorand/go-algorand/data/stateproofmsg" @@ -55,6 +56,7 @@ type Txn struct { VoteLast basics.Round VoteKeyDilution uint64 Nonparticipation bool + StateProofPK merklesignature.Commitment Receiver basics.Address Amount uint64 @@ -228,6 +230,7 @@ func (tx Txn) Txn() transactions.Transaction { VoteLast: tx.VoteLast, VoteKeyDilution: tx.VoteKeyDilution, Nonparticipation: tx.Nonparticipation, + StateProofPK: tx.StateProofPK, }, PaymentTxnFields: transactions.PaymentTxnFields{ Receiver: tx.Receiver, diff --git a/ledger/apply/keyreg.go b/ledger/apply/keyreg.go index 4fe0f0a326..6a83eab316 100644 --- a/ledger/apply/keyreg.go +++ b/ledger/apply/keyreg.go @@ -31,7 +31,7 @@ var errKeyregGoingOnlineFirstVotingInFuture = errors.New("transaction tries to m // Keyreg applies a KeyRegistration transaction using the Balances interface. func Keyreg(keyreg transactions.KeyregTxnFields, header transactions.Header, balances Balances, spec transactions.SpecialAddresses, ad *transactions.ApplyData, round basics.Round) error { if header.Sender == spec.FeeSink { - return fmt.Errorf("cannot register participation key for fee sink's address %v ", header.Sender) + return fmt.Errorf("cannot register participation key for fee sink's address %v", header.Sender) } // Get the user's balance entry @@ -67,6 +67,7 @@ func Keyreg(keyreg transactions.KeyregTxnFields, header transactions.Header, bal record.VoteFirstValid = 0 record.VoteLastValid = 0 record.VoteKeyDilution = 0 + record.IncentiveEligible = false } else { if params.EnableKeyregCoherencyCheck { if keyreg.VoteLast <= round { @@ -80,6 +81,9 @@ func Keyreg(keyreg transactions.KeyregTxnFields, header transactions.Header, bal record.VoteFirstValid = keyreg.VoteFirst record.VoteLastValid = keyreg.VoteLast record.VoteKeyDilution = keyreg.VoteKeyDilution + if header.Fee.GTE(incentiveFeeForEligibility) && params.EnableMining { + record.IncentiveEligible = true + } } // Write the updated entry @@ -90,3 +94,9 @@ func Keyreg(keyreg transactions.KeyregTxnFields, header transactions.Header, bal return nil } + +// incentiveFeeForEligibility imparts a small cost on moving from offline to +// online. This will impose a cost to running unreliable nodes that get +// suspended and then come back online. Becomes a consensus param if ever +// changed. +var incentiveFeeForEligibility = basics.Algos(2) diff --git a/ledger/apptxn_test.go b/ledger/apptxn_test.go index 8126322875..b21833b08c 100644 --- a/ledger/apptxn_test.go +++ b/ledger/apptxn_test.go @@ -26,6 +26,7 @@ import ( "github.com/algorand/go-algorand/config" "github.com/algorand/go-algorand/crypto" + "github.com/algorand/go-algorand/crypto/merklesignature" "github.com/algorand/go-algorand/data/basics" "github.com/algorand/go-algorand/data/transactions" "github.com/algorand/go-algorand/data/transactions/logic" @@ -60,11 +61,19 @@ func TestPayAction(t *testing.T) { // We're going to test some mining effects here too, so that we have an inner transaction example. proposer := basics.Address{0x01, 0x02, 0x03} - dl.txn(&txntest.Txn{ + dl.txns(&txntest.Txn{ Type: "pay", Sender: addrs[7], Receiver: proposer, Amount: 1_000_000 * 1_000_000, // 1 million algos is surely an eligible amount + }, &txntest.Txn{ + Type: "keyreg", + Sender: proposer, + Fee: 3_000_000, + VotePK: crypto.OneTimeSignatureVerifier{0x01}, + SelectionPK: crypto.VRFVerifier{0x02}, + StateProofPK: merklesignature.Commitment{0x03}, + VoteFirst: 1, VoteLast: 1000, }) payout1 := txntest.Txn{ diff --git a/ledger/eval/eval.go b/ledger/eval/eval.go index bdf351c953..fd4f65fa77 100644 --- a/ledger/eval/eval.go +++ b/ledger/eval/eval.go @@ -804,7 +804,7 @@ func StartEvaluator(l LedgerForEvaluator, hdr bookkeeping.BlockHeader, evalOpts return eval, nil } -const ( +var ( // these would become ConsensusParameters if we ever wanted to change them // incentiveMinBalance is the minimum balance an account must have to be @@ -817,7 +817,7 @@ const ( // that assurance, it is difficult to model their behaviour - might many // participants join for the hope of easy financial rewards, but without // caring enough to run a high-quality node? - incentiveMinBalance = 100_000 * 1_000_000 // 100K algos + incentiveMinBalance = basics.Algos(100_000) // incentiveMaxBalance is the maximum balance an account might have to be // eligible for incentives. It encourages large accounts to split their @@ -825,7 +825,7 @@ const ( // nothing in protocol can prevent such accounts from running nodes that // share fate (same machine, same data center, etc), but this serves as a // gentle reminder. - incentiveMaxBalance = 100_000_000 * 1_000_000 // 100M algos + incentiveMaxBalance = basics.Algos(100_000_000) ) func (eval *BlockEvaluator) eligibleForIncentives(proposer basics.Address) bool { @@ -833,15 +833,13 @@ func (eval *BlockEvaluator) eligibleForIncentives(proposer basics.Address) bool if err != nil { return false } - if proposerState.MicroAlgos.Raw < incentiveMinBalance { + if proposerState.MicroAlgos.LessThan(incentiveMinBalance) { return false } - if proposerState.MicroAlgos.Raw > incentiveMaxBalance { + if proposerState.MicroAlgos.GreaterThan(incentiveMaxBalance) { return false } - // We'll also need a flag on the account, set to true if the account - // properly key-regged for incentives by including the "entry fee". - return true + return proposerState.IncentiveEligible } // hotfix for testnet stall 08/26/2019; move some algos from testnet bank to rewards pool to give it enough time until protocol upgrade occur. diff --git a/ledger/eval_simple_test.go b/ledger/eval_simple_test.go index 9f9e15912f..01bc751f65 100644 --- a/ledger/eval_simple_test.go +++ b/ledger/eval_simple_test.go @@ -29,6 +29,7 @@ import ( "github.com/algorand/go-algorand/agreement" "github.com/algorand/go-algorand/config" "github.com/algorand/go-algorand/crypto" + "github.com/algorand/go-algorand/crypto/merklesignature" "github.com/algorand/go-algorand/data/basics" "github.com/algorand/go-algorand/data/bookkeeping" "github.com/algorand/go-algorand/data/transactions" @@ -229,14 +230,31 @@ func TestMiningFees(t *testing.T) { smallest := basics.Address{0x01, 0x033} biggest := basics.Address{0x01, 0x044} - dl.txns(&txntest.Txn{Type: "pay", Sender: addrs[1], Receiver: tooBig, Amount: 100_000_000*1_000_000 + 1}, - &txntest.Txn{Type: "pay", Sender: addrs[1], Receiver: tooSmall, Amount: 100_000*1_000_000 - 1}, - &txntest.Txn{Type: "pay", Sender: addrs[1], Receiver: smallest, Amount: 100_000 * 1_000_000}, - &txntest.Txn{Type: "pay", Sender: addrs[1], Receiver: biggest, Amount: 100_000_000 * 1_000_000}, + const eFee = 3_000_000 + dl.txns( + &txntest.Txn{Type: "pay", Sender: addrs[1], + Receiver: tooBig, Amount: eFee + 100_000_000*1_000_000 + 1}, + &txntest.Txn{Type: "pay", Sender: addrs[1], + Receiver: tooSmall, Amount: eFee + 100_000*1_000_000 - 1}, + &txntest.Txn{Type: "pay", Sender: addrs[1], + Receiver: smallest, Amount: eFee + 100_000*1_000_000}, + &txntest.Txn{Type: "pay", Sender: addrs[1], + Receiver: biggest, Amount: eFee + 100_000_000*1_000_000}, ) for _, proposer := range []basics.Address{tooBig, tooSmall, smallest, biggest} { t.Log(proposer) + + dl.txn(&txntest.Txn{ + Type: "keyreg", + Sender: proposer, + Fee: eFee, + VotePK: crypto.OneTimeSignatureVerifier{0x01}, + SelectionPK: crypto.VRFVerifier{0x02}, + StateProofPK: merklesignature.Commitment{0x03}, + VoteFirst: 1, VoteLast: 1000, + }) + dl.fullBlock() // start with an empty block, so no mining fees are paid at start of next one presink := micros(dl.t, dl.generator, genBalances.FeeSink) @@ -293,6 +311,68 @@ func TestMiningFees(t *testing.T) { }) } +// TestIncentiveEligible checks that keyreg with extra fee turns on the incentive eligible flag +func TestIncentiveEligible(t *testing.T) { + partitiontest.PartitionTest(t) + t.Parallel() + + genBalances, addrs, _ := ledgertesting.NewTestGenesis() + // Incentive-eligible appears 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() + + tooSmall := basics.Address{0x01, 0x011} + smallest := basics.Address{0x01, 0x022} + + // They begin ineligible + for _, addr := range []basics.Address{tooSmall, smallest} { + acct, _, _, err := dl.generator.LookupLatest(addr) + require.NoError(t, err) + require.False(t, acct.IncentiveEligible) + } + + // Fund everyone + dl.txns(&txntest.Txn{Type: "pay", Sender: addrs[1], Receiver: tooSmall, Amount: 10_000_000}, + &txntest.Txn{Type: "pay", Sender: addrs[1], Receiver: smallest, Amount: 10_000_000}, + ) + + // Keyreg (but offline) with various fees. No effect on incentive eligible + dl.txns(&txntest.Txn{Type: "keyreg", Sender: tooSmall, Fee: 2_000_000 - 1}, + &txntest.Txn{Type: "keyreg", Sender: smallest, Fee: 2_000_000}, + ) + + for _, addr := range []basics.Address{tooSmall, smallest} { + acct, _, _, err := dl.generator.LookupLatest(addr) + require.NoError(t, err) + require.False(t, acct.IncentiveEligible) + } + + // Keyreg to get online with various fees. Sufficient fee gets `smallest` eligible + keyreg := txntest.Txn{ + Type: "keyreg", + VotePK: crypto.OneTimeSignatureVerifier{0x01}, + SelectionPK: crypto.VRFVerifier{0x02}, + StateProofPK: merklesignature.Commitment{0x03}, + VoteFirst: 1, VoteLast: 1000, + } + tooSmallKR := keyreg + tooSmallKR.Sender = tooSmall + tooSmallKR.Fee = 2_000_000 - 1 + + smallKR := keyreg + smallKR.Sender = smallest + smallKR.Fee = 2_000_000 + dl.txns(&tooSmallKR, &smallKR) + a, _, _, err := dl.generator.LookupLatest(tooSmall) + require.NoError(t, err) + require.False(t, a.IncentiveEligible) + a, _, _, err = dl.generator.LookupLatest(smallest) + require.NoError(t, err) + require.Equal(t, a.IncentiveEligible, ver > 38) + }) +} + // 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/testing/randomAccounts.go b/ledger/testing/randomAccounts.go index 99a5879301..bd079605a3 100644 --- a/ledger/testing/randomAccounts.go +++ b/ledger/testing/randomAccounts.go @@ -68,17 +68,17 @@ func RandomAccountData(rewardsBase uint64) basics.AccountData { switch crypto.RandUint64() % 3 { case 0: data.Status = basics.Online + data.VoteID = crypto.OneTimeSignatureVerifier{0x01} + data.IncentiveEligible = crypto.RandUint64()%5 == 0 + data.VoteFirstValid = 1 data.VoteLastValid = 10000 case 1: data.Status = basics.Offline - data.VoteLastValid = 0 default: data.Status = basics.NotParticipating } - data.VoteFirstValid = 0 data.RewardsBase = rewardsBase - data.IncentiveEligible = crypto.RandUint64()%5 == 0 return data } diff --git a/test/scripts/e2e_subs/eligible.py b/test/scripts/e2e_subs/eligible.py new file mode 100755 index 0000000000..ddac9a3515 --- /dev/null +++ b/test/scripts/e2e_subs/eligible.py @@ -0,0 +1,51 @@ +#!/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=10_000_000) +assert not err, err + +# Joe is a brand new account, it is not incentive eligible +joe_info = goal.algod.account_info(joe) +assert "incentive-eligible" not in joe_info, joe_info + +# Go online, but without paying enough to be incentive eligible +txinfo, err = goal.keyreg(joe, votekey=base64.b64encode(b'1'*32), + selkey=base64.b64encode(b'1'*32), + sprfkey=base64.b64encode(b'1'*64), + votekd=1, + votefst=1, votelst=2000) +assert not err, err + +# No extra fee paid, so not eligible +joe_info = goal.algod.account_info(joe) +assert "incentive-eligible" not in joe_info, joe_info + +# Pay the extra fee to become eligible +txinfo, err = goal.keyreg(joe, fee=3_000_000, + votekey=base64.b64encode(b'1'*32), + selkey=base64.b64encode(b'1'*32), + sprfkey=base64.b64encode(b'1'*64), + votekd=2, + votefst=1, votelst=2000) +assert not err, err +joe_info = goal.algod.account_info(joe) +assert joe_info.get("incentive-eligible", None) == True, joe_info + + + +stamp = datetime.now().strftime("%Y%m%d_%H%M%S") +print(f"{os.path.basename(sys.argv[0])} OK {stamp}") diff --git a/test/scripts/e2e_subs/goal/goal.py b/test/scripts/e2e_subs/goal/goal.py index a366f1b69e..2a1bb4cd10 100755 --- a/test/scripts/e2e_subs/goal/goal.py +++ b/test/scripts/e2e_subs/goal/goal.py @@ -227,21 +227,21 @@ def finish(self, tx, send): return tx def keyreg(self, sender, votekey=None, selkey=None, votefst=None, - votelst=None, votekd=None, + votelst=None, votekd=None, sprfkey=None, send=None, **kwargs): - params = self.params(kwargs.pop("lifetime", 1000)) + params = self.params(kwargs.pop("lifetime", 1000), kwargs.pop("fee", None)) tx = txn.KeyregTxn(sender, params, - votekey, selkey, votefst, votelst, votekd, + votekey, selkey, votefst, votelst, votekd, sprfkey=sprfkey, **kwargs) return self.finish(tx, send) def pay(self, sender, receiver, amt: int, send=None, **kwargs): - params = self.params(kwargs.pop("lifetime", 1000)) + params = self.params(kwargs.pop("lifetime", 1000), kwargs.pop("fee", None)) tx = txn.PaymentTxn(sender, params, receiver, amt, **kwargs) return self.finish(tx, send) def acfg(self, sender, send=None, **kwargs): - params = self.params(kwargs.pop("lifetime", 1000)) + params = self.params(kwargs.pop("lifetime", 1000), kwargs.pop("fee", None)) 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.params(kwargs.pop("lifetime", 1000)) + params = self.params(kwargs.pop("lifetime", 1000), kwargs.pop("fee", None)) 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.params(kwargs.pop("lifetime", 1000)) + params = self.params(kwargs.pop("lifetime", 1000), kwargs.pop("fee", None)) tx = txn.AssetFreezeTxn(sender, params, index, target, frozen, **kwargs) return self.finish(tx, send) @@ -275,14 +275,18 @@ def coerce_schema(self, values): return txn.StateSchema(num_uints=values[0], num_byte_slices=values[1]) - def params(self, lifetime): + def params(self, lifetime=None, fee=None): params = self.algod.suggested_params() - params.last = params.first + lifetime + if lifetime is not None: + params.last = params.first + lifetime + if fee is not None: + params.flat_fee = True + params.fee = fee return params def appl(self, sender, index: int, on_complete=txn.OnComplete.NoOpOC, send=None, **kwargs): - params = self.params(kwargs.pop("lifetime", 1000)) + params = self.params(kwargs.pop("lifetime", 1000), kwargs.pop("fee", None)) 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 index 04f10e4b7f..3777645073 100755 --- a/test/scripts/e2e_subs/mining.py +++ b/test/scripts/e2e_subs/mining.py @@ -39,7 +39,7 @@ # During construction, the app examines an arbitrary round, a little before the latest. -examined = max(goal.params(1).first-5, 1) +examined = max(goal.params().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'] @@ -82,4 +82,3 @@ stamp = datetime.now().strftime("%Y%m%d_%H%M%S") print(f"{os.path.basename(sys.argv[0])} OK {stamp}") - From fd735c583ff04a56ece998539799d4c7e386a994 Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Thu, 21 Dec 2023 11:32:19 -0500 Subject: [PATCH 6/8] Test assembly of new block fields --- data/transactions/logic/assembler_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/data/transactions/logic/assembler_test.go b/data/transactions/logic/assembler_test.go index 3f609fd7ee..0d2ae828ce 100644 --- a/data/transactions/logic/assembler_test.go +++ b/data/transactions/logic/assembler_test.go @@ -1707,6 +1707,10 @@ block BlkSeed global AssetCreateMinBalance global AssetOptInMinBalance global GenesisHash +pushint 1 +block BlkProposer +pushint 1 +block BlkFeesCollected `, AssemblerMaxVersion) for _, names := range [][]string{GlobalFieldNames[:], TxnFieldNames[:], blockFieldNames[:]} { for _, f := range names { From de07ba95ed43215b3291cf74fed1475397be1f81 Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Tue, 9 Jan 2024 14:11:33 -0500 Subject: [PATCH 7/8] year --- data/basics/fraction.go | 2 +- data/basics/fraction_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/basics/fraction.go b/data/basics/fraction.go index 271da85265..8a643f2520 100644 --- a/data/basics/fraction.go +++ b/data/basics/fraction.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023 Algorand, Inc. +// Copyright (C) 2019-2024 Algorand, Inc. // This file is part of go-algorand // // go-algorand is free software: you can redistribute it and/or modify diff --git a/data/basics/fraction_test.go b/data/basics/fraction_test.go index 9fad8dfa19..bc6a639c29 100644 --- a/data/basics/fraction_test.go +++ b/data/basics/fraction_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023 Algorand, Inc. +// Copyright (C) 2019-2024 Algorand, Inc. // This file is part of go-algorand // // go-algorand is free software: you can redistribute it and/or modify From 55917b80e6a0709f42ec9d50bdb62a03ba705abc Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Tue, 9 Jan 2024 14:30:46 -0500 Subject: [PATCH 8/8] it's v11 now --- ledger/apptxn_test.go | 4 ++-- ledger/eval_simple_test.go | 17 ++++++++--------- test/scripts/e2e_subs/mining.py | 2 +- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/ledger/apptxn_test.go b/ledger/apptxn_test.go index b21833b08c..0e193e3eb2 100644 --- a/ledger/apptxn_test.go +++ b/ledger/apptxn_test.go @@ -89,7 +89,7 @@ func TestPayAction(t *testing.T) { dl.txns(&payout1) vb := dl.endBlock(proposer) // First MiningPct > 0 - if ver >= 39 { + if ver >= 40 { require.True(t, dl.generator.GenesisProto().EnableMining) require.EqualValues(t, proposer, vb.Block().BlockHeader.Proposer) require.EqualValues(t, 2000, vb.Block().BlockHeader.FeesCollected.Raw) @@ -110,7 +110,7 @@ func TestPayAction(t *testing.T) { postsink = micros(dl.t, dl.generator, genBalances.FeeSink) postprop = micros(dl.t, dl.generator, proposer) // First MiningPct > 0 - if ver >= 39 { + if ver >= 40 { require.EqualValues(t, 500, postsink-presink) // based on 75% in config/consensus.go require.EqualValues(t, 1500, postprop-preprop) } else { diff --git a/ledger/eval_simple_test.go b/ledger/eval_simple_test.go index 01bc751f65..ee9a097b06 100644 --- a/ledger/eval_simple_test.go +++ b/ledger/eval_simple_test.go @@ -212,16 +212,15 @@ 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. +// TestMiningFees ensures that the proper portion of tx fees go to the proposer func TestMiningFees(t *testing.T) { partitiontest.PartitionTest(t) t.Parallel() // Lots of balance checks that would be messed up by rewards genBalances, addrs, _ := ledgertesting.NewTestGenesis(ledgertesting.TurnOffRewards) - // 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) { + miningBegins := 40 + ledgertesting.TestConsensusRange(t, miningBegins-1, 0, func(t *testing.T, ver int, cv protocol.ConsensusVersion, cfg config.Local) { dl := NewDoubleLedger(t, genBalances, cv, cfg) defer dl.Close() @@ -271,7 +270,7 @@ func TestMiningFees(t *testing.T) { dl.txns(&pay, pay.Args("again")) vb := dl.endBlock(proposer) - if ver >= 39 { + if ver >= miningBegins { require.True(t, dl.generator.GenesisProto().EnableMining) // version sanity check require.NotZero(t, dl.generator.GenesisProto().MiningPercent) // version sanity check // new fields are in the header @@ -299,7 +298,7 @@ func TestMiningFees(t *testing.T) { postsink = micros(dl.t, dl.generator, genBalances.FeeSink) postprop = micros(dl.t, dl.generator, proposer) - if ver >= 39 && (proposer == smallest || proposer == biggest) { + if ver >= miningBegins && (proposer == smallest || proposer == biggest) { require.EqualValues(t, 500, postsink-presink) // based on 75% in config/consensus.go require.EqualValues(t, 1500, postprop-preprop) } else { @@ -317,8 +316,8 @@ func TestIncentiveEligible(t *testing.T) { t.Parallel() genBalances, addrs, _ := ledgertesting.NewTestGenesis() - // Incentive-eligible appears 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) { + miningBegins := 40 + ledgertesting.TestConsensusRange(t, miningBegins-1, 0, func(t *testing.T, ver int, cv protocol.ConsensusVersion, cfg config.Local) { dl := NewDoubleLedger(t, genBalances, cv, cfg) defer dl.Close() @@ -369,7 +368,7 @@ func TestIncentiveEligible(t *testing.T) { require.False(t, a.IncentiveEligible) a, _, _, err = dl.generator.LookupLatest(smallest) require.NoError(t, err) - require.Equal(t, a.IncentiveEligible, ver > 38) + require.Equal(t, a.IncentiveEligible, ver >= miningBegins) }) } diff --git a/test/scripts/e2e_subs/mining.py b/test/scripts/e2e_subs/mining.py index 3777645073..216ecc93ef 100755 --- a/test/scripts/e2e_subs/mining.py +++ b/test/scripts/e2e_subs/mining.py @@ -23,7 +23,7 @@ assert not err, err get_proposer = """ -#pragma version 10 +#pragma version 11 txn ApplicationArgs 0; btoi block BlkProposer; global ZeroAddress; !=; assert