diff --git a/agreement/abstractions.go b/agreement/abstractions.go
index 44aafa4fd8..25c920e02e 100644
--- a/agreement/abstractions.go
+++ b/agreement/abstractions.go
@@ -59,7 +59,7 @@ type ValidatedBlock interface {
//
// Calls to Seed() or to Digest() on the copy's Block must
// reflect the value of the new seed.
- WithSeed(committee.Seed) ValidatedBlock
+ WithSeed(committee.Seed, basics.Address) ValidatedBlock
// Block returns the underlying block that has been validated.
Block() bookkeeping.Block
diff --git a/agreement/agreementtest/simulate_test.go b/agreement/agreementtest/simulate_test.go
index 53c42411ed..335a781ef0 100644
--- a/agreement/agreementtest/simulate_test.go
+++ b/agreement/agreementtest/simulate_test.go
@@ -79,8 +79,9 @@ func (b testValidatedBlock) Block() bookkeeping.Block {
return b.Inside
}
-func (b testValidatedBlock) WithSeed(s committee.Seed) agreement.ValidatedBlock {
+func (b testValidatedBlock) WithSeed(s committee.Seed, proposer basics.Address) agreement.ValidatedBlock {
b.Inside.BlockHeader.Seed = s
+ b.Inside.BlockHeader.Proposer = proposer
return b
}
diff --git a/agreement/common_test.go b/agreement/common_test.go
index 0c11d9553d..1b4f8d17ba 100644
--- a/agreement/common_test.go
+++ b/agreement/common_test.go
@@ -165,8 +165,9 @@ func (b testValidatedBlock) Block() bookkeeping.Block {
return b.Inside
}
-func (b testValidatedBlock) WithSeed(s committee.Seed) ValidatedBlock {
+func (b testValidatedBlock) WithSeed(s committee.Seed, proposer basics.Address) ValidatedBlock {
b.Inside.BlockHeader.Seed = s
+ b.Inside.BlockHeader.Proposer = proposer
return b
}
diff --git a/agreement/fuzzer/ledger_test.go b/agreement/fuzzer/ledger_test.go
index a62caee4d9..e1f90d5d2a 100644
--- a/agreement/fuzzer/ledger_test.go
+++ b/agreement/fuzzer/ledger_test.go
@@ -93,8 +93,9 @@ func (b testValidatedBlock) Block() bookkeeping.Block {
return b.Inside
}
-func (b testValidatedBlock) WithSeed(s committee.Seed) agreement.ValidatedBlock {
+func (b testValidatedBlock) WithSeed(s committee.Seed, proposer basics.Address) agreement.ValidatedBlock {
b.Inside.BlockHeader.Seed = s
+ b.Inside.BlockHeader.Proposer = proposer
return b
}
diff --git a/agreement/msgp_gen.go b/agreement/msgp_gen.go
index 16679ce797..2906e73048 100644
--- a/agreement/msgp_gen.go
+++ b/agreement/msgp_gen.go
@@ -4493,183 +4493,212 @@ func PlayerMaxSize() (s int) {
func (z *proposal) MarshalMsg(b []byte) (o []byte) {
o = msgp.Require(b, z.Msgsize())
// omitempty: check for empty values
- zb0004Len := uint32(29)
- var zb0004Mask uint64 /* 38 bits */
+ zb0005Len := uint32(32)
+ var zb0005Mask uint64 /* 41 bits */
if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0 {
- zb0004Len--
- zb0004Mask |= 0x40
+ zb0005Len--
+ zb0005Mask |= 0x40
+ }
+ if (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MsgIsZero() {
+ zb0005Len--
+ zb0005Mask |= 0x80
}
if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x80
+ zb0005Len--
+ zb0005Mask |= 0x100
}
if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0 {
- zb0004Len--
- zb0004Mask |= 0x100
+ zb0005Len--
+ zb0005Mask |= 0x200
}
if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "" {
- zb0004Len--
- zb0004Mask |= 0x200
+ zb0005Len--
+ zb0005Mask |= 0x400
}
if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x400
+ zb0005Len--
+ zb0005Mask |= 0x800
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x800
+ zb0005Len--
+ zb0005Mask |= 0x1000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x1000
+ zb0005Len--
+ zb0005Mask |= 0x2000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x2000
+ zb0005Len--
+ zb0005Mask |= 0x4000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0 {
- zb0004Len--
- zb0004Mask |= 0x4000
+ zb0005Len--
+ zb0005Mask |= 0x8000
}
if (*z).unauthenticatedProposal.OriginalPeriod == 0 {
- zb0004Len--
- zb0004Mask |= 0x8000
+ zb0005Len--
+ zb0005Mask |= 0x10000
}
if (*z).unauthenticatedProposal.OriginalProposer.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x10000
+ zb0005Len--
+ zb0005Mask |= 0x20000
+ }
+ if len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) == 0 {
+ zb0005Len--
+ zb0005Mask |= 0x40000
}
if len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 {
- zb0004Len--
- zb0004Mask |= 0x20000
+ zb0005Len--
+ zb0005Mask |= 0x80000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x40000
+ zb0005Len--
+ zb0005Mask |= 0x100000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x80000
+ zb0005Len--
+ zb0005Mask |= 0x200000
+ }
+ if (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MsgIsZero() {
+ zb0005Len--
+ zb0005Mask |= 0x400000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0 {
- zb0004Len--
- zb0004Mask |= 0x100000
+ zb0005Len--
+ zb0005Mask |= 0x800000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x400000
+ zb0005Len--
+ zb0005Mask |= 0x2000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x800000
+ zb0005Len--
+ zb0005Mask |= 0x4000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x1000000
+ zb0005Len--
+ zb0005Mask |= 0x8000000
}
if (*z).unauthenticatedProposal.SeedProof.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x2000000
+ zb0005Len--
+ zb0005Mask |= 0x10000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x4000000
+ zb0005Len--
+ zb0005Mask |= 0x20000000
}
if len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0 {
- zb0004Len--
- zb0004Mask |= 0x8000000
+ zb0005Len--
+ zb0005Mask |= 0x40000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0 {
- zb0004Len--
- zb0004Mask |= 0x10000000
+ zb0005Len--
+ zb0005Mask |= 0x80000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0 {
- zb0004Len--
- zb0004Mask |= 0x20000000
+ zb0005Len--
+ zb0005Mask |= 0x100000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x40000000
+ zb0005Len--
+ zb0005Mask |= 0x200000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x80000000
+ zb0005Len--
+ zb0005Mask |= 0x400000000
}
if (*z).unauthenticatedProposal.Block.Payset.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x100000000
+ zb0005Len--
+ zb0005Mask |= 0x800000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x200000000
+ zb0005Len--
+ zb0005Mask |= 0x1000000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x400000000
+ zb0005Len--
+ zb0005Mask |= 0x2000000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false {
- zb0004Len--
- zb0004Mask |= 0x800000000
+ zb0005Len--
+ zb0005Mask |= 0x4000000000
}
- // variable map header, size zb0004Len
- o = msgp.AppendMapHeader(o, zb0004Len)
- if zb0004Len != 0 {
- if (zb0004Mask & 0x40) == 0 { // if not empty
+ // variable map header, size zb0005Len
+ o = msgp.AppendMapHeader(o, zb0005Len)
+ if zb0005Len != 0 {
+ if (zb0005Mask & 0x40) == 0 { // if not empty
// string "earn"
o = append(o, 0xa4, 0x65, 0x61, 0x72, 0x6e)
o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel)
}
- if (zb0004Mask & 0x80) == 0 { // if not empty
+ if (zb0005Mask & 0x80) == 0 { // if not empty
+ // string "fc"
+ o = append(o, 0xa2, 0x66, 0x63)
+ o = (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MarshalMsg(o)
+ }
+ if (zb0005Mask & 0x100) == 0 { // if not empty
// string "fees"
o = append(o, 0xa4, 0x66, 0x65, 0x65, 0x73)
o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MarshalMsg(o)
}
- if (zb0004Mask & 0x100) == 0 { // if not empty
+ if (zb0005Mask & 0x200) == 0 { // if not empty
// string "frac"
o = append(o, 0xa4, 0x66, 0x72, 0x61, 0x63)
o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue)
}
- if (zb0004Mask & 0x200) == 0 { // if not empty
+ if (zb0005Mask & 0x400) == 0 { // if not empty
// string "gen"
o = append(o, 0xa3, 0x67, 0x65, 0x6e)
o = msgp.AppendString(o, (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID)
}
- if (zb0004Mask & 0x400) == 0 { // if not empty
+ if (zb0005Mask & 0x800) == 0 { // if not empty
// string "gh"
o = append(o, 0xa2, 0x67, 0x68)
o = (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MarshalMsg(o)
}
- if (zb0004Mask & 0x800) == 0 { // if not empty
+ if (zb0005Mask & 0x1000) == 0 { // if not empty
// string "nextbefore"
o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MarshalMsg(o)
}
- if (zb0004Mask & 0x1000) == 0 { // if not empty
+ if (zb0005Mask & 0x2000) == 0 { // if not empty
// string "nextproto"
o = append(o, 0xa9, 0x6e, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MarshalMsg(o)
}
- if (zb0004Mask & 0x2000) == 0 { // if not empty
+ if (zb0005Mask & 0x4000) == 0 { // if not empty
// string "nextswitch"
o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MarshalMsg(o)
}
- if (zb0004Mask & 0x4000) == 0 { // if not empty
+ if (zb0005Mask & 0x8000) == 0 { // if not empty
// string "nextyes"
o = append(o, 0xa7, 0x6e, 0x65, 0x78, 0x74, 0x79, 0x65, 0x73)
o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals)
}
- if (zb0004Mask & 0x8000) == 0 { // if not empty
+ if (zb0005Mask & 0x10000) == 0 { // if not empty
// string "oper"
o = append(o, 0xa4, 0x6f, 0x70, 0x65, 0x72)
o = msgp.AppendUint64(o, uint64((*z).unauthenticatedProposal.OriginalPeriod))
}
- if (zb0004Mask & 0x10000) == 0 { // if not empty
+ if (zb0005Mask & 0x20000) == 0 { // if not empty
// string "oprop"
o = append(o, 0xa5, 0x6f, 0x70, 0x72, 0x6f, 0x70)
o = (*z).unauthenticatedProposal.OriginalProposer.MarshalMsg(o)
}
- if (zb0004Mask & 0x20000) == 0 { // if not empty
+ if (zb0005Mask & 0x40000) == 0 { // if not empty
+ // string "partupdabs"
+ o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x61, 0x62, 0x73)
+ if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts == nil {
+ o = msgp.AppendNil(o)
+ } else {
+ o = msgp.AppendArrayHeader(o, uint32(len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts)))
+ }
+ for zb0004 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts {
+ o = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].MarshalMsg(o)
+ }
+ }
+ if (zb0005Mask & 0x80000) == 0 { // if not empty
// string "partupdrmv"
o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76)
if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts == nil {
@@ -4681,47 +4710,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 (zb0005Mask & 0x100000) == 0 { // if not empty
// string "prev"
o = append(o, 0xa4, 0x70, 0x72, 0x65, 0x76)
o = (*z).unauthenticatedProposal.Block.BlockHeader.Branch.MarshalMsg(o)
}
- if (zb0004Mask & 0x80000) == 0 { // if not empty
+ if (zb0005Mask & 0x200000) == 0 { // if not empty
// string "proto"
o = append(o, 0xa5, 0x70, 0x72, 0x6f, 0x74, 0x6f)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MarshalMsg(o)
}
- if (zb0004Mask & 0x100000) == 0 { // if not empty
+ if (zb0005Mask & 0x400000) == 0 { // if not empty
+ // string "prp"
+ o = append(o, 0xa3, 0x70, 0x72, 0x70)
+ o = (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MarshalMsg(o)
+ }
+ if (zb0005Mask & 0x800000) == 0 { // if not empty
// string "rate"
o = append(o, 0xa4, 0x72, 0x61, 0x74, 0x65)
o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate)
}
- if (zb0004Mask & 0x400000) == 0 { // if not empty
+ if (zb0005Mask & 0x2000000) == 0 { // if not empty
// string "rnd"
o = append(o, 0xa3, 0x72, 0x6e, 0x64)
o = (*z).unauthenticatedProposal.Block.BlockHeader.Round.MarshalMsg(o)
}
- if (zb0004Mask & 0x800000) == 0 { // if not empty
+ if (zb0005Mask & 0x4000000) == 0 { // if not empty
// string "rwcalr"
o = append(o, 0xa6, 0x72, 0x77, 0x63, 0x61, 0x6c, 0x72)
o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MarshalMsg(o)
}
- if (zb0004Mask & 0x1000000) == 0 { // if not empty
+ if (zb0005Mask & 0x8000000) == 0 { // if not empty
// string "rwd"
o = append(o, 0xa3, 0x72, 0x77, 0x64)
o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MarshalMsg(o)
}
- if (zb0004Mask & 0x2000000) == 0 { // if not empty
+ if (zb0005Mask & 0x10000000) == 0 { // if not empty
// string "sdpf"
o = append(o, 0xa4, 0x73, 0x64, 0x70, 0x66)
o = (*z).unauthenticatedProposal.SeedProof.MarshalMsg(o)
}
- if (zb0004Mask & 0x4000000) == 0 { // if not empty
+ if (zb0005Mask & 0x20000000) == 0 { // if not empty
// string "seed"
o = append(o, 0xa4, 0x73, 0x65, 0x65, 0x64)
o = (*z).unauthenticatedProposal.Block.BlockHeader.Seed.MarshalMsg(o)
}
- if (zb0004Mask & 0x8000000) == 0 { // if not empty
+ if (zb0005Mask & 0x40000000) == 0 { // if not empty
// string "spt"
o = append(o, 0xa3, 0x73, 0x70, 0x74)
if (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking == nil {
@@ -4741,42 +4775,42 @@ func (z *proposal) MarshalMsg(b []byte) (o []byte) {
o = zb0002.MarshalMsg(o)
}
}
- if (zb0004Mask & 0x10000000) == 0 { // if not empty
+ if (zb0005Mask & 0x80000000) == 0 { // if not empty
// string "tc"
o = append(o, 0xa2, 0x74, 0x63)
o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter)
}
- if (zb0004Mask & 0x20000000) == 0 { // if not empty
+ if (zb0005Mask & 0x100000000) == 0 { // if not empty
// string "ts"
o = append(o, 0xa2, 0x74, 0x73)
o = msgp.AppendInt64(o, (*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp)
}
- if (zb0004Mask & 0x40000000) == 0 { // if not empty
+ if (zb0005Mask & 0x200000000) == 0 { // if not empty
// string "txn"
o = append(o, 0xa3, 0x74, 0x78, 0x6e)
o = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MarshalMsg(o)
}
- if (zb0004Mask & 0x80000000) == 0 { // if not empty
+ if (zb0005Mask & 0x400000000) == 0 { // if not empty
// string "txn256"
o = append(o, 0xa6, 0x74, 0x78, 0x6e, 0x32, 0x35, 0x36)
o = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MarshalMsg(o)
}
- if (zb0004Mask & 0x100000000) == 0 { // if not empty
+ if (zb0005Mask & 0x800000000) == 0 { // if not empty
// string "txns"
o = append(o, 0xa4, 0x74, 0x78, 0x6e, 0x73)
o = (*z).unauthenticatedProposal.Block.Payset.MarshalMsg(o)
}
- if (zb0004Mask & 0x200000000) == 0 { // if not empty
+ if (zb0005Mask & 0x1000000000) == 0 { // if not empty
// string "upgradedelay"
o = append(o, 0xac, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x65, 0x6c, 0x61, 0x79)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MarshalMsg(o)
}
- if (zb0004Mask & 0x400000000) == 0 { // if not empty
+ if (zb0005Mask & 0x2000000000) == 0 { // if not empty
// string "upgradeprop"
o = append(o, 0xab, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x70, 0x72, 0x6f, 0x70)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MarshalMsg(o)
}
- if (zb0004Mask & 0x800000000) == 0 { // if not empty
+ if (zb0005Mask & 0x4000000000) == 0 { // if not empty
// string "upgradeyes"
o = append(o, 0xaa, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x65, 0x73)
o = msgp.AppendBool(o, (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove)
@@ -4799,73 +4833,73 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o
st.AllowableDepth--
var field []byte
_ = field
- var zb0004 int
- var zb0005 bool
- zb0004, zb0005, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0005 int
+ var zb0006 bool
+ zb0005, zb0006, bts, err = msgp.ReadMapHeaderBytes(bts)
if _, ok := err.(msgp.TypeError); ok {
- zb0004, zb0005, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ zb0005, zb0006, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err)
return
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Round.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Round")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Branch.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Branch")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Seed.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Seed")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NativeSha512_256Commitment")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Sha256Commitment")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp, bts, err = msgp.ReadInt64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "TimeStamp")
return
}
}
- if zb0004 > 0 {
- zb0004--
- var zb0006 int
- zb0006, err = msgp.ReadBytesBytesHeader(bts)
+ if zb0005 > 0 {
+ zb0005--
+ var zb0007 int
+ zb0007, err = msgp.ReadBytesBytesHeader(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "GenesisID")
return
}
- if zb0006 > config.MaxGenesisIDLen {
- err = msgp.ErrOverflow(uint64(zb0006), uint64(config.MaxGenesisIDLen))
+ if zb0007 > config.MaxGenesisIDLen {
+ err = msgp.ErrOverflow(uint64(zb0007), uint64(config.MaxGenesisIDLen))
return
}
(*z).unauthenticatedProposal.Block.BlockHeader.GenesisID, bts, err = msgp.ReadStringBytes(bts)
@@ -4874,157 +4908,173 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "GenesisHash")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
+ bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "Proposer")
+ return
+ }
+ }
+ if zb0005 > 0 {
+ zb0005--
+ bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "FeesCollected")
+ return
+ }
+ }
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "FeeSink")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsPool")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsLevel")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsRate")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsResidue")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsRecalculationRound")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "CurrentProtocol")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NextProtocol")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NextProtocolApprovals")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NextProtocolVoteBefore")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NextProtocolSwitchOn")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "UpgradePropose")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "UpgradeDelay")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove, bts, err = msgp.ReadBoolBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "UpgradeApprove")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "TxnCounter")
return
}
}
- if zb0004 > 0 {
- zb0004--
- var zb0007 int
- var zb0008 bool
- zb0007, zb0008, bts, err = msgp.ReadMapHeaderBytes(bts)
+ if zb0005 > 0 {
+ zb0005--
+ var zb0008 int
+ var zb0009 bool
+ zb0008, zb0009, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "StateProofTracking")
return
}
- if zb0007 > protocol.NumStateProofTypes {
- err = msgp.ErrOverflow(uint64(zb0007), uint64(protocol.NumStateProofTypes))
+ if zb0008 > protocol.NumStateProofTypes {
+ err = msgp.ErrOverflow(uint64(zb0008), uint64(protocol.NumStateProofTypes))
err = msgp.WrapError(err, "struct-from-array", "StateProofTracking")
return
}
- if zb0008 {
+ if zb0009 {
(*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = nil
} else if (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking == nil {
- (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0007)
+ (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0008)
}
- for zb0007 > 0 {
+ for zb0008 > 0 {
var zb0001 protocol.StateProofType
var zb0002 bookkeeping.StateProofTrackingData
- zb0007--
+ zb0008--
bts, err = zb0001.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "StateProofTracking")
@@ -5038,26 +5088,26 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o
(*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking[zb0001] = zb0002
}
}
- if zb0004 > 0 {
- zb0004--
- var zb0009 int
- var zb0010 bool
- zb0009, zb0010, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if zb0005 > 0 {
+ zb0005--
+ var zb0010 int
+ var zb0011 bool
+ zb0010, zb0011, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts")
return
}
- if zb0009 > config.MaxProposedExpiredOnlineAccounts {
- err = msgp.ErrOverflow(uint64(zb0009), uint64(config.MaxProposedExpiredOnlineAccounts))
+ if zb0010 > config.MaxProposedExpiredOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0010), uint64(config.MaxProposedExpiredOnlineAccounts))
err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts")
return
}
- if zb0010 {
+ if zb0011 {
(*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = nil
- } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0009 {
- (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0009]
+ } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0010 {
+ (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0010]
} else {
- (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0009)
+ (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0010)
}
for zb0003 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts {
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].UnmarshalMsgWithState(bts, st)
@@ -5067,44 +5117,73 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o
}
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
+ var zb0012 int
+ var zb0013 bool
+ zb0012, zb0013, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts")
+ return
+ }
+ if zb0012 > config.MaxProposedAbsentOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0012), uint64(config.MaxProposedAbsentOnlineAccounts))
+ err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts")
+ return
+ }
+ if zb0013 {
+ (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = nil
+ } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) >= zb0012 {
+ (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts)[:zb0012]
+ } else {
+ (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = make([]basics.Address, zb0012)
+ }
+ for zb0004 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts {
+ bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts", zb0004)
+ return
+ }
+ }
+ }
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.Payset.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Payset")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.SeedProof.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "SeedProof")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
{
- var zb0011 uint64
- zb0011, bts, err = msgp.ReadUint64Bytes(bts)
+ var zb0014 uint64
+ zb0014, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "OriginalPeriod")
return
}
- (*z).unauthenticatedProposal.OriginalPeriod = period(zb0011)
+ (*z).unauthenticatedProposal.OriginalPeriod = period(zb0014)
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.OriginalProposer.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "OriginalProposer")
return
}
}
- if zb0004 > 0 {
- err = msgp.ErrTooManyArrayFields(zb0004)
+ if zb0005 > 0 {
+ err = msgp.ErrTooManyArrayFields(zb0005)
if err != nil {
err = msgp.WrapError(err, "struct-from-array")
return
@@ -5115,11 +5194,11 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o
err = msgp.WrapError(err)
return
}
- if zb0005 {
+ if zb0006 {
(*z) = proposal{}
}
- for zb0004 > 0 {
- zb0004--
+ for zb0005 > 0 {
+ zb0005--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
err = msgp.WrapError(err)
@@ -5163,14 +5242,14 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o
return
}
case "gen":
- var zb0012 int
- zb0012, err = msgp.ReadBytesBytesHeader(bts)
+ var zb0015 int
+ zb0015, err = msgp.ReadBytesBytesHeader(bts)
if err != nil {
err = msgp.WrapError(err, "GenesisID")
return
}
- if zb0012 > config.MaxGenesisIDLen {
- err = msgp.ErrOverflow(uint64(zb0012), uint64(config.MaxGenesisIDLen))
+ if zb0015 > config.MaxGenesisIDLen {
+ err = msgp.ErrOverflow(uint64(zb0015), uint64(config.MaxGenesisIDLen))
return
}
(*z).unauthenticatedProposal.Block.BlockHeader.GenesisID, bts, err = msgp.ReadStringBytes(bts)
@@ -5184,6 +5263,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 {
@@ -5275,27 +5366,27 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o
return
}
case "spt":
- var zb0013 int
- var zb0014 bool
- zb0013, zb0014, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0016 int
+ var zb0017 bool
+ zb0016, zb0017, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "StateProofTracking")
return
}
- if zb0013 > protocol.NumStateProofTypes {
- err = msgp.ErrOverflow(uint64(zb0013), uint64(protocol.NumStateProofTypes))
+ if zb0016 > protocol.NumStateProofTypes {
+ err = msgp.ErrOverflow(uint64(zb0016), uint64(protocol.NumStateProofTypes))
err = msgp.WrapError(err, "StateProofTracking")
return
}
- if zb0014 {
+ if zb0017 {
(*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = nil
} else if (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking == nil {
- (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0013)
+ (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0016)
}
- for zb0013 > 0 {
+ for zb0016 > 0 {
var zb0001 protocol.StateProofType
var zb0002 bookkeeping.StateProofTrackingData
- zb0013--
+ zb0016--
bts, err = zb0001.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "StateProofTracking")
@@ -5309,24 +5400,24 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o
(*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking[zb0001] = zb0002
}
case "partupdrmv":
- var zb0015 int
- var zb0016 bool
- zb0015, zb0016, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ var zb0018 int
+ var zb0019 bool
+ zb0018, zb0019, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "ExpiredParticipationAccounts")
return
}
- if zb0015 > config.MaxProposedExpiredOnlineAccounts {
- err = msgp.ErrOverflow(uint64(zb0015), uint64(config.MaxProposedExpiredOnlineAccounts))
+ if zb0018 > config.MaxProposedExpiredOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0018), uint64(config.MaxProposedExpiredOnlineAccounts))
err = msgp.WrapError(err, "ExpiredParticipationAccounts")
return
}
- if zb0016 {
+ if zb0019 {
(*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = nil
- } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0015 {
- (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0015]
+ } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0018 {
+ (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0018]
} else {
- (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0015)
+ (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0018)
}
for zb0003 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts {
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].UnmarshalMsgWithState(bts, st)
@@ -5335,6 +5426,33 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o
return
}
}
+ case "partupdabs":
+ var zb0020 int
+ var zb0021 bool
+ zb0020, zb0021, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "AbsentParticipationAccounts")
+ return
+ }
+ if zb0020 > config.MaxProposedAbsentOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0020), uint64(config.MaxProposedAbsentOnlineAccounts))
+ err = msgp.WrapError(err, "AbsentParticipationAccounts")
+ return
+ }
+ if zb0021 {
+ (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = nil
+ } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) >= zb0020 {
+ (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts)[:zb0020]
+ } else {
+ (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = make([]basics.Address, zb0020)
+ }
+ for zb0004 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts {
+ bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "AbsentParticipationAccounts", zb0004)
+ return
+ }
+ }
case "txns":
bts, err = (*z).unauthenticatedProposal.Block.Payset.UnmarshalMsgWithState(bts, st)
if err != nil {
@@ -5349,13 +5467,13 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o
}
case "oper":
{
- var zb0017 uint64
- zb0017, bts, err = msgp.ReadUint64Bytes(bts)
+ var zb0022 uint64
+ zb0022, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "OriginalPeriod")
return
}
- (*z).unauthenticatedProposal.OriginalPeriod = period(zb0017)
+ (*z).unauthenticatedProposal.OriginalPeriod = period(zb0022)
}
case "oprop":
bts, err = (*z).unauthenticatedProposal.OriginalProposer.UnmarshalMsgWithState(bts, st)
@@ -5386,7 +5504,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
@@ -5398,18 +5516,22 @@ func (z *proposal) Msgsize() (s int) {
for zb0003 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts {
s += (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].Msgsize()
}
+ s += 11 + msgp.ArrayHeaderSize
+ for zb0004 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts {
+ s += (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].Msgsize()
+ }
s += 5 + (*z).unauthenticatedProposal.Block.Payset.Msgsize() + 5 + (*z).unauthenticatedProposal.SeedProof.Msgsize() + 5 + msgp.Uint64Size + 6 + (*z).unauthenticatedProposal.OriginalProposer.Msgsize()
return
}
// MsgIsZero returns whether this is a zero value
func (z *proposal) MsgIsZero() bool {
- return ((*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "") && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).unauthenticatedProposal.Block.Payset.MsgIsZero()) && ((*z).unauthenticatedProposal.SeedProof.MsgIsZero()) && ((*z).unauthenticatedProposal.OriginalPeriod == 0) && ((*z).unauthenticatedProposal.OriginalProposer.MsgIsZero())
+ return ((*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "") && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) == 0) && ((*z).unauthenticatedProposal.Block.Payset.MsgIsZero()) && ((*z).unauthenticatedProposal.SeedProof.MsgIsZero()) && ((*z).unauthenticatedProposal.OriginalPeriod == 0) && ((*z).unauthenticatedProposal.OriginalProposer.MsgIsZero())
}
// MaxSize returns a maximum valid message size for this message type
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())
@@ -5418,6 +5540,9 @@ func ProposalMaxSize() (s int) {
s += 11
// Calculating size of slice: z.unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts
s += msgp.ArrayHeaderSize + ((config.MaxProposedExpiredOnlineAccounts) * (basics.AddressMaxSize()))
+ s += 11
+ // Calculating size of slice: z.unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts
+ s += msgp.ArrayHeaderSize + ((config.MaxProposedAbsentOnlineAccounts) * (basics.AddressMaxSize()))
s += 5
// Using maxtotalbytes for: z.unauthenticatedProposal.Block.Payset
s += config.MaxTxnBytesPerBlock
@@ -8856,187 +8981,216 @@ func ThresholdEventMaxSize() (s int) {
func (z *transmittedPayload) MarshalMsg(b []byte) (o []byte) {
o = msgp.Require(b, z.Msgsize())
// omitempty: check for empty values
- zb0004Len := uint32(30)
- var zb0004Mask uint64 /* 38 bits */
+ zb0005Len := uint32(33)
+ var zb0005Mask uint64 /* 41 bits */
if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0 {
- zb0004Len--
- zb0004Mask |= 0x80
+ zb0005Len--
+ zb0005Mask |= 0x80
+ }
+ if (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MsgIsZero() {
+ zb0005Len--
+ zb0005Mask |= 0x100
}
if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x100
+ zb0005Len--
+ zb0005Mask |= 0x200
}
if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0 {
- zb0004Len--
- zb0004Mask |= 0x200
+ zb0005Len--
+ zb0005Mask |= 0x400
}
if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "" {
- zb0004Len--
- zb0004Mask |= 0x400
+ zb0005Len--
+ zb0005Mask |= 0x800
}
if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x800
+ zb0005Len--
+ zb0005Mask |= 0x1000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x1000
+ zb0005Len--
+ zb0005Mask |= 0x2000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x2000
+ zb0005Len--
+ zb0005Mask |= 0x4000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x4000
+ zb0005Len--
+ zb0005Mask |= 0x8000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0 {
- zb0004Len--
- zb0004Mask |= 0x8000
+ zb0005Len--
+ zb0005Mask |= 0x10000
}
if (*z).unauthenticatedProposal.OriginalPeriod == 0 {
- zb0004Len--
- zb0004Mask |= 0x10000
+ zb0005Len--
+ zb0005Mask |= 0x20000
}
if (*z).unauthenticatedProposal.OriginalProposer.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x20000
+ zb0005Len--
+ zb0005Mask |= 0x40000
+ }
+ if len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) == 0 {
+ zb0005Len--
+ zb0005Mask |= 0x80000
}
if len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 {
- zb0004Len--
- zb0004Mask |= 0x40000
+ zb0005Len--
+ zb0005Mask |= 0x100000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x80000
+ zb0005Len--
+ zb0005Mask |= 0x200000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x100000
+ zb0005Len--
+ zb0005Mask |= 0x400000
+ }
+ if (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MsgIsZero() {
+ zb0005Len--
+ zb0005Mask |= 0x800000
}
if (*z).PriorVote.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x200000
+ zb0005Len--
+ zb0005Mask |= 0x1000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0 {
- zb0004Len--
- zb0004Mask |= 0x400000
+ zb0005Len--
+ zb0005Mask |= 0x2000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x1000000
+ zb0005Len--
+ zb0005Mask |= 0x8000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x2000000
+ zb0005Len--
+ zb0005Mask |= 0x10000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x4000000
+ zb0005Len--
+ zb0005Mask |= 0x20000000
}
if (*z).unauthenticatedProposal.SeedProof.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x8000000
+ zb0005Len--
+ zb0005Mask |= 0x40000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x10000000
+ zb0005Len--
+ zb0005Mask |= 0x80000000
}
if len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0 {
- zb0004Len--
- zb0004Mask |= 0x20000000
+ zb0005Len--
+ zb0005Mask |= 0x100000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0 {
- zb0004Len--
- zb0004Mask |= 0x40000000
+ zb0005Len--
+ zb0005Mask |= 0x200000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0 {
- zb0004Len--
- zb0004Mask |= 0x80000000
+ zb0005Len--
+ zb0005Mask |= 0x400000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x100000000
+ zb0005Len--
+ zb0005Mask |= 0x800000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x200000000
+ zb0005Len--
+ zb0005Mask |= 0x1000000000
}
if (*z).unauthenticatedProposal.Block.Payset.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x400000000
+ zb0005Len--
+ zb0005Mask |= 0x2000000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x800000000
+ zb0005Len--
+ zb0005Mask |= 0x4000000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x1000000000
+ zb0005Len--
+ zb0005Mask |= 0x8000000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false {
- zb0004Len--
- zb0004Mask |= 0x2000000000
+ zb0005Len--
+ zb0005Mask |= 0x10000000000
}
- // variable map header, size zb0004Len
- o = msgp.AppendMapHeader(o, zb0004Len)
- if zb0004Len != 0 {
- if (zb0004Mask & 0x80) == 0 { // if not empty
+ // variable map header, size zb0005Len
+ o = msgp.AppendMapHeader(o, zb0005Len)
+ if zb0005Len != 0 {
+ if (zb0005Mask & 0x80) == 0 { // if not empty
// string "earn"
o = append(o, 0xa4, 0x65, 0x61, 0x72, 0x6e)
o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel)
}
- if (zb0004Mask & 0x100) == 0 { // if not empty
+ if (zb0005Mask & 0x100) == 0 { // if not empty
+ // string "fc"
+ o = append(o, 0xa2, 0x66, 0x63)
+ o = (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MarshalMsg(o)
+ }
+ if (zb0005Mask & 0x200) == 0 { // if not empty
// string "fees"
o = append(o, 0xa4, 0x66, 0x65, 0x65, 0x73)
o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MarshalMsg(o)
}
- if (zb0004Mask & 0x200) == 0 { // if not empty
+ if (zb0005Mask & 0x400) == 0 { // if not empty
// string "frac"
o = append(o, 0xa4, 0x66, 0x72, 0x61, 0x63)
o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue)
}
- if (zb0004Mask & 0x400) == 0 { // if not empty
+ if (zb0005Mask & 0x800) == 0 { // if not empty
// string "gen"
o = append(o, 0xa3, 0x67, 0x65, 0x6e)
o = msgp.AppendString(o, (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID)
}
- if (zb0004Mask & 0x800) == 0 { // if not empty
+ if (zb0005Mask & 0x1000) == 0 { // if not empty
// string "gh"
o = append(o, 0xa2, 0x67, 0x68)
o = (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MarshalMsg(o)
}
- if (zb0004Mask & 0x1000) == 0 { // if not empty
+ if (zb0005Mask & 0x2000) == 0 { // if not empty
// string "nextbefore"
o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MarshalMsg(o)
}
- if (zb0004Mask & 0x2000) == 0 { // if not empty
+ if (zb0005Mask & 0x4000) == 0 { // if not empty
// string "nextproto"
o = append(o, 0xa9, 0x6e, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MarshalMsg(o)
}
- if (zb0004Mask & 0x4000) == 0 { // if not empty
+ if (zb0005Mask & 0x8000) == 0 { // if not empty
// string "nextswitch"
o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MarshalMsg(o)
}
- if (zb0004Mask & 0x8000) == 0 { // if not empty
+ if (zb0005Mask & 0x10000) == 0 { // if not empty
// string "nextyes"
o = append(o, 0xa7, 0x6e, 0x65, 0x78, 0x74, 0x79, 0x65, 0x73)
o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals)
}
- if (zb0004Mask & 0x10000) == 0 { // if not empty
+ if (zb0005Mask & 0x20000) == 0 { // if not empty
// string "oper"
o = append(o, 0xa4, 0x6f, 0x70, 0x65, 0x72)
o = msgp.AppendUint64(o, uint64((*z).unauthenticatedProposal.OriginalPeriod))
}
- if (zb0004Mask & 0x20000) == 0 { // if not empty
+ if (zb0005Mask & 0x40000) == 0 { // if not empty
// string "oprop"
o = append(o, 0xa5, 0x6f, 0x70, 0x72, 0x6f, 0x70)
o = (*z).unauthenticatedProposal.OriginalProposer.MarshalMsg(o)
}
- if (zb0004Mask & 0x40000) == 0 { // if not empty
+ if (zb0005Mask & 0x80000) == 0 { // if not empty
+ // string "partupdabs"
+ o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x61, 0x62, 0x73)
+ if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts == nil {
+ o = msgp.AppendNil(o)
+ } else {
+ o = msgp.AppendArrayHeader(o, uint32(len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts)))
+ }
+ for zb0004 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts {
+ o = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].MarshalMsg(o)
+ }
+ }
+ if (zb0005Mask & 0x100000) == 0 { // if not empty
// string "partupdrmv"
o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76)
if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts == nil {
@@ -9048,52 +9202,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 (zb0005Mask & 0x200000) == 0 { // if not empty
// string "prev"
o = append(o, 0xa4, 0x70, 0x72, 0x65, 0x76)
o = (*z).unauthenticatedProposal.Block.BlockHeader.Branch.MarshalMsg(o)
}
- if (zb0004Mask & 0x100000) == 0 { // if not empty
+ if (zb0005Mask & 0x400000) == 0 { // if not empty
// string "proto"
o = append(o, 0xa5, 0x70, 0x72, 0x6f, 0x74, 0x6f)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MarshalMsg(o)
}
- if (zb0004Mask & 0x200000) == 0 { // if not empty
+ if (zb0005Mask & 0x800000) == 0 { // if not empty
+ // string "prp"
+ o = append(o, 0xa3, 0x70, 0x72, 0x70)
+ o = (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MarshalMsg(o)
+ }
+ if (zb0005Mask & 0x1000000) == 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 (zb0005Mask & 0x2000000) == 0 { // if not empty
// string "rate"
o = append(o, 0xa4, 0x72, 0x61, 0x74, 0x65)
o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate)
}
- if (zb0004Mask & 0x1000000) == 0 { // if not empty
+ if (zb0005Mask & 0x8000000) == 0 { // if not empty
// string "rnd"
o = append(o, 0xa3, 0x72, 0x6e, 0x64)
o = (*z).unauthenticatedProposal.Block.BlockHeader.Round.MarshalMsg(o)
}
- if (zb0004Mask & 0x2000000) == 0 { // if not empty
+ if (zb0005Mask & 0x10000000) == 0 { // if not empty
// string "rwcalr"
o = append(o, 0xa6, 0x72, 0x77, 0x63, 0x61, 0x6c, 0x72)
o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MarshalMsg(o)
}
- if (zb0004Mask & 0x4000000) == 0 { // if not empty
+ if (zb0005Mask & 0x20000000) == 0 { // if not empty
// string "rwd"
o = append(o, 0xa3, 0x72, 0x77, 0x64)
o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MarshalMsg(o)
}
- if (zb0004Mask & 0x8000000) == 0 { // if not empty
+ if (zb0005Mask & 0x40000000) == 0 { // if not empty
// string "sdpf"
o = append(o, 0xa4, 0x73, 0x64, 0x70, 0x66)
o = (*z).unauthenticatedProposal.SeedProof.MarshalMsg(o)
}
- if (zb0004Mask & 0x10000000) == 0 { // if not empty
+ if (zb0005Mask & 0x80000000) == 0 { // if not empty
// string "seed"
o = append(o, 0xa4, 0x73, 0x65, 0x65, 0x64)
o = (*z).unauthenticatedProposal.Block.BlockHeader.Seed.MarshalMsg(o)
}
- if (zb0004Mask & 0x20000000) == 0 { // if not empty
+ if (zb0005Mask & 0x100000000) == 0 { // if not empty
// string "spt"
o = append(o, 0xa3, 0x73, 0x70, 0x74)
if (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking == nil {
@@ -9113,42 +9272,42 @@ func (z *transmittedPayload) MarshalMsg(b []byte) (o []byte) {
o = zb0002.MarshalMsg(o)
}
}
- if (zb0004Mask & 0x40000000) == 0 { // if not empty
+ if (zb0005Mask & 0x200000000) == 0 { // if not empty
// string "tc"
o = append(o, 0xa2, 0x74, 0x63)
o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter)
}
- if (zb0004Mask & 0x80000000) == 0 { // if not empty
+ if (zb0005Mask & 0x400000000) == 0 { // if not empty
// string "ts"
o = append(o, 0xa2, 0x74, 0x73)
o = msgp.AppendInt64(o, (*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp)
}
- if (zb0004Mask & 0x100000000) == 0 { // if not empty
+ if (zb0005Mask & 0x800000000) == 0 { // if not empty
// string "txn"
o = append(o, 0xa3, 0x74, 0x78, 0x6e)
o = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MarshalMsg(o)
}
- if (zb0004Mask & 0x200000000) == 0 { // if not empty
+ if (zb0005Mask & 0x1000000000) == 0 { // if not empty
// string "txn256"
o = append(o, 0xa6, 0x74, 0x78, 0x6e, 0x32, 0x35, 0x36)
o = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MarshalMsg(o)
}
- if (zb0004Mask & 0x400000000) == 0 { // if not empty
+ if (zb0005Mask & 0x2000000000) == 0 { // if not empty
// string "txns"
o = append(o, 0xa4, 0x74, 0x78, 0x6e, 0x73)
o = (*z).unauthenticatedProposal.Block.Payset.MarshalMsg(o)
}
- if (zb0004Mask & 0x800000000) == 0 { // if not empty
+ if (zb0005Mask & 0x4000000000) == 0 { // if not empty
// string "upgradedelay"
o = append(o, 0xac, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x65, 0x6c, 0x61, 0x79)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MarshalMsg(o)
}
- if (zb0004Mask & 0x1000000000) == 0 { // if not empty
+ if (zb0005Mask & 0x8000000000) == 0 { // if not empty
// string "upgradeprop"
o = append(o, 0xab, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x70, 0x72, 0x6f, 0x70)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MarshalMsg(o)
}
- if (zb0004Mask & 0x2000000000) == 0 { // if not empty
+ if (zb0005Mask & 0x10000000000) == 0 { // if not empty
// string "upgradeyes"
o = append(o, 0xaa, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x65, 0x73)
o = msgp.AppendBool(o, (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove)
@@ -9171,73 +9330,73 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal
st.AllowableDepth--
var field []byte
_ = field
- var zb0004 int
- var zb0005 bool
- zb0004, zb0005, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0005 int
+ var zb0006 bool
+ zb0005, zb0006, bts, err = msgp.ReadMapHeaderBytes(bts)
if _, ok := err.(msgp.TypeError); ok {
- zb0004, zb0005, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ zb0005, zb0006, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err)
return
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Round.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Round")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Branch.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Branch")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Seed.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Seed")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NativeSha512_256Commitment")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Sha256Commitment")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp, bts, err = msgp.ReadInt64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "TimeStamp")
return
}
}
- if zb0004 > 0 {
- zb0004--
- var zb0006 int
- zb0006, err = msgp.ReadBytesBytesHeader(bts)
+ if zb0005 > 0 {
+ zb0005--
+ var zb0007 int
+ zb0007, err = msgp.ReadBytesBytesHeader(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "GenesisID")
return
}
- if zb0006 > config.MaxGenesisIDLen {
- err = msgp.ErrOverflow(uint64(zb0006), uint64(config.MaxGenesisIDLen))
+ if zb0007 > config.MaxGenesisIDLen {
+ err = msgp.ErrOverflow(uint64(zb0007), uint64(config.MaxGenesisIDLen))
return
}
(*z).unauthenticatedProposal.Block.BlockHeader.GenesisID, bts, err = msgp.ReadStringBytes(bts)
@@ -9246,157 +9405,173 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "GenesisHash")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
+ bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "Proposer")
+ return
+ }
+ }
+ if zb0005 > 0 {
+ zb0005--
+ bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "FeesCollected")
+ return
+ }
+ }
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "FeeSink")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsPool")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsLevel")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsRate")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsResidue")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsRecalculationRound")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "CurrentProtocol")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NextProtocol")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NextProtocolApprovals")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NextProtocolVoteBefore")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NextProtocolSwitchOn")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "UpgradePropose")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "UpgradeDelay")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove, bts, err = msgp.ReadBoolBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "UpgradeApprove")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "TxnCounter")
return
}
}
- if zb0004 > 0 {
- zb0004--
- var zb0007 int
- var zb0008 bool
- zb0007, zb0008, bts, err = msgp.ReadMapHeaderBytes(bts)
+ if zb0005 > 0 {
+ zb0005--
+ var zb0008 int
+ var zb0009 bool
+ zb0008, zb0009, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "StateProofTracking")
return
}
- if zb0007 > protocol.NumStateProofTypes {
- err = msgp.ErrOverflow(uint64(zb0007), uint64(protocol.NumStateProofTypes))
+ if zb0008 > protocol.NumStateProofTypes {
+ err = msgp.ErrOverflow(uint64(zb0008), uint64(protocol.NumStateProofTypes))
err = msgp.WrapError(err, "struct-from-array", "StateProofTracking")
return
}
- if zb0008 {
+ if zb0009 {
(*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = nil
} else if (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking == nil {
- (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0007)
+ (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0008)
}
- for zb0007 > 0 {
+ for zb0008 > 0 {
var zb0001 protocol.StateProofType
var zb0002 bookkeeping.StateProofTrackingData
- zb0007--
+ zb0008--
bts, err = zb0001.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "StateProofTracking")
@@ -9410,26 +9585,26 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal
(*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking[zb0001] = zb0002
}
}
- if zb0004 > 0 {
- zb0004--
- var zb0009 int
- var zb0010 bool
- zb0009, zb0010, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if zb0005 > 0 {
+ zb0005--
+ var zb0010 int
+ var zb0011 bool
+ zb0010, zb0011, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts")
return
}
- if zb0009 > config.MaxProposedExpiredOnlineAccounts {
- err = msgp.ErrOverflow(uint64(zb0009), uint64(config.MaxProposedExpiredOnlineAccounts))
+ if zb0010 > config.MaxProposedExpiredOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0010), uint64(config.MaxProposedExpiredOnlineAccounts))
err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts")
return
}
- if zb0010 {
+ if zb0011 {
(*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = nil
- } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0009 {
- (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0009]
+ } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0010 {
+ (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0010]
} else {
- (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0009)
+ (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0010)
}
for zb0003 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts {
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].UnmarshalMsgWithState(bts, st)
@@ -9439,52 +9614,81 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal
}
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
+ var zb0012 int
+ var zb0013 bool
+ zb0012, zb0013, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts")
+ return
+ }
+ if zb0012 > config.MaxProposedAbsentOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0012), uint64(config.MaxProposedAbsentOnlineAccounts))
+ err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts")
+ return
+ }
+ if zb0013 {
+ (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = nil
+ } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) >= zb0012 {
+ (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts)[:zb0012]
+ } else {
+ (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = make([]basics.Address, zb0012)
+ }
+ for zb0004 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts {
+ bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts", zb0004)
+ return
+ }
+ }
+ }
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.Block.Payset.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Payset")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.SeedProof.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "SeedProof")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
{
- var zb0011 uint64
- zb0011, bts, err = msgp.ReadUint64Bytes(bts)
+ var zb0014 uint64
+ zb0014, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "OriginalPeriod")
return
}
- (*z).unauthenticatedProposal.OriginalPeriod = period(zb0011)
+ (*z).unauthenticatedProposal.OriginalPeriod = period(zb0014)
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).unauthenticatedProposal.OriginalProposer.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "OriginalProposer")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).PriorVote.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "PriorVote")
return
}
}
- if zb0004 > 0 {
- err = msgp.ErrTooManyArrayFields(zb0004)
+ if zb0005 > 0 {
+ err = msgp.ErrTooManyArrayFields(zb0005)
if err != nil {
err = msgp.WrapError(err, "struct-from-array")
return
@@ -9495,11 +9699,11 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal
err = msgp.WrapError(err)
return
}
- if zb0005 {
+ if zb0006 {
(*z) = transmittedPayload{}
}
- for zb0004 > 0 {
- zb0004--
+ for zb0005 > 0 {
+ zb0005--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
err = msgp.WrapError(err)
@@ -9543,14 +9747,14 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal
return
}
case "gen":
- var zb0012 int
- zb0012, err = msgp.ReadBytesBytesHeader(bts)
+ var zb0015 int
+ zb0015, err = msgp.ReadBytesBytesHeader(bts)
if err != nil {
err = msgp.WrapError(err, "GenesisID")
return
}
- if zb0012 > config.MaxGenesisIDLen {
- err = msgp.ErrOverflow(uint64(zb0012), uint64(config.MaxGenesisIDLen))
+ if zb0015 > config.MaxGenesisIDLen {
+ err = msgp.ErrOverflow(uint64(zb0015), uint64(config.MaxGenesisIDLen))
return
}
(*z).unauthenticatedProposal.Block.BlockHeader.GenesisID, bts, err = msgp.ReadStringBytes(bts)
@@ -9564,6 +9768,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 {
@@ -9655,27 +9871,27 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal
return
}
case "spt":
- var zb0013 int
- var zb0014 bool
- zb0013, zb0014, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0016 int
+ var zb0017 bool
+ zb0016, zb0017, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "StateProofTracking")
return
}
- if zb0013 > protocol.NumStateProofTypes {
- err = msgp.ErrOverflow(uint64(zb0013), uint64(protocol.NumStateProofTypes))
+ if zb0016 > protocol.NumStateProofTypes {
+ err = msgp.ErrOverflow(uint64(zb0016), uint64(protocol.NumStateProofTypes))
err = msgp.WrapError(err, "StateProofTracking")
return
}
- if zb0014 {
+ if zb0017 {
(*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = nil
} else if (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking == nil {
- (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0013)
+ (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0016)
}
- for zb0013 > 0 {
+ for zb0016 > 0 {
var zb0001 protocol.StateProofType
var zb0002 bookkeeping.StateProofTrackingData
- zb0013--
+ zb0016--
bts, err = zb0001.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "StateProofTracking")
@@ -9689,24 +9905,24 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal
(*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking[zb0001] = zb0002
}
case "partupdrmv":
- var zb0015 int
- var zb0016 bool
- zb0015, zb0016, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ var zb0018 int
+ var zb0019 bool
+ zb0018, zb0019, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "ExpiredParticipationAccounts")
return
}
- if zb0015 > config.MaxProposedExpiredOnlineAccounts {
- err = msgp.ErrOverflow(uint64(zb0015), uint64(config.MaxProposedExpiredOnlineAccounts))
+ if zb0018 > config.MaxProposedExpiredOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0018), uint64(config.MaxProposedExpiredOnlineAccounts))
err = msgp.WrapError(err, "ExpiredParticipationAccounts")
return
}
- if zb0016 {
+ if zb0019 {
(*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = nil
- } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0015 {
- (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0015]
+ } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0018 {
+ (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0018]
} else {
- (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0015)
+ (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0018)
}
for zb0003 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts {
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].UnmarshalMsgWithState(bts, st)
@@ -9715,6 +9931,33 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal
return
}
}
+ case "partupdabs":
+ var zb0020 int
+ var zb0021 bool
+ zb0020, zb0021, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "AbsentParticipationAccounts")
+ return
+ }
+ if zb0020 > config.MaxProposedAbsentOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0020), uint64(config.MaxProposedAbsentOnlineAccounts))
+ err = msgp.WrapError(err, "AbsentParticipationAccounts")
+ return
+ }
+ if zb0021 {
+ (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = nil
+ } else if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts != nil && cap((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) >= zb0020 {
+ (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = ((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts)[:zb0020]
+ } else {
+ (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = make([]basics.Address, zb0020)
+ }
+ for zb0004 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts {
+ bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "AbsentParticipationAccounts", zb0004)
+ return
+ }
+ }
case "txns":
bts, err = (*z).unauthenticatedProposal.Block.Payset.UnmarshalMsgWithState(bts, st)
if err != nil {
@@ -9729,13 +9972,13 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal
}
case "oper":
{
- var zb0017 uint64
- zb0017, bts, err = msgp.ReadUint64Bytes(bts)
+ var zb0022 uint64
+ zb0022, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "OriginalPeriod")
return
}
- (*z).unauthenticatedProposal.OriginalPeriod = period(zb0017)
+ (*z).unauthenticatedProposal.OriginalPeriod = period(zb0022)
}
case "oprop":
bts, err = (*z).unauthenticatedProposal.OriginalProposer.UnmarshalMsgWithState(bts, st)
@@ -9772,7 +10015,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
@@ -9784,18 +10027,22 @@ func (z *transmittedPayload) Msgsize() (s int) {
for zb0003 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts {
s += (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].Msgsize()
}
+ s += 11 + msgp.ArrayHeaderSize
+ for zb0004 := range (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts {
+ s += (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].Msgsize()
+ }
s += 5 + (*z).unauthenticatedProposal.Block.Payset.Msgsize() + 5 + (*z).unauthenticatedProposal.SeedProof.Msgsize() + 5 + msgp.Uint64Size + 6 + (*z).unauthenticatedProposal.OriginalProposer.Msgsize() + 3 + (*z).PriorVote.Msgsize()
return
}
// MsgIsZero returns whether this is a zero value
func (z *transmittedPayload) MsgIsZero() bool {
- return ((*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "") && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).unauthenticatedProposal.Block.Payset.MsgIsZero()) && ((*z).unauthenticatedProposal.SeedProof.MsgIsZero()) && ((*z).unauthenticatedProposal.OriginalPeriod == 0) && ((*z).unauthenticatedProposal.OriginalProposer.MsgIsZero()) && ((*z).PriorVote.MsgIsZero())
+ return ((*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "") && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) == 0) && ((*z).unauthenticatedProposal.Block.Payset.MsgIsZero()) && ((*z).unauthenticatedProposal.SeedProof.MsgIsZero()) && ((*z).unauthenticatedProposal.OriginalPeriod == 0) && ((*z).unauthenticatedProposal.OriginalProposer.MsgIsZero()) && ((*z).PriorVote.MsgIsZero())
}
// MaxSize returns a maximum valid message size for this message type
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())
@@ -9804,6 +10051,9 @@ func TransmittedPayloadMaxSize() (s int) {
s += 11
// Calculating size of slice: z.unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts
s += msgp.ArrayHeaderSize + ((config.MaxProposedExpiredOnlineAccounts) * (basics.AddressMaxSize()))
+ s += 11
+ // Calculating size of slice: z.unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts
+ s += msgp.ArrayHeaderSize + ((config.MaxProposedAbsentOnlineAccounts) * (basics.AddressMaxSize()))
s += 5
// Using maxtotalbytes for: z.unauthenticatedProposal.Block.Payset
s += config.MaxTxnBytesPerBlock
@@ -10516,183 +10766,212 @@ func UnauthenticatedEquivocationVoteMaxSize() (s int) {
func (z *unauthenticatedProposal) MarshalMsg(b []byte) (o []byte) {
o = msgp.Require(b, z.Msgsize())
// omitempty: check for empty values
- zb0004Len := uint32(29)
- var zb0004Mask uint64 /* 36 bits */
+ zb0005Len := uint32(32)
+ var zb0005Mask uint64 /* 39 bits */
if (*z).Block.BlockHeader.RewardsState.RewardsLevel == 0 {
- zb0004Len--
- zb0004Mask |= 0x40
+ zb0005Len--
+ zb0005Mask |= 0x40
+ }
+ if (*z).Block.BlockHeader.FeesCollected.MsgIsZero() {
+ zb0005Len--
+ zb0005Mask |= 0x80
}
if (*z).Block.BlockHeader.RewardsState.FeeSink.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x80
+ zb0005Len--
+ zb0005Mask |= 0x100
}
if (*z).Block.BlockHeader.RewardsState.RewardsResidue == 0 {
- zb0004Len--
- zb0004Mask |= 0x100
+ zb0005Len--
+ zb0005Mask |= 0x200
}
if (*z).Block.BlockHeader.GenesisID == "" {
- zb0004Len--
- zb0004Mask |= 0x200
+ zb0005Len--
+ zb0005Mask |= 0x400
}
if (*z).Block.BlockHeader.GenesisHash.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x400
+ zb0005Len--
+ zb0005Mask |= 0x800
}
if (*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x800
+ zb0005Len--
+ zb0005Mask |= 0x1000
}
if (*z).Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x1000
+ zb0005Len--
+ zb0005Mask |= 0x2000
}
if (*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x2000
+ zb0005Len--
+ zb0005Mask |= 0x4000
}
if (*z).Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0 {
- zb0004Len--
- zb0004Mask |= 0x4000
+ zb0005Len--
+ zb0005Mask |= 0x8000
}
if (*z).OriginalPeriod == 0 {
- zb0004Len--
- zb0004Mask |= 0x8000
+ zb0005Len--
+ zb0005Mask |= 0x10000
}
if (*z).OriginalProposer.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x10000
+ zb0005Len--
+ zb0005Mask |= 0x20000
+ }
+ if len((*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) == 0 {
+ zb0005Len--
+ zb0005Mask |= 0x40000
}
if len((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 {
- zb0004Len--
- zb0004Mask |= 0x20000
+ zb0005Len--
+ zb0005Mask |= 0x80000
}
if (*z).Block.BlockHeader.Branch.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x40000
+ zb0005Len--
+ zb0005Mask |= 0x100000
}
if (*z).Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x80000
+ zb0005Len--
+ zb0005Mask |= 0x200000
+ }
+ if (*z).Block.BlockHeader.Proposer.MsgIsZero() {
+ zb0005Len--
+ zb0005Mask |= 0x400000
}
if (*z).Block.BlockHeader.RewardsState.RewardsRate == 0 {
- zb0004Len--
- zb0004Mask |= 0x100000
+ zb0005Len--
+ zb0005Mask |= 0x800000
}
if (*z).Block.BlockHeader.Round.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x400000
+ zb0005Len--
+ zb0005Mask |= 0x2000000
}
if (*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x800000
+ zb0005Len--
+ zb0005Mask |= 0x4000000
}
if (*z).Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x1000000
+ zb0005Len--
+ zb0005Mask |= 0x8000000
}
if (*z).SeedProof.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x2000000
+ zb0005Len--
+ zb0005Mask |= 0x10000000
}
if (*z).Block.BlockHeader.Seed.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x4000000
+ zb0005Len--
+ zb0005Mask |= 0x20000000
}
if len((*z).Block.BlockHeader.StateProofTracking) == 0 {
- zb0004Len--
- zb0004Mask |= 0x8000000
+ zb0005Len--
+ zb0005Mask |= 0x40000000
}
if (*z).Block.BlockHeader.TxnCounter == 0 {
- zb0004Len--
- zb0004Mask |= 0x10000000
+ zb0005Len--
+ zb0005Mask |= 0x80000000
}
if (*z).Block.BlockHeader.TimeStamp == 0 {
- zb0004Len--
- zb0004Mask |= 0x20000000
+ zb0005Len--
+ zb0005Mask |= 0x100000000
}
if (*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x40000000
+ zb0005Len--
+ zb0005Mask |= 0x200000000
}
if (*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x80000000
+ zb0005Len--
+ zb0005Mask |= 0x400000000
}
if (*z).Block.Payset.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x100000000
+ zb0005Len--
+ zb0005Mask |= 0x800000000
}
if (*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x200000000
+ zb0005Len--
+ zb0005Mask |= 0x1000000000
}
if (*z).Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x400000000
+ zb0005Len--
+ zb0005Mask |= 0x2000000000
}
if (*z).Block.BlockHeader.UpgradeVote.UpgradeApprove == false {
- zb0004Len--
- zb0004Mask |= 0x800000000
+ zb0005Len--
+ zb0005Mask |= 0x4000000000
}
- // variable map header, size zb0004Len
- o = msgp.AppendMapHeader(o, zb0004Len)
- if zb0004Len != 0 {
- if (zb0004Mask & 0x40) == 0 { // if not empty
+ // variable map header, size zb0005Len
+ o = msgp.AppendMapHeader(o, zb0005Len)
+ if zb0005Len != 0 {
+ if (zb0005Mask & 0x40) == 0 { // if not empty
// string "earn"
o = append(o, 0xa4, 0x65, 0x61, 0x72, 0x6e)
o = msgp.AppendUint64(o, (*z).Block.BlockHeader.RewardsState.RewardsLevel)
}
- if (zb0004Mask & 0x80) == 0 { // if not empty
+ if (zb0005Mask & 0x80) == 0 { // if not empty
+ // string "fc"
+ o = append(o, 0xa2, 0x66, 0x63)
+ o = (*z).Block.BlockHeader.FeesCollected.MarshalMsg(o)
+ }
+ if (zb0005Mask & 0x100) == 0 { // if not empty
// string "fees"
o = append(o, 0xa4, 0x66, 0x65, 0x65, 0x73)
o = (*z).Block.BlockHeader.RewardsState.FeeSink.MarshalMsg(o)
}
- if (zb0004Mask & 0x100) == 0 { // if not empty
+ if (zb0005Mask & 0x200) == 0 { // if not empty
// string "frac"
o = append(o, 0xa4, 0x66, 0x72, 0x61, 0x63)
o = msgp.AppendUint64(o, (*z).Block.BlockHeader.RewardsState.RewardsResidue)
}
- if (zb0004Mask & 0x200) == 0 { // if not empty
+ if (zb0005Mask & 0x400) == 0 { // if not empty
// string "gen"
o = append(o, 0xa3, 0x67, 0x65, 0x6e)
o = msgp.AppendString(o, (*z).Block.BlockHeader.GenesisID)
}
- if (zb0004Mask & 0x400) == 0 { // if not empty
+ if (zb0005Mask & 0x800) == 0 { // if not empty
// string "gh"
o = append(o, 0xa2, 0x67, 0x68)
o = (*z).Block.BlockHeader.GenesisHash.MarshalMsg(o)
}
- if (zb0004Mask & 0x800) == 0 { // if not empty
+ if (zb0005Mask & 0x1000) == 0 { // if not empty
// string "nextbefore"
o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65)
o = (*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MarshalMsg(o)
}
- if (zb0004Mask & 0x1000) == 0 { // if not empty
+ if (zb0005Mask & 0x2000) == 0 { // if not empty
// string "nextproto"
o = append(o, 0xa9, 0x6e, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f)
o = (*z).Block.BlockHeader.UpgradeState.NextProtocol.MarshalMsg(o)
}
- if (zb0004Mask & 0x2000) == 0 { // if not empty
+ if (zb0005Mask & 0x4000) == 0 { // if not empty
// string "nextswitch"
o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68)
o = (*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MarshalMsg(o)
}
- if (zb0004Mask & 0x4000) == 0 { // if not empty
+ if (zb0005Mask & 0x8000) == 0 { // if not empty
// string "nextyes"
o = append(o, 0xa7, 0x6e, 0x65, 0x78, 0x74, 0x79, 0x65, 0x73)
o = msgp.AppendUint64(o, (*z).Block.BlockHeader.UpgradeState.NextProtocolApprovals)
}
- if (zb0004Mask & 0x8000) == 0 { // if not empty
+ if (zb0005Mask & 0x10000) == 0 { // if not empty
// string "oper"
o = append(o, 0xa4, 0x6f, 0x70, 0x65, 0x72)
o = msgp.AppendUint64(o, uint64((*z).OriginalPeriod))
}
- if (zb0004Mask & 0x10000) == 0 { // if not empty
+ if (zb0005Mask & 0x20000) == 0 { // if not empty
// string "oprop"
o = append(o, 0xa5, 0x6f, 0x70, 0x72, 0x6f, 0x70)
o = (*z).OriginalProposer.MarshalMsg(o)
}
- if (zb0004Mask & 0x20000) == 0 { // if not empty
+ if (zb0005Mask & 0x40000) == 0 { // if not empty
+ // string "partupdabs"
+ o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x61, 0x62, 0x73)
+ if (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts == nil {
+ o = msgp.AppendNil(o)
+ } else {
+ o = msgp.AppendArrayHeader(o, uint32(len((*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts)))
+ }
+ for zb0004 := range (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts {
+ o = (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].MarshalMsg(o)
+ }
+ }
+ if (zb0005Mask & 0x80000) == 0 { // if not empty
// string "partupdrmv"
o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76)
if (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts == nil {
@@ -10704,47 +10983,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 (zb0005Mask & 0x100000) == 0 { // if not empty
// string "prev"
o = append(o, 0xa4, 0x70, 0x72, 0x65, 0x76)
o = (*z).Block.BlockHeader.Branch.MarshalMsg(o)
}
- if (zb0004Mask & 0x80000) == 0 { // if not empty
+ if (zb0005Mask & 0x200000) == 0 { // if not empty
// string "proto"
o = append(o, 0xa5, 0x70, 0x72, 0x6f, 0x74, 0x6f)
o = (*z).Block.BlockHeader.UpgradeState.CurrentProtocol.MarshalMsg(o)
}
- if (zb0004Mask & 0x100000) == 0 { // if not empty
+ if (zb0005Mask & 0x400000) == 0 { // if not empty
+ // string "prp"
+ o = append(o, 0xa3, 0x70, 0x72, 0x70)
+ o = (*z).Block.BlockHeader.Proposer.MarshalMsg(o)
+ }
+ if (zb0005Mask & 0x800000) == 0 { // if not empty
// string "rate"
o = append(o, 0xa4, 0x72, 0x61, 0x74, 0x65)
o = msgp.AppendUint64(o, (*z).Block.BlockHeader.RewardsState.RewardsRate)
}
- if (zb0004Mask & 0x400000) == 0 { // if not empty
+ if (zb0005Mask & 0x2000000) == 0 { // if not empty
// string "rnd"
o = append(o, 0xa3, 0x72, 0x6e, 0x64)
o = (*z).Block.BlockHeader.Round.MarshalMsg(o)
}
- if (zb0004Mask & 0x800000) == 0 { // if not empty
+ if (zb0005Mask & 0x4000000) == 0 { // if not empty
// string "rwcalr"
o = append(o, 0xa6, 0x72, 0x77, 0x63, 0x61, 0x6c, 0x72)
o = (*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.MarshalMsg(o)
}
- if (zb0004Mask & 0x1000000) == 0 { // if not empty
+ if (zb0005Mask & 0x8000000) == 0 { // if not empty
// string "rwd"
o = append(o, 0xa3, 0x72, 0x77, 0x64)
o = (*z).Block.BlockHeader.RewardsState.RewardsPool.MarshalMsg(o)
}
- if (zb0004Mask & 0x2000000) == 0 { // if not empty
+ if (zb0005Mask & 0x10000000) == 0 { // if not empty
// string "sdpf"
o = append(o, 0xa4, 0x73, 0x64, 0x70, 0x66)
o = (*z).SeedProof.MarshalMsg(o)
}
- if (zb0004Mask & 0x4000000) == 0 { // if not empty
+ if (zb0005Mask & 0x20000000) == 0 { // if not empty
// string "seed"
o = append(o, 0xa4, 0x73, 0x65, 0x65, 0x64)
o = (*z).Block.BlockHeader.Seed.MarshalMsg(o)
}
- if (zb0004Mask & 0x8000000) == 0 { // if not empty
+ if (zb0005Mask & 0x40000000) == 0 { // if not empty
// string "spt"
o = append(o, 0xa3, 0x73, 0x70, 0x74)
if (*z).Block.BlockHeader.StateProofTracking == nil {
@@ -10764,42 +11048,42 @@ func (z *unauthenticatedProposal) MarshalMsg(b []byte) (o []byte) {
o = zb0002.MarshalMsg(o)
}
}
- if (zb0004Mask & 0x10000000) == 0 { // if not empty
+ if (zb0005Mask & 0x80000000) == 0 { // if not empty
// string "tc"
o = append(o, 0xa2, 0x74, 0x63)
o = msgp.AppendUint64(o, (*z).Block.BlockHeader.TxnCounter)
}
- if (zb0004Mask & 0x20000000) == 0 { // if not empty
+ if (zb0005Mask & 0x100000000) == 0 { // if not empty
// string "ts"
o = append(o, 0xa2, 0x74, 0x73)
o = msgp.AppendInt64(o, (*z).Block.BlockHeader.TimeStamp)
}
- if (zb0004Mask & 0x40000000) == 0 { // if not empty
+ if (zb0005Mask & 0x200000000) == 0 { // if not empty
// string "txn"
o = append(o, 0xa3, 0x74, 0x78, 0x6e)
o = (*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MarshalMsg(o)
}
- if (zb0004Mask & 0x80000000) == 0 { // if not empty
+ if (zb0005Mask & 0x400000000) == 0 { // if not empty
// string "txn256"
o = append(o, 0xa6, 0x74, 0x78, 0x6e, 0x32, 0x35, 0x36)
o = (*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.MarshalMsg(o)
}
- if (zb0004Mask & 0x100000000) == 0 { // if not empty
+ if (zb0005Mask & 0x800000000) == 0 { // if not empty
// string "txns"
o = append(o, 0xa4, 0x74, 0x78, 0x6e, 0x73)
o = (*z).Block.Payset.MarshalMsg(o)
}
- if (zb0004Mask & 0x200000000) == 0 { // if not empty
+ if (zb0005Mask & 0x1000000000) == 0 { // if not empty
// string "upgradedelay"
o = append(o, 0xac, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x65, 0x6c, 0x61, 0x79)
o = (*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.MarshalMsg(o)
}
- if (zb0004Mask & 0x400000000) == 0 { // if not empty
+ if (zb0005Mask & 0x2000000000) == 0 { // if not empty
// string "upgradeprop"
o = append(o, 0xab, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x70, 0x72, 0x6f, 0x70)
o = (*z).Block.BlockHeader.UpgradeVote.UpgradePropose.MarshalMsg(o)
}
- if (zb0004Mask & 0x800000000) == 0 { // if not empty
+ if (zb0005Mask & 0x4000000000) == 0 { // if not empty
// string "upgradeyes"
o = append(o, 0xaa, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x65, 0x73)
o = msgp.AppendBool(o, (*z).Block.BlockHeader.UpgradeVote.UpgradeApprove)
@@ -10822,73 +11106,73 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma
st.AllowableDepth--
var field []byte
_ = field
- var zb0004 int
- var zb0005 bool
- zb0004, zb0005, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0005 int
+ var zb0006 bool
+ zb0005, zb0006, bts, err = msgp.ReadMapHeaderBytes(bts)
if _, ok := err.(msgp.TypeError); ok {
- zb0004, zb0005, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ zb0005, zb0006, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err)
return
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).Block.BlockHeader.Round.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Round")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).Block.BlockHeader.Branch.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Branch")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).Block.BlockHeader.Seed.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Seed")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NativeSha512_256Commitment")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Sha256Commitment")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).Block.BlockHeader.TimeStamp, bts, err = msgp.ReadInt64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "TimeStamp")
return
}
}
- if zb0004 > 0 {
- zb0004--
- var zb0006 int
- zb0006, err = msgp.ReadBytesBytesHeader(bts)
+ if zb0005 > 0 {
+ zb0005--
+ var zb0007 int
+ zb0007, err = msgp.ReadBytesBytesHeader(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "GenesisID")
return
}
- if zb0006 > config.MaxGenesisIDLen {
- err = msgp.ErrOverflow(uint64(zb0006), uint64(config.MaxGenesisIDLen))
+ if zb0007 > config.MaxGenesisIDLen {
+ err = msgp.ErrOverflow(uint64(zb0007), uint64(config.MaxGenesisIDLen))
return
}
(*z).Block.BlockHeader.GenesisID, bts, err = msgp.ReadStringBytes(bts)
@@ -10897,157 +11181,173 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).Block.BlockHeader.GenesisHash.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "GenesisHash")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
+ bts, err = (*z).Block.BlockHeader.Proposer.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "Proposer")
+ return
+ }
+ }
+ if zb0005 > 0 {
+ zb0005--
+ bts, err = (*z).Block.BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "FeesCollected")
+ return
+ }
+ }
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).Block.BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "FeeSink")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).Block.BlockHeader.RewardsState.RewardsPool.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsPool")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).Block.BlockHeader.RewardsState.RewardsLevel, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsLevel")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).Block.BlockHeader.RewardsState.RewardsRate, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsRate")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).Block.BlockHeader.RewardsState.RewardsResidue, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsResidue")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsRecalculationRound")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).Block.BlockHeader.UpgradeState.CurrentProtocol.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "CurrentProtocol")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).Block.BlockHeader.UpgradeState.NextProtocol.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NextProtocol")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).Block.BlockHeader.UpgradeState.NextProtocolApprovals, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NextProtocolApprovals")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NextProtocolVoteBefore")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NextProtocolSwitchOn")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).Block.BlockHeader.UpgradeVote.UpgradePropose.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "UpgradePropose")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "UpgradeDelay")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).Block.BlockHeader.UpgradeVote.UpgradeApprove, bts, err = msgp.ReadBoolBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "UpgradeApprove")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).Block.BlockHeader.TxnCounter, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "TxnCounter")
return
}
}
- if zb0004 > 0 {
- zb0004--
- var zb0007 int
- var zb0008 bool
- zb0007, zb0008, bts, err = msgp.ReadMapHeaderBytes(bts)
+ if zb0005 > 0 {
+ zb0005--
+ var zb0008 int
+ var zb0009 bool
+ zb0008, zb0009, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "StateProofTracking")
return
}
- if zb0007 > protocol.NumStateProofTypes {
- err = msgp.ErrOverflow(uint64(zb0007), uint64(protocol.NumStateProofTypes))
+ if zb0008 > protocol.NumStateProofTypes {
+ err = msgp.ErrOverflow(uint64(zb0008), uint64(protocol.NumStateProofTypes))
err = msgp.WrapError(err, "struct-from-array", "StateProofTracking")
return
}
- if zb0008 {
+ if zb0009 {
(*z).Block.BlockHeader.StateProofTracking = nil
} else if (*z).Block.BlockHeader.StateProofTracking == nil {
- (*z).Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0007)
+ (*z).Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0008)
}
- for zb0007 > 0 {
+ for zb0008 > 0 {
var zb0001 protocol.StateProofType
var zb0002 bookkeeping.StateProofTrackingData
- zb0007--
+ zb0008--
bts, err = zb0001.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "StateProofTracking")
@@ -11061,26 +11361,26 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma
(*z).Block.BlockHeader.StateProofTracking[zb0001] = zb0002
}
}
- if zb0004 > 0 {
- zb0004--
- var zb0009 int
- var zb0010 bool
- zb0009, zb0010, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if zb0005 > 0 {
+ zb0005--
+ var zb0010 int
+ var zb0011 bool
+ zb0010, zb0011, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts")
return
}
- if zb0009 > config.MaxProposedExpiredOnlineAccounts {
- err = msgp.ErrOverflow(uint64(zb0009), uint64(config.MaxProposedExpiredOnlineAccounts))
+ if zb0010 > config.MaxProposedExpiredOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0010), uint64(config.MaxProposedExpiredOnlineAccounts))
err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts")
return
}
- if zb0010 {
+ if zb0011 {
(*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = nil
- } else if (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0009 {
- (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0009]
+ } else if (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0010 {
+ (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0010]
} else {
- (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0009)
+ (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0010)
}
for zb0003 := range (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts {
bts, err = (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].UnmarshalMsgWithState(bts, st)
@@ -11090,44 +11390,73 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma
}
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
+ var zb0012 int
+ var zb0013 bool
+ zb0012, zb0013, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts")
+ return
+ }
+ if zb0012 > config.MaxProposedAbsentOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0012), uint64(config.MaxProposedAbsentOnlineAccounts))
+ err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts")
+ return
+ }
+ if zb0013 {
+ (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = nil
+ } else if (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts != nil && cap((*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) >= zb0012 {
+ (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = ((*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts)[:zb0012]
+ } else {
+ (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = make([]basics.Address, zb0012)
+ }
+ for zb0004 := range (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts {
+ bts, err = (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts", zb0004)
+ return
+ }
+ }
+ }
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).Block.Payset.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Payset")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).SeedProof.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "SeedProof")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
{
- var zb0011 uint64
- zb0011, bts, err = msgp.ReadUint64Bytes(bts)
+ var zb0014 uint64
+ zb0014, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "OriginalPeriod")
return
}
- (*z).OriginalPeriod = period(zb0011)
+ (*z).OriginalPeriod = period(zb0014)
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).OriginalProposer.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "OriginalProposer")
return
}
}
- if zb0004 > 0 {
- err = msgp.ErrTooManyArrayFields(zb0004)
+ if zb0005 > 0 {
+ err = msgp.ErrTooManyArrayFields(zb0005)
if err != nil {
err = msgp.WrapError(err, "struct-from-array")
return
@@ -11138,11 +11467,11 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma
err = msgp.WrapError(err)
return
}
- if zb0005 {
+ if zb0006 {
(*z) = unauthenticatedProposal{}
}
- for zb0004 > 0 {
- zb0004--
+ for zb0005 > 0 {
+ zb0005--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
err = msgp.WrapError(err)
@@ -11186,14 +11515,14 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma
return
}
case "gen":
- var zb0012 int
- zb0012, err = msgp.ReadBytesBytesHeader(bts)
+ var zb0015 int
+ zb0015, err = msgp.ReadBytesBytesHeader(bts)
if err != nil {
err = msgp.WrapError(err, "GenesisID")
return
}
- if zb0012 > config.MaxGenesisIDLen {
- err = msgp.ErrOverflow(uint64(zb0012), uint64(config.MaxGenesisIDLen))
+ if zb0015 > config.MaxGenesisIDLen {
+ err = msgp.ErrOverflow(uint64(zb0015), uint64(config.MaxGenesisIDLen))
return
}
(*z).Block.BlockHeader.GenesisID, bts, err = msgp.ReadStringBytes(bts)
@@ -11207,6 +11536,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 {
@@ -11298,27 +11639,27 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma
return
}
case "spt":
- var zb0013 int
- var zb0014 bool
- zb0013, zb0014, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0016 int
+ var zb0017 bool
+ zb0016, zb0017, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "StateProofTracking")
return
}
- if zb0013 > protocol.NumStateProofTypes {
- err = msgp.ErrOverflow(uint64(zb0013), uint64(protocol.NumStateProofTypes))
+ if zb0016 > protocol.NumStateProofTypes {
+ err = msgp.ErrOverflow(uint64(zb0016), uint64(protocol.NumStateProofTypes))
err = msgp.WrapError(err, "StateProofTracking")
return
}
- if zb0014 {
+ if zb0017 {
(*z).Block.BlockHeader.StateProofTracking = nil
} else if (*z).Block.BlockHeader.StateProofTracking == nil {
- (*z).Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0013)
+ (*z).Block.BlockHeader.StateProofTracking = make(map[protocol.StateProofType]bookkeeping.StateProofTrackingData, zb0016)
}
- for zb0013 > 0 {
+ for zb0016 > 0 {
var zb0001 protocol.StateProofType
var zb0002 bookkeeping.StateProofTrackingData
- zb0013--
+ zb0016--
bts, err = zb0001.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "StateProofTracking")
@@ -11332,24 +11673,24 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma
(*z).Block.BlockHeader.StateProofTracking[zb0001] = zb0002
}
case "partupdrmv":
- var zb0015 int
- var zb0016 bool
- zb0015, zb0016, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ var zb0018 int
+ var zb0019 bool
+ zb0018, zb0019, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "ExpiredParticipationAccounts")
return
}
- if zb0015 > config.MaxProposedExpiredOnlineAccounts {
- err = msgp.ErrOverflow(uint64(zb0015), uint64(config.MaxProposedExpiredOnlineAccounts))
+ if zb0018 > config.MaxProposedExpiredOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0018), uint64(config.MaxProposedExpiredOnlineAccounts))
err = msgp.WrapError(err, "ExpiredParticipationAccounts")
return
}
- if zb0016 {
+ if zb0019 {
(*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = nil
- } else if (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0015 {
- (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0015]
+ } else if (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0018 {
+ (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0018]
} else {
- (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0015)
+ (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0018)
}
for zb0003 := range (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts {
bts, err = (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].UnmarshalMsgWithState(bts, st)
@@ -11358,6 +11699,33 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma
return
}
}
+ case "partupdabs":
+ var zb0020 int
+ var zb0021 bool
+ zb0020, zb0021, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "AbsentParticipationAccounts")
+ return
+ }
+ if zb0020 > config.MaxProposedAbsentOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0020), uint64(config.MaxProposedAbsentOnlineAccounts))
+ err = msgp.WrapError(err, "AbsentParticipationAccounts")
+ return
+ }
+ if zb0021 {
+ (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = nil
+ } else if (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts != nil && cap((*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) >= zb0020 {
+ (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = ((*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts)[:zb0020]
+ } else {
+ (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = make([]basics.Address, zb0020)
+ }
+ for zb0004 := range (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts {
+ bts, err = (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "AbsentParticipationAccounts", zb0004)
+ return
+ }
+ }
case "txns":
bts, err = (*z).Block.Payset.UnmarshalMsgWithState(bts, st)
if err != nil {
@@ -11372,13 +11740,13 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma
}
case "oper":
{
- var zb0017 uint64
- zb0017, bts, err = msgp.ReadUint64Bytes(bts)
+ var zb0022 uint64
+ zb0022, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "OriginalPeriod")
return
}
- (*z).OriginalPeriod = period(zb0017)
+ (*z).OriginalPeriod = period(zb0022)
}
case "oprop":
bts, err = (*z).OriginalProposer.UnmarshalMsgWithState(bts, st)
@@ -11409,7 +11777,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
@@ -11421,18 +11789,22 @@ func (z *unauthenticatedProposal) Msgsize() (s int) {
for zb0003 := range (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts {
s += (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].Msgsize()
}
+ s += 11 + msgp.ArrayHeaderSize
+ for zb0004 := range (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts {
+ s += (*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].Msgsize()
+ }
s += 5 + (*z).Block.Payset.Msgsize() + 5 + (*z).SeedProof.Msgsize() + 5 + msgp.Uint64Size + 6 + (*z).OriginalProposer.Msgsize()
return
}
// MsgIsZero returns whether this is a zero value
func (z *unauthenticatedProposal) MsgIsZero() bool {
- return ((*z).Block.BlockHeader.Round.MsgIsZero()) && ((*z).Block.BlockHeader.Branch.MsgIsZero()) && ((*z).Block.BlockHeader.Seed.MsgIsZero()) && ((*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).Block.BlockHeader.TimeStamp == 0) && ((*z).Block.BlockHeader.GenesisID == "") && ((*z).Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).Block.BlockHeader.TxnCounter == 0) && (len((*z).Block.BlockHeader.StateProofTracking) == 0) && (len((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).Block.Payset.MsgIsZero()) && ((*z).SeedProof.MsgIsZero()) && ((*z).OriginalPeriod == 0) && ((*z).OriginalProposer.MsgIsZero())
+ return ((*z).Block.BlockHeader.Round.MsgIsZero()) && ((*z).Block.BlockHeader.Branch.MsgIsZero()) && ((*z).Block.BlockHeader.Seed.MsgIsZero()) && ((*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).Block.BlockHeader.TimeStamp == 0) && ((*z).Block.BlockHeader.GenesisID == "") && ((*z).Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).Block.BlockHeader.Proposer.MsgIsZero()) && ((*z).Block.BlockHeader.FeesCollected.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).Block.BlockHeader.TxnCounter == 0) && (len((*z).Block.BlockHeader.StateProofTracking) == 0) && (len((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && (len((*z).Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) == 0) && ((*z).Block.Payset.MsgIsZero()) && ((*z).SeedProof.MsgIsZero()) && ((*z).OriginalPeriod == 0) && ((*z).OriginalProposer.MsgIsZero())
}
// MaxSize returns a maximum valid message size for this message type
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())
@@ -11441,6 +11813,9 @@ func UnauthenticatedProposalMaxSize() (s int) {
s += 11
// Calculating size of slice: z.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts
s += msgp.ArrayHeaderSize + ((config.MaxProposedExpiredOnlineAccounts) * (basics.AddressMaxSize()))
+ s += 11
+ // Calculating size of slice: z.Block.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts
+ s += msgp.ArrayHeaderSize + ((config.MaxProposedAbsentOnlineAccounts) * (basics.AddressMaxSize()))
s += 5
// Using maxtotalbytes for: z.Block.Payset
s += config.MaxTxnBytesPerBlock
diff --git a/agreement/proposal.go b/agreement/proposal.go
index bf021f2cfe..51e1407f99 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/cmd/goal/accountsList.go b/cmd/goal/accountsList.go
index 390d3b2b07..2a0f43203d 100644
--- a/cmd/goal/accountsList.go
+++ b/cmd/goal/accountsList.go
@@ -216,6 +216,8 @@ func (accountList *AccountsList) outputAccount(addr string, acctInfo model.Accou
status = "offline"
case basics.NotParticipating.String():
status = "excluded"
+ case basics.Suspended.String():
+ status = "suspended"
default:
panic(fmt.Sprintf("unexpected account status: %v", acctInfo.Status))
}
diff --git a/cmd/incorporate/incorporate.go b/cmd/incorporate/incorporate.go
index 97d4b44d66..7256dcdff7 100644
--- a/cmd/incorporate/incorporate.go
+++ b/cmd/incorporate/incorporate.go
@@ -235,6 +235,8 @@ func parseRecord(cols []string) (rec record) {
rec.Status = basics.Offline
case "NotParticipating":
rec.Status = basics.NotParticipating
+ case "Suspended":
+ rec.Status = basics.Suspended
default:
log.Fatalf("unknown status: %s", cols[3])
}
diff --git a/config/consensus.go b/config/consensus.go
index c3592e40d9..db526c34e5 100644
--- a/config/consensus.go
+++ b/config/consensus.go
@@ -440,10 +440,14 @@ type ConsensusParams struct {
EnableExtraPagesOnAppUpdate bool
- // MaxProposedExpiredOnlineAccounts is the maximum number of online accounts, which need
- // to be taken offline, that would be proposed to be taken offline.
+ // MaxProposedExpiredOnlineAccounts is the maximum number of online accounts
+ // that a proposer can take offline for having expired voting keys.
MaxProposedExpiredOnlineAccounts int
+ // MaxProposedAbsentOnlineAccounts is the maximum number of online accounts,
+ // that a proposer can suspend for not proposing "lately" (TBD)
+ MaxProposedAbsentOnlineAccounts int
+
// EnableAccountDataResourceSeparation enables the support for extended application and asset storage
// in a separate table.
EnableAccountDataResourceSeparation bool
@@ -522,6 +526,19 @@ 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
+}
+
+// EnableAbsenteeTracking returns true if the suspension mechanism of absentee
+// accounts is enabled.
+func (cp ConsensusParams) EnableAbsenteeTracking() bool {
+ return cp.MaxProposedAbsentOnlineAccounts > 0
}
// PaysetCommitType enumerates possible ways for the block header to commit to
@@ -596,10 +613,14 @@ var MaxExtraAppProgramLen int
// supported supported by any of the consensus protocols. used for decoding purposes.
var MaxAvailableAppProgramLen int
-// MaxProposedExpiredOnlineAccounts is the maximum number of online accounts, which need
-// to be taken offline, that would be proposed to be taken offline.
+// MaxProposedExpiredOnlineAccounts is the maximum number of online accounts
+// that a proposer can take offline for having expired voting keys.
var MaxProposedExpiredOnlineAccounts int
+// MaxProposedAbsentOnlineAccounts is the maximum number of online accounts,
+// that a proposer can suspend for not proposing "lately" (TBD)
+var MaxProposedAbsentOnlineAccounts int
+
// MaxAppTotalArgLen is the maximum number of bytes across all arguments of an application
// max sum([len(arg) for arg in txn.ApplicationArgs])
var MaxAppTotalArgLen int
@@ -670,6 +691,7 @@ func checkSetAllocBounds(p ConsensusParams) {
checkSetMax(p.MaxAppProgramLen, &MaxLogCalls)
checkSetMax(p.MaxInnerTransactions*p.MaxTxGroupSize, &MaxInnerTransactionsPerDelta)
checkSetMax(p.MaxProposedExpiredOnlineAccounts, &MaxProposedExpiredOnlineAccounts)
+ checkSetMax(p.MaxProposedAbsentOnlineAccounts, &MaxProposedAbsentOnlineAccounts)
// These bounds are exported to make them available to the msgp generator for calculating
// maximum valid message size for each message going across the wire.
@@ -1372,10 +1394,15 @@ func initConsensusProtocols() {
vFuture.LogicSigVersion = 10 // When moving this to a release, put a new higher LogicSigVersion here
vFuture.EnableLogicSigCostPooling = true
+ vFuture.MaxProposedAbsentOnlineAccounts = 32
+
// Setting DynamicFilterTimeout in vFuture will impact e2e test performance
// by reducing round time. Hence, it is commented out for now.
// vFuture.DynamicFilterTimeout = true
+ 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/crypto/onetimesig.go b/crypto/onetimesig.go
index 1de4854967..f85f8cca1a 100644
--- a/crypto/onetimesig.go
+++ b/crypto/onetimesig.go
@@ -304,6 +304,11 @@ func (s *OneTimeSignatureSecrets) Sign(id OneTimeSignatureIdentifier, message Ha
return OneTimeSignature{}
}
+// IsEmpty returns true is the verifier is empty/zero'd.
+func (v OneTimeSignatureVerifier) IsEmpty() bool {
+ return v == OneTimeSignatureVerifier{}
+}
+
// Verify verifies that some Hashable signature was signed under some
// OneTimeSignatureVerifier and some OneTimeSignatureIdentifier.
//
diff --git a/crypto/vrf.go b/crypto/vrf.go
index 948a84ddc5..a9a8af68d5 100644
--- a/crypto/vrf.go
+++ b/crypto/vrf.go
@@ -134,6 +134,11 @@ func (pk VrfPubkey) verifyBytes(proof VrfProof, msg []byte) (bool, VrfOutput) {
return ret == 0, out
}
+// IsEmpty returns true is the key is empty/zero'd.
+func (pk VrfPubkey) IsEmpty() bool {
+ return pk == VrfPubkey{}
+}
+
// Verify checks a VRF proof of a given Hashable. If the proof is valid the pseudorandom VrfOutput will be returned.
// For a given public key and message, there are potentially multiple valid proofs.
// However, given a public key and message, all valid proofs will yield the same output.
diff --git a/daemon/algod/api/Makefile b/daemon/algod/api/Makefile
index c4104d9e80..c45093e6b4 100644
--- a/daemon/algod/api/Makefile
+++ b/daemon/algod/api/Makefile
@@ -30,6 +30,7 @@ server/v2/generated/model/types.go: algod.oas3.yml
$(GOPATH1)/bin/oapi-codegen -config ./server/v2/generated/model/model_types.yml algod.oas3.yml
algod.oas3.yml: algod.oas2.json
+ jq < algod.oas2.json # fail with a nice explantion if json is malformed
curl -s -X POST "https://converter.swagger.io/api/convert" -H "accept: application/json" -H "Content-Type: application/json" -d @./algod.oas2.json -o .3tmp.json
python3 jsoncanon.py < .3tmp.json > algod.oas3.yml
rm -f .3tmp.json
diff --git a/daemon/algod/api/algod.oas2.json b/daemon/algod/api/algod.oas2.json
index b37f2001c4..c51902064f 100644
--- a/daemon/algod/api/algod.oas2.json
+++ b/daemon/algod/api/algod.oas2.json
@@ -3016,6 +3016,14 @@
"description": "\\[spend\\] the address against which signing should be checked. If empty, the address of the current account is used. This field can be updated in any transaction by setting the RekeyTo field.",
"type": "string",
"x-algorand-format": "Address"
+ },
+ "last-proposed": {
+ "description": "The round in which this account last proposed the block.",
+ "type": "integer"
+ },
+ "last-heartbeat": {
+ "description": "The round in which this account last went online, or explicitly renewed their online status.",
+ "type": "integer"
}
}
},
diff --git a/daemon/algod/api/algod.oas3.yml b/daemon/algod/api/algod.oas3.yml
index c8c82e0d98..bb7508bb43 100644
--- a/daemon/algod/api/algod.oas3.yml
+++ b/daemon/algod/api/algod.oas3.yml
@@ -1067,6 +1067,14 @@
},
"type": "array"
},
+ "last-heartbeat": {
+ "description": "The round in which this account last went online, or explicitly renewed their online status.",
+ "type": "integer"
+ },
+ "last-proposed": {
+ "description": "The round in which this account last proposed the block.",
+ "type": "integer"
+ },
"min-balance": {
"description": "MicroAlgo balance required by the account.\n\nThe requirement grows based on asset and application usage.",
"type": "integer"
diff --git a/daemon/algod/api/server/v2/account.go b/daemon/algod/api/server/v2/account.go
index 31483d63b9..84045439a8 100644
--- a/daemon/algod/api/server/v2/account.go
+++ b/daemon/algod/api/server/v2/account.go
@@ -67,7 +67,7 @@ func AccountDataToAccount(
})
var apiParticipation *model.AccountParticipation
- if record.VoteID != (crypto.OneTimeSignatureVerifier{}) {
+ if !record.VoteID.IsEmpty() {
apiParticipation = &model.AccountParticipation{
VoteParticipationKey: record.VoteID[:],
SelectionParticipationKey: record.SelectionID[:],
@@ -137,6 +137,8 @@ func AccountDataToAccount(
TotalBoxes: omitEmpty(record.TotalBoxes),
TotalBoxBytes: omitEmpty(record.TotalBoxBytes),
MinBalance: minBalance.Raw,
+ LastProposed: omitEmpty(uint64(record.LastProposed)),
+ LastHeartbeat: omitEmpty(uint64(record.LastHeartbeat)),
}, nil
}
@@ -340,6 +342,16 @@ func AccountToAccountData(a *model.Account) (basics.AccountData, error) {
totalBoxBytes = *a.TotalBoxBytes
}
+ var lastProposed uint64
+ if a.LastProposed != nil {
+ lastProposed = *a.LastProposed
+ }
+
+ var lastHeartbeat uint64
+ if a.LastHeartbeat != nil {
+ lastHeartbeat = *a.LastHeartbeat
+ }
+
status, err := basics.UnmarshalStatus(a.Status)
if err != nil {
return basics.AccountData{}, err
@@ -362,6 +374,8 @@ func AccountToAccountData(a *model.Account) (basics.AccountData, error) {
TotalExtraAppPages: totalExtraPages,
TotalBoxes: totalBoxes,
TotalBoxBytes: totalBoxBytes,
+ LastProposed: basics.Round(lastProposed),
+ LastHeartbeat: basics.Round(lastHeartbeat),
}
if a.AuthAddr != nil {
diff --git a/daemon/algod/api/server/v2/generated/data/routes.go b/daemon/algod/api/server/v2/generated/data/routes.go
index 9fd389f273..0c4722b9a6 100644
--- a/daemon/algod/api/server/v2/generated/data/routes.go
+++ b/daemon/algod/api/server/v2/generated/data/routes.go
@@ -192,132 +192,133 @@ var swaggerSpec = []string{
"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",
- "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",
- "AA==",
+ "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",
+ "AAA=",
}
// GetSwagger returns the content of the embedded swagger specification file
diff --git a/daemon/algod/api/server/v2/generated/experimental/routes.go b/daemon/algod/api/server/v2/generated/experimental/routes.go
index 1888e71ef1..b27b87907c 100644
--- a/daemon/algod/api/server/v2/generated/experimental/routes.go
+++ b/daemon/algod/api/server/v2/generated/experimental/routes.go
@@ -90,210 +90,211 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
// Base64 encoded, gzipped, json marshaled Swagger object
var swaggerSpec = []string{
- "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",
- "JZpUkq0x7+7Hz/83AAD//8gL9x7v8QAA",
+ "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",
+ "WaJJJdka8+6+//h/AwAA//8xVaDS7PIAAA==",
}
// GetSwagger returns the content of the embedded swagger specification file
diff --git a/daemon/algod/api/server/v2/generated/model/types.go b/daemon/algod/api/server/v2/generated/model/types.go
index c30caa6c94..c99830a35a 100644
--- a/daemon/algod/api/server/v2/generated/model/types.go
+++ b/daemon/algod/api/server/v2/generated/model/types.go
@@ -185,6 +185,12 @@ type Account struct {
// Note: the raw account uses `map[int] -> Asset` for this type.
CreatedAssets *[]Asset `json:"created-assets,omitempty"`
+ // LastHeartbeat The round in which this account last went online, or explicitly renewed their online status.
+ LastHeartbeat *uint64 `json:"last-heartbeat,omitempty"`
+
+ // LastProposed The round in which this account last proposed the block.
+ LastProposed *uint64 `json:"last-proposed,omitempty"`
+
// MinBalance MicroAlgo balance required by the account.
//
// The requirement grows based on asset and application usage.
diff --git a/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go b/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go
index 3d3c20de36..0ecc35d394 100644
--- a/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go
+++ b/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go
@@ -140,211 +140,212 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
var swaggerSpec = []string{
"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",
- "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",
+ "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",
"AAA=",
}
diff --git a/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go b/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go
index 89202c3fb1..059f7ef6d9 100644
--- a/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go
+++ b/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go
@@ -802,208 +802,209 @@ var swaggerSpec = []string{
"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",
- "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",
+ "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",
}
// GetSwagger returns the content of the embedded swagger specification file
diff --git a/daemon/algod/api/server/v2/generated/participating/private/routes.go b/daemon/algod/api/server/v2/generated/participating/private/routes.go
index 79a65f5721..3ed2dcfedd 100644
--- a/daemon/algod/api/server/v2/generated/participating/private/routes.go
+++ b/daemon/algod/api/server/v2/generated/participating/private/routes.go
@@ -203,216 +203,217 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
// Base64 encoded, gzipped, json marshaled Swagger object
var swaggerSpec = []string{
- "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",
- "CB++b8jjQ3OPODL5+P7j/wsAAP//bjFnIYoHAQA=",
+ "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",
}
// GetSwagger returns the content of the embedded swagger specification file
diff --git a/daemon/algod/api/server/v2/generated/participating/public/routes.go b/daemon/algod/api/server/v2/generated/participating/public/routes.go
index 67e59f47b8..4d6fcda0f7 100644
--- a/daemon/algod/api/server/v2/generated/participating/public/routes.go
+++ b/daemon/algod/api/server/v2/generated/participating/public/routes.go
@@ -255,143 +255,144 @@ var swaggerSpec = []string{
"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",
- "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",
+ "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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 065337f32d..c3e58c007a 100644
--- a/daemon/algod/api/server/v2/handlers.go
+++ b/daemon/algod/api/server/v2/handlers.go
@@ -494,7 +494,7 @@ func (v2 *Handlers) basicAccountInformation(ctx echo.Context, addr basics.Addres
}
var apiParticipation *model.AccountParticipation
- if record.VoteID != (crypto.OneTimeSignatureVerifier{}) {
+ if !record.VoteID.IsEmpty() {
apiParticipation = &model.AccountParticipation{
VoteParticipationKey: record.VoteID[:],
SelectionParticipationKey: record.SelectionID[:],
@@ -537,6 +537,8 @@ func (v2 *Handlers) basicAccountInformation(ctx echo.Context, addr basics.Addres
TotalBoxes: omitEmpty(record.TotalBoxes),
TotalBoxBytes: omitEmpty(record.TotalBoxBytes),
MinBalance: record.MinBalance(&consensus).Raw,
+ LastProposed: omitEmpty(uint64(record.LastProposed)),
+ LastHeartbeat: omitEmpty(uint64(record.LastHeartbeat)),
}
response := model.AccountResponse(account)
return ctx.JSON(http.StatusOK, response)
@@ -1396,10 +1398,7 @@ func (v2 *Handlers) getPendingTransactions(ctx echo.Context, max *uint64, format
}
// MatchAddress uses this to check FeeSink, we don't care about that here.
- spec := transactions.SpecialAddresses{
- FeeSink: basics.Address{},
- RewardsPool: basics.Address{},
- }
+ spec := transactions.SpecialAddresses{}
txnLimit := uint64(math.MaxUint64)
if max != nil && *max != 0 {
diff --git a/daemon/algod/api/server/v2/test/handlers_resources_test.go b/daemon/algod/api/server/v2/test/handlers_resources_test.go
index 1de86ddc19..fc764c2fa7 100644
--- a/daemon/algod/api/server/v2/test/handlers_resources_test.go
+++ b/daemon/algod/api/server/v2/test/handlers_resources_test.go
@@ -19,11 +19,12 @@ package test
import (
"encoding/json"
"fmt"
- "github.com/algorand/go-algorand/data/transactions/logic"
"net/http"
"net/http/httptest"
"testing"
+ "github.com/algorand/go-algorand/data/transactions/logic"
+
"github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
diff --git a/data/basics/fraction.go b/data/basics/fraction.go
new file mode 100644
index 0000000000..271da85265
--- /dev/null
+++ b/data/basics/fraction.go
@@ -0,0 +1,69 @@
+// Copyright (C) 2019-2023 Algorand, Inc.
+// This file is part of go-algorand
+//
+// go-algorand is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// go-algorand is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with go-algorand. If not, see .
+
+package basics
+
+import (
+ "fmt"
+)
+
+// Fraction represents the mathematical notion of rational number, but is much
+// simpler than `big.Rat`. It only supports numerators and denominators of
+// uint64.
+type Fraction struct {
+ Numerator uint64
+ Denominator uint64
+}
+
+// NewFraction creates the obvious Fraction, and checks that is not improper,
+// nor dives by zero.
+func NewFraction(numerator uint64, denominator uint64) Fraction {
+ if denominator == 0 {
+ panic("/0")
+ }
+ if numerator > denominator {
+ panic("improper fraction")
+ }
+ return Fraction{numerator, denominator}
+}
+
+// NewPercent creates a fraction reflecting the given percentage.
+func NewPercent(pct uint64) Fraction {
+ return NewFraction(pct, 100)
+}
+
+// String returns a string representation of Fraction
+func (frac Fraction) String() string {
+ return fmt.Sprintf("%d/%d", frac.Numerator, frac.Denominator)
+}
+
+// Divvy separates a quantity into two parts according to the fraction. The first
+// value is floor(q * frac), the second is q - first.
+func (frac Fraction) Divvy(q uint64) (uint64, uint64) {
+ // can't overflow on proper fractions
+ first, o := Muldiv(q, frac.Numerator, frac.Denominator)
+ if o {
+ panic("overflow")
+ }
+ second := q - first
+ return first, second
+}
+
+// DivvyAlgos is Divvy, but operates on MicroAlgos
+func (frac Fraction) DivvyAlgos(q MicroAlgos) (MicroAlgos, MicroAlgos) {
+ first, second := frac.Divvy(q.Raw)
+ return MicroAlgos{first}, MicroAlgos{second}
+}
diff --git a/data/basics/fraction_test.go b/data/basics/fraction_test.go
new file mode 100644
index 0000000000..9fad8dfa19
--- /dev/null
+++ b/data/basics/fraction_test.go
@@ -0,0 +1,76 @@
+// Copyright (C) 2019-2023 Algorand, Inc.
+// This file is part of go-algorand
+//
+// go-algorand is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// go-algorand is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with go-algorand. If not, see .
+
+package basics
+
+import (
+ "math"
+ "testing"
+
+ "github.com/algorand/go-algorand/test/partitiontest"
+ "github.com/stretchr/testify/require"
+)
+
+func TestFraction(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ t.Parallel()
+
+ third := Fraction{1, 3}
+ a, b := third.Divvy(6)
+ require.EqualValues(t, a, 2)
+ require.EqualValues(t, b, 4)
+
+ a, b = third.Divvy(10)
+ require.EqualValues(t, a, 3)
+ require.EqualValues(t, b, 7)
+}
+
+func TestFractionAvoidsOverflow(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ t.Parallel()
+
+ biggestEven := math.MaxUint64 - uint64(1)
+
+ half := Fraction{biggestEven / 2, biggestEven} // should operate as 1/2 even on large numbers
+ a, b := half.Divvy(6)
+ require.EqualValues(t, a, 3)
+ require.EqualValues(t, b, 3)
+
+ a, b = half.Divvy(biggestEven)
+ require.EqualValues(t, a, biggestEven/2)
+ require.EqualValues(t, b, biggestEven/2)
+
+ // ensure that overflow is avoided even if reduction isn't possible
+ uhalf := Fraction{biggestEven / 2, math.MaxUint64} // should be just under half
+ a, b = uhalf.Divvy(6)
+ require.EqualValues(t, a, 2)
+ require.EqualValues(t, b, 4)
+
+ a, b = uhalf.Divvy(biggestEven)
+ require.EqualValues(t, a, biggestEven/2-1)
+ require.EqualValues(t, b, biggestEven/2+1)
+
+ // and just to be super careful, ensure that there's also no reduction
+ // between q and the denominator by using a q that is relatively prime to
+ // math.MaxUint64
+
+ // prove 23 is relatively prime to math.MaxUint64
+ require.Positive(t, math.MaxUint64%23)
+
+ a, b = uhalf.Divvy(23)
+ require.EqualValues(t, a, 11)
+ require.EqualValues(t, b, 12)
+}
diff --git a/data/basics/msgp_gen.go b/data/basics/msgp_gen.go
index 06190153d6..7e60ace888 100644
--- a/data/basics/msgp_gen.go
+++ b/data/basics/msgp_gen.go
@@ -250,8 +250,8 @@ import (
func (z *AccountData) MarshalMsg(b []byte) (o []byte) {
o = msgp.Require(b, z.Msgsize())
// omitempty: check for empty values
- zb0009Len := uint32(19)
- var zb0009Mask uint32 /* 20 bits */
+ zb0009Len := uint32(21)
+ var zb0009Mask uint32 /* 22 bits */
if (*z).MicroAlgos.MsgIsZero() {
zb0009Len--
zb0009Mask |= 0x2
@@ -280,54 +280,62 @@ func (z *AccountData) MarshalMsg(b []byte) (o []byte) {
zb0009Len--
zb0009Mask |= 0x80
}
- if (*z).Status == 0 {
+ if (*z).LastHeartbeat == 0 {
zb0009Len--
zb0009Mask |= 0x100
}
- if (*z).SelectionID.MsgIsZero() {
+ if (*z).LastProposed == 0 {
zb0009Len--
zb0009Mask |= 0x200
}
- if (*z).AuthAddr.MsgIsZero() {
+ if (*z).Status == 0 {
zb0009Len--
zb0009Mask |= 0x400
}
- if (*z).StateProofID.MsgIsZero() {
+ if (*z).SelectionID.MsgIsZero() {
zb0009Len--
zb0009Mask |= 0x800
}
- if (*z).TotalBoxes == 0 {
+ if (*z).AuthAddr.MsgIsZero() {
zb0009Len--
zb0009Mask |= 0x1000
}
- if (*z).TotalBoxBytes == 0 {
+ if (*z).StateProofID.MsgIsZero() {
zb0009Len--
zb0009Mask |= 0x2000
}
- if (*z).TotalExtraAppPages == 0 {
+ if (*z).TotalBoxes == 0 {
zb0009Len--
zb0009Mask |= 0x4000
}
- if ((*z).TotalAppSchema.NumUint == 0) && ((*z).TotalAppSchema.NumByteSlice == 0) {
+ if (*z).TotalBoxBytes == 0 {
zb0009Len--
zb0009Mask |= 0x8000
}
- if (*z).VoteID.MsgIsZero() {
+ if (*z).TotalExtraAppPages == 0 {
zb0009Len--
zb0009Mask |= 0x10000
}
- if (*z).VoteFirstValid == 0 {
+ if ((*z).TotalAppSchema.NumUint == 0) && ((*z).TotalAppSchema.NumByteSlice == 0) {
zb0009Len--
zb0009Mask |= 0x20000
}
- if (*z).VoteKeyDilution == 0 {
+ if (*z).VoteID.MsgIsZero() {
zb0009Len--
zb0009Mask |= 0x40000
}
- if (*z).VoteLastValid == 0 {
+ if (*z).VoteFirstValid == 0 {
zb0009Len--
zb0009Mask |= 0x80000
}
+ if (*z).VoteKeyDilution == 0 {
+ zb0009Len--
+ zb0009Mask |= 0x100000
+ }
+ if (*z).VoteLastValid == 0 {
+ zb0009Len--
+ zb0009Mask |= 0x200000
+ }
// variable map header, size zb0009Len
o = msgp.AppendMapHeader(o, zb0009Len)
if zb0009Len != 0 {
@@ -451,41 +459,51 @@ func (z *AccountData) MarshalMsg(b []byte) (o []byte) {
o = (*z).RewardedMicroAlgos.MarshalMsg(o)
}
if (zb0009Mask & 0x100) == 0 { // if not empty
+ // string "lhb"
+ o = append(o, 0xa3, 0x6c, 0x68, 0x62)
+ o = msgp.AppendUint64(o, uint64((*z).LastHeartbeat))
+ }
+ if (zb0009Mask & 0x200) == 0 { // if not empty
+ // string "lpr"
+ o = append(o, 0xa3, 0x6c, 0x70, 0x72)
+ o = msgp.AppendUint64(o, uint64((*z).LastProposed))
+ }
+ if (zb0009Mask & 0x400) == 0 { // if not empty
// string "onl"
o = append(o, 0xa3, 0x6f, 0x6e, 0x6c)
o = msgp.AppendByte(o, byte((*z).Status))
}
- if (zb0009Mask & 0x200) == 0 { // if not empty
+ if (zb0009Mask & 0x800) == 0 { // if not empty
// string "sel"
o = append(o, 0xa3, 0x73, 0x65, 0x6c)
o = (*z).SelectionID.MarshalMsg(o)
}
- if (zb0009Mask & 0x400) == 0 { // if not empty
+ if (zb0009Mask & 0x1000) == 0 { // if not empty
// string "spend"
o = append(o, 0xa5, 0x73, 0x70, 0x65, 0x6e, 0x64)
o = (*z).AuthAddr.MarshalMsg(o)
}
- if (zb0009Mask & 0x800) == 0 { // if not empty
+ if (zb0009Mask & 0x2000) == 0 { // if not empty
// string "stprf"
o = append(o, 0xa5, 0x73, 0x74, 0x70, 0x72, 0x66)
o = (*z).StateProofID.MarshalMsg(o)
}
- if (zb0009Mask & 0x1000) == 0 { // if not empty
+ if (zb0009Mask & 0x4000) == 0 { // if not empty
// string "tbx"
o = append(o, 0xa3, 0x74, 0x62, 0x78)
o = msgp.AppendUint64(o, (*z).TotalBoxes)
}
- if (zb0009Mask & 0x2000) == 0 { // if not empty
+ if (zb0009Mask & 0x8000) == 0 { // if not empty
// string "tbxb"
o = append(o, 0xa4, 0x74, 0x62, 0x78, 0x62)
o = msgp.AppendUint64(o, (*z).TotalBoxBytes)
}
- if (zb0009Mask & 0x4000) == 0 { // if not empty
+ if (zb0009Mask & 0x10000) == 0 { // if not empty
// string "teap"
o = append(o, 0xa4, 0x74, 0x65, 0x61, 0x70)
o = msgp.AppendUint32(o, (*z).TotalExtraAppPages)
}
- if (zb0009Mask & 0x8000) == 0 { // if not empty
+ if (zb0009Mask & 0x20000) == 0 { // if not empty
// string "tsch"
o = append(o, 0xa4, 0x74, 0x73, 0x63, 0x68)
// omitempty: check for empty values
@@ -512,22 +530,22 @@ func (z *AccountData) MarshalMsg(b []byte) (o []byte) {
o = msgp.AppendUint64(o, (*z).TotalAppSchema.NumUint)
}
}
- if (zb0009Mask & 0x10000) == 0 { // if not empty
+ if (zb0009Mask & 0x40000) == 0 { // if not empty
// string "vote"
o = append(o, 0xa4, 0x76, 0x6f, 0x74, 0x65)
o = (*z).VoteID.MarshalMsg(o)
}
- if (zb0009Mask & 0x20000) == 0 { // if not empty
+ if (zb0009Mask & 0x80000) == 0 { // if not empty
// string "voteFst"
o = append(o, 0xa7, 0x76, 0x6f, 0x74, 0x65, 0x46, 0x73, 0x74)
o = msgp.AppendUint64(o, uint64((*z).VoteFirstValid))
}
- if (zb0009Mask & 0x40000) == 0 { // if not empty
+ if (zb0009Mask & 0x100000) == 0 { // if not empty
// string "voteKD"
o = append(o, 0xa6, 0x76, 0x6f, 0x74, 0x65, 0x4b, 0x44)
o = msgp.AppendUint64(o, (*z).VoteKeyDilution)
}
- if (zb0009Mask & 0x80000) == 0 { // if not empty
+ if (zb0009Mask & 0x200000) == 0 { // if not empty
// string "voteLst"
o = append(o, 0xa7, 0x76, 0x6f, 0x74, 0x65, 0x4c, 0x73, 0x74)
o = msgp.AppendUint64(o, uint64((*z).VoteLastValid))
@@ -653,27 +671,51 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
}
if zb0009 > 0 {
zb0009--
- var zb0014 int
- var zb0015 bool
- zb0014, zb0015, bts, err = msgp.ReadMapHeaderBytes(bts)
+ {
+ var zb0014 uint64
+ zb0014, bts, err = msgp.ReadUint64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "LastProposed")
+ return
+ }
+ (*z).LastProposed = Round(zb0014)
+ }
+ }
+ if zb0009 > 0 {
+ zb0009--
+ {
+ var zb0015 uint64
+ zb0015, bts, err = msgp.ReadUint64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "LastHeartbeat")
+ return
+ }
+ (*z).LastHeartbeat = Round(zb0015)
+ }
+ }
+ if zb0009 > 0 {
+ zb0009--
+ var zb0016 int
+ var zb0017 bool
+ zb0016, zb0017, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "AssetParams")
return
}
- if zb0014 > encodedMaxAssetsPerAccount {
- err = msgp.ErrOverflow(uint64(zb0014), uint64(encodedMaxAssetsPerAccount))
+ if zb0016 > encodedMaxAssetsPerAccount {
+ err = msgp.ErrOverflow(uint64(zb0016), uint64(encodedMaxAssetsPerAccount))
err = msgp.WrapError(err, "struct-from-array", "AssetParams")
return
}
- if zb0015 {
+ if zb0017 {
(*z).AssetParams = nil
} else if (*z).AssetParams == nil {
- (*z).AssetParams = make(map[AssetIndex]AssetParams, zb0014)
+ (*z).AssetParams = make(map[AssetIndex]AssetParams, zb0016)
}
- for zb0014 > 0 {
+ for zb0016 > 0 {
var zb0001 AssetIndex
var zb0002 AssetParams
- zb0014--
+ zb0016--
bts, err = zb0001.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "AssetParams")
@@ -689,59 +731,59 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
}
if zb0009 > 0 {
zb0009--
- var zb0016 int
- var zb0017 bool
- zb0016, zb0017, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0018 int
+ var zb0019 bool
+ zb0018, zb0019, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Assets")
return
}
- if zb0016 > encodedMaxAssetsPerAccount {
- err = msgp.ErrOverflow(uint64(zb0016), uint64(encodedMaxAssetsPerAccount))
+ if zb0018 > encodedMaxAssetsPerAccount {
+ err = msgp.ErrOverflow(uint64(zb0018), uint64(encodedMaxAssetsPerAccount))
err = msgp.WrapError(err, "struct-from-array", "Assets")
return
}
- if zb0017 {
+ if zb0019 {
(*z).Assets = nil
} else if (*z).Assets == nil {
- (*z).Assets = make(map[AssetIndex]AssetHolding, zb0016)
+ (*z).Assets = make(map[AssetIndex]AssetHolding, zb0018)
}
- for zb0016 > 0 {
+ for zb0018 > 0 {
var zb0003 AssetIndex
var zb0004 AssetHolding
- zb0016--
+ zb0018--
bts, err = zb0003.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Assets")
return
}
- var zb0018 int
- var zb0019 bool
- zb0018, zb0019, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0020 int
+ var zb0021 bool
+ zb0020, zb0021, bts, err = msgp.ReadMapHeaderBytes(bts)
if _, ok := err.(msgp.TypeError); ok {
- zb0018, zb0019, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ zb0020, zb0021, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003)
return
}
- if zb0018 > 0 {
- zb0018--
+ if zb0020 > 0 {
+ zb0020--
zb0004.Amount, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003, "struct-from-array", "Amount")
return
}
}
- if zb0018 > 0 {
- zb0018--
+ if zb0020 > 0 {
+ zb0020--
zb0004.Frozen, bts, err = msgp.ReadBoolBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003, "struct-from-array", "Frozen")
return
}
}
- if zb0018 > 0 {
- err = msgp.ErrTooManyArrayFields(zb0018)
+ if zb0020 > 0 {
+ err = msgp.ErrTooManyArrayFields(zb0020)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003, "struct-from-array")
return
@@ -752,11 +794,11 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003)
return
}
- if zb0019 {
+ if zb0021 {
zb0004 = AssetHolding{}
}
- for zb0018 > 0 {
- zb0018--
+ for zb0020 > 0 {
+ zb0020--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003)
@@ -797,27 +839,27 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
}
if zb0009 > 0 {
zb0009--
- var zb0020 int
- var zb0021 bool
- zb0020, zb0021, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0022 int
+ var zb0023 bool
+ zb0022, zb0023, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "AppLocalStates")
return
}
- if zb0020 > EncodedMaxAppLocalStates {
- err = msgp.ErrOverflow(uint64(zb0020), uint64(EncodedMaxAppLocalStates))
+ if zb0022 > EncodedMaxAppLocalStates {
+ err = msgp.ErrOverflow(uint64(zb0022), uint64(EncodedMaxAppLocalStates))
err = msgp.WrapError(err, "struct-from-array", "AppLocalStates")
return
}
- if zb0021 {
+ if zb0023 {
(*z).AppLocalStates = nil
} else if (*z).AppLocalStates == nil {
- (*z).AppLocalStates = make(map[AppIndex]AppLocalState, zb0020)
+ (*z).AppLocalStates = make(map[AppIndex]AppLocalState, zb0022)
}
- for zb0020 > 0 {
+ for zb0022 > 0 {
var zb0005 AppIndex
var zb0006 AppLocalState
- zb0020--
+ zb0022--
bts, err = zb0005.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "AppLocalStates")
@@ -833,27 +875,27 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
}
if zb0009 > 0 {
zb0009--
- var zb0022 int
- var zb0023 bool
- zb0022, zb0023, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0024 int
+ var zb0025 bool
+ zb0024, zb0025, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "AppParams")
return
}
- if zb0022 > EncodedMaxAppParams {
- err = msgp.ErrOverflow(uint64(zb0022), uint64(EncodedMaxAppParams))
+ if zb0024 > EncodedMaxAppParams {
+ err = msgp.ErrOverflow(uint64(zb0024), uint64(EncodedMaxAppParams))
err = msgp.WrapError(err, "struct-from-array", "AppParams")
return
}
- if zb0023 {
+ if zb0025 {
(*z).AppParams = nil
} else if (*z).AppParams == nil {
- (*z).AppParams = make(map[AppIndex]AppParams, zb0022)
+ (*z).AppParams = make(map[AppIndex]AppParams, zb0024)
}
- for zb0022 > 0 {
+ for zb0024 > 0 {
var zb0007 AppIndex
var zb0008 AppParams
- zb0022--
+ zb0024--
bts, err = zb0007.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "AppParams")
@@ -869,33 +911,33 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
}
if zb0009 > 0 {
zb0009--
- var zb0024 int
- var zb0025 bool
- zb0024, zb0025, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0026 int
+ var zb0027 bool
+ zb0026, zb0027, bts, err = msgp.ReadMapHeaderBytes(bts)
if _, ok := err.(msgp.TypeError); ok {
- zb0024, zb0025, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ zb0026, zb0027, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema")
return
}
- if zb0024 > 0 {
- zb0024--
+ if zb0026 > 0 {
+ zb0026--
(*z).TotalAppSchema.NumUint, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema", "struct-from-array", "NumUint")
return
}
}
- if zb0024 > 0 {
- zb0024--
+ if zb0026 > 0 {
+ zb0026--
(*z).TotalAppSchema.NumByteSlice, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema", "struct-from-array", "NumByteSlice")
return
}
}
- if zb0024 > 0 {
- err = msgp.ErrTooManyArrayFields(zb0024)
+ if zb0026 > 0 {
+ err = msgp.ErrTooManyArrayFields(zb0026)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema", "struct-from-array")
return
@@ -906,11 +948,11 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema")
return
}
- if zb0025 {
+ if zb0027 {
(*z).TotalAppSchema = StateSchema{}
}
- for zb0024 > 0 {
- zb0024--
+ for zb0026 > 0 {
+ zb0026--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema")
@@ -988,13 +1030,13 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
switch string(field) {
case "onl":
{
- var zb0026 byte
- zb0026, bts, err = msgp.ReadByteBytes(bts)
+ var zb0028 byte
+ zb0028, bts, err = msgp.ReadByteBytes(bts)
if err != nil {
err = msgp.WrapError(err, "Status")
return
}
- (*z).Status = Status(zb0026)
+ (*z).Status = Status(zb0028)
}
case "algo":
bts, err = (*z).MicroAlgos.UnmarshalMsgWithState(bts, st)
@@ -1034,23 +1076,23 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
}
case "voteFst":
{
- var zb0027 uint64
- zb0027, bts, err = msgp.ReadUint64Bytes(bts)
+ var zb0029 uint64
+ zb0029, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "VoteFirstValid")
return
}
- (*z).VoteFirstValid = Round(zb0027)
+ (*z).VoteFirstValid = Round(zb0029)
}
case "voteLst":
{
- var zb0028 uint64
- zb0028, bts, err = msgp.ReadUint64Bytes(bts)
+ var zb0030 uint64
+ zb0030, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "VoteLastValid")
return
}
- (*z).VoteLastValid = Round(zb0028)
+ (*z).VoteLastValid = Round(zb0030)
}
case "voteKD":
(*z).VoteKeyDilution, bts, err = msgp.ReadUint64Bytes(bts)
@@ -1058,28 +1100,48 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
err = msgp.WrapError(err, "VoteKeyDilution")
return
}
+ case "lpr":
+ {
+ var zb0031 uint64
+ zb0031, bts, err = msgp.ReadUint64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "LastProposed")
+ return
+ }
+ (*z).LastProposed = Round(zb0031)
+ }
+ case "lhb":
+ {
+ var zb0032 uint64
+ zb0032, bts, err = msgp.ReadUint64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "LastHeartbeat")
+ return
+ }
+ (*z).LastHeartbeat = Round(zb0032)
+ }
case "apar":
- var zb0029 int
- var zb0030 bool
- zb0029, zb0030, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0033 int
+ var zb0034 bool
+ zb0033, zb0034, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "AssetParams")
return
}
- if zb0029 > encodedMaxAssetsPerAccount {
- err = msgp.ErrOverflow(uint64(zb0029), uint64(encodedMaxAssetsPerAccount))
+ if zb0033 > encodedMaxAssetsPerAccount {
+ err = msgp.ErrOverflow(uint64(zb0033), uint64(encodedMaxAssetsPerAccount))
err = msgp.WrapError(err, "AssetParams")
return
}
- if zb0030 {
+ if zb0034 {
(*z).AssetParams = nil
} else if (*z).AssetParams == nil {
- (*z).AssetParams = make(map[AssetIndex]AssetParams, zb0029)
+ (*z).AssetParams = make(map[AssetIndex]AssetParams, zb0033)
}
- for zb0029 > 0 {
+ for zb0033 > 0 {
var zb0001 AssetIndex
var zb0002 AssetParams
- zb0029--
+ zb0033--
bts, err = zb0001.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "AssetParams")
@@ -1093,59 +1155,59 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
(*z).AssetParams[zb0001] = zb0002
}
case "asset":
- var zb0031 int
- var zb0032 bool
- zb0031, zb0032, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0035 int
+ var zb0036 bool
+ zb0035, zb0036, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "Assets")
return
}
- if zb0031 > encodedMaxAssetsPerAccount {
- err = msgp.ErrOverflow(uint64(zb0031), uint64(encodedMaxAssetsPerAccount))
+ if zb0035 > encodedMaxAssetsPerAccount {
+ err = msgp.ErrOverflow(uint64(zb0035), uint64(encodedMaxAssetsPerAccount))
err = msgp.WrapError(err, "Assets")
return
}
- if zb0032 {
+ if zb0036 {
(*z).Assets = nil
} else if (*z).Assets == nil {
- (*z).Assets = make(map[AssetIndex]AssetHolding, zb0031)
+ (*z).Assets = make(map[AssetIndex]AssetHolding, zb0035)
}
- for zb0031 > 0 {
+ for zb0035 > 0 {
var zb0003 AssetIndex
var zb0004 AssetHolding
- zb0031--
+ zb0035--
bts, err = zb0003.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "Assets")
return
}
- var zb0033 int
- var zb0034 bool
- zb0033, zb0034, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0037 int
+ var zb0038 bool
+ zb0037, zb0038, bts, err = msgp.ReadMapHeaderBytes(bts)
if _, ok := err.(msgp.TypeError); ok {
- zb0033, zb0034, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ zb0037, zb0038, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "Assets", zb0003)
return
}
- if zb0033 > 0 {
- zb0033--
+ if zb0037 > 0 {
+ zb0037--
zb0004.Amount, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "Assets", zb0003, "struct-from-array", "Amount")
return
}
}
- if zb0033 > 0 {
- zb0033--
+ if zb0037 > 0 {
+ zb0037--
zb0004.Frozen, bts, err = msgp.ReadBoolBytes(bts)
if err != nil {
err = msgp.WrapError(err, "Assets", zb0003, "struct-from-array", "Frozen")
return
}
}
- if zb0033 > 0 {
- err = msgp.ErrTooManyArrayFields(zb0033)
+ if zb0037 > 0 {
+ err = msgp.ErrTooManyArrayFields(zb0037)
if err != nil {
err = msgp.WrapError(err, "Assets", zb0003, "struct-from-array")
return
@@ -1156,11 +1218,11 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
err = msgp.WrapError(err, "Assets", zb0003)
return
}
- if zb0034 {
+ if zb0038 {
zb0004 = AssetHolding{}
}
- for zb0033 > 0 {
- zb0033--
+ for zb0037 > 0 {
+ zb0037--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
err = msgp.WrapError(err, "Assets", zb0003)
@@ -1197,27 +1259,27 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
return
}
case "appl":
- var zb0035 int
- var zb0036 bool
- zb0035, zb0036, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0039 int
+ var zb0040 bool
+ zb0039, zb0040, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "AppLocalStates")
return
}
- if zb0035 > EncodedMaxAppLocalStates {
- err = msgp.ErrOverflow(uint64(zb0035), uint64(EncodedMaxAppLocalStates))
+ if zb0039 > EncodedMaxAppLocalStates {
+ err = msgp.ErrOverflow(uint64(zb0039), uint64(EncodedMaxAppLocalStates))
err = msgp.WrapError(err, "AppLocalStates")
return
}
- if zb0036 {
+ if zb0040 {
(*z).AppLocalStates = nil
} else if (*z).AppLocalStates == nil {
- (*z).AppLocalStates = make(map[AppIndex]AppLocalState, zb0035)
+ (*z).AppLocalStates = make(map[AppIndex]AppLocalState, zb0039)
}
- for zb0035 > 0 {
+ for zb0039 > 0 {
var zb0005 AppIndex
var zb0006 AppLocalState
- zb0035--
+ zb0039--
bts, err = zb0005.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "AppLocalStates")
@@ -1231,27 +1293,27 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
(*z).AppLocalStates[zb0005] = zb0006
}
case "appp":
- var zb0037 int
- var zb0038 bool
- zb0037, zb0038, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0041 int
+ var zb0042 bool
+ zb0041, zb0042, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "AppParams")
return
}
- if zb0037 > EncodedMaxAppParams {
- err = msgp.ErrOverflow(uint64(zb0037), uint64(EncodedMaxAppParams))
+ if zb0041 > EncodedMaxAppParams {
+ err = msgp.ErrOverflow(uint64(zb0041), uint64(EncodedMaxAppParams))
err = msgp.WrapError(err, "AppParams")
return
}
- if zb0038 {
+ if zb0042 {
(*z).AppParams = nil
} else if (*z).AppParams == nil {
- (*z).AppParams = make(map[AppIndex]AppParams, zb0037)
+ (*z).AppParams = make(map[AppIndex]AppParams, zb0041)
}
- for zb0037 > 0 {
+ for zb0041 > 0 {
var zb0007 AppIndex
var zb0008 AppParams
- zb0037--
+ zb0041--
bts, err = zb0007.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "AppParams")
@@ -1265,33 +1327,33 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
(*z).AppParams[zb0007] = zb0008
}
case "tsch":
- var zb0039 int
- var zb0040 bool
- zb0039, zb0040, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0043 int
+ var zb0044 bool
+ zb0043, zb0044, bts, err = msgp.ReadMapHeaderBytes(bts)
if _, ok := err.(msgp.TypeError); ok {
- zb0039, zb0040, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ zb0043, zb0044, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "TotalAppSchema")
return
}
- if zb0039 > 0 {
- zb0039--
+ if zb0043 > 0 {
+ zb0043--
(*z).TotalAppSchema.NumUint, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "TotalAppSchema", "struct-from-array", "NumUint")
return
}
}
- if zb0039 > 0 {
- zb0039--
+ if zb0043 > 0 {
+ zb0043--
(*z).TotalAppSchema.NumByteSlice, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "TotalAppSchema", "struct-from-array", "NumByteSlice")
return
}
}
- if zb0039 > 0 {
- err = msgp.ErrTooManyArrayFields(zb0039)
+ if zb0043 > 0 {
+ err = msgp.ErrTooManyArrayFields(zb0043)
if err != nil {
err = msgp.WrapError(err, "TotalAppSchema", "struct-from-array")
return
@@ -1302,11 +1364,11 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
err = msgp.WrapError(err, "TotalAppSchema")
return
}
- if zb0040 {
+ if zb0044 {
(*z).TotalAppSchema = StateSchema{}
}
- for zb0039 > 0 {
- zb0039--
+ for zb0043 > 0 {
+ zb0043--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
err = msgp.WrapError(err, "TotalAppSchema")
@@ -1375,7 +1437,7 @@ func (_ *AccountData) CanUnmarshalMsg(z interface{}) bool {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *AccountData) Msgsize() (s int) {
- s = 3 + 4 + msgp.ByteSize + 5 + (*z).MicroAlgos.Msgsize() + 6 + msgp.Uint64Size + 4 + (*z).RewardedMicroAlgos.Msgsize() + 5 + (*z).VoteID.Msgsize() + 4 + (*z).SelectionID.Msgsize() + 6 + (*z).StateProofID.Msgsize() + 8 + msgp.Uint64Size + 8 + msgp.Uint64Size + 7 + msgp.Uint64Size + 5 + msgp.MapHeaderSize
+ s = 3 + 4 + msgp.ByteSize + 5 + (*z).MicroAlgos.Msgsize() + 6 + msgp.Uint64Size + 4 + (*z).RewardedMicroAlgos.Msgsize() + 5 + (*z).VoteID.Msgsize() + 4 + (*z).SelectionID.Msgsize() + 6 + (*z).StateProofID.Msgsize() + 8 + msgp.Uint64Size + 8 + msgp.Uint64Size + 7 + msgp.Uint64Size + 4 + msgp.Uint64Size + 4 + msgp.Uint64Size + 5 + msgp.MapHeaderSize
if (*z).AssetParams != nil {
for zb0001, zb0002 := range (*z).AssetParams {
_ = zb0001
@@ -1413,12 +1475,12 @@ func (z *AccountData) Msgsize() (s int) {
// MsgIsZero returns whether this is a zero value
func (z *AccountData) MsgIsZero() bool {
- return ((*z).Status == 0) && ((*z).MicroAlgos.MsgIsZero()) && ((*z).RewardsBase == 0) && ((*z).RewardedMicroAlgos.MsgIsZero()) && ((*z).VoteID.MsgIsZero()) && ((*z).SelectionID.MsgIsZero()) && ((*z).StateProofID.MsgIsZero()) && ((*z).VoteFirstValid == 0) && ((*z).VoteLastValid == 0) && ((*z).VoteKeyDilution == 0) && (len((*z).AssetParams) == 0) && (len((*z).Assets) == 0) && ((*z).AuthAddr.MsgIsZero()) && (len((*z).AppLocalStates) == 0) && (len((*z).AppParams) == 0) && (((*z).TotalAppSchema.NumUint == 0) && ((*z).TotalAppSchema.NumByteSlice == 0)) && ((*z).TotalExtraAppPages == 0) && ((*z).TotalBoxes == 0) && ((*z).TotalBoxBytes == 0)
+ return ((*z).Status == 0) && ((*z).MicroAlgos.MsgIsZero()) && ((*z).RewardsBase == 0) && ((*z).RewardedMicroAlgos.MsgIsZero()) && ((*z).VoteID.MsgIsZero()) && ((*z).SelectionID.MsgIsZero()) && ((*z).StateProofID.MsgIsZero()) && ((*z).VoteFirstValid == 0) && ((*z).VoteLastValid == 0) && ((*z).VoteKeyDilution == 0) && ((*z).LastProposed == 0) && ((*z).LastHeartbeat == 0) && (len((*z).AssetParams) == 0) && (len((*z).Assets) == 0) && ((*z).AuthAddr.MsgIsZero()) && (len((*z).AppLocalStates) == 0) && (len((*z).AppParams) == 0) && (((*z).TotalAppSchema.NumUint == 0) && ((*z).TotalAppSchema.NumByteSlice == 0)) && ((*z).TotalExtraAppPages == 0) && ((*z).TotalBoxes == 0) && ((*z).TotalBoxBytes == 0)
}
// MaxSize returns a maximum valid message size for this message type
func AccountDataMaxSize() (s int) {
- s = 3 + 4 + msgp.ByteSize + 5 + MicroAlgosMaxSize() + 6 + msgp.Uint64Size + 4 + MicroAlgosMaxSize() + 5 + crypto.OneTimeSignatureVerifierMaxSize() + 4 + crypto.VRFVerifierMaxSize() + 6 + merklesignature.CommitmentMaxSize() + 8 + msgp.Uint64Size + 8 + msgp.Uint64Size + 7 + msgp.Uint64Size + 5
+ s = 3 + 4 + msgp.ByteSize + 5 + MicroAlgosMaxSize() + 6 + msgp.Uint64Size + 4 + MicroAlgosMaxSize() + 5 + crypto.OneTimeSignatureVerifierMaxSize() + 4 + crypto.VRFVerifierMaxSize() + 6 + merklesignature.CommitmentMaxSize() + 8 + msgp.Uint64Size + 8 + msgp.Uint64Size + 7 + msgp.Uint64Size + 4 + msgp.Uint64Size + 4 + msgp.Uint64Size + 5
s += msgp.MapHeaderSize
// Adding size of map keys for z.AssetParams
s += encodedMaxAssetsPerAccount * (AssetIndexMaxSize())
@@ -3199,8 +3261,8 @@ func AssetParamsMaxSize() (s int) {
func (z *BalanceRecord) MarshalMsg(b []byte) (o []byte) {
o = msgp.Require(b, z.Msgsize())
// omitempty: check for empty values
- zb0009Len := uint32(20)
- var zb0009Mask uint32 /* 22 bits */
+ zb0009Len := uint32(22)
+ var zb0009Mask uint32 /* 24 bits */
if (*z).Addr.MsgIsZero() {
zb0009Len--
zb0009Mask |= 0x4
@@ -3233,54 +3295,62 @@ func (z *BalanceRecord) MarshalMsg(b []byte) (o []byte) {
zb0009Len--
zb0009Mask |= 0x200
}
- if (*z).AccountData.Status == 0 {
+ if (*z).AccountData.LastHeartbeat == 0 {
zb0009Len--
zb0009Mask |= 0x400
}
- if (*z).AccountData.SelectionID.MsgIsZero() {
+ if (*z).AccountData.LastProposed == 0 {
zb0009Len--
zb0009Mask |= 0x800
}
- if (*z).AccountData.AuthAddr.MsgIsZero() {
+ if (*z).AccountData.Status == 0 {
zb0009Len--
zb0009Mask |= 0x1000
}
- if (*z).AccountData.StateProofID.MsgIsZero() {
+ if (*z).AccountData.SelectionID.MsgIsZero() {
zb0009Len--
zb0009Mask |= 0x2000
}
- if (*z).AccountData.TotalBoxes == 0 {
+ if (*z).AccountData.AuthAddr.MsgIsZero() {
zb0009Len--
zb0009Mask |= 0x4000
}
- if (*z).AccountData.TotalBoxBytes == 0 {
+ if (*z).AccountData.StateProofID.MsgIsZero() {
zb0009Len--
zb0009Mask |= 0x8000
}
- if (*z).AccountData.TotalExtraAppPages == 0 {
+ if (*z).AccountData.TotalBoxes == 0 {
zb0009Len--
zb0009Mask |= 0x10000
}
- if ((*z).AccountData.TotalAppSchema.NumUint == 0) && ((*z).AccountData.TotalAppSchema.NumByteSlice == 0) {
+ if (*z).AccountData.TotalBoxBytes == 0 {
zb0009Len--
zb0009Mask |= 0x20000
}
- if (*z).AccountData.VoteID.MsgIsZero() {
+ if (*z).AccountData.TotalExtraAppPages == 0 {
zb0009Len--
zb0009Mask |= 0x40000
}
- if (*z).AccountData.VoteFirstValid == 0 {
+ if ((*z).AccountData.TotalAppSchema.NumUint == 0) && ((*z).AccountData.TotalAppSchema.NumByteSlice == 0) {
zb0009Len--
zb0009Mask |= 0x80000
}
- if (*z).AccountData.VoteKeyDilution == 0 {
+ if (*z).AccountData.VoteID.MsgIsZero() {
zb0009Len--
zb0009Mask |= 0x100000
}
- if (*z).AccountData.VoteLastValid == 0 {
+ if (*z).AccountData.VoteFirstValid == 0 {
zb0009Len--
zb0009Mask |= 0x200000
}
+ if (*z).AccountData.VoteKeyDilution == 0 {
+ zb0009Len--
+ zb0009Mask |= 0x400000
+ }
+ if (*z).AccountData.VoteLastValid == 0 {
+ zb0009Len--
+ zb0009Mask |= 0x800000
+ }
// variable map header, size zb0009Len
o = msgp.AppendMapHeader(o, zb0009Len)
if zb0009Len != 0 {
@@ -3409,41 +3479,51 @@ func (z *BalanceRecord) MarshalMsg(b []byte) (o []byte) {
o = (*z).AccountData.RewardedMicroAlgos.MarshalMsg(o)
}
if (zb0009Mask & 0x400) == 0 { // if not empty
+ // string "lhb"
+ o = append(o, 0xa3, 0x6c, 0x68, 0x62)
+ o = msgp.AppendUint64(o, uint64((*z).AccountData.LastHeartbeat))
+ }
+ if (zb0009Mask & 0x800) == 0 { // if not empty
+ // string "lpr"
+ o = append(o, 0xa3, 0x6c, 0x70, 0x72)
+ o = msgp.AppendUint64(o, uint64((*z).AccountData.LastProposed))
+ }
+ if (zb0009Mask & 0x1000) == 0 { // if not empty
// string "onl"
o = append(o, 0xa3, 0x6f, 0x6e, 0x6c)
o = msgp.AppendByte(o, byte((*z).AccountData.Status))
}
- if (zb0009Mask & 0x800) == 0 { // if not empty
+ if (zb0009Mask & 0x2000) == 0 { // if not empty
// string "sel"
o = append(o, 0xa3, 0x73, 0x65, 0x6c)
o = (*z).AccountData.SelectionID.MarshalMsg(o)
}
- if (zb0009Mask & 0x1000) == 0 { // if not empty
+ if (zb0009Mask & 0x4000) == 0 { // if not empty
// string "spend"
o = append(o, 0xa5, 0x73, 0x70, 0x65, 0x6e, 0x64)
o = (*z).AccountData.AuthAddr.MarshalMsg(o)
}
- if (zb0009Mask & 0x2000) == 0 { // if not empty
+ if (zb0009Mask & 0x8000) == 0 { // if not empty
// string "stprf"
o = append(o, 0xa5, 0x73, 0x74, 0x70, 0x72, 0x66)
o = (*z).AccountData.StateProofID.MarshalMsg(o)
}
- if (zb0009Mask & 0x4000) == 0 { // if not empty
+ if (zb0009Mask & 0x10000) == 0 { // if not empty
// string "tbx"
o = append(o, 0xa3, 0x74, 0x62, 0x78)
o = msgp.AppendUint64(o, (*z).AccountData.TotalBoxes)
}
- if (zb0009Mask & 0x8000) == 0 { // if not empty
+ if (zb0009Mask & 0x20000) == 0 { // if not empty
// string "tbxb"
o = append(o, 0xa4, 0x74, 0x62, 0x78, 0x62)
o = msgp.AppendUint64(o, (*z).AccountData.TotalBoxBytes)
}
- if (zb0009Mask & 0x10000) == 0 { // if not empty
+ if (zb0009Mask & 0x40000) == 0 { // if not empty
// string "teap"
o = append(o, 0xa4, 0x74, 0x65, 0x61, 0x70)
o = msgp.AppendUint32(o, (*z).AccountData.TotalExtraAppPages)
}
- if (zb0009Mask & 0x20000) == 0 { // if not empty
+ if (zb0009Mask & 0x80000) == 0 { // if not empty
// string "tsch"
o = append(o, 0xa4, 0x74, 0x73, 0x63, 0x68)
// omitempty: check for empty values
@@ -3470,22 +3550,22 @@ func (z *BalanceRecord) MarshalMsg(b []byte) (o []byte) {
o = msgp.AppendUint64(o, (*z).AccountData.TotalAppSchema.NumUint)
}
}
- if (zb0009Mask & 0x40000) == 0 { // if not empty
+ if (zb0009Mask & 0x100000) == 0 { // if not empty
// string "vote"
o = append(o, 0xa4, 0x76, 0x6f, 0x74, 0x65)
o = (*z).AccountData.VoteID.MarshalMsg(o)
}
- if (zb0009Mask & 0x80000) == 0 { // if not empty
+ if (zb0009Mask & 0x200000) == 0 { // if not empty
// string "voteFst"
o = append(o, 0xa7, 0x76, 0x6f, 0x74, 0x65, 0x46, 0x73, 0x74)
o = msgp.AppendUint64(o, uint64((*z).AccountData.VoteFirstValid))
}
- if (zb0009Mask & 0x100000) == 0 { // if not empty
+ if (zb0009Mask & 0x400000) == 0 { // if not empty
// string "voteKD"
o = append(o, 0xa6, 0x76, 0x6f, 0x74, 0x65, 0x4b, 0x44)
o = msgp.AppendUint64(o, (*z).AccountData.VoteKeyDilution)
}
- if (zb0009Mask & 0x200000) == 0 { // if not empty
+ if (zb0009Mask & 0x800000) == 0 { // if not empty
// string "voteLst"
o = append(o, 0xa7, 0x76, 0x6f, 0x74, 0x65, 0x4c, 0x73, 0x74)
o = msgp.AppendUint64(o, uint64((*z).AccountData.VoteLastValid))
@@ -3619,27 +3699,51 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState
}
if zb0009 > 0 {
zb0009--
- var zb0014 int
- var zb0015 bool
- zb0014, zb0015, bts, err = msgp.ReadMapHeaderBytes(bts)
+ {
+ var zb0014 uint64
+ zb0014, bts, err = msgp.ReadUint64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "LastProposed")
+ return
+ }
+ (*z).AccountData.LastProposed = Round(zb0014)
+ }
+ }
+ if zb0009 > 0 {
+ zb0009--
+ {
+ var zb0015 uint64
+ zb0015, bts, err = msgp.ReadUint64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "LastHeartbeat")
+ return
+ }
+ (*z).AccountData.LastHeartbeat = Round(zb0015)
+ }
+ }
+ if zb0009 > 0 {
+ zb0009--
+ var zb0016 int
+ var zb0017 bool
+ zb0016, zb0017, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "AssetParams")
return
}
- if zb0014 > encodedMaxAssetsPerAccount {
- err = msgp.ErrOverflow(uint64(zb0014), uint64(encodedMaxAssetsPerAccount))
+ if zb0016 > encodedMaxAssetsPerAccount {
+ err = msgp.ErrOverflow(uint64(zb0016), uint64(encodedMaxAssetsPerAccount))
err = msgp.WrapError(err, "struct-from-array", "AssetParams")
return
}
- if zb0015 {
+ if zb0017 {
(*z).AccountData.AssetParams = nil
} else if (*z).AccountData.AssetParams == nil {
- (*z).AccountData.AssetParams = make(map[AssetIndex]AssetParams, zb0014)
+ (*z).AccountData.AssetParams = make(map[AssetIndex]AssetParams, zb0016)
}
- for zb0014 > 0 {
+ for zb0016 > 0 {
var zb0001 AssetIndex
var zb0002 AssetParams
- zb0014--
+ zb0016--
bts, err = zb0001.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "AssetParams")
@@ -3655,59 +3759,59 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState
}
if zb0009 > 0 {
zb0009--
- var zb0016 int
- var zb0017 bool
- zb0016, zb0017, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0018 int
+ var zb0019 bool
+ zb0018, zb0019, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Assets")
return
}
- if zb0016 > encodedMaxAssetsPerAccount {
- err = msgp.ErrOverflow(uint64(zb0016), uint64(encodedMaxAssetsPerAccount))
+ if zb0018 > encodedMaxAssetsPerAccount {
+ err = msgp.ErrOverflow(uint64(zb0018), uint64(encodedMaxAssetsPerAccount))
err = msgp.WrapError(err, "struct-from-array", "Assets")
return
}
- if zb0017 {
+ if zb0019 {
(*z).AccountData.Assets = nil
} else if (*z).AccountData.Assets == nil {
- (*z).AccountData.Assets = make(map[AssetIndex]AssetHolding, zb0016)
+ (*z).AccountData.Assets = make(map[AssetIndex]AssetHolding, zb0018)
}
- for zb0016 > 0 {
+ for zb0018 > 0 {
var zb0003 AssetIndex
var zb0004 AssetHolding
- zb0016--
+ zb0018--
bts, err = zb0003.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Assets")
return
}
- var zb0018 int
- var zb0019 bool
- zb0018, zb0019, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0020 int
+ var zb0021 bool
+ zb0020, zb0021, bts, err = msgp.ReadMapHeaderBytes(bts)
if _, ok := err.(msgp.TypeError); ok {
- zb0018, zb0019, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ zb0020, zb0021, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003)
return
}
- if zb0018 > 0 {
- zb0018--
+ if zb0020 > 0 {
+ zb0020--
zb0004.Amount, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003, "struct-from-array", "Amount")
return
}
}
- if zb0018 > 0 {
- zb0018--
+ if zb0020 > 0 {
+ zb0020--
zb0004.Frozen, bts, err = msgp.ReadBoolBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003, "struct-from-array", "Frozen")
return
}
}
- if zb0018 > 0 {
- err = msgp.ErrTooManyArrayFields(zb0018)
+ if zb0020 > 0 {
+ err = msgp.ErrTooManyArrayFields(zb0020)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003, "struct-from-array")
return
@@ -3718,11 +3822,11 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState
err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003)
return
}
- if zb0019 {
+ if zb0021 {
zb0004 = AssetHolding{}
}
- for zb0018 > 0 {
- zb0018--
+ for zb0020 > 0 {
+ zb0020--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Assets", zb0003)
@@ -3763,27 +3867,27 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState
}
if zb0009 > 0 {
zb0009--
- var zb0020 int
- var zb0021 bool
- zb0020, zb0021, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0022 int
+ var zb0023 bool
+ zb0022, zb0023, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "AppLocalStates")
return
}
- if zb0020 > EncodedMaxAppLocalStates {
- err = msgp.ErrOverflow(uint64(zb0020), uint64(EncodedMaxAppLocalStates))
+ if zb0022 > EncodedMaxAppLocalStates {
+ err = msgp.ErrOverflow(uint64(zb0022), uint64(EncodedMaxAppLocalStates))
err = msgp.WrapError(err, "struct-from-array", "AppLocalStates")
return
}
- if zb0021 {
+ if zb0023 {
(*z).AccountData.AppLocalStates = nil
} else if (*z).AccountData.AppLocalStates == nil {
- (*z).AccountData.AppLocalStates = make(map[AppIndex]AppLocalState, zb0020)
+ (*z).AccountData.AppLocalStates = make(map[AppIndex]AppLocalState, zb0022)
}
- for zb0020 > 0 {
+ for zb0022 > 0 {
var zb0005 AppIndex
var zb0006 AppLocalState
- zb0020--
+ zb0022--
bts, err = zb0005.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "AppLocalStates")
@@ -3799,27 +3903,27 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState
}
if zb0009 > 0 {
zb0009--
- var zb0022 int
- var zb0023 bool
- zb0022, zb0023, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0024 int
+ var zb0025 bool
+ zb0024, zb0025, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "AppParams")
return
}
- if zb0022 > EncodedMaxAppParams {
- err = msgp.ErrOverflow(uint64(zb0022), uint64(EncodedMaxAppParams))
+ if zb0024 > EncodedMaxAppParams {
+ err = msgp.ErrOverflow(uint64(zb0024), uint64(EncodedMaxAppParams))
err = msgp.WrapError(err, "struct-from-array", "AppParams")
return
}
- if zb0023 {
+ if zb0025 {
(*z).AccountData.AppParams = nil
} else if (*z).AccountData.AppParams == nil {
- (*z).AccountData.AppParams = make(map[AppIndex]AppParams, zb0022)
+ (*z).AccountData.AppParams = make(map[AppIndex]AppParams, zb0024)
}
- for zb0022 > 0 {
+ for zb0024 > 0 {
var zb0007 AppIndex
var zb0008 AppParams
- zb0022--
+ zb0024--
bts, err = zb0007.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "AppParams")
@@ -3835,33 +3939,33 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState
}
if zb0009 > 0 {
zb0009--
- var zb0024 int
- var zb0025 bool
- zb0024, zb0025, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0026 int
+ var zb0027 bool
+ zb0026, zb0027, bts, err = msgp.ReadMapHeaderBytes(bts)
if _, ok := err.(msgp.TypeError); ok {
- zb0024, zb0025, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ zb0026, zb0027, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema")
return
}
- if zb0024 > 0 {
- zb0024--
+ if zb0026 > 0 {
+ zb0026--
(*z).AccountData.TotalAppSchema.NumUint, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema", "struct-from-array", "NumUint")
return
}
}
- if zb0024 > 0 {
- zb0024--
+ if zb0026 > 0 {
+ zb0026--
(*z).AccountData.TotalAppSchema.NumByteSlice, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema", "struct-from-array", "NumByteSlice")
return
}
}
- if zb0024 > 0 {
- err = msgp.ErrTooManyArrayFields(zb0024)
+ if zb0026 > 0 {
+ err = msgp.ErrTooManyArrayFields(zb0026)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema", "struct-from-array")
return
@@ -3872,11 +3976,11 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState
err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema")
return
}
- if zb0025 {
+ if zb0027 {
(*z).AccountData.TotalAppSchema = StateSchema{}
}
- for zb0024 > 0 {
- zb0024--
+ for zb0026 > 0 {
+ zb0026--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "TotalAppSchema")
@@ -3960,13 +4064,13 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState
}
case "onl":
{
- var zb0026 byte
- zb0026, bts, err = msgp.ReadByteBytes(bts)
+ var zb0028 byte
+ zb0028, bts, err = msgp.ReadByteBytes(bts)
if err != nil {
err = msgp.WrapError(err, "Status")
return
}
- (*z).AccountData.Status = Status(zb0026)
+ (*z).AccountData.Status = Status(zb0028)
}
case "algo":
bts, err = (*z).AccountData.MicroAlgos.UnmarshalMsgWithState(bts, st)
@@ -4006,23 +4110,23 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState
}
case "voteFst":
{
- var zb0027 uint64
- zb0027, bts, err = msgp.ReadUint64Bytes(bts)
+ var zb0029 uint64
+ zb0029, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "VoteFirstValid")
return
}
- (*z).AccountData.VoteFirstValid = Round(zb0027)
+ (*z).AccountData.VoteFirstValid = Round(zb0029)
}
case "voteLst":
{
- var zb0028 uint64
- zb0028, bts, err = msgp.ReadUint64Bytes(bts)
+ var zb0030 uint64
+ zb0030, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "VoteLastValid")
return
}
- (*z).AccountData.VoteLastValid = Round(zb0028)
+ (*z).AccountData.VoteLastValid = Round(zb0030)
}
case "voteKD":
(*z).AccountData.VoteKeyDilution, bts, err = msgp.ReadUint64Bytes(bts)
@@ -4030,28 +4134,48 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState
err = msgp.WrapError(err, "VoteKeyDilution")
return
}
+ case "lpr":
+ {
+ var zb0031 uint64
+ zb0031, bts, err = msgp.ReadUint64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "LastProposed")
+ return
+ }
+ (*z).AccountData.LastProposed = Round(zb0031)
+ }
+ case "lhb":
+ {
+ var zb0032 uint64
+ zb0032, bts, err = msgp.ReadUint64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "LastHeartbeat")
+ return
+ }
+ (*z).AccountData.LastHeartbeat = Round(zb0032)
+ }
case "apar":
- var zb0029 int
- var zb0030 bool
- zb0029, zb0030, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0033 int
+ var zb0034 bool
+ zb0033, zb0034, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "AssetParams")
return
}
- if zb0029 > encodedMaxAssetsPerAccount {
- err = msgp.ErrOverflow(uint64(zb0029), uint64(encodedMaxAssetsPerAccount))
+ if zb0033 > encodedMaxAssetsPerAccount {
+ err = msgp.ErrOverflow(uint64(zb0033), uint64(encodedMaxAssetsPerAccount))
err = msgp.WrapError(err, "AssetParams")
return
}
- if zb0030 {
+ if zb0034 {
(*z).AccountData.AssetParams = nil
} else if (*z).AccountData.AssetParams == nil {
- (*z).AccountData.AssetParams = make(map[AssetIndex]AssetParams, zb0029)
+ (*z).AccountData.AssetParams = make(map[AssetIndex]AssetParams, zb0033)
}
- for zb0029 > 0 {
+ for zb0033 > 0 {
var zb0001 AssetIndex
var zb0002 AssetParams
- zb0029--
+ zb0033--
bts, err = zb0001.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "AssetParams")
@@ -4065,59 +4189,59 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState
(*z).AccountData.AssetParams[zb0001] = zb0002
}
case "asset":
- var zb0031 int
- var zb0032 bool
- zb0031, zb0032, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0035 int
+ var zb0036 bool
+ zb0035, zb0036, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "Assets")
return
}
- if zb0031 > encodedMaxAssetsPerAccount {
- err = msgp.ErrOverflow(uint64(zb0031), uint64(encodedMaxAssetsPerAccount))
+ if zb0035 > encodedMaxAssetsPerAccount {
+ err = msgp.ErrOverflow(uint64(zb0035), uint64(encodedMaxAssetsPerAccount))
err = msgp.WrapError(err, "Assets")
return
}
- if zb0032 {
+ if zb0036 {
(*z).AccountData.Assets = nil
} else if (*z).AccountData.Assets == nil {
- (*z).AccountData.Assets = make(map[AssetIndex]AssetHolding, zb0031)
+ (*z).AccountData.Assets = make(map[AssetIndex]AssetHolding, zb0035)
}
- for zb0031 > 0 {
+ for zb0035 > 0 {
var zb0003 AssetIndex
var zb0004 AssetHolding
- zb0031--
+ zb0035--
bts, err = zb0003.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "Assets")
return
}
- var zb0033 int
- var zb0034 bool
- zb0033, zb0034, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0037 int
+ var zb0038 bool
+ zb0037, zb0038, bts, err = msgp.ReadMapHeaderBytes(bts)
if _, ok := err.(msgp.TypeError); ok {
- zb0033, zb0034, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ zb0037, zb0038, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "Assets", zb0003)
return
}
- if zb0033 > 0 {
- zb0033--
+ if zb0037 > 0 {
+ zb0037--
zb0004.Amount, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "Assets", zb0003, "struct-from-array", "Amount")
return
}
}
- if zb0033 > 0 {
- zb0033--
+ if zb0037 > 0 {
+ zb0037--
zb0004.Frozen, bts, err = msgp.ReadBoolBytes(bts)
if err != nil {
err = msgp.WrapError(err, "Assets", zb0003, "struct-from-array", "Frozen")
return
}
}
- if zb0033 > 0 {
- err = msgp.ErrTooManyArrayFields(zb0033)
+ if zb0037 > 0 {
+ err = msgp.ErrTooManyArrayFields(zb0037)
if err != nil {
err = msgp.WrapError(err, "Assets", zb0003, "struct-from-array")
return
@@ -4128,11 +4252,11 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState
err = msgp.WrapError(err, "Assets", zb0003)
return
}
- if zb0034 {
+ if zb0038 {
zb0004 = AssetHolding{}
}
- for zb0033 > 0 {
- zb0033--
+ for zb0037 > 0 {
+ zb0037--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
err = msgp.WrapError(err, "Assets", zb0003)
@@ -4169,27 +4293,27 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState
return
}
case "appl":
- var zb0035 int
- var zb0036 bool
- zb0035, zb0036, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0039 int
+ var zb0040 bool
+ zb0039, zb0040, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "AppLocalStates")
return
}
- if zb0035 > EncodedMaxAppLocalStates {
- err = msgp.ErrOverflow(uint64(zb0035), uint64(EncodedMaxAppLocalStates))
+ if zb0039 > EncodedMaxAppLocalStates {
+ err = msgp.ErrOverflow(uint64(zb0039), uint64(EncodedMaxAppLocalStates))
err = msgp.WrapError(err, "AppLocalStates")
return
}
- if zb0036 {
+ if zb0040 {
(*z).AccountData.AppLocalStates = nil
} else if (*z).AccountData.AppLocalStates == nil {
- (*z).AccountData.AppLocalStates = make(map[AppIndex]AppLocalState, zb0035)
+ (*z).AccountData.AppLocalStates = make(map[AppIndex]AppLocalState, zb0039)
}
- for zb0035 > 0 {
+ for zb0039 > 0 {
var zb0005 AppIndex
var zb0006 AppLocalState
- zb0035--
+ zb0039--
bts, err = zb0005.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "AppLocalStates")
@@ -4203,27 +4327,27 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState
(*z).AccountData.AppLocalStates[zb0005] = zb0006
}
case "appp":
- var zb0037 int
- var zb0038 bool
- zb0037, zb0038, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0041 int
+ var zb0042 bool
+ zb0041, zb0042, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "AppParams")
return
}
- if zb0037 > EncodedMaxAppParams {
- err = msgp.ErrOverflow(uint64(zb0037), uint64(EncodedMaxAppParams))
+ if zb0041 > EncodedMaxAppParams {
+ err = msgp.ErrOverflow(uint64(zb0041), uint64(EncodedMaxAppParams))
err = msgp.WrapError(err, "AppParams")
return
}
- if zb0038 {
+ if zb0042 {
(*z).AccountData.AppParams = nil
} else if (*z).AccountData.AppParams == nil {
- (*z).AccountData.AppParams = make(map[AppIndex]AppParams, zb0037)
+ (*z).AccountData.AppParams = make(map[AppIndex]AppParams, zb0041)
}
- for zb0037 > 0 {
+ for zb0041 > 0 {
var zb0007 AppIndex
var zb0008 AppParams
- zb0037--
+ zb0041--
bts, err = zb0007.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "AppParams")
@@ -4237,33 +4361,33 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState
(*z).AccountData.AppParams[zb0007] = zb0008
}
case "tsch":
- var zb0039 int
- var zb0040 bool
- zb0039, zb0040, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0043 int
+ var zb0044 bool
+ zb0043, zb0044, bts, err = msgp.ReadMapHeaderBytes(bts)
if _, ok := err.(msgp.TypeError); ok {
- zb0039, zb0040, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ zb0043, zb0044, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "TotalAppSchema")
return
}
- if zb0039 > 0 {
- zb0039--
+ if zb0043 > 0 {
+ zb0043--
(*z).AccountData.TotalAppSchema.NumUint, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "TotalAppSchema", "struct-from-array", "NumUint")
return
}
}
- if zb0039 > 0 {
- zb0039--
+ if zb0043 > 0 {
+ zb0043--
(*z).AccountData.TotalAppSchema.NumByteSlice, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "TotalAppSchema", "struct-from-array", "NumByteSlice")
return
}
}
- if zb0039 > 0 {
- err = msgp.ErrTooManyArrayFields(zb0039)
+ if zb0043 > 0 {
+ err = msgp.ErrTooManyArrayFields(zb0043)
if err != nil {
err = msgp.WrapError(err, "TotalAppSchema", "struct-from-array")
return
@@ -4274,11 +4398,11 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState
err = msgp.WrapError(err, "TotalAppSchema")
return
}
- if zb0040 {
+ if zb0044 {
(*z).AccountData.TotalAppSchema = StateSchema{}
}
- for zb0039 > 0 {
- zb0039--
+ for zb0043 > 0 {
+ zb0043--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
err = msgp.WrapError(err, "TotalAppSchema")
@@ -4347,7 +4471,7 @@ func (_ *BalanceRecord) CanUnmarshalMsg(z interface{}) bool {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *BalanceRecord) Msgsize() (s int) {
- s = 3 + 5 + (*z).Addr.Msgsize() + 4 + msgp.ByteSize + 5 + (*z).AccountData.MicroAlgos.Msgsize() + 6 + msgp.Uint64Size + 4 + (*z).AccountData.RewardedMicroAlgos.Msgsize() + 5 + (*z).AccountData.VoteID.Msgsize() + 4 + (*z).AccountData.SelectionID.Msgsize() + 6 + (*z).AccountData.StateProofID.Msgsize() + 8 + msgp.Uint64Size + 8 + msgp.Uint64Size + 7 + msgp.Uint64Size + 5 + msgp.MapHeaderSize
+ s = 3 + 5 + (*z).Addr.Msgsize() + 4 + msgp.ByteSize + 5 + (*z).AccountData.MicroAlgos.Msgsize() + 6 + msgp.Uint64Size + 4 + (*z).AccountData.RewardedMicroAlgos.Msgsize() + 5 + (*z).AccountData.VoteID.Msgsize() + 4 + (*z).AccountData.SelectionID.Msgsize() + 6 + (*z).AccountData.StateProofID.Msgsize() + 8 + msgp.Uint64Size + 8 + msgp.Uint64Size + 7 + msgp.Uint64Size + 4 + msgp.Uint64Size + 4 + msgp.Uint64Size + 5 + msgp.MapHeaderSize
if (*z).AccountData.AssetParams != nil {
for zb0001, zb0002 := range (*z).AccountData.AssetParams {
_ = zb0001
@@ -4385,12 +4509,12 @@ func (z *BalanceRecord) Msgsize() (s int) {
// MsgIsZero returns whether this is a zero value
func (z *BalanceRecord) MsgIsZero() bool {
- return ((*z).Addr.MsgIsZero()) && ((*z).AccountData.Status == 0) && ((*z).AccountData.MicroAlgos.MsgIsZero()) && ((*z).AccountData.RewardsBase == 0) && ((*z).AccountData.RewardedMicroAlgos.MsgIsZero()) && ((*z).AccountData.VoteID.MsgIsZero()) && ((*z).AccountData.SelectionID.MsgIsZero()) && ((*z).AccountData.StateProofID.MsgIsZero()) && ((*z).AccountData.VoteFirstValid == 0) && ((*z).AccountData.VoteLastValid == 0) && ((*z).AccountData.VoteKeyDilution == 0) && (len((*z).AccountData.AssetParams) == 0) && (len((*z).AccountData.Assets) == 0) && ((*z).AccountData.AuthAddr.MsgIsZero()) && (len((*z).AccountData.AppLocalStates) == 0) && (len((*z).AccountData.AppParams) == 0) && (((*z).AccountData.TotalAppSchema.NumUint == 0) && ((*z).AccountData.TotalAppSchema.NumByteSlice == 0)) && ((*z).AccountData.TotalExtraAppPages == 0) && ((*z).AccountData.TotalBoxes == 0) && ((*z).AccountData.TotalBoxBytes == 0)
+ return ((*z).Addr.MsgIsZero()) && ((*z).AccountData.Status == 0) && ((*z).AccountData.MicroAlgos.MsgIsZero()) && ((*z).AccountData.RewardsBase == 0) && ((*z).AccountData.RewardedMicroAlgos.MsgIsZero()) && ((*z).AccountData.VoteID.MsgIsZero()) && ((*z).AccountData.SelectionID.MsgIsZero()) && ((*z).AccountData.StateProofID.MsgIsZero()) && ((*z).AccountData.VoteFirstValid == 0) && ((*z).AccountData.VoteLastValid == 0) && ((*z).AccountData.VoteKeyDilution == 0) && ((*z).AccountData.LastProposed == 0) && ((*z).AccountData.LastHeartbeat == 0) && (len((*z).AccountData.AssetParams) == 0) && (len((*z).AccountData.Assets) == 0) && ((*z).AccountData.AuthAddr.MsgIsZero()) && (len((*z).AccountData.AppLocalStates) == 0) && (len((*z).AccountData.AppParams) == 0) && (((*z).AccountData.TotalAppSchema.NumUint == 0) && ((*z).AccountData.TotalAppSchema.NumByteSlice == 0)) && ((*z).AccountData.TotalExtraAppPages == 0) && ((*z).AccountData.TotalBoxes == 0) && ((*z).AccountData.TotalBoxBytes == 0)
}
// MaxSize returns a maximum valid message size for this message type
func BalanceRecordMaxSize() (s int) {
- s = 3 + 5 + AddressMaxSize() + 4 + msgp.ByteSize + 5 + MicroAlgosMaxSize() + 6 + msgp.Uint64Size + 4 + MicroAlgosMaxSize() + 5 + crypto.OneTimeSignatureVerifierMaxSize() + 4 + crypto.VRFVerifierMaxSize() + 6 + merklesignature.CommitmentMaxSize() + 8 + msgp.Uint64Size + 8 + msgp.Uint64Size + 7 + msgp.Uint64Size + 5
+ s = 3 + 5 + AddressMaxSize() + 4 + msgp.ByteSize + 5 + MicroAlgosMaxSize() + 6 + msgp.Uint64Size + 4 + MicroAlgosMaxSize() + 5 + crypto.OneTimeSignatureVerifierMaxSize() + 4 + crypto.VRFVerifierMaxSize() + 6 + merklesignature.CommitmentMaxSize() + 8 + msgp.Uint64Size + 8 + msgp.Uint64Size + 7 + msgp.Uint64Size + 4 + msgp.Uint64Size + 4 + msgp.Uint64Size + 5
s += msgp.MapHeaderSize
// Adding size of map keys for z.AccountData.AssetParams
s += encodedMaxAssetsPerAccount * (AssetIndexMaxSize())
diff --git a/data/basics/userBalance.go b/data/basics/userBalance.go
index e87517f28d..88caa2a0d0 100644
--- a/data/basics/userBalance.go
+++ b/data/basics/userBalance.go
@@ -42,6 +42,11 @@ const (
// Two special accounts that are defined as NotParticipating are the incentive pool (also know as rewards pool) and the fee sink.
// These two accounts also have additional Algo transfer restrictions.
NotParticipating
+ // Suspended indicates that an account has registered keys, intending to
+ // particpate, but appears to have gone dark. Their balance should no longer
+ // be considered online, but their voting keys should be retained so they
+ // can easily get back online by sending a "heartbeat".
+ Suspended
// encodedMaxAssetsPerAccount is the decoder limit of number of assets stored per account.
// it's being verified by the unit test TestEncodedAccountAllocationBounds to align
@@ -75,6 +80,8 @@ func (s Status) String() string {
return "Online"
case NotParticipating:
return "Not Participating"
+ case Suspended:
+ return "Suspended"
}
return ""
}
@@ -88,6 +95,8 @@ func UnmarshalStatus(value string) (s Status, err error) {
s = Online
case "Not Participating":
s = NotParticipating
+ case "Suspended":
+ s = Suspended
default:
err = fmt.Errorf("unknown account status: %v", value)
}
@@ -115,8 +124,13 @@ type OnlineAccountData struct {
// AccountData contains the data associated with a given address.
//
-// This includes the account balance, cryptographic public keys,
-// consensus delegation status, asset data, and application data.
+// This includes the account balance, cryptographic public keys, consensus
+// status, asset params (for assets made by this account), asset holdings (for
+// assets the account is opted into), and application data (globals if account
+// created, locals if opted-in). This can be thought of as the fully "hydrated"
+// structure and could take an arbitrary number of db queries to fill. As such,
+// it is mostly used only for shuttling complete accounts into the ledger
+// (genesis, catchpoints, REST API). And a lot of legacy tests.
type AccountData struct {
_struct struct{} `codec:",omitempty,omitemptyarray"`
@@ -172,6 +186,13 @@ type AccountData struct {
VoteLastValid Round `codec:"voteLst"`
VoteKeyDilution uint64 `codec:"voteKD"`
+ // LastProposed is the last round that the account is known to have
+ // proposed. It is updated at the start of the _next_ round.
+ LastProposed Round `codec:"lpr"`
+ // LastHeartbeat is the last round an account has indicated it is ready to
+ // vote by sending a heartbeat transaction, signed by its partkey.
+ LastHeartbeat Round `codec:"lhb"`
+
// If this account created an asset, AssetParams stores
// the parameters defining that asset. The params are indexed
// by the Index of the AssetID; the Creator is this account's address.
diff --git a/data/bookkeeping/block.go b/data/bookkeeping/block.go
index 39842aa758..d26ec5b7f2 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
@@ -145,6 +155,10 @@ type (
// that needs to be converted to offline since their
// participation key expired.
ExpiredParticipationAccounts []basics.Address `codec:"partupdrmv,allocbound=config.MaxProposedExpiredOnlineAccounts"`
+
+ // AbsentParticipationAccounts contains a list of online accounts that
+ // needs to be converted to offline since they are not proposing.
+ AbsentParticipationAccounts []basics.Address `codec:"partupdabs,allocbound=config.MaxProposedAbsentOnlineAccounts"`
}
// RewardsState represents the global parameters controlling the rate
@@ -275,9 +289,13 @@ func (block Block) GenesisHash() crypto.Digest {
}
// WithSeed returns a copy of the Block with the seed set to s.
-func (block Block) WithSeed(s committee.Seed) Block {
+func (block Block) WithSeed(s committee.Seed, proposer basics.Address) Block {
c := block
c.BlockHeader.Seed = s
+ if !c.BlockHeader.Proposer.IsZero() {
+ panic("Attempt to re-set the proposer.")
+ }
+ c.BlockHeader.Proposer = proposer
return c
}
diff --git a/data/bookkeeping/msgp_gen.go b/data/bookkeeping/msgp_gen.go
index 7eda4de555..a5c8b49933 100644
--- a/data/bookkeeping/msgp_gen.go
+++ b/data/bookkeeping/msgp_gen.go
@@ -143,161 +143,190 @@ 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 */
+ zb0005Len := uint32(29)
+ var zb0005Mask uint64 /* 34 bits */
if (*z).BlockHeader.RewardsState.RewardsLevel == 0 {
- zb0004Len--
- zb0004Mask |= 0x20
+ zb0005Len--
+ zb0005Mask |= 0x20
+ }
+ if (*z).BlockHeader.FeesCollected.MsgIsZero() {
+ zb0005Len--
+ zb0005Mask |= 0x40
}
if (*z).BlockHeader.RewardsState.FeeSink.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x40
+ zb0005Len--
+ zb0005Mask |= 0x80
}
if (*z).BlockHeader.RewardsState.RewardsResidue == 0 {
- zb0004Len--
- zb0004Mask |= 0x80
+ zb0005Len--
+ zb0005Mask |= 0x100
}
if (*z).BlockHeader.GenesisID == "" {
- zb0004Len--
- zb0004Mask |= 0x100
+ zb0005Len--
+ zb0005Mask |= 0x200
}
if (*z).BlockHeader.GenesisHash.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x200
+ zb0005Len--
+ zb0005Mask |= 0x400
}
if (*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x400
+ zb0005Len--
+ zb0005Mask |= 0x800
}
if (*z).BlockHeader.UpgradeState.NextProtocol.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x800
+ zb0005Len--
+ zb0005Mask |= 0x1000
}
if (*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x1000
+ zb0005Len--
+ zb0005Mask |= 0x2000
}
if (*z).BlockHeader.UpgradeState.NextProtocolApprovals == 0 {
- zb0004Len--
- zb0004Mask |= 0x2000
+ zb0005Len--
+ zb0005Mask |= 0x4000
+ }
+ if len((*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) == 0 {
+ zb0005Len--
+ zb0005Mask |= 0x8000
}
if len((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 {
- zb0004Len--
- zb0004Mask |= 0x4000
+ zb0005Len--
+ zb0005Mask |= 0x10000
}
if (*z).BlockHeader.Branch.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x8000
+ zb0005Len--
+ zb0005Mask |= 0x20000
}
if (*z).BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x10000
+ zb0005Len--
+ zb0005Mask |= 0x40000
+ }
+ if (*z).BlockHeader.Proposer.MsgIsZero() {
+ zb0005Len--
+ zb0005Mask |= 0x80000
}
if (*z).BlockHeader.RewardsState.RewardsRate == 0 {
- zb0004Len--
- zb0004Mask |= 0x20000
+ zb0005Len--
+ zb0005Mask |= 0x100000
}
if (*z).BlockHeader.Round.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x40000
+ zb0005Len--
+ zb0005Mask |= 0x200000
}
if (*z).BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x80000
+ zb0005Len--
+ zb0005Mask |= 0x400000
}
if (*z).BlockHeader.RewardsState.RewardsPool.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x100000
+ zb0005Len--
+ zb0005Mask |= 0x800000
}
if (*z).BlockHeader.Seed.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x200000
+ zb0005Len--
+ zb0005Mask |= 0x1000000
}
if len((*z).BlockHeader.StateProofTracking) == 0 {
- zb0004Len--
- zb0004Mask |= 0x400000
+ zb0005Len--
+ zb0005Mask |= 0x2000000
}
if (*z).BlockHeader.TxnCounter == 0 {
- zb0004Len--
- zb0004Mask |= 0x800000
+ zb0005Len--
+ zb0005Mask |= 0x4000000
}
if (*z).BlockHeader.TimeStamp == 0 {
- zb0004Len--
- zb0004Mask |= 0x1000000
+ zb0005Len--
+ zb0005Mask |= 0x8000000
}
if (*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x2000000
+ zb0005Len--
+ zb0005Mask |= 0x10000000
}
if (*z).BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x4000000
+ zb0005Len--
+ zb0005Mask |= 0x20000000
}
if (*z).Payset.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x8000000
+ zb0005Len--
+ zb0005Mask |= 0x40000000
}
if (*z).BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x10000000
+ zb0005Len--
+ zb0005Mask |= 0x80000000
}
if (*z).BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x20000000
+ zb0005Len--
+ zb0005Mask |= 0x100000000
}
if (*z).BlockHeader.UpgradeVote.UpgradeApprove == false {
- zb0004Len--
- zb0004Mask |= 0x40000000
+ zb0005Len--
+ zb0005Mask |= 0x200000000
}
- // variable map header, size zb0004Len
- o = msgp.AppendMapHeader(o, zb0004Len)
- if zb0004Len != 0 {
- if (zb0004Mask & 0x20) == 0 { // if not empty
+ // variable map header, size zb0005Len
+ o = msgp.AppendMapHeader(o, zb0005Len)
+ if zb0005Len != 0 {
+ if (zb0005Mask & 0x20) == 0 { // if not empty
// string "earn"
o = append(o, 0xa4, 0x65, 0x61, 0x72, 0x6e)
o = msgp.AppendUint64(o, (*z).BlockHeader.RewardsState.RewardsLevel)
}
- if (zb0004Mask & 0x40) == 0 { // if not empty
+ if (zb0005Mask & 0x40) == 0 { // if not empty
+ // string "fc"
+ o = append(o, 0xa2, 0x66, 0x63)
+ o = (*z).BlockHeader.FeesCollected.MarshalMsg(o)
+ }
+ if (zb0005Mask & 0x80) == 0 { // if not empty
// string "fees"
o = append(o, 0xa4, 0x66, 0x65, 0x65, 0x73)
o = (*z).BlockHeader.RewardsState.FeeSink.MarshalMsg(o)
}
- if (zb0004Mask & 0x80) == 0 { // if not empty
+ if (zb0005Mask & 0x100) == 0 { // if not empty
// string "frac"
o = append(o, 0xa4, 0x66, 0x72, 0x61, 0x63)
o = msgp.AppendUint64(o, (*z).BlockHeader.RewardsState.RewardsResidue)
}
- if (zb0004Mask & 0x100) == 0 { // if not empty
+ if (zb0005Mask & 0x200) == 0 { // if not empty
// string "gen"
o = append(o, 0xa3, 0x67, 0x65, 0x6e)
o = msgp.AppendString(o, (*z).BlockHeader.GenesisID)
}
- if (zb0004Mask & 0x200) == 0 { // if not empty
+ if (zb0005Mask & 0x400) == 0 { // if not empty
// string "gh"
o = append(o, 0xa2, 0x67, 0x68)
o = (*z).BlockHeader.GenesisHash.MarshalMsg(o)
}
- if (zb0004Mask & 0x400) == 0 { // if not empty
+ if (zb0005Mask & 0x800) == 0 { // if not empty
// string "nextbefore"
o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65)
o = (*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.MarshalMsg(o)
}
- if (zb0004Mask & 0x800) == 0 { // if not empty
+ if (zb0005Mask & 0x1000) == 0 { // if not empty
// string "nextproto"
o = append(o, 0xa9, 0x6e, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f)
o = (*z).BlockHeader.UpgradeState.NextProtocol.MarshalMsg(o)
}
- if (zb0004Mask & 0x1000) == 0 { // if not empty
+ if (zb0005Mask & 0x2000) == 0 { // if not empty
// string "nextswitch"
o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68)
o = (*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.MarshalMsg(o)
}
- if (zb0004Mask & 0x2000) == 0 { // if not empty
+ if (zb0005Mask & 0x4000) == 0 { // if not empty
// string "nextyes"
o = append(o, 0xa7, 0x6e, 0x65, 0x78, 0x74, 0x79, 0x65, 0x73)
o = msgp.AppendUint64(o, (*z).BlockHeader.UpgradeState.NextProtocolApprovals)
}
- if (zb0004Mask & 0x4000) == 0 { // if not empty
+ if (zb0005Mask & 0x8000) == 0 { // if not empty
+ // string "partupdabs"
+ o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x61, 0x62, 0x73)
+ if (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts == nil {
+ o = msgp.AppendNil(o)
+ } else {
+ o = msgp.AppendArrayHeader(o, uint32(len((*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts)))
+ }
+ for zb0004 := range (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts {
+ o = (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].MarshalMsg(o)
+ }
+ }
+ if (zb0005Mask & 0x10000) == 0 { // if not empty
// string "partupdrmv"
o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76)
if (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts == nil {
@@ -309,42 +338,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 (zb0005Mask & 0x20000) == 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 (zb0005Mask & 0x40000) == 0 { // if not empty
// string "proto"
o = append(o, 0xa5, 0x70, 0x72, 0x6f, 0x74, 0x6f)
o = (*z).BlockHeader.UpgradeState.CurrentProtocol.MarshalMsg(o)
}
- if (zb0004Mask & 0x20000) == 0 { // if not empty
+ if (zb0005Mask & 0x80000) == 0 { // if not empty
+ // string "prp"
+ o = append(o, 0xa3, 0x70, 0x72, 0x70)
+ o = (*z).BlockHeader.Proposer.MarshalMsg(o)
+ }
+ if (zb0005Mask & 0x100000) == 0 { // if not empty
// string "rate"
o = append(o, 0xa4, 0x72, 0x61, 0x74, 0x65)
o = msgp.AppendUint64(o, (*z).BlockHeader.RewardsState.RewardsRate)
}
- if (zb0004Mask & 0x40000) == 0 { // if not empty
+ if (zb0005Mask & 0x200000) == 0 { // if not empty
// string "rnd"
o = append(o, 0xa3, 0x72, 0x6e, 0x64)
o = (*z).BlockHeader.Round.MarshalMsg(o)
}
- if (zb0004Mask & 0x80000) == 0 { // if not empty
+ if (zb0005Mask & 0x400000) == 0 { // if not empty
// string "rwcalr"
o = append(o, 0xa6, 0x72, 0x77, 0x63, 0x61, 0x6c, 0x72)
o = (*z).BlockHeader.RewardsState.RewardsRecalculationRound.MarshalMsg(o)
}
- if (zb0004Mask & 0x100000) == 0 { // if not empty
+ if (zb0005Mask & 0x800000) == 0 { // if not empty
// string "rwd"
o = append(o, 0xa3, 0x72, 0x77, 0x64)
o = (*z).BlockHeader.RewardsState.RewardsPool.MarshalMsg(o)
}
- if (zb0004Mask & 0x200000) == 0 { // if not empty
+ if (zb0005Mask & 0x1000000) == 0 { // if not empty
// string "seed"
o = append(o, 0xa4, 0x73, 0x65, 0x65, 0x64)
o = (*z).BlockHeader.Seed.MarshalMsg(o)
}
- if (zb0004Mask & 0x400000) == 0 { // if not empty
+ if (zb0005Mask & 0x2000000) == 0 { // if not empty
// string "spt"
o = append(o, 0xa3, 0x73, 0x70, 0x74)
if (*z).BlockHeader.StateProofTracking == nil {
@@ -364,42 +398,42 @@ func (z *Block) MarshalMsg(b []byte) (o []byte) {
o = zb0002.MarshalMsg(o)
}
}
- if (zb0004Mask & 0x800000) == 0 { // if not empty
+ if (zb0005Mask & 0x4000000) == 0 { // if not empty
// string "tc"
o = append(o, 0xa2, 0x74, 0x63)
o = msgp.AppendUint64(o, (*z).BlockHeader.TxnCounter)
}
- if (zb0004Mask & 0x1000000) == 0 { // if not empty
+ if (zb0005Mask & 0x8000000) == 0 { // if not empty
// string "ts"
o = append(o, 0xa2, 0x74, 0x73)
o = msgp.AppendInt64(o, (*z).BlockHeader.TimeStamp)
}
- if (zb0004Mask & 0x2000000) == 0 { // if not empty
+ if (zb0005Mask & 0x10000000) == 0 { // if not empty
// string "txn"
o = append(o, 0xa3, 0x74, 0x78, 0x6e)
o = (*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.MarshalMsg(o)
}
- if (zb0004Mask & 0x4000000) == 0 { // if not empty
+ if (zb0005Mask & 0x20000000) == 0 { // if not empty
// string "txn256"
o = append(o, 0xa6, 0x74, 0x78, 0x6e, 0x32, 0x35, 0x36)
o = (*z).BlockHeader.TxnCommitments.Sha256Commitment.MarshalMsg(o)
}
- if (zb0004Mask & 0x8000000) == 0 { // if not empty
+ if (zb0005Mask & 0x40000000) == 0 { // if not empty
// string "txns"
o = append(o, 0xa4, 0x74, 0x78, 0x6e, 0x73)
o = (*z).Payset.MarshalMsg(o)
}
- if (zb0004Mask & 0x10000000) == 0 { // if not empty
+ if (zb0005Mask & 0x80000000) == 0 { // if not empty
// string "upgradedelay"
o = append(o, 0xac, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x65, 0x6c, 0x61, 0x79)
o = (*z).BlockHeader.UpgradeVote.UpgradeDelay.MarshalMsg(o)
}
- if (zb0004Mask & 0x20000000) == 0 { // if not empty
+ if (zb0005Mask & 0x100000000) == 0 { // if not empty
// string "upgradeprop"
o = append(o, 0xab, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x70, 0x72, 0x6f, 0x70)
o = (*z).BlockHeader.UpgradeVote.UpgradePropose.MarshalMsg(o)
}
- if (zb0004Mask & 0x40000000) == 0 { // if not empty
+ if (zb0005Mask & 0x200000000) == 0 { // if not empty
// string "upgradeyes"
o = append(o, 0xaa, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x65, 0x73)
o = msgp.AppendBool(o, (*z).BlockHeader.UpgradeVote.UpgradeApprove)
@@ -422,73 +456,73 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b
st.AllowableDepth--
var field []byte
_ = field
- var zb0004 int
- var zb0005 bool
- zb0004, zb0005, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0005 int
+ var zb0006 bool
+ zb0005, zb0006, bts, err = msgp.ReadMapHeaderBytes(bts)
if _, ok := err.(msgp.TypeError); ok {
- zb0004, zb0005, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ zb0005, zb0006, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err)
return
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).BlockHeader.Round.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Round")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).BlockHeader.Branch.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Branch")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).BlockHeader.Seed.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Seed")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NativeSha512_256Commitment")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).BlockHeader.TxnCommitments.Sha256Commitment.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Sha256Commitment")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).BlockHeader.TimeStamp, bts, err = msgp.ReadInt64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "TimeStamp")
return
}
}
- if zb0004 > 0 {
- zb0004--
- var zb0006 int
- zb0006, err = msgp.ReadBytesBytesHeader(bts)
+ if zb0005 > 0 {
+ zb0005--
+ var zb0007 int
+ zb0007, err = msgp.ReadBytesBytesHeader(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "GenesisID")
return
}
- if zb0006 > config.MaxGenesisIDLen {
- err = msgp.ErrOverflow(uint64(zb0006), uint64(config.MaxGenesisIDLen))
+ if zb0007 > config.MaxGenesisIDLen {
+ err = msgp.ErrOverflow(uint64(zb0007), uint64(config.MaxGenesisIDLen))
return
}
(*z).BlockHeader.GenesisID, bts, err = msgp.ReadStringBytes(bts)
@@ -497,157 +531,173 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).BlockHeader.GenesisHash.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "GenesisHash")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
+ bts, err = (*z).BlockHeader.Proposer.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "Proposer")
+ return
+ }
+ }
+ if zb0005 > 0 {
+ zb0005--
+ bts, err = (*z).BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "FeesCollected")
+ return
+ }
+ }
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "FeeSink")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).BlockHeader.RewardsState.RewardsPool.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsPool")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).BlockHeader.RewardsState.RewardsLevel, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsLevel")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).BlockHeader.RewardsState.RewardsRate, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsRate")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).BlockHeader.RewardsState.RewardsResidue, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsResidue")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).BlockHeader.RewardsState.RewardsRecalculationRound.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsRecalculationRound")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).BlockHeader.UpgradeState.CurrentProtocol.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "CurrentProtocol")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).BlockHeader.UpgradeState.NextProtocol.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NextProtocol")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).BlockHeader.UpgradeState.NextProtocolApprovals, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NextProtocolApprovals")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NextProtocolVoteBefore")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NextProtocolSwitchOn")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).BlockHeader.UpgradeVote.UpgradePropose.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "UpgradePropose")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).BlockHeader.UpgradeVote.UpgradeDelay.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "UpgradeDelay")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).BlockHeader.UpgradeVote.UpgradeApprove, bts, err = msgp.ReadBoolBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "UpgradeApprove")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).BlockHeader.TxnCounter, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "TxnCounter")
return
}
}
- if zb0004 > 0 {
- zb0004--
- var zb0007 int
- var zb0008 bool
- zb0007, zb0008, bts, err = msgp.ReadMapHeaderBytes(bts)
+ if zb0005 > 0 {
+ zb0005--
+ var zb0008 int
+ var zb0009 bool
+ zb0008, zb0009, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "StateProofTracking")
return
}
- if zb0007 > protocol.NumStateProofTypes {
- err = msgp.ErrOverflow(uint64(zb0007), uint64(protocol.NumStateProofTypes))
+ if zb0008 > protocol.NumStateProofTypes {
+ err = msgp.ErrOverflow(uint64(zb0008), uint64(protocol.NumStateProofTypes))
err = msgp.WrapError(err, "struct-from-array", "StateProofTracking")
return
}
- if zb0008 {
+ if zb0009 {
(*z).BlockHeader.StateProofTracking = nil
} else if (*z).BlockHeader.StateProofTracking == nil {
- (*z).BlockHeader.StateProofTracking = make(map[protocol.StateProofType]StateProofTrackingData, zb0007)
+ (*z).BlockHeader.StateProofTracking = make(map[protocol.StateProofType]StateProofTrackingData, zb0008)
}
- for zb0007 > 0 {
+ for zb0008 > 0 {
var zb0001 protocol.StateProofType
var zb0002 StateProofTrackingData
- zb0007--
+ zb0008--
bts, err = zb0001.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "StateProofTracking")
@@ -661,26 +711,26 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b
(*z).BlockHeader.StateProofTracking[zb0001] = zb0002
}
}
- if zb0004 > 0 {
- zb0004--
- var zb0009 int
- var zb0010 bool
- zb0009, zb0010, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if zb0005 > 0 {
+ zb0005--
+ var zb0010 int
+ var zb0011 bool
+ zb0010, zb0011, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts")
return
}
- if zb0009 > config.MaxProposedExpiredOnlineAccounts {
- err = msgp.ErrOverflow(uint64(zb0009), uint64(config.MaxProposedExpiredOnlineAccounts))
+ if zb0010 > config.MaxProposedExpiredOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0010), uint64(config.MaxProposedExpiredOnlineAccounts))
err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts")
return
}
- if zb0010 {
+ if zb0011 {
(*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = nil
- } else if (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0009 {
- (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0009]
+ } else if (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0010 {
+ (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0010]
} else {
- (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0009)
+ (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0010)
}
for zb0003 := range (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts {
bts, err = (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].UnmarshalMsgWithState(bts, st)
@@ -690,16 +740,45 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b
}
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
+ var zb0012 int
+ var zb0013 bool
+ zb0012, zb0013, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts")
+ return
+ }
+ if zb0012 > config.MaxProposedAbsentOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0012), uint64(config.MaxProposedAbsentOnlineAccounts))
+ err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts")
+ return
+ }
+ if zb0013 {
+ (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = nil
+ } else if (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts != nil && cap((*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) >= zb0012 {
+ (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = ((*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts)[:zb0012]
+ } else {
+ (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = make([]basics.Address, zb0012)
+ }
+ for zb0004 := range (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts {
+ bts, err = (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts", zb0004)
+ return
+ }
+ }
+ }
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).Payset.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Payset")
return
}
}
- if zb0004 > 0 {
- err = msgp.ErrTooManyArrayFields(zb0004)
+ if zb0005 > 0 {
+ err = msgp.ErrTooManyArrayFields(zb0005)
if err != nil {
err = msgp.WrapError(err, "struct-from-array")
return
@@ -710,11 +789,11 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b
err = msgp.WrapError(err)
return
}
- if zb0005 {
+ if zb0006 {
(*z) = Block{}
}
- for zb0004 > 0 {
- zb0004--
+ for zb0005 > 0 {
+ zb0005--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
err = msgp.WrapError(err)
@@ -758,14 +837,14 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b
return
}
case "gen":
- var zb0011 int
- zb0011, err = msgp.ReadBytesBytesHeader(bts)
+ var zb0014 int
+ zb0014, err = msgp.ReadBytesBytesHeader(bts)
if err != nil {
err = msgp.WrapError(err, "GenesisID")
return
}
- if zb0011 > config.MaxGenesisIDLen {
- err = msgp.ErrOverflow(uint64(zb0011), uint64(config.MaxGenesisIDLen))
+ if zb0014 > config.MaxGenesisIDLen {
+ err = msgp.ErrOverflow(uint64(zb0014), uint64(config.MaxGenesisIDLen))
return
}
(*z).BlockHeader.GenesisID, bts, err = msgp.ReadStringBytes(bts)
@@ -779,6 +858,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 {
@@ -870,27 +961,27 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b
return
}
case "spt":
- var zb0012 int
- var zb0013 bool
- zb0012, zb0013, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0015 int
+ var zb0016 bool
+ zb0015, zb0016, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "StateProofTracking")
return
}
- if zb0012 > protocol.NumStateProofTypes {
- err = msgp.ErrOverflow(uint64(zb0012), uint64(protocol.NumStateProofTypes))
+ if zb0015 > protocol.NumStateProofTypes {
+ err = msgp.ErrOverflow(uint64(zb0015), uint64(protocol.NumStateProofTypes))
err = msgp.WrapError(err, "StateProofTracking")
return
}
- if zb0013 {
+ if zb0016 {
(*z).BlockHeader.StateProofTracking = nil
} else if (*z).BlockHeader.StateProofTracking == nil {
- (*z).BlockHeader.StateProofTracking = make(map[protocol.StateProofType]StateProofTrackingData, zb0012)
+ (*z).BlockHeader.StateProofTracking = make(map[protocol.StateProofType]StateProofTrackingData, zb0015)
}
- for zb0012 > 0 {
+ for zb0015 > 0 {
var zb0001 protocol.StateProofType
var zb0002 StateProofTrackingData
- zb0012--
+ zb0015--
bts, err = zb0001.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "StateProofTracking")
@@ -904,24 +995,24 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b
(*z).BlockHeader.StateProofTracking[zb0001] = zb0002
}
case "partupdrmv":
- var zb0014 int
- var zb0015 bool
- zb0014, zb0015, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ var zb0017 int
+ var zb0018 bool
+ zb0017, zb0018, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "ExpiredParticipationAccounts")
return
}
- if zb0014 > config.MaxProposedExpiredOnlineAccounts {
- err = msgp.ErrOverflow(uint64(zb0014), uint64(config.MaxProposedExpiredOnlineAccounts))
+ if zb0017 > config.MaxProposedExpiredOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0017), uint64(config.MaxProposedExpiredOnlineAccounts))
err = msgp.WrapError(err, "ExpiredParticipationAccounts")
return
}
- if zb0015 {
+ if zb0018 {
(*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = nil
- } else if (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0014 {
- (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0014]
+ } else if (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) >= zb0017 {
+ (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = ((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts)[:zb0017]
} else {
- (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0014)
+ (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0017)
}
for zb0003 := range (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts {
bts, err = (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].UnmarshalMsgWithState(bts, st)
@@ -930,6 +1021,33 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b
return
}
}
+ case "partupdabs":
+ var zb0019 int
+ var zb0020 bool
+ zb0019, zb0020, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "AbsentParticipationAccounts")
+ return
+ }
+ if zb0019 > config.MaxProposedAbsentOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0019), uint64(config.MaxProposedAbsentOnlineAccounts))
+ err = msgp.WrapError(err, "AbsentParticipationAccounts")
+ return
+ }
+ if zb0020 {
+ (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = nil
+ } else if (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts != nil && cap((*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) >= zb0019 {
+ (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = ((*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts)[:zb0019]
+ } else {
+ (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts = make([]basics.Address, zb0019)
+ }
+ for zb0004 := range (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts {
+ bts, err = (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "AbsentParticipationAccounts", zb0004)
+ return
+ }
+ }
case "txns":
bts, err = (*z).Payset.UnmarshalMsgWithState(bts, st)
if err != nil {
@@ -959,7 +1077,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
@@ -971,18 +1089,22 @@ func (z *Block) Msgsize() (s int) {
for zb0003 := range (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts {
s += (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].Msgsize()
}
+ s += 11 + msgp.ArrayHeaderSize
+ for zb0004 := range (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts {
+ s += (*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts[zb0004].Msgsize()
+ }
s += 5 + (*z).Payset.Msgsize()
return
}
// MsgIsZero returns whether this is a zero value
func (z *Block) MsgIsZero() bool {
- return ((*z).BlockHeader.Round.MsgIsZero()) && ((*z).BlockHeader.Branch.MsgIsZero()) && ((*z).BlockHeader.Seed.MsgIsZero()) && ((*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).BlockHeader.TimeStamp == 0) && ((*z).BlockHeader.GenesisID == "") && ((*z).BlockHeader.GenesisHash.MsgIsZero()) && ((*z).BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).BlockHeader.RewardsState.RewardsRate == 0) && ((*z).BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).BlockHeader.TxnCounter == 0) && (len((*z).BlockHeader.StateProofTracking) == 0) && (len((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).Payset.MsgIsZero())
+ return ((*z).BlockHeader.Round.MsgIsZero()) && ((*z).BlockHeader.Branch.MsgIsZero()) && ((*z).BlockHeader.Seed.MsgIsZero()) && ((*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).BlockHeader.TimeStamp == 0) && ((*z).BlockHeader.GenesisID == "") && ((*z).BlockHeader.GenesisHash.MsgIsZero()) && ((*z).BlockHeader.Proposer.MsgIsZero()) && ((*z).BlockHeader.FeesCollected.MsgIsZero()) && ((*z).BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).BlockHeader.RewardsState.RewardsRate == 0) && ((*z).BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).BlockHeader.TxnCounter == 0) && (len((*z).BlockHeader.StateProofTracking) == 0) && (len((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && (len((*z).BlockHeader.ParticipationUpdates.AbsentParticipationAccounts) == 0) && ((*z).Payset.MsgIsZero())
}
// MaxSize returns a maximum valid message size for this message type
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())
@@ -991,6 +1113,9 @@ func BlockMaxSize() (s int) {
s += 11
// Calculating size of slice: z.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts
s += msgp.ArrayHeaderSize + ((config.MaxProposedExpiredOnlineAccounts) * (basics.AddressMaxSize()))
+ s += 11
+ // Calculating size of slice: z.BlockHeader.ParticipationUpdates.AbsentParticipationAccounts
+ s += msgp.ArrayHeaderSize + ((config.MaxProposedAbsentOnlineAccounts) * (basics.AddressMaxSize()))
s += 5
// Using maxtotalbytes for: z.Payset
s += config.MaxTxnBytesPerBlock
@@ -1037,157 +1162,186 @@ func BlockHashMaxSize() int {
func (z *BlockHeader) MarshalMsg(b []byte) (o []byte) {
o = msgp.Require(b, z.Msgsize())
// omitempty: check for empty values
- zb0004Len := uint32(25)
- var zb0004Mask uint32 /* 30 bits */
+ zb0005Len := uint32(28)
+ var zb0005Mask uint64 /* 33 bits */
if (*z).RewardsState.RewardsLevel == 0 {
- zb0004Len--
- zb0004Mask |= 0x20
+ zb0005Len--
+ zb0005Mask |= 0x20
+ }
+ if (*z).FeesCollected.MsgIsZero() {
+ zb0005Len--
+ zb0005Mask |= 0x40
}
if (*z).RewardsState.FeeSink.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x40
+ zb0005Len--
+ zb0005Mask |= 0x80
}
if (*z).RewardsState.RewardsResidue == 0 {
- zb0004Len--
- zb0004Mask |= 0x80
+ zb0005Len--
+ zb0005Mask |= 0x100
}
if (*z).GenesisID == "" {
- zb0004Len--
- zb0004Mask |= 0x100
+ zb0005Len--
+ zb0005Mask |= 0x200
}
if (*z).GenesisHash.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x200
+ zb0005Len--
+ zb0005Mask |= 0x400
}
if (*z).UpgradeState.NextProtocolVoteBefore.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x400
+ zb0005Len--
+ zb0005Mask |= 0x800
}
if (*z).UpgradeState.NextProtocol.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x800
+ zb0005Len--
+ zb0005Mask |= 0x1000
}
if (*z).UpgradeState.NextProtocolSwitchOn.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x1000
+ zb0005Len--
+ zb0005Mask |= 0x2000
}
if (*z).UpgradeState.NextProtocolApprovals == 0 {
- zb0004Len--
- zb0004Mask |= 0x2000
+ zb0005Len--
+ zb0005Mask |= 0x4000
+ }
+ if len((*z).ParticipationUpdates.AbsentParticipationAccounts) == 0 {
+ zb0005Len--
+ zb0005Mask |= 0x8000
}
if len((*z).ParticipationUpdates.ExpiredParticipationAccounts) == 0 {
- zb0004Len--
- zb0004Mask |= 0x4000
+ zb0005Len--
+ zb0005Mask |= 0x10000
}
if (*z).Branch.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x8000
+ zb0005Len--
+ zb0005Mask |= 0x20000
}
if (*z).UpgradeState.CurrentProtocol.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x10000
+ zb0005Len--
+ zb0005Mask |= 0x40000
+ }
+ if (*z).Proposer.MsgIsZero() {
+ zb0005Len--
+ zb0005Mask |= 0x80000
}
if (*z).RewardsState.RewardsRate == 0 {
- zb0004Len--
- zb0004Mask |= 0x20000
+ zb0005Len--
+ zb0005Mask |= 0x100000
}
if (*z).Round.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x40000
+ zb0005Len--
+ zb0005Mask |= 0x200000
}
if (*z).RewardsState.RewardsRecalculationRound.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x80000
+ zb0005Len--
+ zb0005Mask |= 0x400000
}
if (*z).RewardsState.RewardsPool.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x100000
+ zb0005Len--
+ zb0005Mask |= 0x800000
}
if (*z).Seed.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x200000
+ zb0005Len--
+ zb0005Mask |= 0x1000000
}
if len((*z).StateProofTracking) == 0 {
- zb0004Len--
- zb0004Mask |= 0x400000
+ zb0005Len--
+ zb0005Mask |= 0x2000000
}
if (*z).TxnCounter == 0 {
- zb0004Len--
- zb0004Mask |= 0x800000
+ zb0005Len--
+ zb0005Mask |= 0x4000000
}
if (*z).TimeStamp == 0 {
- zb0004Len--
- zb0004Mask |= 0x1000000
+ zb0005Len--
+ zb0005Mask |= 0x8000000
}
if (*z).TxnCommitments.NativeSha512_256Commitment.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x2000000
+ zb0005Len--
+ zb0005Mask |= 0x10000000
}
if (*z).TxnCommitments.Sha256Commitment.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x4000000
+ zb0005Len--
+ zb0005Mask |= 0x20000000
}
if (*z).UpgradeVote.UpgradeDelay.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x8000000
+ zb0005Len--
+ zb0005Mask |= 0x40000000
}
if (*z).UpgradeVote.UpgradePropose.MsgIsZero() {
- zb0004Len--
- zb0004Mask |= 0x10000000
+ zb0005Len--
+ zb0005Mask |= 0x80000000
}
if (*z).UpgradeVote.UpgradeApprove == false {
- zb0004Len--
- zb0004Mask |= 0x20000000
+ zb0005Len--
+ zb0005Mask |= 0x100000000
}
- // variable map header, size zb0004Len
- o = msgp.AppendMapHeader(o, zb0004Len)
- if zb0004Len != 0 {
- if (zb0004Mask & 0x20) == 0 { // if not empty
+ // variable map header, size zb0005Len
+ o = msgp.AppendMapHeader(o, zb0005Len)
+ if zb0005Len != 0 {
+ if (zb0005Mask & 0x20) == 0 { // if not empty
// string "earn"
o = append(o, 0xa4, 0x65, 0x61, 0x72, 0x6e)
o = msgp.AppendUint64(o, (*z).RewardsState.RewardsLevel)
}
- if (zb0004Mask & 0x40) == 0 { // if not empty
+ if (zb0005Mask & 0x40) == 0 { // if not empty
+ // string "fc"
+ o = append(o, 0xa2, 0x66, 0x63)
+ o = (*z).FeesCollected.MarshalMsg(o)
+ }
+ if (zb0005Mask & 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 (zb0005Mask & 0x100) == 0 { // if not empty
// string "frac"
o = append(o, 0xa4, 0x66, 0x72, 0x61, 0x63)
o = msgp.AppendUint64(o, (*z).RewardsState.RewardsResidue)
}
- if (zb0004Mask & 0x100) == 0 { // if not empty
+ if (zb0005Mask & 0x200) == 0 { // if not empty
// string "gen"
o = append(o, 0xa3, 0x67, 0x65, 0x6e)
o = msgp.AppendString(o, (*z).GenesisID)
}
- if (zb0004Mask & 0x200) == 0 { // if not empty
+ if (zb0005Mask & 0x400) == 0 { // if not empty
// string "gh"
o = append(o, 0xa2, 0x67, 0x68)
o = (*z).GenesisHash.MarshalMsg(o)
}
- if (zb0004Mask & 0x400) == 0 { // if not empty
+ if (zb0005Mask & 0x800) == 0 { // if not empty
// string "nextbefore"
o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65)
o = (*z).UpgradeState.NextProtocolVoteBefore.MarshalMsg(o)
}
- if (zb0004Mask & 0x800) == 0 { // if not empty
+ if (zb0005Mask & 0x1000) == 0 { // if not empty
// string "nextproto"
o = append(o, 0xa9, 0x6e, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f)
o = (*z).UpgradeState.NextProtocol.MarshalMsg(o)
}
- if (zb0004Mask & 0x1000) == 0 { // if not empty
+ if (zb0005Mask & 0x2000) == 0 { // if not empty
// string "nextswitch"
o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68)
o = (*z).UpgradeState.NextProtocolSwitchOn.MarshalMsg(o)
}
- if (zb0004Mask & 0x2000) == 0 { // if not empty
+ if (zb0005Mask & 0x4000) == 0 { // if not empty
// string "nextyes"
o = append(o, 0xa7, 0x6e, 0x65, 0x78, 0x74, 0x79, 0x65, 0x73)
o = msgp.AppendUint64(o, (*z).UpgradeState.NextProtocolApprovals)
}
- if (zb0004Mask & 0x4000) == 0 { // if not empty
+ if (zb0005Mask & 0x8000) == 0 { // if not empty
+ // string "partupdabs"
+ o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x61, 0x62, 0x73)
+ if (*z).ParticipationUpdates.AbsentParticipationAccounts == nil {
+ o = msgp.AppendNil(o)
+ } else {
+ o = msgp.AppendArrayHeader(o, uint32(len((*z).ParticipationUpdates.AbsentParticipationAccounts)))
+ }
+ for zb0004 := range (*z).ParticipationUpdates.AbsentParticipationAccounts {
+ o = (*z).ParticipationUpdates.AbsentParticipationAccounts[zb0004].MarshalMsg(o)
+ }
+ }
+ if (zb0005Mask & 0x10000) == 0 { // if not empty
// string "partupdrmv"
o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76)
if (*z).ParticipationUpdates.ExpiredParticipationAccounts == nil {
@@ -1199,42 +1353,47 @@ func (z *BlockHeader) MarshalMsg(b []byte) (o []byte) {
o = (*z).ParticipationUpdates.ExpiredParticipationAccounts[zb0003].MarshalMsg(o)
}
}
- if (zb0004Mask & 0x8000) == 0 { // if not empty
+ if (zb0005Mask & 0x20000) == 0 { // if not empty
// string "prev"
o = append(o, 0xa4, 0x70, 0x72, 0x65, 0x76)
o = (*z).Branch.MarshalMsg(o)
}
- if (zb0004Mask & 0x10000) == 0 { // if not empty
+ if (zb0005Mask & 0x40000) == 0 { // if not empty
// string "proto"
o = append(o, 0xa5, 0x70, 0x72, 0x6f, 0x74, 0x6f)
o = (*z).UpgradeState.CurrentProtocol.MarshalMsg(o)
}
- if (zb0004Mask & 0x20000) == 0 { // if not empty
+ if (zb0005Mask & 0x80000) == 0 { // if not empty
+ // string "prp"
+ o = append(o, 0xa3, 0x70, 0x72, 0x70)
+ o = (*z).Proposer.MarshalMsg(o)
+ }
+ if (zb0005Mask & 0x100000) == 0 { // if not empty
// string "rate"
o = append(o, 0xa4, 0x72, 0x61, 0x74, 0x65)
o = msgp.AppendUint64(o, (*z).RewardsState.RewardsRate)
}
- if (zb0004Mask & 0x40000) == 0 { // if not empty
+ if (zb0005Mask & 0x200000) == 0 { // if not empty
// string "rnd"
o = append(o, 0xa3, 0x72, 0x6e, 0x64)
o = (*z).Round.MarshalMsg(o)
}
- if (zb0004Mask & 0x80000) == 0 { // if not empty
+ if (zb0005Mask & 0x400000) == 0 { // if not empty
// string "rwcalr"
o = append(o, 0xa6, 0x72, 0x77, 0x63, 0x61, 0x6c, 0x72)
o = (*z).RewardsState.RewardsRecalculationRound.MarshalMsg(o)
}
- if (zb0004Mask & 0x100000) == 0 { // if not empty
+ if (zb0005Mask & 0x800000) == 0 { // if not empty
// string "rwd"
o = append(o, 0xa3, 0x72, 0x77, 0x64)
o = (*z).RewardsState.RewardsPool.MarshalMsg(o)
}
- if (zb0004Mask & 0x200000) == 0 { // if not empty
+ if (zb0005Mask & 0x1000000) == 0 { // if not empty
// string "seed"
o = append(o, 0xa4, 0x73, 0x65, 0x65, 0x64)
o = (*z).Seed.MarshalMsg(o)
}
- if (zb0004Mask & 0x400000) == 0 { // if not empty
+ if (zb0005Mask & 0x2000000) == 0 { // if not empty
// string "spt"
o = append(o, 0xa3, 0x73, 0x70, 0x74)
if (*z).StateProofTracking == nil {
@@ -1254,37 +1413,37 @@ func (z *BlockHeader) MarshalMsg(b []byte) (o []byte) {
o = zb0002.MarshalMsg(o)
}
}
- if (zb0004Mask & 0x800000) == 0 { // if not empty
+ if (zb0005Mask & 0x4000000) == 0 { // if not empty
// string "tc"
o = append(o, 0xa2, 0x74, 0x63)
o = msgp.AppendUint64(o, (*z).TxnCounter)
}
- if (zb0004Mask & 0x1000000) == 0 { // if not empty
+ if (zb0005Mask & 0x8000000) == 0 { // if not empty
// string "ts"
o = append(o, 0xa2, 0x74, 0x73)
o = msgp.AppendInt64(o, (*z).TimeStamp)
}
- if (zb0004Mask & 0x2000000) == 0 { // if not empty
+ if (zb0005Mask & 0x10000000) == 0 { // if not empty
// string "txn"
o = append(o, 0xa3, 0x74, 0x78, 0x6e)
o = (*z).TxnCommitments.NativeSha512_256Commitment.MarshalMsg(o)
}
- if (zb0004Mask & 0x4000000) == 0 { // if not empty
+ if (zb0005Mask & 0x20000000) == 0 { // if not empty
// string "txn256"
o = append(o, 0xa6, 0x74, 0x78, 0x6e, 0x32, 0x35, 0x36)
o = (*z).TxnCommitments.Sha256Commitment.MarshalMsg(o)
}
- if (zb0004Mask & 0x8000000) == 0 { // if not empty
+ if (zb0005Mask & 0x40000000) == 0 { // if not empty
// string "upgradedelay"
o = append(o, 0xac, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x65, 0x6c, 0x61, 0x79)
o = (*z).UpgradeVote.UpgradeDelay.MarshalMsg(o)
}
- if (zb0004Mask & 0x10000000) == 0 { // if not empty
+ if (zb0005Mask & 0x80000000) == 0 { // if not empty
// string "upgradeprop"
o = append(o, 0xab, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x70, 0x72, 0x6f, 0x70)
o = (*z).UpgradeVote.UpgradePropose.MarshalMsg(o)
}
- if (zb0004Mask & 0x20000000) == 0 { // if not empty
+ if (zb0005Mask & 0x100000000) == 0 { // if not empty
// string "upgradeyes"
o = append(o, 0xaa, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x65, 0x73)
o = msgp.AppendBool(o, (*z).UpgradeVote.UpgradeApprove)
@@ -1307,73 +1466,73 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
st.AllowableDepth--
var field []byte
_ = field
- var zb0004 int
- var zb0005 bool
- zb0004, zb0005, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0005 int
+ var zb0006 bool
+ zb0005, zb0006, bts, err = msgp.ReadMapHeaderBytes(bts)
if _, ok := err.(msgp.TypeError); ok {
- zb0004, zb0005, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ zb0005, zb0006, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err)
return
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).Round.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Round")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).Branch.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Branch")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).Seed.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Seed")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).TxnCommitments.NativeSha512_256Commitment.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NativeSha512_256Commitment")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).TxnCommitments.Sha256Commitment.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "Sha256Commitment")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).TimeStamp, bts, err = msgp.ReadInt64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "TimeStamp")
return
}
}
- if zb0004 > 0 {
- zb0004--
- var zb0006 int
- zb0006, err = msgp.ReadBytesBytesHeader(bts)
+ if zb0005 > 0 {
+ zb0005--
+ var zb0007 int
+ zb0007, err = msgp.ReadBytesBytesHeader(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "GenesisID")
return
}
- if zb0006 > config.MaxGenesisIDLen {
- err = msgp.ErrOverflow(uint64(zb0006), uint64(config.MaxGenesisIDLen))
+ if zb0007 > config.MaxGenesisIDLen {
+ err = msgp.ErrOverflow(uint64(zb0007), uint64(config.MaxGenesisIDLen))
return
}
(*z).GenesisID, bts, err = msgp.ReadStringBytes(bts)
@@ -1382,157 +1541,173 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).GenesisHash.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "GenesisHash")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
+ bts, err = (*z).Proposer.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "Proposer")
+ return
+ }
+ }
+ if zb0005 > 0 {
+ zb0005--
+ bts, err = (*z).FeesCollected.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "FeesCollected")
+ return
+ }
+ }
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).RewardsState.FeeSink.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "FeeSink")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).RewardsState.RewardsPool.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsPool")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).RewardsState.RewardsLevel, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsLevel")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).RewardsState.RewardsRate, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsRate")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).RewardsState.RewardsResidue, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsResidue")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).RewardsState.RewardsRecalculationRound.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "RewardsRecalculationRound")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).UpgradeState.CurrentProtocol.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "CurrentProtocol")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).UpgradeState.NextProtocol.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NextProtocol")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).UpgradeState.NextProtocolApprovals, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NextProtocolApprovals")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).UpgradeState.NextProtocolVoteBefore.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NextProtocolVoteBefore")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).UpgradeState.NextProtocolSwitchOn.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "NextProtocolSwitchOn")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).UpgradeVote.UpgradePropose.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "UpgradePropose")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
bts, err = (*z).UpgradeVote.UpgradeDelay.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "UpgradeDelay")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).UpgradeVote.UpgradeApprove, bts, err = msgp.ReadBoolBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "UpgradeApprove")
return
}
}
- if zb0004 > 0 {
- zb0004--
+ if zb0005 > 0 {
+ zb0005--
(*z).TxnCounter, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "TxnCounter")
return
}
}
- if zb0004 > 0 {
- zb0004--
- var zb0007 int
- var zb0008 bool
- zb0007, zb0008, bts, err = msgp.ReadMapHeaderBytes(bts)
+ if zb0005 > 0 {
+ zb0005--
+ var zb0008 int
+ var zb0009 bool
+ zb0008, zb0009, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "StateProofTracking")
return
}
- if zb0007 > protocol.NumStateProofTypes {
- err = msgp.ErrOverflow(uint64(zb0007), uint64(protocol.NumStateProofTypes))
+ if zb0008 > protocol.NumStateProofTypes {
+ err = msgp.ErrOverflow(uint64(zb0008), uint64(protocol.NumStateProofTypes))
err = msgp.WrapError(err, "struct-from-array", "StateProofTracking")
return
}
- if zb0008 {
+ if zb0009 {
(*z).StateProofTracking = nil
} else if (*z).StateProofTracking == nil {
- (*z).StateProofTracking = make(map[protocol.StateProofType]StateProofTrackingData, zb0007)
+ (*z).StateProofTracking = make(map[protocol.StateProofType]StateProofTrackingData, zb0008)
}
- for zb0007 > 0 {
+ for zb0008 > 0 {
var zb0001 protocol.StateProofType
var zb0002 StateProofTrackingData
- zb0007--
+ zb0008--
bts, err = zb0001.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "StateProofTracking")
@@ -1546,26 +1721,26 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
(*z).StateProofTracking[zb0001] = zb0002
}
}
- if zb0004 > 0 {
- zb0004--
- var zb0009 int
- var zb0010 bool
- zb0009, zb0010, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if zb0005 > 0 {
+ zb0005--
+ var zb0010 int
+ var zb0011 bool
+ zb0010, zb0011, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts")
return
}
- if zb0009 > config.MaxProposedExpiredOnlineAccounts {
- err = msgp.ErrOverflow(uint64(zb0009), uint64(config.MaxProposedExpiredOnlineAccounts))
+ if zb0010 > config.MaxProposedExpiredOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0010), uint64(config.MaxProposedExpiredOnlineAccounts))
err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts")
return
}
- if zb0010 {
+ if zb0011 {
(*z).ParticipationUpdates.ExpiredParticipationAccounts = nil
- } else if (*z).ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).ParticipationUpdates.ExpiredParticipationAccounts) >= zb0009 {
- (*z).ParticipationUpdates.ExpiredParticipationAccounts = ((*z).ParticipationUpdates.ExpiredParticipationAccounts)[:zb0009]
+ } else if (*z).ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).ParticipationUpdates.ExpiredParticipationAccounts) >= zb0010 {
+ (*z).ParticipationUpdates.ExpiredParticipationAccounts = ((*z).ParticipationUpdates.ExpiredParticipationAccounts)[:zb0010]
} else {
- (*z).ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0009)
+ (*z).ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0010)
}
for zb0003 := range (*z).ParticipationUpdates.ExpiredParticipationAccounts {
bts, err = (*z).ParticipationUpdates.ExpiredParticipationAccounts[zb0003].UnmarshalMsgWithState(bts, st)
@@ -1575,8 +1750,37 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
}
}
}
- if zb0004 > 0 {
- err = msgp.ErrTooManyArrayFields(zb0004)
+ if zb0005 > 0 {
+ zb0005--
+ var zb0012 int
+ var zb0013 bool
+ zb0012, zb0013, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts")
+ return
+ }
+ if zb0012 > config.MaxProposedAbsentOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0012), uint64(config.MaxProposedAbsentOnlineAccounts))
+ err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts")
+ return
+ }
+ if zb0013 {
+ (*z).ParticipationUpdates.AbsentParticipationAccounts = nil
+ } else if (*z).ParticipationUpdates.AbsentParticipationAccounts != nil && cap((*z).ParticipationUpdates.AbsentParticipationAccounts) >= zb0012 {
+ (*z).ParticipationUpdates.AbsentParticipationAccounts = ((*z).ParticipationUpdates.AbsentParticipationAccounts)[:zb0012]
+ } else {
+ (*z).ParticipationUpdates.AbsentParticipationAccounts = make([]basics.Address, zb0012)
+ }
+ for zb0004 := range (*z).ParticipationUpdates.AbsentParticipationAccounts {
+ bts, err = (*z).ParticipationUpdates.AbsentParticipationAccounts[zb0004].UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts", zb0004)
+ return
+ }
+ }
+ }
+ if zb0005 > 0 {
+ err = msgp.ErrTooManyArrayFields(zb0005)
if err != nil {
err = msgp.WrapError(err, "struct-from-array")
return
@@ -1587,11 +1791,11 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
err = msgp.WrapError(err)
return
}
- if zb0005 {
+ if zb0006 {
(*z) = BlockHeader{}
}
- for zb0004 > 0 {
- zb0004--
+ for zb0005 > 0 {
+ zb0005--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
err = msgp.WrapError(err)
@@ -1635,14 +1839,14 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
return
}
case "gen":
- var zb0011 int
- zb0011, err = msgp.ReadBytesBytesHeader(bts)
+ var zb0014 int
+ zb0014, err = msgp.ReadBytesBytesHeader(bts)
if err != nil {
err = msgp.WrapError(err, "GenesisID")
return
}
- if zb0011 > config.MaxGenesisIDLen {
- err = msgp.ErrOverflow(uint64(zb0011), uint64(config.MaxGenesisIDLen))
+ if zb0014 > config.MaxGenesisIDLen {
+ err = msgp.ErrOverflow(uint64(zb0014), uint64(config.MaxGenesisIDLen))
return
}
(*z).GenesisID, bts, err = msgp.ReadStringBytes(bts)
@@ -1656,6 +1860,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 {
@@ -1747,27 +1963,27 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
return
}
case "spt":
- var zb0012 int
- var zb0013 bool
- zb0012, zb0013, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0015 int
+ var zb0016 bool
+ zb0015, zb0016, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "StateProofTracking")
return
}
- if zb0012 > protocol.NumStateProofTypes {
- err = msgp.ErrOverflow(uint64(zb0012), uint64(protocol.NumStateProofTypes))
+ if zb0015 > protocol.NumStateProofTypes {
+ err = msgp.ErrOverflow(uint64(zb0015), uint64(protocol.NumStateProofTypes))
err = msgp.WrapError(err, "StateProofTracking")
return
}
- if zb0013 {
+ if zb0016 {
(*z).StateProofTracking = nil
} else if (*z).StateProofTracking == nil {
- (*z).StateProofTracking = make(map[protocol.StateProofType]StateProofTrackingData, zb0012)
+ (*z).StateProofTracking = make(map[protocol.StateProofType]StateProofTrackingData, zb0015)
}
- for zb0012 > 0 {
+ for zb0015 > 0 {
var zb0001 protocol.StateProofType
var zb0002 StateProofTrackingData
- zb0012--
+ zb0015--
bts, err = zb0001.UnmarshalMsgWithState(bts, st)
if err != nil {
err = msgp.WrapError(err, "StateProofTracking")
@@ -1781,24 +1997,24 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
(*z).StateProofTracking[zb0001] = zb0002
}
case "partupdrmv":
- var zb0014 int
- var zb0015 bool
- zb0014, zb0015, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ var zb0017 int
+ var zb0018 bool
+ zb0017, zb0018, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "ExpiredParticipationAccounts")
return
}
- if zb0014 > config.MaxProposedExpiredOnlineAccounts {
- err = msgp.ErrOverflow(uint64(zb0014), uint64(config.MaxProposedExpiredOnlineAccounts))
+ if zb0017 > config.MaxProposedExpiredOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0017), uint64(config.MaxProposedExpiredOnlineAccounts))
err = msgp.WrapError(err, "ExpiredParticipationAccounts")
return
}
- if zb0015 {
+ if zb0018 {
(*z).ParticipationUpdates.ExpiredParticipationAccounts = nil
- } else if (*z).ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).ParticipationUpdates.ExpiredParticipationAccounts) >= zb0014 {
- (*z).ParticipationUpdates.ExpiredParticipationAccounts = ((*z).ParticipationUpdates.ExpiredParticipationAccounts)[:zb0014]
+ } else if (*z).ParticipationUpdates.ExpiredParticipationAccounts != nil && cap((*z).ParticipationUpdates.ExpiredParticipationAccounts) >= zb0017 {
+ (*z).ParticipationUpdates.ExpiredParticipationAccounts = ((*z).ParticipationUpdates.ExpiredParticipationAccounts)[:zb0017]
} else {
- (*z).ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0014)
+ (*z).ParticipationUpdates.ExpiredParticipationAccounts = make([]basics.Address, zb0017)
}
for zb0003 := range (*z).ParticipationUpdates.ExpiredParticipationAccounts {
bts, err = (*z).ParticipationUpdates.ExpiredParticipationAccounts[zb0003].UnmarshalMsgWithState(bts, st)
@@ -1807,6 +2023,33 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
return
}
}
+ case "partupdabs":
+ var zb0019 int
+ var zb0020 bool
+ zb0019, zb0020, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "AbsentParticipationAccounts")
+ return
+ }
+ if zb0019 > config.MaxProposedAbsentOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0019), uint64(config.MaxProposedAbsentOnlineAccounts))
+ err = msgp.WrapError(err, "AbsentParticipationAccounts")
+ return
+ }
+ if zb0020 {
+ (*z).ParticipationUpdates.AbsentParticipationAccounts = nil
+ } else if (*z).ParticipationUpdates.AbsentParticipationAccounts != nil && cap((*z).ParticipationUpdates.AbsentParticipationAccounts) >= zb0019 {
+ (*z).ParticipationUpdates.AbsentParticipationAccounts = ((*z).ParticipationUpdates.AbsentParticipationAccounts)[:zb0019]
+ } else {
+ (*z).ParticipationUpdates.AbsentParticipationAccounts = make([]basics.Address, zb0019)
+ }
+ for zb0004 := range (*z).ParticipationUpdates.AbsentParticipationAccounts {
+ bts, err = (*z).ParticipationUpdates.AbsentParticipationAccounts[zb0004].UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "AbsentParticipationAccounts", zb0004)
+ return
+ }
+ }
default:
err = msgp.ErrNoField(string(field))
if err != nil {
@@ -1830,7 +2073,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
@@ -1842,17 +2085,21 @@ func (z *BlockHeader) Msgsize() (s int) {
for zb0003 := range (*z).ParticipationUpdates.ExpiredParticipationAccounts {
s += (*z).ParticipationUpdates.ExpiredParticipationAccounts[zb0003].Msgsize()
}
+ s += 11 + msgp.ArrayHeaderSize
+ for zb0004 := range (*z).ParticipationUpdates.AbsentParticipationAccounts {
+ s += (*z).ParticipationUpdates.AbsentParticipationAccounts[zb0004].Msgsize()
+ }
return
}
// MsgIsZero returns whether this is a zero value
func (z *BlockHeader) MsgIsZero() bool {
- return ((*z).Round.MsgIsZero()) && ((*z).Branch.MsgIsZero()) && ((*z).Seed.MsgIsZero()) && ((*z).TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).TimeStamp == 0) && ((*z).GenesisID == "") && ((*z).GenesisHash.MsgIsZero()) && ((*z).RewardsState.FeeSink.MsgIsZero()) && ((*z).RewardsState.RewardsPool.MsgIsZero()) && ((*z).RewardsState.RewardsLevel == 0) && ((*z).RewardsState.RewardsRate == 0) && ((*z).RewardsState.RewardsResidue == 0) && ((*z).RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).UpgradeState.NextProtocol.MsgIsZero()) && ((*z).UpgradeState.NextProtocolApprovals == 0) && ((*z).UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).UpgradeVote.UpgradeApprove == false) && ((*z).TxnCounter == 0) && (len((*z).StateProofTracking) == 0) && (len((*z).ParticipationUpdates.ExpiredParticipationAccounts) == 0)
+ return ((*z).Round.MsgIsZero()) && ((*z).Branch.MsgIsZero()) && ((*z).Seed.MsgIsZero()) && ((*z).TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).TimeStamp == 0) && ((*z).GenesisID == "") && ((*z).GenesisHash.MsgIsZero()) && ((*z).Proposer.MsgIsZero()) && ((*z).FeesCollected.MsgIsZero()) && ((*z).RewardsState.FeeSink.MsgIsZero()) && ((*z).RewardsState.RewardsPool.MsgIsZero()) && ((*z).RewardsState.RewardsLevel == 0) && ((*z).RewardsState.RewardsRate == 0) && ((*z).RewardsState.RewardsResidue == 0) && ((*z).RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).UpgradeState.NextProtocol.MsgIsZero()) && ((*z).UpgradeState.NextProtocolApprovals == 0) && ((*z).UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).UpgradeVote.UpgradeApprove == false) && ((*z).TxnCounter == 0) && (len((*z).StateProofTracking) == 0) && (len((*z).ParticipationUpdates.ExpiredParticipationAccounts) == 0) && (len((*z).ParticipationUpdates.AbsentParticipationAccounts) == 0)
}
// MaxSize returns a maximum valid message size for this message type
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())
@@ -1861,6 +2108,9 @@ func BlockHeaderMaxSize() (s int) {
s += 11
// Calculating size of slice: z.ParticipationUpdates.ExpiredParticipationAccounts
s += msgp.ArrayHeaderSize + ((config.MaxProposedExpiredOnlineAccounts) * (basics.AddressMaxSize()))
+ s += 11
+ // Calculating size of slice: z.ParticipationUpdates.AbsentParticipationAccounts
+ s += msgp.ArrayHeaderSize + ((config.MaxProposedAbsentOnlineAccounts) * (basics.AddressMaxSize()))
return
}
@@ -2852,16 +3102,32 @@ func LightBlockHeaderMaxSize() (s int) {
func (z *ParticipationUpdates) MarshalMsg(b []byte) (o []byte) {
o = msgp.Require(b, z.Msgsize())
// omitempty: check for empty values
- zb0002Len := uint32(1)
- var zb0002Mask uint8 /* 2 bits */
- if len((*z).ExpiredParticipationAccounts) == 0 {
- zb0002Len--
- zb0002Mask |= 0x2
+ zb0003Len := uint32(2)
+ var zb0003Mask uint8 /* 3 bits */
+ if len((*z).AbsentParticipationAccounts) == 0 {
+ zb0003Len--
+ zb0003Mask |= 0x2
}
- // variable map header, size zb0002Len
- o = append(o, 0x80|uint8(zb0002Len))
- if zb0002Len != 0 {
- if (zb0002Mask & 0x2) == 0 { // if not empty
+ if len((*z).ExpiredParticipationAccounts) == 0 {
+ zb0003Len--
+ zb0003Mask |= 0x4
+ }
+ // variable map header, size zb0003Len
+ o = append(o, 0x80|uint8(zb0003Len))
+ if zb0003Len != 0 {
+ if (zb0003Mask & 0x2) == 0 { // if not empty
+ // string "partupdabs"
+ o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x61, 0x62, 0x73)
+ if (*z).AbsentParticipationAccounts == nil {
+ o = msgp.AppendNil(o)
+ } else {
+ o = msgp.AppendArrayHeader(o, uint32(len((*z).AbsentParticipationAccounts)))
+ }
+ for zb0002 := range (*z).AbsentParticipationAccounts {
+ o = (*z).AbsentParticipationAccounts[zb0002].MarshalMsg(o)
+ }
+ }
+ if (zb0003Mask & 0x4) == 0 { // if not empty
// string "partupdrmv"
o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76)
if (*z).ExpiredParticipationAccounts == nil {
@@ -2891,35 +3157,35 @@ func (z *ParticipationUpdates) UnmarshalMsgWithState(bts []byte, st msgp.Unmarsh
st.AllowableDepth--
var field []byte
_ = field
- var zb0002 int
- var zb0003 bool
- zb0002, zb0003, bts, err = msgp.ReadMapHeaderBytes(bts)
+ var zb0003 int
+ var zb0004 bool
+ zb0003, zb0004, bts, err = msgp.ReadMapHeaderBytes(bts)
if _, ok := err.(msgp.TypeError); ok {
- zb0002, zb0003, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ zb0003, zb0004, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err)
return
}
- if zb0002 > 0 {
- zb0002--
- var zb0004 int
- var zb0005 bool
- zb0004, zb0005, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if zb0003 > 0 {
+ zb0003--
+ var zb0005 int
+ var zb0006 bool
+ zb0005, zb0006, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts")
return
}
- if zb0004 > config.MaxProposedExpiredOnlineAccounts {
- err = msgp.ErrOverflow(uint64(zb0004), uint64(config.MaxProposedExpiredOnlineAccounts))
+ if zb0005 > config.MaxProposedExpiredOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0005), uint64(config.MaxProposedExpiredOnlineAccounts))
err = msgp.WrapError(err, "struct-from-array", "ExpiredParticipationAccounts")
return
}
- if zb0005 {
+ if zb0006 {
(*z).ExpiredParticipationAccounts = nil
- } else if (*z).ExpiredParticipationAccounts != nil && cap((*z).ExpiredParticipationAccounts) >= zb0004 {
- (*z).ExpiredParticipationAccounts = ((*z).ExpiredParticipationAccounts)[:zb0004]
+ } else if (*z).ExpiredParticipationAccounts != nil && cap((*z).ExpiredParticipationAccounts) >= zb0005 {
+ (*z).ExpiredParticipationAccounts = ((*z).ExpiredParticipationAccounts)[:zb0005]
} else {
- (*z).ExpiredParticipationAccounts = make([]basics.Address, zb0004)
+ (*z).ExpiredParticipationAccounts = make([]basics.Address, zb0005)
}
for zb0001 := range (*z).ExpiredParticipationAccounts {
bts, err = (*z).ExpiredParticipationAccounts[zb0001].UnmarshalMsgWithState(bts, st)
@@ -2929,8 +3195,37 @@ func (z *ParticipationUpdates) UnmarshalMsgWithState(bts []byte, st msgp.Unmarsh
}
}
}
- if zb0002 > 0 {
- err = msgp.ErrTooManyArrayFields(zb0002)
+ if zb0003 > 0 {
+ zb0003--
+ var zb0007 int
+ var zb0008 bool
+ zb0007, zb0008, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts")
+ return
+ }
+ if zb0007 > config.MaxProposedAbsentOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0007), uint64(config.MaxProposedAbsentOnlineAccounts))
+ err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts")
+ return
+ }
+ if zb0008 {
+ (*z).AbsentParticipationAccounts = nil
+ } else if (*z).AbsentParticipationAccounts != nil && cap((*z).AbsentParticipationAccounts) >= zb0007 {
+ (*z).AbsentParticipationAccounts = ((*z).AbsentParticipationAccounts)[:zb0007]
+ } else {
+ (*z).AbsentParticipationAccounts = make([]basics.Address, zb0007)
+ }
+ for zb0002 := range (*z).AbsentParticipationAccounts {
+ bts, err = (*z).AbsentParticipationAccounts[zb0002].UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "AbsentParticipationAccounts", zb0002)
+ return
+ }
+ }
+ }
+ if zb0003 > 0 {
+ err = msgp.ErrTooManyArrayFields(zb0003)
if err != nil {
err = msgp.WrapError(err, "struct-from-array")
return
@@ -2941,11 +3236,11 @@ func (z *ParticipationUpdates) UnmarshalMsgWithState(bts []byte, st msgp.Unmarsh
err = msgp.WrapError(err)
return
}
- if zb0003 {
+ if zb0004 {
(*z) = ParticipationUpdates{}
}
- for zb0002 > 0 {
- zb0002--
+ for zb0003 > 0 {
+ zb0003--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
err = msgp.WrapError(err)
@@ -2953,24 +3248,24 @@ func (z *ParticipationUpdates) UnmarshalMsgWithState(bts []byte, st msgp.Unmarsh
}
switch string(field) {
case "partupdrmv":
- var zb0006 int
- var zb0007 bool
- zb0006, zb0007, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ var zb0009 int
+ var zb0010 bool
+ zb0009, zb0010, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
err = msgp.WrapError(err, "ExpiredParticipationAccounts")
return
}
- if zb0006 > config.MaxProposedExpiredOnlineAccounts {
- err = msgp.ErrOverflow(uint64(zb0006), uint64(config.MaxProposedExpiredOnlineAccounts))
+ if zb0009 > config.MaxProposedExpiredOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0009), uint64(config.MaxProposedExpiredOnlineAccounts))
err = msgp.WrapError(err, "ExpiredParticipationAccounts")
return
}
- if zb0007 {
+ if zb0010 {
(*z).ExpiredParticipationAccounts = nil
- } else if (*z).ExpiredParticipationAccounts != nil && cap((*z).ExpiredParticipationAccounts) >= zb0006 {
- (*z).ExpiredParticipationAccounts = ((*z).ExpiredParticipationAccounts)[:zb0006]
+ } else if (*z).ExpiredParticipationAccounts != nil && cap((*z).ExpiredParticipationAccounts) >= zb0009 {
+ (*z).ExpiredParticipationAccounts = ((*z).ExpiredParticipationAccounts)[:zb0009]
} else {
- (*z).ExpiredParticipationAccounts = make([]basics.Address, zb0006)
+ (*z).ExpiredParticipationAccounts = make([]basics.Address, zb0009)
}
for zb0001 := range (*z).ExpiredParticipationAccounts {
bts, err = (*z).ExpiredParticipationAccounts[zb0001].UnmarshalMsgWithState(bts, st)
@@ -2979,6 +3274,33 @@ func (z *ParticipationUpdates) UnmarshalMsgWithState(bts []byte, st msgp.Unmarsh
return
}
}
+ case "partupdabs":
+ var zb0011 int
+ var zb0012 bool
+ zb0011, zb0012, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "AbsentParticipationAccounts")
+ return
+ }
+ if zb0011 > config.MaxProposedAbsentOnlineAccounts {
+ err = msgp.ErrOverflow(uint64(zb0011), uint64(config.MaxProposedAbsentOnlineAccounts))
+ err = msgp.WrapError(err, "AbsentParticipationAccounts")
+ return
+ }
+ if zb0012 {
+ (*z).AbsentParticipationAccounts = nil
+ } else if (*z).AbsentParticipationAccounts != nil && cap((*z).AbsentParticipationAccounts) >= zb0011 {
+ (*z).AbsentParticipationAccounts = ((*z).AbsentParticipationAccounts)[:zb0011]
+ } else {
+ (*z).AbsentParticipationAccounts = make([]basics.Address, zb0011)
+ }
+ for zb0002 := range (*z).AbsentParticipationAccounts {
+ bts, err = (*z).AbsentParticipationAccounts[zb0002].UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "AbsentParticipationAccounts", zb0002)
+ return
+ }
+ }
default:
err = msgp.ErrNoField(string(field))
if err != nil {
@@ -3006,12 +3328,16 @@ func (z *ParticipationUpdates) Msgsize() (s int) {
for zb0001 := range (*z).ExpiredParticipationAccounts {
s += (*z).ExpiredParticipationAccounts[zb0001].Msgsize()
}
+ s += 11 + msgp.ArrayHeaderSize
+ for zb0002 := range (*z).AbsentParticipationAccounts {
+ s += (*z).AbsentParticipationAccounts[zb0002].Msgsize()
+ }
return
}
// MsgIsZero returns whether this is a zero value
func (z *ParticipationUpdates) MsgIsZero() bool {
- return (len((*z).ExpiredParticipationAccounts) == 0)
+ return (len((*z).ExpiredParticipationAccounts) == 0) && (len((*z).AbsentParticipationAccounts) == 0)
}
// MaxSize returns a maximum valid message size for this message type
@@ -3019,6 +3345,9 @@ func ParticipationUpdatesMaxSize() (s int) {
s = 1 + 11
// Calculating size of slice: z.ExpiredParticipationAccounts
s += msgp.ArrayHeaderSize + ((config.MaxProposedExpiredOnlineAccounts) * (basics.AddressMaxSize()))
+ s += 11
+ // Calculating size of slice: z.AbsentParticipationAccounts
+ s += msgp.ArrayHeaderSize + ((config.MaxProposedAbsentOnlineAccounts) * (basics.AddressMaxSize()))
return
}
diff --git a/data/datatest/impls.go b/data/datatest/impls.go
index fefcb054da..8e14885c96 100644
--- a/data/datatest/impls.go
+++ b/data/datatest/impls.go
@@ -65,8 +65,8 @@ func (i entryFactoryImpl) AssembleBlock(round basics.Round) (agreement.Validated
}
// WithSeed implements the agreement.ValidatedBlock interface.
-func (ve validatedBlock) WithSeed(s committee.Seed) agreement.ValidatedBlock {
- newblock := ve.blk.WithSeed(s)
+func (ve validatedBlock) WithSeed(s committee.Seed, proposer basics.Address) agreement.ValidatedBlock {
+ newblock := ve.blk.WithSeed(s, proposer)
return validatedBlock{blk: &newblock}
}
diff --git a/data/transactions/logic/README.md b/data/transactions/logic/README.md
index 1ec45b6e2c..9bb080bc98 100644
--- a/data/transactions/logic/README.md
+++ b/data/transactions/logic/README.md
@@ -469,6 +469,7 @@ these results may contain leading zero bytes.
| `ed25519verify` | for (data A, signature B, pubkey C) verify the signature of ("ProgData" \|\| program_hash \|\| data) against the pubkey => {0 or 1} |
| `ed25519verify_bare` | for (data A, signature B, pubkey C) verify the signature of the data against the pubkey => {0 or 1} |
| `ecdsa_verify v` | for (data A, signature B, C and pubkey D, E) verify the signature of the data against the pubkey => {0 or 1} |
+| `heartbeat` | for (signature components A, B, C, D, E, and account F) verify the signature of the block seed from round txn.FirstValid-1 using F's partkey for txn.LastValid |
| `ecdsa_pk_recover v` | for (data A, recovery id B, signature C, D) recover a public key |
| `ecdsa_pk_decompress v` | decompress pubkey A into components X, Y |
| `vrf_verify s` | Verify the proof B of message A against pubkey C. Returns vrf output and verification flag. |
@@ -696,6 +697,8 @@ Account fields used in the `acct_params_get` opcode.
| 9 | AcctTotalAssets | uint64 | v8 | The numbers of ASAs held by this account (including ASAs this account created). |
| 10 | AcctTotalBoxes | uint64 | v8 | The number of existing boxes created by this account's app. |
| 11 | AcctTotalBoxBytes | uint64 | v8 | The total number of bytes used by this account's app's box keys and values. |
+| 12 | AcctLastProposed | uint64 | v10 | The round in which this account last proposed. |
+| 13 | AcctLastHeartbeat | uint64 | v10 | The round in which the account went online or executed `heartbeat`. |
### Flow Control
diff --git a/data/transactions/logic/TEAL_opcodes_v10.md b/data/transactions/logic/TEAL_opcodes_v10.md
index 4ec00a52bb..16c99c0261 100644
--- a/data/transactions/logic/TEAL_opcodes_v10.md
+++ b/data/transactions/logic/TEAL_opcodes_v10.md
@@ -1081,6 +1081,8 @@ Fields
| 9 | AcctTotalAssets | uint64 | v8 | The numbers of ASAs held by this account (including ASAs this account created). |
| 10 | AcctTotalBoxes | uint64 | v8 | The number of existing boxes created by this account's app. |
| 11 | AcctTotalBoxBytes | uint64 | v8 | The total number of bytes used by this account's app's box keys and values. |
+| 12 | AcctLastProposed | uint64 | v10 | The round in which this account last proposed. |
+| 13 | AcctLastHeartbeat | uint64 | v10 | The round in which the account went online or executed `heartbeat`. |
## min_balance
@@ -1141,6 +1143,15 @@ pushints args are not added to the intcblock during assembly processes
- **Cost**: 1900
- Availability: v7
+## heartbeat
+
+- Bytecode: 0x87
+- Stack: ..., A: [64]byte, B: [32]byte, C: [64]byte, D: [32]byte, E: [64]byte, F → ...
+- for (signature components A, B, C, D, E, and account F) verify the signature of the block seed from round txn.FirstValid-1 using F's partkey for txn.LastValid
+- **Cost**: 5700
+- Availability: v10
+- Mode: Application
+
## callsub
- Syntax: `callsub TARGET` ∋ TARGET: branch offset
@@ -1635,10 +1646,12 @@ Standards
Fields
-| Index | Name | Type | Notes |
-| - | ------ | -- | --------- |
-| 0 | BlkSeed | []byte | |
-| 1 | BlkTimestamp | uint64 | |
+| Index | Name | Type | In | Notes |
+| - | ------ | -- | - | --------- |
+| 0 | BlkSeed | []byte | | |
+| 1 | BlkTimestamp | uint64 | | |
+| 2 | BlkProposer | address | v10 | |
+| 3 | BlkFeesCollected | uint64 | v10 | |
## ec_add
diff --git a/data/transactions/logic/assembler.go b/data/transactions/logic/assembler.go
index aa32c51eba..d9f839cbb7 100644
--- a/data/transactions/logic/assembler.go
+++ b/data/transactions/logic/assembler.go
@@ -1992,8 +1992,8 @@ func (ops *OpStream) trackStack(args StackTypes, returns StackTypes, instruction
ops.trace(", %s", argType)
}
if !stype.overlaps(argType) {
- ops.typeErrorf(tokens[0], "%s arg %d wanted type %s got %s",
- reJoin(instruction, tokens[1:]), i, argType, stype)
+ ops.typeErrorf(tokens[0], "%s arg %c wanted type %s got %s",
+ reJoin(instruction, tokens[1:]), argName(i), argType, stype)
}
}
if !firstPop {
diff --git a/data/transactions/logic/assembler_test.go b/data/transactions/logic/assembler_test.go
index 0a6a0c1f89..08cdb3d69c 100644
--- a/data/transactions/logic/assembler_test.go
+++ b/data/transactions/logic/assembler_test.go
@@ -430,7 +430,8 @@ pushbytess "1" "2" "1"
const v8Nonsense = v7Nonsense + switchNonsense + frameNonsense + matchNonsense + boxNonsense
const v9Nonsense = v8Nonsense
-const v10Nonsense = v9Nonsense + pairingNonsense
+
+const v10Nonsense = v9Nonsense + pairingNonsense + incentiveNonsense
const v6Compiled = "2004010002b7a60c26050242420c68656c6c6f20776f726c6421070123456789abcd208dae2087fbba51304eb02b91f656948397a7946390e8cb70fc9ea4d95f92251d047465737400320032013202320380021234292929292b0431003101310231043105310731083109310a310b310c310d310e310f3111311231133114311533000033000133000233000433000533000733000833000933000a33000b33000c33000d33000e33000f3300113300123300133300143300152d2e01022581f8acd19181cf959a1281f8acd19181cf951a81f8acd19181cf1581f8acd191810f082209240a220b230c240d250e230f2310231123122313231418191a1b1c28171615400003290349483403350222231d4a484848482b50512a632223524100034200004322602261222704634848222862482864286548482228246628226723286828692322700048482371004848361c0037001a0031183119311b311d311e311f312023221e312131223123312431253126312731283129312a312b312c312d312e312f447825225314225427042455220824564c4d4b0222382124391c0081e80780046a6f686e2281d00f23241f880003420001892224902291922494249593a0a1a2a3a4a5a6a7a8a9aaabacadae24af3a00003b003c003d816472064e014f012a57000823810858235b235a2359b03139330039b1b200b322c01a23c1001a2323c21a23c3233e233f8120af06002a494905002a49490700b400b53a03b6b7043cb8033a0c2349c42a9631007300810881088120978101c53a8101c6003a"
@@ -447,7 +448,7 @@ const matchCompiled = "83030102018e02fff500008203013101320131"
const v8Compiled = v7Compiled + switchCompiled + frameCompiled + matchCompiled + boxCompiled
const v9Compiled = v8Compiled
-const v10Compiled = v9Compiled + pairingCompiled
+const v10Compiled = v9Compiled + pairingCompiled + incentiveCompiled
var nonsense = map[uint64]string{
1: v1Nonsense,
@@ -797,9 +798,9 @@ func TestAssembleGlobal(t *testing.T) {
testProg(t, "global MinTxnFee; int 2; +", AssemblerMaxVersion)
testProg(t, "global ZeroAddress; byte 0x12; concat; len", AssemblerMaxVersion)
testProg(t, "global MinTxnFee; byte 0x12; concat", AssemblerMaxVersion,
- exp(1, "concat arg 0 wanted type []byte...", 29))
+ exp(1, "concat arg A wanted type []byte...", 29))
testProg(t, "int 2; global ZeroAddress; +", AssemblerMaxVersion,
- exp(1, "+ arg 1 wanted type uint64...", 27))
+ exp(1, "+ arg B wanted type uint64...", 27))
}
func TestAssembleDefault(t *testing.T) {
@@ -811,7 +812,7 @@ int 1
+
// comment
`
- testProg(t, source, AssemblerMaxVersion, exp(3, "+ arg 0 wanted type uint64 got [5]byte", 1))
+ testProg(t, source, AssemblerMaxVersion, exp(3, "+ arg A wanted type uint64 got [5]byte", 1))
}
// mutateProgVersion replaces version (first two symbols) in hex-encoded program
@@ -1945,7 +1946,7 @@ balance
int 1
==`
for v := uint64(2); v < directRefEnabledVersion; v++ {
- testProg(t, source, v, exp(2, "balance arg 0 wanted type uint64 got [1]byte"))
+ testProg(t, source, v, exp(2, "balance arg A wanted type uint64 got [1]byte"))
}
for v := uint64(directRefEnabledVersion); v <= AssemblerMaxVersion; v++ {
testProg(t, source, v)
@@ -1961,7 +1962,7 @@ min_balance
int 1
==`
for v := uint64(3); v < directRefEnabledVersion; v++ {
- testProg(t, source, v, exp(2, "min_balance arg 0 wanted type uint64 got [1]byte"))
+ testProg(t, source, v, exp(2, "min_balance arg A wanted type uint64 got [1]byte"))
}
for v := uint64(directRefEnabledVersion); v <= AssemblerMaxVersion; v++ {
testProg(t, source, v)
@@ -1985,15 +1986,15 @@ func TestAssembleAsset(t *testing.T) {
exp(1, "asset_holding_get unknown field: \"ABC\""))
testProg(t, "byte 0x1234; asset_params_get ABC 1", v,
- exp(1, "asset_params_get ABC 1 arg 0 wanted type uint64..."))
+ exp(1, "asset_params_get ABC 1 arg A wanted type uint64..."))
// Test that AssetUnitName is known to return bytes
testProg(t, "int 1; asset_params_get AssetUnitName; pop; int 1; +", v,
- exp(1, "+ arg 0 wanted type uint64..."))
+ exp(1, "+ arg A wanted type uint64..."))
// Test that AssetTotal is known to return uint64
testProg(t, "int 1; asset_params_get AssetTotal; pop; byte 0x12; concat", v,
- exp(1, "concat arg 0 wanted type []byte..."))
+ exp(1, "concat arg A wanted type []byte..."))
testLine(t, "asset_params_get ABC 1", v, "asset_params_get expects 1 immediate argument")
testLine(t, "asset_params_get ABC", v, "asset_params_get unknown field: \"ABC\"")
@@ -2620,10 +2621,10 @@ func TestSwapTypeCheck(t *testing.T) {
t.Parallel()
/* reconfirm that we detect this type error */
- testProg(t, "int 1; byte 0x1234; +", AssemblerMaxVersion, exp(1, "+ arg 1..."))
+ testProg(t, "int 1; byte 0x1234; +", AssemblerMaxVersion, exp(1, "+ arg B..."))
/* despite swap, we track types */
- testProg(t, "int 1; byte 0x1234; swap; +", AssemblerMaxVersion, exp(1, "+ arg 0..."))
- testProg(t, "byte 0x1234; int 1; swap; +", AssemblerMaxVersion, exp(1, "+ arg 1..."))
+ testProg(t, "int 1; byte 0x1234; swap; +", AssemblerMaxVersion, exp(1, "+ arg A..."))
+ testProg(t, "byte 0x1234; int 1; swap; +", AssemblerMaxVersion, exp(1, "+ arg B..."))
}
func TestDigAsm(t *testing.T) {
@@ -2634,7 +2635,7 @@ func TestDigAsm(t *testing.T) {
testProg(t, "int 1; byte 0x1234; int 2; dig 2; +", AssemblerMaxVersion)
testProg(t, "byte 0x32; byte 0x1234; int 2; dig 2; +", AssemblerMaxVersion,
- exp(1, "+ arg 1..."))
+ exp(1, "+ arg B..."))
testProg(t, "byte 0x32; byte 0x1234; int 2; dig 3; +", AssemblerMaxVersion,
exp(1, "dig 3 expects 4..."))
testProg(t, "int 1; byte 0x1234; int 2; dig 12; +", AssemblerMaxVersion,
@@ -2642,7 +2643,7 @@ func TestDigAsm(t *testing.T) {
// Confirm that digging something out does not ruin our knowledge about the types in the middle
testProg(t, "int 1; byte 0x1234; byte 0x1234; dig 2; dig 3; +; pop; +", AssemblerMaxVersion,
- exp(1, "+ arg 1..."))
+ exp(1, "+ arg B..."))
testProg(t, "int 3; pushbytes \"123456\"; int 1; dig 2; substring3", AssemblerMaxVersion)
}
@@ -2655,7 +2656,7 @@ func TestBuryAsm(t *testing.T) {
testProg(t, "int 1; byte 0x1234; int 2; bury 1; +", AssemblerMaxVersion) // the 2 replaces the byte string
testProg(t, "int 2; int 2; byte 0x1234; bury 1; +", AssemblerMaxVersion,
- exp(1, "+ arg 1..."))
+ exp(1, "+ arg B..."))
testProg(t, "byte 0x32; byte 0x1234; int 2; bury 3; +", AssemblerMaxVersion,
exp(1, "bury 3 expects 4..."))
testProg(t, "int 1; byte 0x1234; int 2; bury 12; +", AssemblerMaxVersion,
@@ -2663,11 +2664,11 @@ func TestBuryAsm(t *testing.T) {
// We do not lose track of the ints between ToS and bury index
testProg(t, "int 0; int 1; int 2; int 4; bury 3; concat", AssemblerMaxVersion,
- exp(1, "concat arg 1 wanted type []byte..."))
+ exp(1, "concat arg B wanted type []byte..."))
// Even when we are burying into unknown (seems repetitive, but is an easy bug)
testProg(t, "int 0; int 0; b LABEL; LABEL: int 1; int 2; int 4; bury 4; concat", AssemblerMaxVersion,
- exp(1, "concat arg 1 wanted type []byte..."))
+ exp(1, "concat arg B wanted type []byte..."))
testProg(t, "intcblock 55; bury 1; int 1", AssemblerMaxVersion, exp(1, "bury 1 expects 2 stack arguments...", 14))
testProg(t, "intcblock 55; int 2; bury 1; int 1", AssemblerMaxVersion, exp(1, "bury 1 expects 2 stack arguments...", 21))
@@ -2677,39 +2678,39 @@ func TestBuryAsm(t *testing.T) {
func TestEqualsTypeCheck(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()
- testProg(t, "int 1; byte 0x1234; ==", AssemblerMaxVersion, exp(1, "== arg 0..."))
- testProg(t, "int 1; byte 0x1234; !=", AssemblerMaxVersion, exp(1, "!= arg 0..."))
- testProg(t, "byte 0x1234; int 1; ==", AssemblerMaxVersion, exp(1, "== arg 0..."))
- testProg(t, "byte 0x1234; int 1; !=", AssemblerMaxVersion, exp(1, "!= arg 0..."))
+ testProg(t, "int 1; byte 0x1234; ==", AssemblerMaxVersion, exp(1, "== arg A..."))
+ testProg(t, "int 1; byte 0x1234; !=", AssemblerMaxVersion, exp(1, "!= arg A..."))
+ testProg(t, "byte 0x1234; int 1; ==", AssemblerMaxVersion, exp(1, "== arg A..."))
+ testProg(t, "byte 0x1234; int 1; !=", AssemblerMaxVersion, exp(1, "!= arg A..."))
}
func TestDupTypeCheck(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()
- testProg(t, "byte 0x1234; dup; int 1; +", AssemblerMaxVersion, exp(1, "+ arg 0..."))
+ testProg(t, "byte 0x1234; dup; int 1; +", AssemblerMaxVersion, exp(1, "+ arg A..."))
testProg(t, "byte 0x1234; int 1; dup; +", AssemblerMaxVersion)
- testProg(t, "byte 0x1234; int 1; dup2; +", AssemblerMaxVersion, exp(1, "+ arg 0..."))
- testProg(t, "int 1; byte 0x1234; dup2; +", AssemblerMaxVersion, exp(1, "+ arg 1..."))
+ testProg(t, "byte 0x1234; int 1; dup2; +", AssemblerMaxVersion, exp(1, "+ arg A..."))
+ testProg(t, "int 1; byte 0x1234; dup2; +", AssemblerMaxVersion, exp(1, "+ arg B..."))
- testProg(t, "byte 0x1234; int 1; dup; dig 1; len", AssemblerMaxVersion, exp(1, "len arg 0..."))
- testProg(t, "int 1; byte 0x1234; dup; dig 1; !", AssemblerMaxVersion, exp(1, "! arg 0..."))
+ testProg(t, "byte 0x1234; int 1; dup; dig 1; len", AssemblerMaxVersion, exp(1, "len arg A..."))
+ testProg(t, "int 1; byte 0x1234; dup; dig 1; !", AssemblerMaxVersion, exp(1, "! arg A..."))
- testProg(t, "byte 0x1234; int 1; dup2; dig 2; len", AssemblerMaxVersion, exp(1, "len arg 0..."))
- testProg(t, "int 1; byte 0x1234; dup2; dig 2; !", AssemblerMaxVersion, exp(1, "! arg 0..."))
+ testProg(t, "byte 0x1234; int 1; dup2; dig 2; len", AssemblerMaxVersion, exp(1, "len arg A..."))
+ testProg(t, "int 1; byte 0x1234; dup2; dig 2; !", AssemblerMaxVersion, exp(1, "! arg A..."))
}
func TestSelectTypeCheck(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()
- testProg(t, "int 1; int 2; int 3; select; len", AssemblerMaxVersion, exp(1, "len arg 0..."))
- testProg(t, "byte 0x1234; byte 0x5678; int 3; select; !", AssemblerMaxVersion, exp(1, "! arg 0..."))
+ testProg(t, "int 1; int 2; int 3; select; len", AssemblerMaxVersion, exp(1, "len arg A..."))
+ testProg(t, "byte 0x1234; byte 0x5678; int 3; select; !", AssemblerMaxVersion, exp(1, "! arg A..."))
}
func TestSetBitTypeCheck(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()
- testProg(t, "int 1; int 2; int 3; setbit; len", AssemblerMaxVersion, exp(1, "len arg 0..."))
- testProg(t, "byte 0x1234; int 2; int 3; setbit; !", AssemblerMaxVersion, exp(1, "! arg 0..."))
+ testProg(t, "int 1; int 2; int 3; setbit; len", AssemblerMaxVersion, exp(1, "len arg A..."))
+ testProg(t, "byte 0x1234; int 2; int 3; setbit; !", AssemblerMaxVersion, exp(1, "! arg A..."))
}
func TestScratchTypeCheck(t *testing.T) {
@@ -2718,15 +2719,15 @@ func TestScratchTypeCheck(t *testing.T) {
// All scratch slots should start as uint64
testProg(t, "load 0; int 1; +", AssemblerMaxVersion)
// Check load and store accurately using the scratch space
- testProg(t, "byte 0x01; store 0; load 0; int 1; +", AssemblerMaxVersion, exp(1, "+ arg 0..."))
+ testProg(t, "byte 0x01; store 0; load 0; int 1; +", AssemblerMaxVersion, exp(1, "+ arg A..."))
// Loads should know the type it's loading if all the slots are the same type
- testProg(t, "int 0; loads; btoi", AssemblerMaxVersion, exp(1, "btoi arg 0..."))
+ testProg(t, "int 0; loads; btoi", AssemblerMaxVersion, exp(1, "btoi arg A..."))
// Loads only knows the type when slot is a const
- testProg(t, "byte 0x01; store 0; int 1; loads; btoi", AssemblerMaxVersion, exp(1, "btoi arg 0..."))
+ testProg(t, "byte 0x01; store 0; int 1; loads; btoi", AssemblerMaxVersion, exp(1, "btoi arg A..."))
// Loads doesnt know the type if its the result of some other expression where we lose information
testProg(t, "byte 0x01; store 0; load 0; btoi; loads; btoi", AssemblerMaxVersion)
// Stores should only set slots to StackAny if they are not the same type as what is being stored
- testProg(t, "byte 0x01; store 0; int 3; byte 0x01; stores; load 0; int 1; +", AssemblerMaxVersion, exp(1, "+ arg 0..."))
+ testProg(t, "byte 0x01; store 0; int 3; byte 0x01; stores; load 0; int 1; +", AssemblerMaxVersion, exp(1, "+ arg A..."))
// ScratchSpace should reset after hitting label in deadcode
testProg(t, "byte 0x01; store 0; b label1; label1:; load 0; int 1; +", AssemblerMaxVersion)
// But it should reset to StackAny not uint64
@@ -2734,7 +2735,7 @@ func TestScratchTypeCheck(t *testing.T) {
// Callsubs should also reset the scratch space
testProg(t, "callsub A; load 0; btoi; return; A: byte 0x01; store 0; retsub", AssemblerMaxVersion)
// But the scratchspace should still be tracked after the callsub
- testProg(t, "callsub A; int 1; store 0; load 0; btoi; return; A: retsub", AssemblerMaxVersion, exp(1, "btoi arg 0..."))
+ testProg(t, "callsub A; int 1; store 0; load 0; btoi; return; A: retsub", AssemblerMaxVersion, exp(1, "btoi arg A..."))
}
@@ -2773,7 +2774,7 @@ func TestScratchBounds(t *testing.T) {
require.Equal(t, osv.AVMType, avmAny)
require.ElementsMatch(t, osv.Bound, static(0))
- testProg(t, "byte 0xff; store 1; load 1; return", AssemblerMaxVersion, exp(1, "return arg 0 wanted type uint64 ..."))
+ testProg(t, "byte 0xff; store 1; load 1; return", AssemblerMaxVersion, exp(1, "return arg A wanted type uint64 ..."))
}
// TestProtoAsm confirms that the assembler will yell at you if you are
@@ -2806,7 +2807,7 @@ func TestCoverAsm(t *testing.T) {
t.Parallel()
testProg(t, `int 4; byte "john"; int 5; cover 2; pop; +`, AssemblerMaxVersion)
testProg(t, `int 4; byte "ayush"; int 5; cover 1; pop; +`, AssemblerMaxVersion)
- testProg(t, `int 4; byte "john"; int 5; cover 2; +`, AssemblerMaxVersion, exp(1, "+ arg 1..."))
+ testProg(t, `int 4; byte "john"; int 5; cover 2; +`, AssemblerMaxVersion, exp(1, "+ arg B..."))
testProg(t, `int 4; cover junk`, AssemblerMaxVersion, exp(1, "cover unable to parse n ..."))
testProg(t, notrack(`int 4; int 5; cover 0`), AssemblerMaxVersion)
@@ -2818,7 +2819,7 @@ func TestUncoverAsm(t *testing.T) {
testProg(t, `int 4; byte "john"; int 5; uncover 2; +`, AssemblerMaxVersion)
testProg(t, `int 4; byte "ayush"; int 5; uncover 1; pop; +`, AssemblerMaxVersion)
testProg(t, `int 1; byte "jj"; byte "ayush"; byte "john"; int 5; uncover 4; +`, AssemblerMaxVersion)
- testProg(t, `int 4; byte "ayush"; int 5; uncover 1; +`, AssemblerMaxVersion, exp(1, "+ arg 1..."))
+ testProg(t, `int 4; byte "ayush"; int 5; uncover 1; +`, AssemblerMaxVersion, exp(1, "+ arg B..."))
}
func TestTxTypes(t *testing.T) {
@@ -2866,7 +2867,7 @@ func TestTypeTracking(t *testing.T) {
// but we do want to ensure we're not just treating the code after callsub as dead
testProg(t, "callsub A; int 1; concat; return; A: int 1; int 2; retsub", LogicVersion,
- exp(1, "concat arg 1 wanted..."))
+ exp(1, "concat arg B wanted..."))
// retsub deadens code, like any unconditional branch
testProg(t, "callsub A; +; return; A: int 1; int 2; retsub; concat", LogicVersion)
@@ -2882,7 +2883,7 @@ label:
+
confusion:
b label
-`, LogicVersion, exp(7, "+ arg 0 wanted type uint64..."))
+`, LogicVersion, exp(7, "+ arg A wanted type uint64..."))
// Unless that same error is in dead code.
testProg(t, `
@@ -2936,7 +2937,7 @@ done:
concat
#pragma typetrack true
concat
-`, LogicVersion, exp(5, "concat arg 1 wanted type []byte..."))
+`, LogicVersion, exp(5, "concat arg B wanted type []byte..."))
}
func TestMergeProtos(t *testing.T) {
@@ -2994,7 +2995,7 @@ func TestReplacePseudo(t *testing.T) {
testProg(t, "byte 0x0000; byte 0x1234; replace 0", v)
testProg(t, "byte 0x0000; int 0; byte 0x1234; replace", v)
testProg(t, "byte 0x0000; byte 0x1234; replace", v, exp(1, "replace without immediates expects 3 stack arguments but stack height is 2"))
- testProg(t, "byte 0x0000; int 0; byte 0x1234; replace 0", v, exp(1, "replace 0 arg 0 wanted type []byte got 0"))
+ testProg(t, "byte 0x0000; int 0; byte 0x1234; replace 0", v, exp(1, "replace 0 arg A wanted type []byte got 0"))
}
}
@@ -3055,7 +3056,7 @@ func TestAssembleSwitch(t *testing.T) {
byte "fail"
switch label1
labe11:
- `, AssemblerMaxVersion, exp(3, "switch label1 arg 0 wanted type uint64..."))
+ `, AssemblerMaxVersion, exp(3, "switch label1 arg A wanted type uint64..."))
// No labels is pretty degenerate, but ok, I suppose. It's just a no-op
testProg(t, `
@@ -3569,9 +3570,9 @@ func TestAssemblePushConsts(t *testing.T) {
source = `pushbytess 1 2 3`
testProg(t, source, AssemblerMaxVersion, exp(1, "pushbytess arg did not parse: 1"))
source = `pushints 6 4; concat`
- testProg(t, source, AssemblerMaxVersion, exp(1, "concat arg 1 wanted type []byte got uint64"))
+ testProg(t, source, AssemblerMaxVersion, exp(1, "concat arg B wanted type []byte got uint64"))
source = `pushbytess "x" "y"; +`
- testProg(t, source, AssemblerMaxVersion, exp(1, "+ arg 1 wanted type uint64 got []byte"))
+ testProg(t, source, AssemblerMaxVersion, exp(1, "+ arg B wanted type uint64 got []byte"))
}
func TestAssembleEmpty(t *testing.T) {
diff --git a/data/transactions/logic/crypto.go b/data/transactions/logic/crypto.go
index 43fe4d50d5..f0c5552f4e 100644
--- a/data/transactions/logic/crypto.go
+++ b/data/transactions/logic/crypto.go
@@ -27,6 +27,7 @@ import (
"github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/crypto/secp256k1"
+ "github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/protocol"
"golang.org/x/crypto/sha3"
)
@@ -136,6 +137,62 @@ func opEd25519VerifyBare(cx *EvalContext) error {
return nil
}
+func opHeartbeat(cx *EvalContext) error {
+ last := len(cx.Stack) - 1
+ pk2sig := last - 1
+ pk2 := last - 2
+ pk1sig := last - 3
+ pk := last - 4
+ sig := last - 5
+
+ addr, _, err := cx.accountReference(cx.Stack[last])
+ if err != nil {
+ return err
+ }
+
+ account, err := cx.Ledger.AccountData(addr)
+ if err != nil {
+ return err
+ }
+
+ sv := account.VoteID
+ if sv.IsEmpty() {
+ return fmt.Errorf("Account %s has has no voting keys\n", addr)
+ }
+ id := basics.OneTimeIDForRound(cx.txn.Txn.LastValid, account.VoteKeyDilution)
+
+ err = cx.checkStackArgBounds()
+ if err != nil {
+ return err
+ }
+
+ ots := crypto.OneTimeSignature{
+ Sig: [64]byte(cx.Stack[sig].Bytes), // the sig for the message, by PK
+ PK: [32]byte(cx.Stack[pk].Bytes), // the actual key that signed the message
+ PK1Sig: [64]byte(cx.Stack[pk1sig].Bytes), // the sig that proves PK is valid
+ PK2: [32]byte(cx.Stack[pk2].Bytes), // the key that signed to create PK1Sig
+ PK2Sig: [64]byte(cx.Stack[pk2sig].Bytes), // the sig that proves PK2 is valid, signed by VoteID
+ }
+
+ rnd, err := cx.availableRound(uint64(cx.txn.Txn.FirstValid) - 1)
+ if err != nil {
+ return err
+ }
+ hdr, err := cx.SigLedger.BlockHdr(rnd)
+ if err != nil {
+ return err
+ }
+
+ if !sv.Verify(id, hdr.Seed, ots) {
+ return errors.New("Improper heartbeat")
+ }
+
+ cx.Ledger.Heartbeat(addr)
+
+ cx.Stack = cx.Stack[:sig]
+ return nil
+}
+
func leadingZeros(size int, b *big.Int) ([]byte, error) {
byteLength := (b.BitLen() + 7) / 8
if size < byteLength {
diff --git a/data/transactions/logic/crypto_test.go b/data/transactions/logic/crypto_test.go
index 7c0dc5f582..22e6fd8d68 100644
--- a/data/transactions/logic/crypto_test.go
+++ b/data/transactions/logic/crypto_test.go
@@ -112,9 +112,9 @@ func TestVrfVerify(t *testing.T) {
t.Parallel()
ep := defaultAppParams()
- testApp(t, notrack("int 1; int 2; int 3; vrf_verify VrfAlgorand"), ep, "arg 0 wanted")
- testApp(t, notrack("byte 0x1122; int 2; int 3; vrf_verify VrfAlgorand"), ep, "arg 1 wanted")
- testApp(t, notrack("byte 0x1122; byte 0x2233; int 3; vrf_verify VrfAlgorand"), ep, "arg 2 wanted")
+ testApp(t, notrack("int 1; int 2; int 3; vrf_verify VrfAlgorand"), ep, "arg A wanted")
+ testApp(t, notrack("byte 0x1122; int 2; int 3; vrf_verify VrfAlgorand"), ep, "arg B wanted")
+ testApp(t, notrack("byte 0x1122; byte 0x2233; int 3; vrf_verify VrfAlgorand"), ep, "arg C wanted")
ep = defaultSigParams()
testLogic(t, notrack("byte 0x1122; byte 0x2233; byte 0x3344; vrf_verify VrfAlgorand"), LogicVersion, ep, "vrf proof wrong size")
@@ -184,13 +184,17 @@ pop // output`, "int 1"},
}
}
+func randSeed() crypto.Seed {
+ var s crypto.Seed
+ crypto.RandBytes(s[:])
+ return s
+}
+
func TestEd25519verify(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()
- var s crypto.Seed
- crypto.RandBytes(s[:])
- c := crypto.GenerateSignatureSecrets(s)
+ c := crypto.GenerateSignatureSecrets(randSeed())
msg := "62fdfc072182654f163f5f0f9a621d729566c74d0aa413bf009c9800418c19cd"
data, err := hex.DecodeString(msg)
require.NoError(t, err)
@@ -229,9 +233,7 @@ func TestEd25519VerifyBare(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()
- var s crypto.Seed
- crypto.RandBytes(s[:])
- c := crypto.GenerateSignatureSecrets(s)
+ c := crypto.GenerateSignatureSecrets(randSeed())
msg := "62fdfc072182654f163f5f0f9a621d729566c74d0aa413bf009c9800418c19cd"
data, err := hex.DecodeString(msg)
require.NoError(t, err)
@@ -264,6 +266,64 @@ func TestEd25519VerifyBare(t *testing.T) {
}
}
+func TestPartkeyVerify(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ t.Parallel()
+
+ for v := uint64(10); v <= AssemblerMaxVersion; v++ {
+ t.Run(fmt.Sprintf("v=%d", v), func(t *testing.T) {
+ ops := testProg(t, `
+ // OneTimeSignature in 5 parts
+ txn ApplicationArgs 0;
+ txn ApplicationArgs 1;
+ txn ApplicationArgs 2;
+ txn ApplicationArgs 3;
+ txn ApplicationArgs 4;
+
+ txn Sender;
+ heartbeat;
+
+ txn Sender
+ acct_params_get AcctLastHeartbeat
+ assert
+ global Round
+ ==
+`, v)
+ ep, tx, ledger := makeSampleEnv()
+ ep.Proto.MaxAppProgramCost = 6000 // ugly. real heartbeats would need a lot of opup
+
+ id := basics.OneTimeIDForRound(tx.LastValid, 10_000)
+ otss := crypto.GenerateOneTimeSignatureSecrets(id.Batch, 1)
+
+ hdr, err := ledger.BlockHdr(tx.FirstValid - 1)
+ require.NoError(t, err)
+ ots := otss.Sign(id, hdr.Seed)
+
+ tx.ApplicationArgs = [][]byte{
+ ots.Sig[:],
+ ots.PK[:],
+ ots.PK1Sig[:],
+ ots.PK2[:],
+ ots.PK2Sig[:],
+ }
+ testLogicBytes(t, ops.Program, defaultSigParams(transactions.SignedTxn{Txn: *tx}),
+ "not allowed in current mode", "not allowed in current mode")
+ ledger.NewAccount(tx.Sender, 1_000_000)
+ ledger.NewVoting(tx.Sender, otss.OneTimeSignatureVerifier)
+ testAppBytes(t, ops.Program, ep)
+
+ // change a byte in any arg, fail
+ for i := range tx.ApplicationArgs {
+ tx.ApplicationArgs[i][0]++
+ testAppBytes(t, ops.Program, ep, "REJECT")
+ tx.ApplicationArgs[i][0]--
+ }
+ // confirm back to passing
+ testAppBytes(t, ops.Program, ep)
+ })
+ }
+}
+
func keyToByte(tb testing.TB, b *big.Int) []byte {
k := make([]byte, 32)
require.NotPanics(tb, func() {
@@ -680,9 +740,7 @@ func BenchmarkEd25519Verifyx1(b *testing.B) {
crypto.RandBytes(buffer[:])
data = append(data, buffer)
- var s crypto.Seed //generate programs and signatures
- crypto.RandBytes(s[:])
- secret := crypto.GenerateSignatureSecrets(s)
+ secret := crypto.GenerateSignatureSecrets(randSeed()) //generate programs and signatures
pk := basics.Address(secret.SignatureVerifier)
pkStr := pk.String()
ops, err := AssembleStringWithVersion(fmt.Sprintf(`arg 0
@@ -864,3 +922,13 @@ int 1`
benchmarkEcdsa(b, source, Secp256k1)
})
}
+
+const incentiveNonsense = `
+pushbytes "X"
+pushbytes "sig"
+int 1
+heartbeat
+`
+
+// ------------------------pb 1 X pb 3 S I G 1 pv
+const incentiveCompiled = "80 01 58 80 03 73 69 67 22 87"
diff --git a/data/transactions/logic/doc.go b/data/transactions/logic/doc.go
index c060d82623..1e3f48de86 100644
--- a/data/transactions/logic/doc.go
+++ b/data/transactions/logic/doc.go
@@ -41,6 +41,7 @@ var opDescByName = map[string]OpDesc{
"ed25519verify": {"for (data A, signature B, pubkey C) verify the signature of (\"ProgData\" || program_hash || data) against the pubkey => {0 or 1}", "The 32 byte public key is the last element on the stack, preceded by the 64 byte signature at the second-to-last element on the stack, preceded by the data which was signed at the third-to-last element on the stack.", nil},
"ed25519verify_bare": {"for (data A, signature B, pubkey C) verify the signature of the data against the pubkey => {0 or 1}", "", nil},
"ecdsa_verify": {"for (data A, signature B, C and pubkey D, E) verify the signature of the data against the pubkey => {0 or 1}", "The 32 byte Y-component of a public key is the last element on the stack, preceded by X-component of a pubkey, preceded by S and R components of a signature, preceded by the data that is fifth element on the stack. All values are big-endian encoded. The signed data must be 32 bytes long, and signatures in lower-S form are only accepted.", []string{"curve index"}},
+ "heartbeat": {"for (signature components A, B, C, D, E, and account F) verify the signature of the block seed from round txn.FirstValid-1 using F's partkey for txn.LastValid", "", nil},
"ecdsa_pk_decompress": {"decompress pubkey A into components X, Y", "The 33 byte public key in a compressed form to be decompressed into X and Y (top) components. All values are big-endian encoded.", []string{"curve index"}},
"ecdsa_pk_recover": {"for (data A, recovery id B, signature C, D) recover a public key", "S (top) and R elements of a signature, recovery id and data (bottom) are expected on the stack and used to deriver a public key. All values are big-endian encoded. The signed data must be 32 bytes long.", []string{"curve index"}},
@@ -347,7 +348,7 @@ var OpGroups = map[string][]string{
"Byte Array Manipulation": {"getbit", "setbit", "getbyte", "setbyte", "concat", "len", "substring", "substring3", "extract", "extract3", "extract_uint16", "extract_uint32", "extract_uint64", "replace2", "replace3", "base64_decode", "json_ref"},
"Byte Array Arithmetic": {"b+", "b-", "b/", "b*", "b<", "b>", "b<=", "b>=", "b==", "b!=", "b%", "bsqrt"},
"Byte Array Logic": {"b|", "b&", "b^", "b~"},
- "Cryptography": {"sha256", "keccak256", "sha512_256", "sha3_256", "ed25519verify", "ed25519verify_bare", "ecdsa_verify", "ecdsa_pk_recover", "ecdsa_pk_decompress", "vrf_verify", "ec_add", "ec_scalar_mul", "ec_pairing_check", "ec_multi_scalar_mul", "ec_subgroup_check", "ec_map_to"},
+ "Cryptography": {"sha256", "keccak256", "sha512_256", "sha3_256", "ed25519verify", "ed25519verify_bare", "ecdsa_verify", "heartbeat", "ecdsa_pk_recover", "ecdsa_pk_decompress", "vrf_verify", "ec_add", "ec_scalar_mul", "ec_pairing_check", "ec_multi_scalar_mul", "ec_subgroup_check", "ec_map_to"},
"Loading Values": {"intcblock", "intc", "intc_0", "intc_1", "intc_2", "intc_3", "pushint", "pushints", "bytecblock", "bytec", "bytec_0", "bytec_1", "bytec_2", "bytec_3", "pushbytes", "pushbytess", "bzero", "arg", "arg_0", "arg_1", "arg_2", "arg_3", "args", "txn", "gtxn", "txna", "txnas", "gtxna", "gtxnas", "gtxns", "gtxnsa", "gtxnsas", "global", "load", "loads", "store", "stores", "gload", "gloads", "gloadss", "gaid", "gaids"},
"Flow Control": {"err", "bnz", "bz", "b", "return", "pop", "popn", "dup", "dup2", "dupn", "dig", "bury", "cover", "uncover", "frame_dig", "frame_bury", "swap", "select", "assert", "callsub", "proto", "retsub", "switch", "match"},
"State Access": {"balance", "min_balance", "app_opted_in", "app_local_get", "app_local_get_ex", "app_global_get", "app_global_get_ex", "app_local_put", "app_global_put", "app_local_del", "app_global_del", "asset_holding_get", "asset_params_get", "app_params_get", "acct_params_get", "log", "block"},
diff --git a/data/transactions/logic/eval.go b/data/transactions/logic/eval.go
index 2db51b24a7..62caf20356 100644
--- a/data/transactions/logic/eval.go
+++ b/data/transactions/logic/eval.go
@@ -239,6 +239,8 @@ type LedgerForLogic interface {
Perform(gi int, ep *EvalParams) error
Counter() uint64
+
+ Heartbeat(addr basics.Address) error
}
// BoxRef is the "hydrated" form of a transactions.BoxRef - it has the actual app id, not an index
@@ -900,6 +902,32 @@ func (st StackType) overlaps(expected StackType) bool {
return smin <= emax && smax >= emin
}
+func (st StackType) checkBounds(value stackValue) error {
+ switch st.AVMType {
+ case avmAny:
+ return nil
+ case avmUint64:
+ if value.Uint < st.Bound[0] {
+ return fmt.Errorf("value is too small (%d < %d)", value.Uint, st.Bound[0])
+ }
+ if value.Uint > st.Bound[1] {
+ return fmt.Errorf("value is too large (%d > %d)", value.Uint, st.Bound[1])
+ }
+ return nil
+ case avmBytes:
+ l := uint64(len(value.Bytes))
+ if l < st.Bound[0] {
+ return fmt.Errorf("length is too small (%d < %d)", l, st.Bound[0])
+ }
+ if l > st.Bound[1] {
+ return fmt.Errorf("length is too large (%d > %d)", l, st.Bound[1])
+ }
+ return nil
+ default:
+ panic(st)
+ }
+}
+
func (st StackType) String() string {
return st.Name
}
@@ -1383,6 +1411,29 @@ func (cx *EvalContext) remainingInners() int {
return cx.Proto.MaxInnerTransactions - len(cx.txn.EvalDelta.InnerTxns)
}
+// checkStackArgBounds confirms that all arguments obey StackType bounds. It
+// plows along without check the AVMType because that will already have been
+// checked. It is only invoked explicitly by specific opcodes, rather than in
+// step() to avoid pointless overhead, as most opcodes have no specific bounds.
+
+func argName(i int) rune {
+ return rune(int('A') + i)
+}
+
+func (cx *EvalContext) checkStackArgBounds() error {
+ opcode := cx.program[cx.pc]
+ spec := &opsByOpcode[cx.version][opcode]
+
+ first := len(cx.Stack) - len(spec.Arg.Types)
+ for i, argType := range spec.Arg.Types {
+ value := cx.Stack[first+i]
+ if err := argType.checkBounds(value); err != nil {
+ return fmt.Errorf("%s arg %c's %w", spec.Name, argName(i), err)
+ }
+ }
+ return nil
+}
+
func (cx *EvalContext) step() error {
opcode := cx.program[cx.pc]
spec := &opsByOpcode[cx.version][opcode]
@@ -1402,7 +1453,7 @@ func (cx *EvalContext) step() error {
first := len(cx.Stack) - len(spec.Arg.Types)
for i, argType := range spec.Arg.Types {
if !opCompat(argType.AVMType, cx.Stack[first+i].avmType()) {
- return fmt.Errorf("%s arg %d wanted %s but got %s", spec.Name, i, argType, cx.Stack[first+i].typeName())
+ return fmt.Errorf("%s arg %c wanted %s but got %s", spec.Name, argName(i), argType, cx.Stack[first+i].typeName())
}
}
@@ -1443,17 +1494,17 @@ func (cx *EvalContext) step() error {
if err == nil && !spec.trusted {
postheight := len(cx.Stack)
if postheight-preheight != len(spec.Return.Types)-len(spec.Arg.Types) && !spec.AlwaysExits() {
- return fmt.Errorf("%s changed stack height improperly %d != %d",
- spec.Name, postheight-preheight, len(spec.Return.Types)-len(spec.Arg.Types))
+ return fmt.Errorf("%s changed stack height improperly. Expected %d, Actual %d",
+ spec.Name, len(spec.Return.Types)-len(spec.Arg.Types), postheight-preheight)
}
first = postheight - len(spec.Return.Types)
- for i, argType := range spec.Return.Types {
+ for i, retType := range spec.Return.Types {
stackType := cx.Stack[first+i].avmType()
- if !opCompat(argType.AVMType, stackType) {
- if spec.AlwaysExits() { // We test in the loop because it's the uncommon case.
+ if !opCompat(retType.AVMType, stackType) {
+ if spec.AlwaysExits() { // We check "late", because it's the uncommon case.
break
}
- return fmt.Errorf("%s produced %s but intended %s", spec.Name, cx.Stack[first+i].typeName(), argType)
+ return fmt.Errorf("%s produced %s but intended %s", spec.Name, cx.Stack[first+i].typeName(), retType)
}
if stackType == avmBytes && len(cx.Stack[first+i].Bytes) > maxStringSize {
return fmt.Errorf("%s produced a too big (%d) byte-array", spec.Name, len(cx.Stack[first+i].Bytes))
@@ -1530,7 +1581,7 @@ func (cx *EvalContext) step() error {
// because the static cost would be wrong. But then again, a static cost model
// wouldn't work before backBranchEnabledVersion, so such an opcode is already
// unacceptable. TestLinearOpcodes ensures.
-var blankStack = make([]stackValue, 5)
+var blankStack = make([]stackValue, 6)
func (cx *EvalContext) checkStep() (int, error) {
cx.instructionStarts[cx.pc] = true
@@ -4897,6 +4948,14 @@ func opAcctParamsGet(cx *EvalContext) error {
value.Uint = account.TotalBoxes
case AcctTotalBoxBytes:
value.Uint = account.TotalBoxBytes
+
+ case AcctLastProposed:
+ value.Uint = uint64(account.LastProposed)
+ case AcctLastHeartbeat:
+ value.Uint = uint64(account.LastHeartbeat)
+
+ default:
+ return fmt.Errorf("invalid acct_params_get field %s", paramField)
}
cx.Stack[last] = value
cx.Stack = append(cx.Stack, boolToSV(account.MicroAlgos.Raw > 0))
@@ -5578,17 +5637,20 @@ func opBlock(cx *EvalContext) error {
switch fs.field {
case BlkSeed:
cx.Stack[last].Bytes = hdr.Seed[:]
- return nil
case BlkTimestamp:
cx.Stack[last].Bytes = nil
if hdr.TimeStamp < 0 {
return fmt.Errorf("block(%d) timestamp %d < 0", round, hdr.TimeStamp)
}
cx.Stack[last].Uint = uint64(hdr.TimeStamp)
- return nil
+ case BlkProposer:
+ cx.Stack[last].Bytes = hdr.Proposer[:]
+ case BlkFeesCollected:
+ cx.Stack[last].Uint = hdr.FeesCollected.Raw
default:
return fmt.Errorf("invalid block field %d", fs.field)
}
+ return nil
}
// pcDetails return PC and disassembled instructions at PC up to 2 opcodes back
diff --git a/data/transactions/logic/evalStateful_test.go b/data/transactions/logic/evalStateful_test.go
index 436643e4c2..3c6a7dc00a 100644
--- a/data/transactions/logic/evalStateful_test.go
+++ b/data/transactions/logic/evalStateful_test.go
@@ -406,7 +406,7 @@ func TestBalance(t *testing.T) {
// won't assemble in old version teal
if v < directRefEnabledVersion {
testProg(t, source, ep.Proto.LogicSigVersion,
- exp(1, "balance arg 0 wanted type uint64..."))
+ exp(1, "balance arg A wanted type uint64..."))
return
}
@@ -655,7 +655,7 @@ func TestAppCheckOptedIn(t *testing.T) {
testApp(t, "int 1; int 2; app_opted_in; int 0; ==", pre) // in pre, int 2 is an actual app id
testApp(t, "byte \"aoeuiaoeuiaoeuiaoeuiaoeuiaoeui01\"; int 2; app_opted_in; int 1; ==", now)
testProg(t, "byte \"aoeuiaoeuiaoeuiaoeuiaoeuiaoeui01\"; int 2; app_opted_in; int 1; ==", directRefEnabledVersion-1,
- exp(1, "app_opted_in arg 0 wanted type uint64..."))
+ exp(1, "app_opted_in arg A wanted type uint64..."))
// Receiver opts into 888, the current app in testApp
ledger.NewLocals(txn.Txn.Receiver, 888)
@@ -730,7 +730,7 @@ byte "ALGO"
testApp(t, text, now)
testApp(t, strings.Replace(text, "int 1 // account idx", "byte \"aoeuiaoeuiaoeuiaoeuiaoeuiaoeui01\"", -1), now)
testProg(t, strings.Replace(text, "int 1 // account idx", "byte \"aoeuiaoeuiaoeuiaoeuiaoeuiaoeui01\"", -1), directRefEnabledVersion-1,
- exp(4, "app_local_get_ex arg 0 wanted type uint64..."))
+ exp(4, "app_local_get_ex arg A wanted type uint64..."))
testApp(t, strings.Replace(text, "int 100 // app id", "int 2", -1), now)
// Next we're testing if the use of the current app's id works
// as a direct reference. The error is because the receiver
@@ -803,7 +803,7 @@ byte "ALGO"
testApp(t, text, now)
testApp(t, strings.Replace(text, "int 0 // account idx", "byte \"aoeuiaoeuiaoeuiaoeuiaoeuiaoeui00\"", -1), now)
testProg(t, strings.Replace(text, "int 0 // account idx", "byte \"aoeuiaoeuiaoeuiaoeuiaoeuiaoeui00\"", -1), directRefEnabledVersion-1,
- exp(3, "app_local_get arg 0 wanted type uint64..."))
+ exp(3, "app_local_get arg A wanted type uint64..."))
testApp(t, strings.Replace(text, "int 0 // account idx", "byte \"aoeuiaoeuiaoeuiaoeuiaoeuiaoeui01\"", -1), now)
testApp(t, strings.Replace(text, "int 0 // account idx", "byte \"aoeuiaoeuiaoeuiaoeuiaoeuiaoeui02\"", -1), now,
"invalid Account reference")
@@ -1065,7 +1065,7 @@ func testAssetsByVersion(t *testing.T, assetsTestProgram string, version uint64)
// it wasn't legal to use a direct ref for account
testProg(t, `byte "aoeuiaoeuiaoeuiaoeuiaoeuiaoeui00"; int 54; asset_holding_get AssetBalance`,
- directRefEnabledVersion-1, exp(1, "asset_holding_get AssetBalance arg 0 wanted type uint64..."))
+ directRefEnabledVersion-1, exp(1, "asset_holding_get AssetBalance arg A wanted type uint64..."))
// but it is now (empty asset yields 0,0 on stack)
testApp(t, `byte "aoeuiaoeuiaoeuiaoeuiaoeuiaoeui00"; int 55; asset_holding_get AssetBalance; ==`, now)
// This is receiver, who is in Assets array
@@ -1108,7 +1108,7 @@ func testAssetsByVersion(t *testing.T, assetsTestProgram string, version uint64)
testApp(t, strings.Replace(assetsTestProgram, "int 55", "int 0", -1), now)
// but old code cannot
- testProg(t, strings.Replace(assetsTestProgram, "int 0//account", "byte \"aoeuiaoeuiaoeuiaoeuiaoeuiaoeui00\"", -1), directRefEnabledVersion-1, exp(3, "asset_holding_get AssetBalance arg 0 wanted type uint64..."))
+ testProg(t, strings.Replace(assetsTestProgram, "int 0//account", "byte \"aoeuiaoeuiaoeuiaoeuiaoeuiaoeui00\"", -1), directRefEnabledVersion-1, exp(3, "asset_holding_get AssetBalance arg A wanted type uint64..."))
if version < 5 {
// Can't run these with AppCreator anyway
@@ -2445,7 +2445,7 @@ int 1
delta := testApp(t, withBytes, ep)
// But won't even compile in old teal
testProg(t, withBytes, directRefEnabledVersion-1,
- exp(4, "app_local_put arg 0 wanted..."), exp(11, "app_local_del arg 0 wanted..."))
+ exp(4, "app_local_put arg A wanted..."), exp(11, "app_local_del arg A wanted..."))
require.Equal(t, 0, len(delta.GlobalDelta))
require.Equal(t, 2, len(delta.LocalDeltas))
ledger.Reset()
@@ -3098,7 +3098,8 @@ func TestReturnTypes(t *testing.T) {
"err": true,
"return": true,
- "ecdsa_pk_decompress": true,
+ "ecdsa_pk_decompress": true, // requires a [33]byte arg
+ "heartbeat": true, // panics unless it verifies
"frame_dig": true, // would need a "proto" subroutine
"frame_bury": true, // would need a "proto" subroutine
@@ -3366,7 +3367,7 @@ func TestLog(t *testing.T) {
},
{
source: `load 0; log`,
- errContains: "log arg 0 wanted []byte but got uint64",
+ errContains: "log arg A wanted []byte but got uint64",
assembledBytes: []byte{byte(ep.Proto.LogicSigVersion), 0x34, 0x00, 0xb0},
},
}
diff --git a/data/transactions/logic/eval_test.go b/data/transactions/logic/eval_test.go
index fd8b9ff806..06f2efbed9 100644
--- a/data/transactions/logic/eval_test.go
+++ b/data/transactions/logic/eval_test.go
@@ -3083,7 +3083,7 @@ func TestWrongStackTypeRuntime(t *testing.T) {
t.Run(fmt.Sprintf("v=%d", v), func(t *testing.T) {
ops := testProg(t, `int 1`, v)
ops.Program = append(ops.Program, 0x01, 0x15) // sha256, len
- testLogicBytes(t, ops.Program, nil, "sha256 arg 0 wanted")
+ testLogicBytes(t, ops.Program, nil, "sha256 arg A wanted")
})
}
}
@@ -3123,7 +3123,7 @@ func TestWrongStackTypeRuntime2(t *testing.T) {
t.Run(fmt.Sprintf("v=%d", v), func(t *testing.T) {
ops := testProg(t, `byte 0x1234; int 1`, v)
ops.Program = append(ops.Program, 0x08) // +
- testLogicBytes(t, ops.Program, nil, "+ arg 0 wanted")
+ testLogicBytes(t, ops.Program, nil, "+ arg A wanted")
})
}
}
diff --git a/data/transactions/logic/fields.go b/data/transactions/logic/fields.go
index bb5c2179e9..a6b01a500a 100644
--- a/data/transactions/logic/fields.go
+++ b/data/transactions/logic/fields.go
@@ -961,6 +961,10 @@ const (
BlkSeed BlockField = iota
// BlkTimestamp is the Block's timestamp, seconds from epoch
BlkTimestamp
+ // BlkProposer is the Block's proposer, or ZeroAddress, pre EnableMining
+ BlkProposer
+ // BlkFeesCollected is the sum of fees for the block, or 0, pre EnableMining
+ BlkFeesCollected
invalidBlockField // compile-time constant for number of fields
)
@@ -975,6 +979,8 @@ type blockFieldSpec struct {
var blockFieldSpecs = [...]blockFieldSpec{
{BlkSeed, StackBytes, randomnessVersion},
{BlkTimestamp, StackUint64, randomnessVersion},
+ {BlkProposer, StackAddress, incentiveVersion},
+ {BlkFeesCollected, StackUint64, incentiveVersion},
}
func blockFieldSpecByField(r BlockField) (blockFieldSpec, bool) {
@@ -1307,6 +1313,12 @@ const (
// AcctTotalAppSchema - consider how to expose
+ // AcctLastProposed is the last round that this account was the propser
+ AcctLastProposed
+ // AcctLastHeartbeat is the last round in which this account went online,
+ // or the `heartbeat` opcode executed in a valid transaction for it.
+ AcctLastHeartbeat
+
invalidAcctParamsField // compile-time constant for number of fields
)
@@ -1349,6 +1361,9 @@ var acctParamsFieldSpecs = [...]acctParamsFieldSpec{
{AcctTotalAssets, StackUint64, 8, "The numbers of ASAs held by this account (including ASAs this account created)."},
{AcctTotalBoxes, StackUint64, boxVersion, "The number of existing boxes created by this account's app."},
{AcctTotalBoxBytes, StackUint64, boxVersion, "The total number of bytes used by this account's app's box keys and values."},
+
+ {AcctLastProposed, StackUint64, incentiveVersion, "The round in which this account last proposed."},
+ {AcctLastHeartbeat, StackUint64, incentiveVersion, "The round in which the account went online or executed `heartbeat`."},
}
func acctParamsFieldSpecByField(f AcctParamsField) (acctParamsFieldSpec, bool) {
diff --git a/data/transactions/logic/fields_string.go b/data/transactions/logic/fields_string.go
index 7d3c2b42f2..17d17cb844 100644
--- a/data/transactions/logic/fields_string.go
+++ b/data/transactions/logic/fields_string.go
@@ -194,12 +194,14 @@ func _() {
_ = x[AcctTotalAssets-9]
_ = x[AcctTotalBoxes-10]
_ = x[AcctTotalBoxBytes-11]
- _ = x[invalidAcctParamsField-12]
+ _ = x[AcctLastProposed-12]
+ _ = x[AcctLastHeartbeat-13]
+ _ = x[invalidAcctParamsField-14]
}
-const _AcctParamsField_name = "AcctBalanceAcctMinBalanceAcctAuthAddrAcctTotalNumUintAcctTotalNumByteSliceAcctTotalExtraAppPagesAcctTotalAppsCreatedAcctTotalAppsOptedInAcctTotalAssetsCreatedAcctTotalAssetsAcctTotalBoxesAcctTotalBoxBytesinvalidAcctParamsField"
+const _AcctParamsField_name = "AcctBalanceAcctMinBalanceAcctAuthAddrAcctTotalNumUintAcctTotalNumByteSliceAcctTotalExtraAppPagesAcctTotalAppsCreatedAcctTotalAppsOptedInAcctTotalAssetsCreatedAcctTotalAssetsAcctTotalBoxesAcctTotalBoxBytesAcctLastProposedAcctLastHeartbeatinvalidAcctParamsField"
-var _AcctParamsField_index = [...]uint8{0, 11, 25, 37, 53, 74, 96, 116, 136, 158, 173, 187, 204, 226}
+var _AcctParamsField_index = [...]uint16{0, 11, 25, 37, 53, 74, 96, 116, 136, 158, 173, 187, 204, 220, 237, 259}
func (i AcctParamsField) String() string {
if i < 0 || i >= AcctParamsField(len(_AcctParamsField_index)-1) {
@@ -351,12 +353,14 @@ func _() {
var x [1]struct{}
_ = x[BlkSeed-0]
_ = x[BlkTimestamp-1]
- _ = x[invalidBlockField-2]
+ _ = x[BlkProposer-2]
+ _ = x[BlkFeesCollected-3]
+ _ = x[invalidBlockField-4]
}
-const _BlockField_name = "BlkSeedBlkTimestampinvalidBlockField"
+const _BlockField_name = "BlkSeedBlkTimestampBlkProposerBlkFeesCollectedinvalidBlockField"
-var _BlockField_index = [...]uint8{0, 7, 19, 36}
+var _BlockField_index = [...]uint8{0, 7, 19, 30, 46, 63}
func (i BlockField) String() string {
if i < 0 || i >= BlockField(len(_BlockField_index)-1) {
diff --git a/data/transactions/logic/langspec_v10.json b/data/transactions/logic/langspec_v10.json
index 7ee54fb98d..192b10a149 100644
--- a/data/transactions/logic/langspec_v10.json
+++ b/data/transactions/logic/langspec_v10.json
@@ -2891,7 +2891,9 @@
"AcctTotalAssetsCreated",
"AcctTotalAssets",
"AcctTotalBoxes",
- "AcctTotalBoxBytes"
+ "AcctTotalBoxBytes",
+ "AcctLastProposed",
+ "AcctLastHeartbeat"
],
"ArgEnumTypes": [
"uint64",
@@ -2905,6 +2907,8 @@
"uint64",
"uint64",
"uint64",
+ "uint64",
+ "uint64",
"uint64"
],
"DocCost": "1",
@@ -3041,6 +3045,25 @@
"Cryptography"
]
},
+ {
+ "Opcode": 135,
+ "Name": "heartbeat",
+ "Args": [
+ "[64]byte",
+ "[32]byte",
+ "[64]byte",
+ "[32]byte",
+ "[64]byte",
+ "any"
+ ],
+ "Size": 1,
+ "DocCost": "5700",
+ "Doc": "for (signature components A, B, C, D, E, and account F) verify the signature of the block seed from round txn.FirstValid-1 using F's partkey for txn.LastValid",
+ "IntroducedVersion": 10,
+ "Groups": [
+ "Cryptography"
+ ]
+ },
{
"Opcode": 136,
"Name": "callsub",
@@ -4623,10 +4646,14 @@
"Size": 2,
"ArgEnum": [
"BlkSeed",
- "BlkTimestamp"
+ "BlkTimestamp",
+ "BlkProposer",
+ "BlkFeesCollected"
],
"ArgEnumTypes": [
"[]byte",
+ "uint64",
+ "address",
"uint64"
],
"DocCost": "1",
diff --git a/data/transactions/logic/ledger_test.go b/data/transactions/logic/ledger_test.go
index a111eec131..6b490b0981 100644
--- a/data/transactions/logic/ledger_test.go
+++ b/data/transactions/logic/ledger_test.go
@@ -36,6 +36,7 @@ import (
"math"
"math/rand"
+ "github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/data/bookkeeping"
"github.com/algorand/go-algorand/data/committee"
@@ -45,9 +46,12 @@ import (
)
type balanceRecord struct {
- addr basics.Address
- auth basics.Address
- balance uint64
+ addr basics.Address
+ auth basics.Address
+ balance uint64
+ voting ledgercore.VotingData
+ heartbeat basics.Round // The last round that this account sent a heartbeat to show it was online.
+
locals map[basics.AppIndex]basics.TealKeyValue
holdings map[basics.AssetIndex]basics.AssetHolding
mods map[basics.AppIndex]map[string]basics.ValueDelta
@@ -118,6 +122,18 @@ func (l *Ledger) NewAccount(addr basics.Address, balance uint64) {
l.balances[addr] = newBalanceRecord(addr, balance)
}
+// NewVoting sets VoteID on the account. Could expand to set other voting data
+// if that became useful in tests.
+func (l *Ledger) NewVoting(addr basics.Address, voteID crypto.OneTimeSignatureVerifier) {
+ br, ok := l.balances[addr]
+ if !ok {
+ br = newBalanceRecord(addr, 0)
+ }
+ br.voting.VoteID = voteID
+ br.voting.VoteKeyDilution = 10_000
+ l.balances[addr] = br
+}
+
// NewApp add a new AVM app to the Ledger. In most uses, it only sets up the id
// and schema but no code, as testing will want to try many different code
// sequences.
@@ -305,7 +321,10 @@ func (l *Ledger) AccountData(addr basics.Address) (ledgercore.AccountData, error
TotalBoxes: uint64(boxesTotal),
TotalBoxBytes: uint64(boxBytesTotal),
+
+ LastHeartbeat: br.heartbeat,
},
+ VotingData: br.voting,
}, nil
}
@@ -900,6 +919,18 @@ func (l *Ledger) Perform(gi int, ep *EvalParams) error {
}
}
+// Heartbeat increments the given addr's LastHeartbeat
+func (l *Ledger) Heartbeat(addr basics.Address) error {
+ br, ok := l.balances[addr]
+ if !ok {
+ return fmt.Errorf("no account %s", addr)
+ }
+ br.heartbeat = l.Round()
+ fmt.Printf("%+v\n", br)
+ l.balances[addr] = br
+ return nil
+}
+
// Get returns the AccountData of an address. This test ledger does
// not handle rewards, so the pening rewards flag is ignored.
func (l *Ledger) Get(addr basics.Address, withPendingRewards bool) (basics.AccountData, error) {
@@ -913,6 +944,7 @@ func (l *Ledger) Get(addr basics.Address, withPendingRewards bool) (basics.Accou
Assets: map[basics.AssetIndex]basics.AssetHolding{},
AppLocalStates: map[basics.AppIndex]basics.AppLocalState{},
AppParams: map[basics.AppIndex]basics.AppParams{},
+ LastHeartbeat: br.heartbeat,
}, nil
}
diff --git a/data/transactions/logic/opcodes.go b/data/transactions/logic/opcodes.go
index dc2d44bc09..0bd22668b0 100644
--- a/data/transactions/logic/opcodes.go
+++ b/data/transactions/logic/opcodes.go
@@ -74,7 +74,8 @@ const sharedResourcesVersion = 9 // apps can access resources from other transac
// EXPERIMENTAL. These should be revisited whenever a new LogicSigVersion is
// moved from vFuture to a new consensus version. If they remain unready, bump
// their version, and fixup TestAssemble() in assembler_test.go.
-const pairingVersion = 10 // bn256 opcodes. will add bls12-381, and unify the available opcodes.
+const pairingVersion = 10 // bn256 opcodes. will add bls12-381, and unify the available opcodes.
+const incentiveVersion = 10 // block fields, heartbeat
// Unlimited Global Storage opcodes
const boxVersion = 8 // box_*
@@ -117,11 +118,10 @@ func (lc *linearCost) docCost(argLen int) string {
return strconv.Itoa(lc.baseCost)
}
idxFromStart := argLen - lc.depth - 1
- stackArg := rune(int('A') + idxFromStart)
if lc.chunkSize == 1 {
- return fmt.Sprintf("%d + %d per byte of %c", lc.baseCost, lc.chunkCost, stackArg)
+ return fmt.Sprintf("%d + %d per byte of %c", lc.baseCost, lc.chunkCost, argName(idxFromStart))
}
- return fmt.Sprintf("%d + %d per %d bytes of %c", lc.baseCost, lc.chunkCost, lc.chunkSize, stackArg)
+ return fmt.Sprintf("%d + %d per %d bytes of %c", lc.baseCost, lc.chunkCost, lc.chunkSize, argName(idxFromStart))
}
// OpDetails records details such as non-standard costs, immediate arguments, or
@@ -646,6 +646,9 @@ var OpSpecs = []OpSpec{
{0x83, "pushints", opPushInts, proto(":", "", "[N items]").stackExplain(opPushIntsStackChange), 8, constants(asmPushInts, checkIntImmArgs, "uint ...", immInts).typed(typePushInts).trust()},
{0x84, "ed25519verify_bare", opEd25519VerifyBare, proto("b63:T"), 7, costly(1900)},
+ {0x84, "ed25519verify_bare", opEd25519VerifyBare, proto("b63:T"), 7, costly(1900)},
+ // leaving room for falcon_verify and sumhash512
+ {0x87, "heartbeat", opHeartbeat, proto("63636a:"), incentiveVersion, only(ModeApp).costs(3 * 1900)},
// "Function oriented"
{0x88, "callsub", opCallSub, proto(":"), 4, detBranch()},
diff --git a/data/transactions/logic/teal.tmLanguage.json b/data/transactions/logic/teal.tmLanguage.json
index 56cf7b5dc8..1691070cab 100644
--- a/data/transactions/logic/teal.tmLanguage.json
+++ b/data/transactions/logic/teal.tmLanguage.json
@@ -76,7 +76,7 @@
},
{
"name": "keyword.operator.teal",
- "match": "^(\\!|\\!\\=|%|\u0026|\u0026\u0026|\\*|\\+|\\-|/|\\\u003c|\\\u003c\\=|\\=\\=|\\\u003e|\\\u003e\\=|\\^|addw|bitlen|btoi|divmodw|divw|exp|expw|itob|mulw|shl|shr|sqrt|\\||\\|\\||\\~|b\\!\\=|b%|b\\*|b\\+|b\\-|b/|b\\\u003c|b\\\u003c\\=|b\\=\\=|b\\\u003e|b\\\u003e\\=|bsqrt|b\u0026|b\\^|b\\||b\\~|base64_decode|concat|extract|extract3|extract_uint16|extract_uint32|extract_uint64|getbit|getbyte|json_ref|len|replace2|replace3|setbit|setbyte|substring|substring3|ec_add|ec_map_to|ec_multi_scalar_mul|ec_pairing_check|ec_scalar_mul|ec_subgroup_check|ecdsa_pk_decompress|ecdsa_pk_recover|ecdsa_verify|ed25519verify|ed25519verify_bare|keccak256|sha256|sha3_256|sha512_256|vrf_verify|gitxn|gitxna|gitxnas|itxn|itxn_begin|itxn_field|itxn_next|itxn_submit|itxna|itxnas)\\b"
+ "match": "^(\\!|\\!\\=|%|\u0026|\u0026\u0026|\\*|\\+|\\-|/|\\\u003c|\\\u003c\\=|\\=\\=|\\\u003e|\\\u003e\\=|\\^|addw|bitlen|btoi|divmodw|divw|exp|expw|itob|mulw|shl|shr|sqrt|\\||\\|\\||\\~|b\\!\\=|b%|b\\*|b\\+|b\\-|b/|b\\\u003c|b\\\u003c\\=|b\\=\\=|b\\\u003e|b\\\u003e\\=|bsqrt|b\u0026|b\\^|b\\||b\\~|base64_decode|concat|extract|extract3|extract_uint16|extract_uint32|extract_uint64|getbit|getbyte|json_ref|len|replace2|replace3|setbit|setbyte|substring|substring3|ec_add|ec_map_to|ec_multi_scalar_mul|ec_pairing_check|ec_scalar_mul|ec_subgroup_check|ecdsa_pk_decompress|ecdsa_pk_recover|ecdsa_verify|ed25519verify|ed25519verify_bare|heartbeat|keccak256|sha256|sha3_256|sha512_256|vrf_verify|gitxn|gitxna|gitxnas|itxn|itxn_begin|itxn_field|itxn_next|itxn_submit|itxna|itxnas)\\b"
}
]
},
@@ -112,7 +112,7 @@
},
{
"name": "variable.parameter.teal",
- "match": "\\b(unknown|pay|keyreg|acfg|axfer|afrz|appl|NoOp|OptIn|CloseOut|ClearState|UpdateApplication|DeleteApplication|Secp256k1|Secp256r1|Sender|Fee|FirstValid|FirstValidTime|LastValid|Note|Lease|Receiver|Amount|CloseRemainderTo|VotePK|SelectionPK|VoteFirst|VoteLast|VoteKeyDilution|Type|TypeEnum|XferAsset|AssetAmount|AssetSender|AssetReceiver|AssetCloseTo|GroupIndex|TxID|ApplicationID|OnCompletion|NumAppArgs|NumAccounts|ApprovalProgram|ClearStateProgram|RekeyTo|ConfigAsset|ConfigAssetTotal|ConfigAssetDecimals|ConfigAssetDefaultFrozen|ConfigAssetUnitName|ConfigAssetName|ConfigAssetURL|ConfigAssetMetadataHash|ConfigAssetManager|ConfigAssetReserve|ConfigAssetFreeze|ConfigAssetClawback|FreezeAsset|FreezeAssetAccount|FreezeAssetFrozen|NumAssets|NumApplications|GlobalNumUint|GlobalNumByteSlice|LocalNumUint|LocalNumByteSlice|ExtraProgramPages|Nonparticipation|NumLogs|CreatedAssetID|CreatedApplicationID|LastLog|StateProofPK|NumApprovalProgramPages|NumClearStateProgramPages|MinTxnFee|MinBalance|MaxTxnLife|ZeroAddress|GroupSize|LogicSigVersion|Round|LatestTimestamp|CurrentApplicationID|CreatorAddress|CurrentApplicationAddress|GroupID|OpcodeBudget|CallerApplicationID|CallerApplicationAddress|AssetCreateMinBalance|AssetOptInMinBalance|ApplicationArgs|Accounts|Assets|Applications|Logs|ApprovalProgramPages|ClearStateProgramPages|URLEncoding|StdEncoding|JSONString|JSONUint64|JSONObject|AssetBalance|AssetFrozen|AssetTotal|AssetDecimals|AssetDefaultFrozen|AssetUnitName|AssetName|AssetURL|AssetMetadataHash|AssetManager|AssetReserve|AssetFreeze|AssetClawback|AssetCreator|AppApprovalProgram|AppClearStateProgram|AppGlobalNumUint|AppGlobalNumByteSlice|AppLocalNumUint|AppLocalNumByteSlice|AppExtraProgramPages|AppCreator|AppAddress|AcctBalance|AcctMinBalance|AcctAuthAddr|AcctTotalNumUint|AcctTotalNumByteSlice|AcctTotalExtraAppPages|AcctTotalAppsCreated|AcctTotalAppsOptedIn|AcctTotalAssetsCreated|AcctTotalAssets|AcctTotalBoxes|AcctTotalBoxBytes|VrfAlgorand|BlkSeed|BlkTimestamp|BN254g1|BN254g2|BLS12_381g1|BLS12_381g2)\\b"
+ "match": "\\b(unknown|pay|keyreg|acfg|axfer|afrz|appl|NoOp|OptIn|CloseOut|ClearState|UpdateApplication|DeleteApplication|Secp256k1|Secp256r1|Sender|Fee|FirstValid|FirstValidTime|LastValid|Note|Lease|Receiver|Amount|CloseRemainderTo|VotePK|SelectionPK|VoteFirst|VoteLast|VoteKeyDilution|Type|TypeEnum|XferAsset|AssetAmount|AssetSender|AssetReceiver|AssetCloseTo|GroupIndex|TxID|ApplicationID|OnCompletion|NumAppArgs|NumAccounts|ApprovalProgram|ClearStateProgram|RekeyTo|ConfigAsset|ConfigAssetTotal|ConfigAssetDecimals|ConfigAssetDefaultFrozen|ConfigAssetUnitName|ConfigAssetName|ConfigAssetURL|ConfigAssetMetadataHash|ConfigAssetManager|ConfigAssetReserve|ConfigAssetFreeze|ConfigAssetClawback|FreezeAsset|FreezeAssetAccount|FreezeAssetFrozen|NumAssets|NumApplications|GlobalNumUint|GlobalNumByteSlice|LocalNumUint|LocalNumByteSlice|ExtraProgramPages|Nonparticipation|NumLogs|CreatedAssetID|CreatedApplicationID|LastLog|StateProofPK|NumApprovalProgramPages|NumClearStateProgramPages|MinTxnFee|MinBalance|MaxTxnLife|ZeroAddress|GroupSize|LogicSigVersion|Round|LatestTimestamp|CurrentApplicationID|CreatorAddress|CurrentApplicationAddress|GroupID|OpcodeBudget|CallerApplicationID|CallerApplicationAddress|AssetCreateMinBalance|AssetOptInMinBalance|ApplicationArgs|Accounts|Assets|Applications|Logs|ApprovalProgramPages|ClearStateProgramPages|URLEncoding|StdEncoding|JSONString|JSONUint64|JSONObject|AssetBalance|AssetFrozen|AssetTotal|AssetDecimals|AssetDefaultFrozen|AssetUnitName|AssetName|AssetURL|AssetMetadataHash|AssetManager|AssetReserve|AssetFreeze|AssetClawback|AssetCreator|AppApprovalProgram|AppClearStateProgram|AppGlobalNumUint|AppGlobalNumByteSlice|AppLocalNumUint|AppLocalNumByteSlice|AppExtraProgramPages|AppCreator|AppAddress|AcctBalance|AcctMinBalance|AcctAuthAddr|AcctTotalNumUint|AcctTotalNumByteSlice|AcctTotalExtraAppPages|AcctTotalAppsCreated|AcctTotalAppsOptedIn|AcctTotalAssetsCreated|AcctTotalAssets|AcctTotalBoxes|AcctTotalBoxBytes|AcctLastProposed|AcctLastHeartbeat|VrfAlgorand|BlkSeed|BlkTimestamp|BlkProposer|BlkFeesCollected|BN254g1|BN254g2|BLS12_381g1|BLS12_381g2)\\b"
}
]
},
diff --git a/data/transactions/payment.go b/data/transactions/payment.go
index fee9c395ee..62f3e8ca6a 100644
--- a/data/transactions/payment.go
+++ b/data/transactions/payment.go
@@ -42,8 +42,11 @@ func (payment PaymentTxnFields) checkSpender(header Header, spec SpecialAddresse
return fmt.Errorf("transaction cannot close account to its sender %v", header.Sender)
}
- // the FeeSink account may only spend to the IncentivePool
+ // the FeeSink account may only spend to the IncentivePool (not at all, if EnableMining)
if header.Sender == spec.FeeSink {
+ if proto.EnableMining {
+ return fmt.Errorf("cannot spend from fee sink address %v", header.Sender)
+ }
if payment.Receiver != spec.RewardsPool {
return fmt.Errorf("cannot spend from fee sink's address %v to non incentive pool address %v", header.Sender, payment.Receiver)
}
diff --git a/data/transactions/transaction.go b/data/transactions/transaction.go
index 725f9d7ec2..17af770f12 100644
--- a/data/transactions/transaction.go
+++ b/data/transactions/transaction.go
@@ -365,8 +365,8 @@ func (tx Transaction) WellFormed(spec SpecialAddresses, proto config.ConsensusPa
}
// The trio of [VotePK, SelectionPK, VoteKeyDilution] needs to be all zeros or all non-zero for the transaction to be valid.
- if !((tx.KeyregTxnFields.VotePK == crypto.OneTimeSignatureVerifier{} && tx.KeyregTxnFields.SelectionPK == crypto.VRFVerifier{} && tx.KeyregTxnFields.VoteKeyDilution == 0) ||
- (tx.KeyregTxnFields.VotePK != crypto.OneTimeSignatureVerifier{} && tx.KeyregTxnFields.SelectionPK != crypto.VRFVerifier{} && tx.KeyregTxnFields.VoteKeyDilution != 0)) {
+ if !((tx.KeyregTxnFields.VotePK.IsEmpty() && tx.KeyregTxnFields.SelectionPK.IsEmpty() && tx.KeyregTxnFields.VoteKeyDilution == 0) ||
+ (!tx.KeyregTxnFields.VotePK.IsEmpty() && !tx.KeyregTxnFields.SelectionPK.IsEmpty() && tx.KeyregTxnFields.VoteKeyDilution != 0)) {
return errKeyregTxnNonCoherentVotingKeys
}
@@ -395,7 +395,7 @@ func (tx Transaction) WellFormed(spec SpecialAddresses, proto config.ConsensusPa
// that type of transaction, it is invalid.
return errKeyregTxnUnsupportedSwitchToNonParticipating
}
- suppliesNullKeys := tx.KeyregTxnFields.VotePK == crypto.OneTimeSignatureVerifier{} || tx.KeyregTxnFields.SelectionPK == crypto.VRFVerifier{}
+ suppliesNullKeys := tx.KeyregTxnFields.VotePK.IsEmpty() || tx.KeyregTxnFields.SelectionPK.IsEmpty()
if !suppliesNullKeys {
return errKeyregTxnGoingOnlineWithNonParticipating
}
@@ -673,7 +673,7 @@ func (tx Transaction) stateProofPKWellFormed(proto config.ConsensusParams) error
return nil
}
- if tx.VotePK == (crypto.OneTimeSignatureVerifier{}) || tx.SelectionPK == (crypto.VRFVerifier{}) {
+ if tx.VotePK.IsEmpty() || tx.SelectionPK.IsEmpty() {
if !isEmpty {
return errKeyregTxnOfflineShouldBeEmptyStateProofPK
}
diff --git a/data/transactions/transaction_test.go b/data/transactions/transaction_test.go
index 0f3cf18258..77d8feabb2 100644
--- a/data/transactions/transaction_test.go
+++ b/data/transactions/transaction_test.go
@@ -101,13 +101,13 @@ func TestGoOnlineGoNonparticipatingContradiction(t *testing.T) {
tx.KeyregTxnFields = KeyregTxnFields{
VotePK: v.OneTimeSignatureVerifier,
SelectionPK: vrf.PK,
+ VoteKeyDilution: 1,
Nonparticipation: true,
}
// this tx tries to both register keys to go online, and mark an account as non-participating.
// it is not well-formed.
- feeSink := basics.Address{0x7, 0xda, 0xcb, 0x4b, 0x6d, 0x9e, 0xd1, 0x41, 0xb1, 0x75, 0x76, 0xbd, 0x45, 0x9a, 0xe6, 0x42, 0x1d, 0x48, 0x6d, 0xa3, 0xd4, 0xef, 0x22, 0x47, 0xc4, 0x9, 0xa3, 0x96, 0xb8, 0x2e, 0xa2, 0x21}
- err = tx.WellFormed(SpecialAddresses{FeeSink: feeSink}, config.Consensus[protocol.ConsensusCurrentVersion])
- require.Error(t, err)
+ err = tx.WellFormed(SpecialAddresses{}, config.Consensus[protocol.ConsensusCurrentVersion])
+ require.ErrorContains(t, err, "go online, but vote last is set to zero")
}
func TestGoNonparticipatingWellFormed(t *testing.T) {
@@ -125,19 +125,17 @@ func TestGoNonparticipatingWellFormed(t *testing.T) {
}
// this tx is well-formed
- feeSink := basics.Address{0x7, 0xda, 0xcb, 0x4b, 0x6d, 0x9e, 0xd1, 0x41, 0xb1, 0x75, 0x76, 0xbd, 0x45, 0x9a, 0xe6, 0x42, 0x1d, 0x48, 0x6d, 0xa3, 0xd4, 0xef, 0x22, 0x47, 0xc4, 0x9, 0xa3, 0x96, 0xb8, 0x2e, 0xa2, 0x21}
- err = tx.WellFormed(SpecialAddresses{FeeSink: feeSink}, curProto)
+ err = tx.WellFormed(SpecialAddresses{}, curProto)
require.NoError(t, err)
// but it should stop being well-formed if the protocol does not support it
curProto.SupportBecomeNonParticipatingTransactions = false
- err = tx.WellFormed(SpecialAddresses{FeeSink: feeSink}, curProto)
- require.Error(t, err)
+ err = tx.WellFormed(SpecialAddresses{}, curProto)
+ require.ErrorContains(t, err, "mark an account as nonparticipating, but")
}
func TestAppCallCreateWellFormed(t *testing.T) {
partitiontest.PartitionTest(t)
- feeSink := basics.Address{0x7, 0xda, 0xcb, 0x4b, 0x6d, 0x9e, 0xd1, 0x41, 0xb1, 0x75, 0x76, 0xbd, 0x45, 0x9a, 0xe6, 0x42, 0x1d, 0x48, 0x6d, 0xa3, 0xd4, 0xef, 0x22, 0x47, 0xc4, 0x9, 0xa3, 0x96, 0xb8, 0x2e, 0xa2, 0x21}
curProto := config.Consensus[protocol.ConsensusCurrentVersion]
futureProto := config.Consensus[protocol.ConsensusFuture]
addr1, err := basics.UnmarshalChecksumAddress("NDQCJNNY5WWWFLP4GFZ7MEF2QJSMZYK6OWIV2AQ7OMAVLEFCGGRHFPKJJA")
@@ -253,7 +251,7 @@ func TestAppCallCreateWellFormed(t *testing.T) {
}
for i, usecase := range usecases {
t.Run(fmt.Sprintf("i=%d", i), func(t *testing.T) {
- err := usecase.tx.WellFormed(SpecialAddresses{FeeSink: feeSink}, usecase.proto)
+ err := usecase.tx.WellFormed(SpecialAddresses{}, usecase.proto)
if usecase.expectedError != "" {
require.Error(t, err)
require.Contains(t, err.Error(), usecase.expectedError)
@@ -267,8 +265,6 @@ func TestAppCallCreateWellFormed(t *testing.T) {
func TestWellFormedErrors(t *testing.T) {
partitiontest.PartitionTest(t)
- feeSink := basics.Address{0x7, 0xda, 0xcb, 0x4b, 0x6d, 0x9e, 0xd1, 0x41, 0xb1, 0x75, 0x76, 0xbd, 0x45, 0x9a, 0xe6, 0x42, 0x1d, 0x48, 0x6d, 0xa3, 0xd4, 0xef, 0x22, 0x47, 0xc4, 0x9, 0xa3, 0x96, 0xb8, 0x2e, 0xa2, 0x21}
- specialAddr := SpecialAddresses{FeeSink: feeSink}
curProto := config.Consensus[protocol.ConsensusCurrentVersion]
futureProto := config.Consensus[protocol.ConsensusFuture]
protoV27 := config.Consensus[protocol.ConsensusV27]
@@ -595,7 +591,7 @@ func TestWellFormedErrors(t *testing.T) {
},
}
for _, usecase := range usecases {
- err := usecase.tx.WellFormed(specialAddr, usecase.proto)
+ err := usecase.tx.WellFormed(SpecialAddresses{}, usecase.proto)
require.Equal(t, usecase.expectedError, err)
}
}
@@ -632,14 +628,12 @@ func TestWellFormedKeyRegistrationTx(t *testing.T) {
tx := generateDummyGoNonparticpatingTransaction(addr)
curProto := config.Consensus[protocol.ConsensusCurrentVersion]
- feeSink := basics.Address{0x7, 0xda, 0xcb, 0x4b, 0x6d, 0x9e, 0xd1, 0x41, 0xb1, 0x75, 0x76, 0xbd, 0x45, 0x9a, 0xe6, 0x42, 0x1d, 0x48, 0x6d, 0xa3, 0xd4, 0xef, 0x22, 0x47, 0xc4, 0x9, 0xa3, 0x96, 0xb8, 0x2e, 0xa2, 0x21}
- spec := SpecialAddresses{FeeSink: feeSink}
if !curProto.SupportBecomeNonParticipatingTransactions {
t.Skipf("Skipping rest of test because current protocol version %v does not support become-nonparticipating transactions", protocol.ConsensusCurrentVersion)
}
// this tx is well-formed
- err = tx.WellFormed(spec, curProto)
+ err = tx.WellFormed(SpecialAddresses{}, curProto)
require.NoError(t, err)
type keyRegTestCase struct {
@@ -677,7 +671,7 @@ func TestWellFormedKeyRegistrationTx(t *testing.T) {
curProto.EnableKeyregCoherencyCheck = testCase.enableKeyregCoherencyCheck
curProto.EnableStateProofKeyregCheck = testCase.enableStateProofKeyregCheck
curProto.MaxKeyregValidPeriod = maxValidPeriod // TODO: remove this when MaxKeyregValidPeriod is in CurrentVersion
- return tx.WellFormed(spec, curProto)
+ return tx.WellFormed(SpecialAddresses{}, curProto)
}
if *generateFlag == true {
diff --git a/data/txntest/txn.go b/data/txntest/txn.go
index 5815aacc60..dfda6cdd33 100644
--- a/data/txntest/txn.go
+++ b/data/txntest/txn.go
@@ -147,30 +147,39 @@ func (tx *Txn) FillDefaults(params config.ConsensusParams) {
tx.LastValid = tx.FirstValid + basics.Round(params.MaxTxnLife)
}
- if tx.Type == protocol.ApplicationCallTx &&
- (tx.ApplicationID == 0 || tx.OnCompletion == transactions.UpdateApplicationOC) {
-
- switch program := tx.ApprovalProgram.(type) {
- case nil:
- tx.ApprovalProgram = fmt.Sprintf("#pragma version %d\nint 1", params.LogicSigVersion)
- case string:
- if program != "" && !strings.Contains(program, "#pragma version") {
- pragma := fmt.Sprintf("#pragma version %d\n", params.LogicSigVersion)
- tx.ApprovalProgram = pragma + program
+ switch tx.Type {
+ case protocol.KeyRegistrationTx:
+ if !tx.VotePK.MsgIsZero() && !tx.SelectionPK.MsgIsZero() {
+ if tx.VoteLast == 0 {
+ tx.VoteLast = tx.VoteFirst + 1_000_000
}
- case []byte:
}
+ case protocol.ApplicationCallTx:
+ // fill in empty programs
+ if tx.ApplicationID == 0 || tx.OnCompletion == transactions.UpdateApplicationOC {
+ switch program := tx.ApprovalProgram.(type) {
+ case nil:
+ tx.ApprovalProgram = fmt.Sprintf("#pragma version %d\nint 1", params.LogicSigVersion)
+ case string:
+ if program != "" && !strings.Contains(program, "#pragma version") {
+ pragma := fmt.Sprintf("#pragma version %d\n", params.LogicSigVersion)
+ tx.ApprovalProgram = pragma + program
+ }
+ case []byte:
+ }
- switch program := tx.ClearStateProgram.(type) {
- case nil:
- tx.ClearStateProgram = tx.ApprovalProgram
- case string:
- if program != "" && !strings.Contains(program, "#pragma version") {
- pragma := fmt.Sprintf("#pragma version %d\n", params.LogicSigVersion)
- tx.ClearStateProgram = pragma + program
+ switch program := tx.ClearStateProgram.(type) {
+ case nil:
+ tx.ClearStateProgram = tx.ApprovalProgram
+ case string:
+ if program != "" && !strings.Contains(program, "#pragma version") {
+ pragma := fmt.Sprintf("#pragma version %d\n", params.LogicSigVersion)
+ tx.ClearStateProgram = pragma + program
+ }
+ case []byte:
}
- case []byte:
}
+
}
}
diff --git a/ledger/acctdeltas.go b/ledger/acctdeltas.go
index 42d5d93b2f..9071b4009b 100644
--- a/ledger/acctdeltas.go
+++ b/ledger/acctdeltas.go
@@ -1013,15 +1013,15 @@ func onlineAccountsNewRoundImpl(
}
updatedAccounts = append(updatedAccounts, updated)
prevAcct = updated
- } else if !newAcct.IsVotingEmpty() {
+ } else if !newAcct.IsVotingEmpty() && newStatus != basics.Suspended {
err = fmt.Errorf("non-empty voting data for non-online account %s: %v", data.address.String(), newAcct)
return nil, err
}
}
} else {
// non-zero rowid means we had a previous value.
- if newAcct.IsVotingEmpty() {
- // new value is zero then go offline
+ if newAcct.IsVotingEmpty() || newStatus == basics.Suspended {
+ // new value is zero, or the account is suspended then go offline
if newStatus == basics.Online {
err = fmt.Errorf("empty voting data but online account %s: %v", data.address.String(), newAcct)
return nil, err
diff --git a/ledger/acctdeltas_test.go b/ledger/acctdeltas_test.go
index bf4bd6e399..57da3c4983 100644
--- a/ledger/acctdeltas_test.go
+++ b/ledger/acctdeltas_test.go
@@ -74,7 +74,7 @@ func checkAccounts(t *testing.T, tx trackerdb.TransactionScope, rnd basics.Round
switch d.Status {
case basics.Online:
totalOnline += d.MicroAlgos.Raw
- case basics.Offline:
+ case basics.Offline, basics.Suspended:
totalOffline += d.MicroAlgos.Raw
case basics.NotParticipating:
totalNotPart += d.MicroAlgos.Raw
diff --git a/ledger/acctupdates_test.go b/ledger/acctupdates_test.go
index 1f3ca086a2..f31d4fcae5 100644
--- a/ledger/acctupdates_test.go
+++ b/ledger/acctupdates_test.go
@@ -385,18 +385,23 @@ func checkAcctUpdates(t *testing.T, au *accountUpdates, ao *onlineAccounts, base
// TODO: make lookupOnlineAccountData returning extended version of ledgercore.VotingData ?
od, err := ao.lookupOnlineAccountData(rnd, addr)
require.NoError(t, err)
- require.Equal(t, od.VoteID, data.VoteID)
- require.Equal(t, od.SelectionID, data.SelectionID)
- require.Equal(t, od.VoteFirstValid, data.VoteFirstValid)
- require.Equal(t, od.VoteLastValid, data.VoteLastValid)
- require.Equal(t, od.VoteKeyDilution, data.VoteKeyDilution)
+ // Unless suspended an account's voting data should agree with
+ // the online account tracker. (Vaccuously true, when account is
+ // offline or non-part).
+ if data.Status != basics.Suspended {
+ require.Equal(t, od.VoteID, data.VoteID)
+ require.Equal(t, od.SelectionID, data.SelectionID)
+ require.Equal(t, od.VoteFirstValid, data.VoteFirstValid)
+ require.Equal(t, od.VoteLastValid, data.VoteLastValid)
+ require.Equal(t, od.VoteKeyDilution, data.VoteKeyDilution)
+ }
rewardsDelta := rewards[rnd] - d.RewardsBase
switch d.Status {
case basics.Online:
totalOnline += d.MicroAlgos.Raw
totalOnline += (d.MicroAlgos.Raw / proto.RewardUnit) * rewardsDelta
- case basics.Offline:
+ case basics.Offline, basics.Suspended:
totalOffline += d.MicroAlgos.Raw
totalOffline += (d.MicroAlgos.Raw / proto.RewardUnit) * rewardsDelta
case basics.NotParticipating:
@@ -504,6 +509,10 @@ func checkOnlineAcctUpdatesConsistency(t *testing.T, ao *onlineAccounts, rnd bas
for i := 0; i < latest.Len(); i++ {
addr, acct := latest.GetByIdx(i)
od, err := ao.lookupOnlineAccountData(rnd, addr)
+ if acct.Status == basics.Suspended {
+ // suspended accounts will not match, since they have vote info but not in online accounts
+ continue
+ }
require.NoError(t, err)
require.Equal(t, acct.VoteID, od.VoteID)
require.Equal(t, acct.SelectionID, od.SelectionID)
diff --git a/ledger/apply/asset_test.go b/ledger/apply/asset_test.go
index 802c692c82..c096f8aca8 100644
--- a/ledger/apply/asset_test.go
+++ b/ledger/apply/asset_test.go
@@ -90,7 +90,7 @@ func TestAssetTransfer(t *testing.T) {
}
var ad transactions.ApplyData
- err := AssetTransfer(tx.AssetTransferTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, &ad)
+ err := AssetTransfer(tx.AssetTransferTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, &ad)
require.NoError(t, err)
if config.Consensus[protocol.ConsensusCurrentVersion].EnableAssetCloseAmount {
diff --git a/ledger/apply/keyreg.go b/ledger/apply/keyreg.go
index 206ff31bf3..207fd440f0 100644
--- a/ledger/apply/keyreg.go
+++ b/ledger/apply/keyreg.go
@@ -20,7 +20,6 @@ import (
"errors"
"fmt"
- "github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/data/transactions"
)
@@ -54,7 +53,7 @@ func Keyreg(keyreg transactions.KeyregTxnFields, header transactions.Header, bal
if params.EnableStateProofKeyregCheck {
record.StateProofID = keyreg.StateProofPK
}
- if (keyreg.VotePK == crypto.OneTimeSignatureVerifier{} || keyreg.SelectionPK == crypto.VRFVerifier{}) {
+ if keyreg.VotePK.IsEmpty() || keyreg.SelectionPK.IsEmpty() {
if keyreg.Nonparticipation {
if params.SupportBecomeNonParticipatingTransactions {
record.Status = basics.NotParticipating
@@ -77,6 +76,9 @@ func Keyreg(keyreg transactions.KeyregTxnFields, header transactions.Header, bal
}
}
record.Status = basics.Online
+ if params.EnableAbsenteeTracking() {
+ record.LastHeartbeat = header.FirstValid
+ }
record.VoteFirstValid = keyreg.VoteFirst
record.VoteLastValid = keyreg.VoteLast
record.VoteKeyDilution = keyreg.VoteKeyDilution
diff --git a/ledger/apply/keyreg_test.go b/ledger/apply/keyreg_test.go
index 7589b9fb1f..bb04e23f90 100644
--- a/ledger/apply/keyreg_test.go
+++ b/ledger/apply/keyreg_test.go
@@ -136,20 +136,20 @@ func TestKeyregApply(t *testing.T) {
// Going from offline to online should be okay
mockBal.addrs[src] = basics.AccountData{Status: basics.Offline}
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0))
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0))
require.NoError(t, err)
// Going from online to nonparticipatory should be okay, if the protocol supports that
if mockBal.ConsensusParams().SupportBecomeNonParticipatingTransactions {
tx.KeyregTxnFields = transactions.KeyregTxnFields{}
tx.KeyregTxnFields.Nonparticipation = true
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0))
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0))
require.NoError(t, err)
// Nonparticipatory accounts should not be able to change status
mockBal.addrs[src] = basics.AccountData{Status: basics.NotParticipating}
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0))
- require.Error(t, err)
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0))
+ require.ErrorContains(t, err, "cannot change online/offline status of non-participating account")
}
mockBal.version = "future"
@@ -171,25 +171,25 @@ func TestKeyregApply(t *testing.T) {
},
}
mockBal.addrs[src] = basics.AccountData{Status: basics.Offline}
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(999))
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(999))
require.NoError(t, err)
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(1000))
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(1000))
require.Equal(t, errKeyregGoingOnlineExpiredParticipationKey, err)
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(1001))
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(1001))
require.Equal(t, errKeyregGoingOnlineExpiredParticipationKey, err)
tx.KeyregTxnFields.VoteFirst = basics.Round(1100)
tx.KeyregTxnFields.VoteLast = basics.Round(1200)
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(1098))
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(1098))
require.Equal(t, errKeyregGoingOnlineFirstVotingInFuture, err)
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(1099))
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(1099))
require.NoError(t, err)
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(1100))
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(1100))
require.NoError(t, err)
testStateProofPKBeingStored(t, tx, mockBal)
@@ -197,7 +197,7 @@ func TestKeyregApply(t *testing.T) {
}
func testStateProofPKBeingStored(t *testing.T, tx transactions.Transaction, mockBal *keyregTestBalances) {
- err := Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(1100))
+ err := Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(1100))
require.NoError(t, err) // expects no error with empty keyRegistration attempt
rec, err := mockBal.Get(tx.Header.Sender, false)
@@ -215,7 +215,7 @@ func TestStateProofPKKeyReg(t *testing.T) {
tx := createTestTxn(t, src, secretParticipation, vrfSecrets)
mockBal := makeMockBalances(protocol.ConsensusV30)
- err := Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0))
+ err := Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0))
require.NoError(t, err)
acct, err := mockBal.Get(tx.Src(), false)
@@ -223,7 +223,7 @@ func TestStateProofPKKeyReg(t *testing.T) {
require.True(t, acct.StateProofID.IsEmpty())
mockBal = makeMockBalances(protocol.ConsensusCurrentVersion)
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0))
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0))
require.NoError(t, err)
acct, err = mockBal.Get(tx.Src(), false)
@@ -232,7 +232,7 @@ func TestStateProofPKKeyReg(t *testing.T) {
// go offline in current consensus version: StateProofID should be empty
emptyKeyreg := transactions.KeyregTxnFields{}
- err = Keyreg(emptyKeyreg, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0))
+ err = Keyreg(emptyKeyreg, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0))
require.NoError(t, err)
acct, err = mockBal.Get(tx.Src(), false)
@@ -241,7 +241,7 @@ func TestStateProofPKKeyReg(t *testing.T) {
// run same test using vFuture
mockBal = makeMockBalances(protocol.ConsensusFuture)
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0))
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0))
require.NoError(t, err)
acct, err = mockBal.Get(tx.Src(), false)
@@ -249,7 +249,7 @@ func TestStateProofPKKeyReg(t *testing.T) {
require.False(t, acct.StateProofID.IsEmpty())
// go offline in vFuture: StateProofID should be empty
- err = Keyreg(emptyKeyreg, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0))
+ err = Keyreg(emptyKeyreg, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0))
require.NoError(t, err)
acct, err = mockBal.Get(tx.Src(), false)
diff --git a/ledger/apply/payment_test.go b/ledger/apply/payment_test.go
index db82869e23..59b28ad899 100644
--- a/ledger/apply/payment_test.go
+++ b/ledger/apply/payment_test.go
@@ -104,7 +104,7 @@ func TestPaymentApply(t *testing.T) {
},
}
var ad transactions.ApplyData
- err := Payment(tx.PaymentTxnFields, tx.Header, mockBalV0, transactions.SpecialAddresses{FeeSink: feeSink}, &ad)
+ err := Payment(tx.PaymentTxnFields, tx.Header, mockBalV0, transactions.SpecialAddresses{}, &ad)
require.NoError(t, err)
}
diff --git a/ledger/apptxn_test.go b/ledger/apptxn_test.go
index 982c9f01b2..cbdcb1791f 100644
--- a/ledger/apptxn_test.go
+++ b/ledger/apptxn_test.go
@@ -58,6 +58,10 @@ func TestPayAction(t *testing.T) {
itxn_submit
`))
+ // We're going to test some mining effects here too, so that we have an inner transaction example.
+ // Do a block with no txns, so the fee sink balance as we start the next block is stable
+ dl.fullBlock()
+
payout1 := txntest.Txn{
Type: "appl",
Sender: addrs[1],
@@ -65,7 +69,40 @@ func TestPayAction(t *testing.T) {
Accounts: []basics.Address{addrs[1]}, // pay self
}
- dl.fullBlock(&payout1)
+ proposer := addrs[7]
+ presink := micros(dl.t, dl.generator, genBalances.FeeSink)
+ preprop := micros(dl.t, dl.generator, proposer)
+ dl.beginBlock()
+ dl.txns(&payout1)
+ vb := dl.endBlock(proposer)
+ // First MiningPct > 0
+ if ver >= 39 {
+ require.True(t, dl.generator.GenesisProto().EnableMining)
+ require.EqualValues(t, proposer, vb.Block().BlockHeader.Proposer)
+ require.EqualValues(t, 2000, vb.Block().BlockHeader.FeesCollected.Raw)
+ } else {
+ require.False(t, dl.generator.GenesisProto().EnableMining)
+ require.Zero(t, vb.Block().BlockHeader.Proposer)
+ require.Zero(t, vb.Block().BlockHeader.FeesCollected)
+ }
+
+ postsink := micros(dl.t, dl.generator, genBalances.FeeSink)
+ postprop := micros(dl.t, dl.generator, proposer)
+
+ // Mining checks
+ require.EqualValues(t, 0, postprop-preprop) // mining not moved yet
+ require.EqualValues(t, 2000, postsink-presink)
+
+ dl.fullBlock()
+ postsink = micros(dl.t, dl.generator, genBalances.FeeSink)
+ postprop = micros(dl.t, dl.generator, proposer)
+ // First MiningPct > 0
+ if ver >= 39 {
+ require.EqualValues(t, 500, postsink-presink) // based on 75% in config/consensus.go
+ require.EqualValues(t, 1500, postprop-preprop)
+ } else {
+ require.EqualValues(t, 2000, postsink-presink) // no mining yet
+ }
ad0 := micros(dl.t, dl.generator, addrs[0])
ad1 := micros(dl.t, dl.generator, addrs[1])
@@ -90,7 +127,7 @@ func TestPayAction(t *testing.T) {
ApplicationID: ai,
Accounts: []basics.Address{addrs[2]}, // pay other
}
- vb := dl.fullBlock(&payout2)
+ vb = dl.fullBlock(&payout2)
// confirm that modifiedAccounts can see account in inner txn
deltas := vb.Delta()
diff --git a/ledger/double_test.go b/ledger/double_test.go
index 16d38e7681..419a8da55f 100644
--- a/ledger/double_test.go
+++ b/ledger/double_test.go
@@ -48,6 +48,9 @@ type DoubleLedger struct {
validator *Ledger
eval *eval.BlockEvaluator
+
+ // proposer is the default proposer unless one is supplied to endBlock.
+ proposer basics.Address
}
func (dl DoubleLedger) Close() {
@@ -59,7 +62,7 @@ func (dl DoubleLedger) Close() {
func NewDoubleLedger(t testing.TB, balances bookkeeping.GenesisBalances, cv protocol.ConsensusVersion, cfg config.Local, opts ...simpleLedgerOption) DoubleLedger {
g := newSimpleLedgerWithConsensusVersion(t, balances, cv, cfg, opts...)
v := newSimpleLedgerFull(t, balances, cv, g.GenesisHash(), cfg, opts...)
- return DoubleLedger{t, g, v, nil}
+ return DoubleLedger{t, g, v, nil, balances.FeeSink} // FeeSink as proposer will make old code work as expected
}
func (dl *DoubleLedger) beginBlock() *eval.BlockEvaluator {
@@ -134,8 +137,12 @@ func (dl *DoubleLedger) fullBlock(txs ...*txntest.Txn) *ledgercore.ValidatedBloc
return dl.endBlock()
}
-func (dl *DoubleLedger) endBlock() *ledgercore.ValidatedBlock {
- vb := endBlock(dl.t, dl.generator, dl.eval)
+func (dl *DoubleLedger) endBlock(proposer ...basics.Address) *ledgercore.ValidatedBlock {
+ prp := dl.proposer
+ if len(proposer) > 0 {
+ prp = proposer[0]
+ }
+ vb := endBlock(dl.t, dl.generator, dl.eval, prp)
if dl.validator != nil { // Allows setting to nil while debugging, to simplify
checkBlock(dl.t, dl.validator, vb)
}
@@ -195,7 +202,7 @@ func checkBlock(t testing.TB, checkLedger *Ledger, vb *ledgercore.ValidatedBlock
require.NoError(t, err, "%+v", reconstituted.Payset)
}
check.SetGenerateForTesting(true)
- cb := endBlock(t, checkLedger, check)
+ cb := endBlock(t, checkLedger, check, vb.Block().Proposer)
check.SetGenerateForTesting(false)
require.Equal(t, vb.Block(), cb.Block())
diff --git a/ledger/eval/applications.go b/ledger/eval/applications.go
index 5419bc9525..06cc467187 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
}
@@ -349,3 +348,12 @@ func (cs *roundCowState) Perform(gi int, ep *logic.EvalParams) error {
return nil
}
+
+func (cs *roundCowState) Heartbeat(addr basics.Address) error {
+ acct, err := cs.lookup(addr)
+ if err != nil {
+ return err
+ }
+ acct.LastHeartbeat = cs.Round()
+ return cs.Put(addr, acct)
+}
diff --git a/ledger/eval/cow.go b/ledger/eval/cow.go
index d797a4a560..1d48d8abf7 100644
--- a/ledger/eval/cow.go
+++ b/ledger/eval/cow.go
@@ -93,6 +93,8 @@ type roundCowState struct {
// prevTotals contains the accounts totals for the previous round. It's being used to calculate the totals for the new round
// so that we could perform the validation test on these to ensure the block evaluator generate a valid changeset.
prevTotals ledgercore.AccountTotals
+
+ feesCollected basics.MicroAlgos
}
var childPool = sync.Pool{
@@ -293,6 +295,8 @@ func (cb *roundCowState) commitToParent() {
cb.commitParent.mods.Txids[txid] = ledgercore.IncludedTransactions{LastValid: incTxn.LastValid, Intra: commitParentBaseIdx + incTxn.Intra}
}
cb.commitParent.txnCount += cb.txnCount
+ // no overflow because of 10B algo cap
+ cb.commitParent.feesCollected, _ = basics.OAddA(cb.commitParent.feesCollected, cb.feesCollected)
for txl, expires := range cb.mods.Txleases {
cb.commitParent.mods.AddTxLease(txl, expires)
@@ -336,6 +340,7 @@ func (cb *roundCowState) reset() {
cb.compatibilityMode = false
maps.Clear(cb.compatibilityGetKeyCache)
cb.prevTotals = ledgercore.AccountTotals{}
+ cb.feesCollected = basics.MicroAlgos{}
}
// recycle resets the roundcowstate and returns it to the sync.Pool
diff --git a/ledger/eval/cow_test.go b/ledger/eval/cow_test.go
index 225b037997..eb4bc5e38b 100644
--- a/ledger/eval/cow_test.go
+++ b/ledger/eval/cow_test.go
@@ -281,6 +281,7 @@ func TestCowChildReflect(t *testing.T) {
"compatibilityMode": {},
"compatibilityGetKeyCache": {},
"prevTotals": {},
+ "feesCollected": {},
}
cow := roundCowState{}
@@ -288,7 +289,7 @@ func TestCowChildReflect(t *testing.T) {
st := v.Type()
for i := 0; i < v.NumField(); i++ {
reflectedCowName := st.Field(i).Name
- require.Containsf(t, cowFieldNames, reflectedCowName, "new field:\"%v\" added to roundCowState, please update roundCowState.reset() to handle it before fixing the test", reflectedCowName)
+ require.Containsf(t, cowFieldNames, reflectedCowName, "new field:\"%v\" added to roundCowState, please update roundCowState.reset() to handle it before fixing this test", reflectedCowName)
}
}
diff --git a/ledger/eval/eval.go b/ledger/eval/eval.go
index 66b1133457..e9f1eb6573 100644
--- a/ledger/eval/eval.go
+++ b/ledger/eval/eval.go
@@ -783,6 +783,25 @@ func StartEvaluator(l LedgerForEvaluator, hdr bookkeeping.BlockHeader, evalOpts
return nil, fmt.Errorf("overflowed subtracting rewards for block %v", hdr.Round)
}
+ // Pay the previous proposer
+ miningIncentive, _ := basics.NewPercent(proto.MiningPercent).DivvyAlgos(prevHeader.FeesCollected)
+ err = eval.state.Move(prevHeader.FeeSink, prevHeader.Proposer, miningIncentive, nil, nil)
+ if err != nil {
+ // This should be impossible. The fees were just collected, and the FeeSink cannot be emptied.
+ return nil, fmt.Errorf("unable to Move mining incentive")
+ }
+
+ // Note their proposal
+ prp, err := eval.state.Get(prevHeader.Proposer, false)
+ if err != nil {
+ return nil, err
+ }
+ prp.LastProposed = hdr.Round - 1
+ err = eval.state.Put(prevHeader.Proposer, prp)
+ if err != nil {
+ return nil, err
+ }
+
if eval.Tracer != nil {
eval.Tracer.BeforeBlock(&eval.block.BlockHeader)
}
@@ -1160,12 +1179,27 @@ func (eval *BlockEvaluator) transaction(txn transactions.SignedTxn, evalParams *
return nil
}
+func (cs *roundCowState) takeFee(tx *transactions.Transaction, senderRewards *basics.MicroAlgos, ep *logic.EvalParams) error {
+ err := cs.Move(tx.Sender, ep.Specials.FeeSink, tx.Fee, senderRewards, nil)
+ if err != nil {
+ return err
+ }
+ // transactions from FeeSink should be exceedingly rare. But we can't count
+ // them in feesCollected because there are no net algos added to the Sink
+ if tx.Sender == ep.Specials.FeeSink {
+ return nil
+ }
+ // overflow impossible, since these sum the fees actually paid. 10B algo limit
+ cs.feesCollected, _ = basics.OAddA(cs.feesCollected, tx.Fee)
+ return nil
+
+}
+
// applyTransaction changes the balances according to this transaction.
func (eval *BlockEvaluator) applyTransaction(tx transactions.Transaction, cow *roundCowState, evalParams *logic.EvalParams, gi int, ctr uint64) (ad transactions.ApplyData, err error) {
params := cow.ConsensusParams()
- // move fee to pool
- err = cow.Move(tx.Sender, eval.specials.FeeSink, tx.Fee, &ad.SenderRewards, nil)
+ err = cow.takeFee(&tx, &ad.SenderRewards, evalParams)
if err != nil {
return
}
@@ -1267,7 +1301,11 @@ func (eval *BlockEvaluator) endOfBlock() error {
eval.block.TxnCounter = 0
}
- eval.generateExpiredOnlineAccountsList()
+ if eval.proto.EnableMining {
+ eval.block.FeesCollected = eval.state.feesCollected
+ }
+
+ eval.generateKnockOfflineAccountsList()
if eval.proto.StateProofInterval > 0 {
var basicStateProof bookkeeping.StateProofTrackingData
@@ -1283,13 +1321,17 @@ func (eval *BlockEvaluator) endOfBlock() error {
}
}
- err := eval.validateExpiredOnlineAccounts()
- if err != nil {
+ if err := eval.validateExpiredOnlineAccounts(); err != nil {
+ return err
+ }
+ if err := eval.resetExpiredOnlineAccountsParticipationKeys(); err != nil {
return err
}
- err = eval.resetExpiredOnlineAccountsParticipationKeys()
- if err != nil {
+ if err := eval.validateAbsentOnlineAccounts(); err != nil {
+ return err
+ }
+ if err := eval.suspendAbsentAccounts(); err != nil {
return err
}
@@ -1311,6 +1353,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
@@ -1346,8 +1396,7 @@ func (eval *BlockEvaluator) endOfBlock() error {
}
}
- err = eval.state.CalculateTotals()
- if err != nil {
+ if err := eval.state.CalculateTotals(); err != nil {
return err
}
@@ -1358,9 +1407,10 @@ func (eval *BlockEvaluator) endOfBlock() error {
return nil
}
-// generateExpiredOnlineAccountsList creates the list of the expired participation accounts by traversing over the
-// modified accounts in the state deltas and testing if any of them needs to be reset.
-func (eval *BlockEvaluator) generateExpiredOnlineAccountsList() {
+// generateKnockOfflineAccountsList creates the lists of expired or absent
+// participation accounts by traversing over the modified accounts in the state
+// deltas and testing if any of them needs to be reset/suspended.
+func (eval *BlockEvaluator) generateKnockOfflineAccountsList() {
if !eval.generate {
return
}
@@ -1369,32 +1419,59 @@ func (eval *BlockEvaluator) generateExpiredOnlineAccountsList() {
// Then we are going to go through each modified account and
// see if it meets the criteria for adding it to the expired
// participation accounts list.
- modifiedAccounts := eval.state.modifiedAccounts()
currentRound := eval.Round()
expectedMaxNumberOfExpiredAccounts := eval.proto.MaxProposedExpiredOnlineAccounts
+ expectedMaxNumberOfAbsentAccounts := eval.proto.MaxProposedAbsentOnlineAccounts
+
+ updates := &eval.block.ParticipationUpdates
- for i := 0; i < len(modifiedAccounts) && len(eval.block.ParticipationUpdates.ExpiredParticipationAccounts) < expectedMaxNumberOfExpiredAccounts; i++ {
- accountAddr := modifiedAccounts[i]
+ for _, accountAddr := range eval.state.modifiedAccounts() {
acctDelta, found := eval.state.mods.Accts.GetData(accountAddr)
if !found {
continue
}
- // true if the account is online
- isOnline := acctDelta.Status == basics.Online
- // true if the accounts last valid round has passed
- pastCurrentRound := acctDelta.VoteLastValid < currentRound
+ if acctDelta.Status == basics.Online || acctDelta.Status == basics.Suspended {
+ expiresBeforeCurrent := acctDelta.VoteLastValid < currentRound
+ if expiresBeforeCurrent &&
+ len(updates.ExpiredParticipationAccounts) < expectedMaxNumberOfExpiredAccounts {
+ updates.ExpiredParticipationAccounts = append(
+ updates.ExpiredParticipationAccounts,
+ accountAddr,
+ )
+ continue // if marking expired, do not also suspend
+ }
+ }
- if isOnline && pastCurrentRound {
- eval.block.ParticipationUpdates.ExpiredParticipationAccounts = append(
- eval.block.ParticipationUpdates.ExpiredParticipationAccounts,
- accountAddr,
- )
+ if acctDelta.Status == basics.Online {
+ lastSeen := max(acctDelta.LastHeartbeat, acctDelta.LastHeartbeat)
+ if isAbsent(eval.state.prevTotals.Online.Money, acctDelta.MicroAlgos, lastSeen, currentRound) &&
+ len(updates.AbsentParticipationAccounts) < expectedMaxNumberOfAbsentAccounts {
+ updates.AbsentParticipationAccounts = append(
+ updates.AbsentParticipationAccounts,
+ accountAddr,
+ )
+ }
}
}
}
+// delete me in Go 1.21
+func max(a, b basics.Round) basics.Round {
+ if a > b {
+ return a
+ }
+ return b
+}
+
+func isAbsent(totalOnlineStake basics.MicroAlgos, acctStake basics.MicroAlgos, lastSeen basics.Round, current basics.Round) bool {
+ // See if the account has exceeded 10x their expected observation interval.
+ allowableLag := basics.Round(10 * totalOnlineStake.Raw / acctStake.Raw)
+ fmt.Printf("%d / %d -> %d \n", acctStake, totalOnlineStake, allowableLag)
+ return lastSeen+allowableLag < current
+}
+
// validateExpiredOnlineAccounts tests the expired online accounts specified in ExpiredParticipationAccounts, and verify
// that they have all expired and need to be reset.
func (eval *BlockEvaluator) validateExpiredOnlineAccounts() error {
@@ -1415,7 +1492,7 @@ func (eval *BlockEvaluator) validateExpiredOnlineAccounts() error {
// are unique. We make this map to keep track of previously seen address
addressSet := make(map[basics.Address]bool, lengthOfExpiredParticipationAccounts)
- // Validate that all expired accounts meet the current criteria
+ // Validate that all proposed accounts have expired keys
currentRound := eval.Round()
for _, accountAddr := range eval.block.ParticipationUpdates.ExpiredParticipationAccounts {
@@ -1432,22 +1509,63 @@ func (eval *BlockEvaluator) validateExpiredOnlineAccounts() error {
return fmt.Errorf("endOfBlock was unable to retrieve account %v : %w", accountAddr, err)
}
- // true if the account is online
- isOnline := acctData.Status == basics.Online
- // true if the accounts last valid round has passed
- pastCurrentRound := acctData.VoteLastValid < currentRound
-
- if !isOnline {
+ if acctData.Status != basics.Online && acctData.Status != basics.Suspended {
return fmt.Errorf("endOfBlock found %v was not online but %v", accountAddr, acctData.Status)
}
- if !pastCurrentRound {
+ if acctData.VoteLastValid >= currentRound {
return fmt.Errorf("endOfBlock found %v round (%d) was not less than current round (%d)", accountAddr, acctData.VoteLastValid, currentRound)
}
}
return nil
}
+// validateAbsentOnlineAccounts tests the accounts specified in
+// AbsentParticipationAccounts, and verifies that they need to be reset.
+func (eval *BlockEvaluator) validateAbsentOnlineAccounts() error {
+ if !eval.validate {
+ return nil
+ }
+ expectedMaxNumberOfAbsentAccounts := eval.proto.MaxProposedAbsentOnlineAccounts
+ lengthOfAbsentParticipationAccounts := len(eval.block.ParticipationUpdates.AbsentParticipationAccounts)
+
+ // If the length of the array is strictly greater than our max then we have an error.
+ // This works when the expected number of accounts is zero (i.e. it is disabled) as well
+ if lengthOfAbsentParticipationAccounts > expectedMaxNumberOfAbsentAccounts {
+ return fmt.Errorf("length of absent accounts (%d) was greater than expected (%d)",
+ lengthOfAbsentParticipationAccounts, expectedMaxNumberOfAbsentAccounts)
+ }
+
+ // For consistency with expired account handling, we preclude duplicates
+ addressSet := make(map[basics.Address]bool, lengthOfAbsentParticipationAccounts)
+
+ // Validate that all accounts have been absent
+ currentRound := eval.Round()
+ for _, accountAddr := range eval.block.ParticipationUpdates.AbsentParticipationAccounts {
+
+ if _, exists := addressSet[accountAddr]; exists {
+ return fmt.Errorf("duplicate address found: %v", accountAddr)
+ }
+ addressSet[accountAddr] = true
+
+ acctData, err := eval.state.lookup(accountAddr)
+ if err != nil {
+ return fmt.Errorf("unable to retrieve proposed absent account %v : %w", accountAddr, err)
+ }
+
+ if acctData.Status != basics.Online {
+ return fmt.Errorf("proposed absent acct %v was not online but %v", accountAddr, acctData.Status)
+ }
+
+ lastSeen := max(acctData.LastHeartbeat, acctData.LastHeartbeat)
+ if !isAbsent(eval.state.prevTotals.Online.Money, acctData.MicroAlgos, lastSeen, currentRound) {
+ return fmt.Errorf("proposed absent account %v is not absent in %d, %d",
+ accountAddr, acctData.LastProposed, acctData.LastHeartbeat)
+ }
+ }
+ return nil
+}
+
// resetExpiredOnlineAccountsParticipationKeys after all transactions and rewards are processed, modify the accounts so that their status is offline
func (eval *BlockEvaluator) resetExpiredOnlineAccountsParticipationKeys() error {
expectedMaxNumberOfExpiredAccounts := eval.proto.MaxProposedExpiredOnlineAccounts
@@ -1478,6 +1596,24 @@ func (eval *BlockEvaluator) resetExpiredOnlineAccountsParticipationKeys() error
return nil
}
+// suspendAbsentAccounts suspends the proposed list of absent accounts.
+func (eval *BlockEvaluator) suspendAbsentAccounts() error {
+ for _, addr := range eval.block.ParticipationUpdates.AbsentParticipationAccounts {
+ acct, err := eval.state.lookup(addr)
+ if err != nil {
+ return err
+ }
+
+ acct.Suspend()
+
+ err = eval.state.putAccount(addr, acct)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
// GenerateBlock produces a complete block from the BlockEvaluator. This is
// used during proposal to get an actual block that will be proposed, after
// feeding in tentative transactions into this block evaluator.
diff --git a/ledger/eval/prefetcher/prefetcher_alignment_test.go b/ledger/eval/prefetcher/prefetcher_alignment_test.go
index 81ce168d43..c64ae6d3db 100644
--- a/ledger/eval/prefetcher/prefetcher_alignment_test.go
+++ b/ledger/eval/prefetcher/prefetcher_alignment_test.go
@@ -58,6 +58,10 @@ func rewardsPool() basics.Address {
return makeAddress(101)
}
+func proposer() basics.Address {
+ return basics.Address{}
+}
+
func genesisBlock() (bookkeeping.Block, error) {
block, err := bookkeeping.MakeGenesisBlock(
proto,
@@ -261,6 +265,18 @@ type ledgerData struct {
Creators map[creatable]struct{}
}
+// pretend adds the `before` addresses to the Accounts. It "pretends" that the
+// addresses were prefetched, so we can get agreement with what was actually
+// requested. We do this to include two addresses that are going to end up
+// requested *before* prefetch is even attempted. So there's no point in
+// PrefetchAccounts being modified to return them, they have been "prefetched"
+// simply by accessing them.
+func (ld *ledgerData) pretend(before ...basics.Address) {
+ for _, a := range before {
+ ld.Accounts[a] = struct{}{}
+ }
+}
+
func prefetch(t *testing.T, l prefetcher.Ledger, txn transactions.Transaction) ledgerData {
group := makeGroupFromTxn(txn)
@@ -361,7 +377,7 @@ func TestEvaluatorPrefetcherAlignmentPayment(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -393,7 +409,7 @@ func TestEvaluatorPrefetcherAlignmentCreateAsset(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
// Only one (non-existing) asset is requested. Ignore it.
require.Len(t, requested.Assets, 1)
require.Len(t, requested.Assets[makeAddress(1)], 1)
@@ -449,7 +465,7 @@ func TestEvaluatorPrefetcherAlignmentReconfigAsset(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -504,7 +520,7 @@ func TestEvaluatorPrefetcherAlignmentAssetOptIn(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -570,7 +586,7 @@ func TestEvaluatorPrefetcherAlignmentAssetOptInCloseTo(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -641,7 +657,7 @@ func TestEvaluatorPrefetcherAlignmentAssetTransfer(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
// zero transfer of any asset
@@ -660,7 +676,7 @@ func TestEvaluatorPrefetcherAlignmentAssetTransfer(t *testing.T) {
requested, prefetched = run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -741,7 +757,7 @@ func TestEvaluatorPrefetcherAlignmentAssetClawback(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -811,7 +827,7 @@ func TestEvaluatorPrefetcherAlignmentAssetFreeze(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -858,7 +874,7 @@ func TestEvaluatorPrefetcherAlignmentKeyreg(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -895,7 +911,7 @@ func TestEvaluatorPrefetcherAlignmentCreateApplication(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
// Only one (non-existing) asset is requested. Ignore it.
require.Len(t, requested.Apps, 1)
require.Len(t, requested.Apps[makeAddress(1)], 1)
@@ -953,7 +969,7 @@ func TestEvaluatorPrefetcherAlignmentDeleteApplication(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -1011,7 +1027,7 @@ func TestEvaluatorPrefetcherAlignmentApplicationOptIn(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -1075,7 +1091,7 @@ func TestEvaluatorPrefetcherAlignmentApplicationCloseOut(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -1139,7 +1155,7 @@ func TestEvaluatorPrefetcherAlignmentApplicationClearState(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -1203,7 +1219,7 @@ func TestEvaluatorPrefetcherAlignmentApplicationCallAccountsDeclaration(t *testi
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
// Foreign accounts are not loaded, ensure they are not prefetched
require.NotContains(t, prefetched.Accounts, makeAddress(5))
require.NotContains(t, prefetched.Accounts, makeAddress(3))
@@ -1271,7 +1287,7 @@ func TestEvaluatorPrefetcherAlignmentApplicationCallForeignAppsDeclaration(t *te
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
// Foreign apps are not loaded, ensure they are not prefetched
require.NotContains(t, prefetched.Creators, creatable{cindex: 6, ctype: basics.AppCreatable})
require.NotContains(t, prefetched.Creators, creatable{cindex: 8, ctype: basics.AppCreatable})
@@ -1338,7 +1354,7 @@ func TestEvaluatorPrefetcherAlignmentApplicationCallForeignAssetsDeclaration(t *
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
// Foreign apps are not loaded, ensure they are not prefetched
require.NotContains(t, prefetched.Creators, creatable{cindex: 6, ctype: basics.AssetCreatable})
require.NotContains(t, prefetched.Creators, creatable{cindex: 8, ctype: basics.AssetCreatable})
@@ -1385,6 +1401,6 @@ func TestEvaluatorPrefetcherAlignmentStateProof(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
diff --git a/ledger/eval_simple_test.go b/ledger/eval_simple_test.go
index 606ee4931d..a45241dbad 100644
--- a/ledger/eval_simple_test.go
+++ b/ledger/eval_simple_test.go
@@ -211,6 +211,194 @@ 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
+ }
+ })
+}
+
+// TestAbsentTracking checks that LastProposed and LastHeartbeat are updated
+// properly.
+func TestAbsentTracking(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ t.Parallel()
+
+ genBalances, addrs, _ := ledgertesting.NewTestGenesis(func(cfg *ledgertesting.GenesisCfg) {
+ cfg.OnlineCount = 2 // So we know proposer should propose every 2 rounds, on average
+ })
+ // Absentee checking begins in v39. Start checking in v38 to test that is unchanged.
+ ledgertesting.TestConsensusRange(t, 38, 0, func(t *testing.T, ver int, cv protocol.ConsensusVersion, cfg config.Local) {
+ dl := NewDoubleLedger(t, genBalances, cv, cfg)
+ defer dl.Close()
+
+ totals, err := dl.generator.Totals(0)
+ require.NoError(t, err)
+ require.NotZero(t, totals.Online.Money.Raw)
+ for i, addr := range addrs {
+ fmt.Printf("addrs[%d] == %v\n", i, addr)
+ }
+ require.True(t, lookup(t, dl.generator, addrs[0]).Status == basics.Online)
+ require.True(t, lookup(t, dl.generator, addrs[1]).Status == basics.Online)
+ require.False(t, lookup(t, dl.generator, addrs[2]).Status == basics.Online)
+
+ dl.fullBlock()
+
+ proposer := addrs[7]
+ dl.beginBlock()
+ dl.txns(&txntest.Txn{
+ Type: "pay",
+ Sender: addrs[1],
+ Receiver: addrs[2],
+ Amount: 100_000,
+ })
+ dl.endBlock(proposer)
+
+ newtotals, err := dl.generator.Totals(dl.generator.Latest())
+ require.NoError(t, err)
+ // payment and fee left the online account
+ require.Equal(t, totals.Online.Money.Raw-100_000-1000, newtotals.Online.Money.Raw)
+ totals = newtotals
+
+ dl.fullBlock()
+
+ prp := lookup(t, dl.validator, proposer)
+
+ if ver >= 39 {
+ // version sanity check
+ require.True(t, dl.generator.GenesisProto().EnableAbsenteeTracking())
+ require.NotZero(t, prp.LastProposed)
+ require.Zero(t, prp.LastHeartbeat) // genesis participants have never hb
+ } else {
+ require.False(t, dl.generator.GenesisProto().EnableAbsenteeTracking())
+ require.Zero(t, prp.LastProposed)
+ require.Zero(t, prp.LastHeartbeat)
+ }
+
+ // addrs[2] was already offline
+ dl.txns(&txntest.Txn{Type: "keyreg", Sender: addrs[2]}) // OFFLINE keyreg
+ regger := lookup(t, dl.validator, addrs[2])
+
+ newtotals, err = dl.generator.Totals(dl.generator.Latest())
+ require.NoError(t, err)
+ require.Equal(t, totals.Online.Money.Raw, newtotals.Online.Money.Raw)
+
+ // offline transaction records nothing
+ require.Zero(t, regger.LastProposed)
+ require.Zero(t, regger.LastHeartbeat)
+
+ // ONLINE keyreg
+ dl.txns(&txntest.Txn{
+ Type: "keyreg",
+ Sender: addrs[2],
+ VotePK: [32]byte{1},
+ SelectionPK: [32]byte{1},
+ })
+ newtotals, err = dl.generator.Totals(dl.generator.Latest())
+ require.NoError(t, err)
+ require.Greater(t, newtotals.Online.Money.Raw, totals.Online.Money.Raw)
+
+ regger = lookup(t, dl.validator, addrs[2])
+ require.Zero(t, regger.LastProposed)
+ require.True(t, regger.Status == basics.Online)
+
+ if ver >= 39 {
+ require.NotZero(t, regger.LastHeartbeat) // online keyreg caused update
+ } else {
+ require.Zero(t, regger.LastHeartbeat)
+ }
+
+ for i := 0; i < 5; i++ {
+ dl.fullBlock()
+ require.True(t, lookup(t, dl.generator, addrs[0]).Status == basics.Online)
+ require.True(t, lookup(t, dl.generator, addrs[1]).Status == basics.Online)
+ require.True(t, lookup(t, dl.generator, addrs[2]).Status == basics.Online)
+ }
+
+ // all are still online after a few blocks
+ require.True(t, lookup(t, dl.generator, addrs[0]).Status == basics.Online)
+ require.True(t, lookup(t, dl.generator, addrs[1]).Status == basics.Online)
+ require.True(t, lookup(t, dl.generator, addrs[2]).Status == basics.Online)
+
+ for i := 0; i < 30; i++ {
+ dl.fullBlock()
+ }
+
+ // addrs 0-2 all have about 1/3 of stake, so become eligible for
+ // suspension after 30 rounds. We're at about 35. But, since blocks are
+ // empty, nobody's susspendible account is noticed.
+ require.True(t, lookup(t, dl.generator, addrs[0]).Status == basics.Online)
+ require.True(t, lookup(t, dl.generator, addrs[1]).Status == basics.Online)
+ require.True(t, lookup(t, dl.generator, addrs[2]).Status == basics.Online)
+
+ // when 2 pays 0, they both get noticed and get suspended
+ dl.txns(&txntest.Txn{
+ Type: "pay",
+ Sender: addrs[2],
+ Receiver: addrs[0],
+ Amount: 0,
+ })
+ require.Equal(t, ver < 39, lookup(t, dl.generator, addrs[0]).Status == basics.Online)
+ require.True(t, lookup(t, dl.generator, addrs[1]).Status == basics.Online)
+ require.Equal(t, ver < 39, lookup(t, dl.generator, addrs[2]).Status == basics.Online)
+
+ })
+}
+
// 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.go b/ledger/ledger.go
index dc3baaf766..cf90649db0 100644
--- a/ledger/ledger.go
+++ b/ledger/ledger.go
@@ -680,7 +680,7 @@ func (l *Ledger) Block(rnd basics.Round) (blk bookkeeping.Block, err error) {
func (l *Ledger) BlockHdr(rnd basics.Round) (blk bookkeeping.BlockHeader, err error) {
// Expected availability range in txTail.blockHeader is [Latest - MaxTxnLife, Latest]
- // allowing (MaxTxnLife + 1) = 1001 rounds back loopback.
+ // allowing (MaxTxnLife + 1) = 1001 rounds lookback.
// The depth besides the MaxTxnLife is controlled by DeeperBlockHeaderHistory parameter
// and currently set to 1.
// Explanation:
diff --git a/ledger/ledger_test.go b/ledger/ledger_test.go
index 19bb6a0796..602fc7f8b6 100644
--- a/ledger/ledger_test.go
+++ b/ledger/ledger_test.go
@@ -174,6 +174,9 @@ func (l *Ledger) appendUnvalidatedSignedTx(t *testing.T, initAccounts map[basics
if proto.TxnCounter {
blk.TxnCounter = blk.TxnCounter + 1
}
+ if proto.EnableMining {
+ blk.FeesCollected = stx.Txn.Fee
+ }
blk.Payset = append(blk.Payset, txib)
blk.TxnCommitments, err = blk.PaysetCommit()
require.NoError(t, err)
diff --git a/ledger/ledgercore/accountdata.go b/ledger/ledgercore/accountdata.go
index 69e2c543eb..4efe905563 100644
--- a/ledger/ledgercore/accountdata.go
+++ b/ledger/ledgercore/accountdata.go
@@ -48,6 +48,9 @@ type AccountBaseData struct {
TotalAssets uint64 // Total of asset creations and optins (i.e. number of holdings)
TotalBoxes uint64 // Total number of boxes associated to this account
TotalBoxBytes uint64 // Total bytes for this account's boxes. keys _and_ values count
+
+ LastProposed basics.Round // The last round that this account proposed the winning block.
+ LastHeartbeat basics.Round // The last round that this account sent a heartbeat to show it was online.
}
// VotingData holds participation information
@@ -86,6 +89,9 @@ func ToAccountData(acct basics.AccountData) AccountData {
TotalAppLocalStates: uint64(len(acct.AppLocalStates)),
TotalBoxes: acct.TotalBoxes,
TotalBoxBytes: acct.TotalBoxBytes,
+
+ LastProposed: acct.LastProposed,
+ LastHeartbeat: acct.LastHeartbeat,
},
VotingData: VotingData{
VoteID: acct.VoteID,
@@ -118,6 +124,9 @@ func AssignAccountData(a *basics.AccountData, acct AccountData) {
a.TotalExtraAppPages = acct.TotalExtraAppPages
a.TotalBoxes = acct.TotalBoxes
a.TotalBoxBytes = acct.TotalBoxBytes
+
+ a.LastProposed = acct.LastProposed
+ a.LastHeartbeat = acct.LastHeartbeat
}
// WithUpdatedRewards calls basics account data WithUpdatedRewards
@@ -134,6 +143,12 @@ func (u *AccountData) ClearOnlineState() {
u.VotingData = VotingData{}
}
+// Suspend sets the status to Suspended, but does _not_ clear voting keys, so
+// that a heartbeat can bring the account back Online
+func (u *AccountData) Suspend() {
+ u.Status = basics.Suspended
+}
+
// MinBalance computes the minimum balance requirements for an account based on
// some consensus parameters. MinBalance should correspond roughly to how much
// storage the account is allowed to store on disk.
diff --git a/ledger/ledgercore/totals.go b/ledger/ledgercore/totals.go
index 904cac9114..a38393ab03 100644
--- a/ledger/ledgercore/totals.go
+++ b/ledger/ledgercore/totals.go
@@ -66,7 +66,7 @@ func (at *AccountTotals) statusField(status basics.Status) *AlgoCount {
switch status {
case basics.Online:
return &at.Online
- case basics.Offline:
+ case basics.Offline, basics.Suspended:
return &at.Offline
case basics.NotParticipating:
return &at.NotParticipating
diff --git a/ledger/ledgercore/validatedBlock.go b/ledger/ledgercore/validatedBlock.go
index 84d09e2a9a..ced5265635 100644
--- a/ledger/ledgercore/validatedBlock.go
+++ b/ledger/ledgercore/validatedBlock.go
@@ -17,6 +17,7 @@
package ledgercore
import (
+ "github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/data/bookkeeping"
"github.com/algorand/go-algorand/data/committee"
)
@@ -39,11 +40,15 @@ func (vb ValidatedBlock) Delta() StateDelta {
return vb.delta
}
-// WithSeed returns a copy of the ValidatedBlock with a modified seed.
-func (vb ValidatedBlock) WithSeed(s committee.Seed) ValidatedBlock {
+// WithSeed returns a copy of the ValidatedBlock with a modified seed and associated proposer
+func (vb ValidatedBlock) WithSeed(s committee.Seed, proposer basics.Address) ValidatedBlock {
newblock := vb.blk
newblock.BlockHeader.Seed = s
+ if vb.blk.ConsensusProtocol().EnableMining {
+ newblock.BlockHeader.Proposer = proposer
+ }
+
return ValidatedBlock{
blk: newblock,
delta: vb.delta,
diff --git a/ledger/simple_test.go b/ledger/simple_test.go
index 1f4c612902..3d9f1ad0aa 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"
@@ -100,6 +101,9 @@ func fillDefaults(t testing.TB, ledger *Ledger, eval *eval.BlockEvaluator, txn *
if txn.FirstValid == 0 {
txn.FirstValid = eval.Round()
}
+ if txn.Type == protocol.KeyRegistrationTx && txn.VoteFirst == 0 {
+ txn.VoteFirst = eval.Round()
+ }
txn.FillDefaults(ledger.GenesisProto())
}
@@ -136,11 +140,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 +165,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/ledger/store/trackerdb/data.go b/ledger/store/trackerdb/data.go
index 264c055821..3823864ddc 100644
--- a/ledger/store/trackerdb/data.go
+++ b/ledger/store/trackerdb/data.go
@@ -48,6 +48,9 @@ type BaseAccountData struct {
TotalBoxes uint64 `codec:"m"`
TotalBoxBytes uint64 `codec:"n"`
+ LastProposed basics.Round `codec:"o"`
+ LastHeartbeat basics.Round `codec:"p"`
+
BaseVotingData
// UpdateRound is the round that modified this account data last. Since we want all the nodes to have the exact same
@@ -287,6 +290,9 @@ func (ba *BaseAccountData) SetCoreAccountData(ad *ledgercore.AccountData) {
ba.TotalBoxes = ad.TotalBoxes
ba.TotalBoxBytes = ad.TotalBoxBytes
+ ba.LastProposed = ad.LastProposed
+ ba.LastHeartbeat = ad.LastHeartbeat
+
ba.BaseVotingData.SetCoreAccountData(ad)
}
@@ -307,6 +313,9 @@ func (ba *BaseAccountData) SetAccountData(ad *basics.AccountData) {
ba.TotalBoxes = ad.TotalBoxes
ba.TotalBoxBytes = ad.TotalBoxBytes
+ ba.LastProposed = ad.LastProposed
+ ba.LastHeartbeat = ad.LastHeartbeat
+
ba.BaseVotingData.VoteID = ad.VoteID
ba.BaseVotingData.SelectionID = ad.SelectionID
ba.BaseVotingData.StateProofID = ad.StateProofID
@@ -342,6 +351,9 @@ func (ba *BaseAccountData) GetLedgerCoreAccountBaseData() ledgercore.AccountBase
TotalAssets: ba.TotalAssets,
TotalBoxes: ba.TotalBoxes,
TotalBoxBytes: ba.TotalBoxBytes,
+
+ LastProposed: ba.LastProposed,
+ LastHeartbeat: ba.LastHeartbeat,
}
}
@@ -379,6 +391,9 @@ func (ba *BaseAccountData) GetAccountData() basics.AccountData {
VoteFirstValid: ba.VoteFirstValid,
VoteLastValid: ba.VoteLastValid,
VoteKeyDilution: ba.VoteKeyDilution,
+
+ LastProposed: ba.LastProposed,
+ LastHeartbeat: ba.LastHeartbeat,
}
}
@@ -398,6 +413,8 @@ func (ba *BaseAccountData) IsEmpty() bool {
ba.TotalAppLocalStates == 0 &&
ba.TotalBoxes == 0 &&
ba.TotalBoxBytes == 0 &&
+ ba.LastProposed == 0 &&
+ ba.LastHeartbeat == 0 &&
ba.BaseVotingData.IsEmpty()
}
@@ -421,7 +438,7 @@ func (bo *BaseOnlineAccountData) IsVotingEmpty() bool {
return bo.BaseVotingData.IsEmpty()
}
-// IsEmpty return true if any of the fields are non-zero.
+// IsEmpty return true if all of the fields are zero.
func (bo *BaseOnlineAccountData) IsEmpty() bool {
return bo.IsVotingEmpty() &&
bo.MicroAlgos.Raw == 0 &&
diff --git a/ledger/store/trackerdb/data_test.go b/ledger/store/trackerdb/data_test.go
index fe253304fd..f6adeec983 100644
--- a/ledger/store/trackerdb/data_test.go
+++ b/ledger/store/trackerdb/data_test.go
@@ -1105,7 +1105,7 @@ func TestBaseAccountDataIsEmpty(t *testing.T) {
structureTesting := func(t *testing.T) {
encoding, err := json.Marshal(&empty)
zeros32 := "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
- expectedEncoding := `{"Status":0,"MicroAlgos":{"Raw":0},"RewardsBase":0,"RewardedMicroAlgos":{"Raw":0},"AuthAddr":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ","TotalAppSchemaNumUint":0,"TotalAppSchemaNumByteSlice":0,"TotalExtraAppPages":0,"TotalAssetParams":0,"TotalAssets":0,"TotalAppParams":0,"TotalAppLocalStates":0,"TotalBoxes":0,"TotalBoxBytes":0,"VoteID":[` + zeros32 + `],"SelectionID":[` + zeros32 + `],"VoteFirstValid":0,"VoteLastValid":0,"VoteKeyDilution":0,"StateProofID":[` + zeros32 + `,` + zeros32 + `],"UpdateRound":0}`
+ expectedEncoding := `{"Status":0,"MicroAlgos":{"Raw":0},"RewardsBase":0,"RewardedMicroAlgos":{"Raw":0},"AuthAddr":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ","TotalAppSchemaNumUint":0,"TotalAppSchemaNumByteSlice":0,"TotalExtraAppPages":0,"TotalAssetParams":0,"TotalAssets":0,"TotalAppParams":0,"TotalAppLocalStates":0,"TotalBoxes":0,"TotalBoxBytes":0,"LastProposed":0,"LastHeartbeat":0,"VoteID":[` + zeros32 + `],"SelectionID":[` + zeros32 + `],"VoteFirstValid":0,"VoteLastValid":0,"VoteKeyDilution":0,"StateProofID":[` + zeros32 + `,` + zeros32 + `],"UpdateRound":0}`
require.NoError(t, err)
require.Equal(t, expectedEncoding, string(encoding))
}
diff --git a/ledger/store/trackerdb/msgp_gen.go b/ledger/store/trackerdb/msgp_gen.go
index a13469c0ab..576f9ff0d6 100644
--- a/ledger/store/trackerdb/msgp_gen.go
+++ b/ledger/store/trackerdb/msgp_gen.go
@@ -100,8 +100,8 @@ import (
func (z *BaseAccountData) MarshalMsg(b []byte) (o []byte) {
o = msgp.Require(b, z.Msgsize())
// omitempty: check for empty values
- zb0001Len := uint32(21)
- var zb0001Mask uint32 /* 23 bits */
+ zb0001Len := uint32(23)
+ var zb0001Mask uint32 /* 25 bits */
if (*z).BaseVotingData.VoteID.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x1
@@ -182,10 +182,18 @@ func (z *BaseAccountData) MarshalMsg(b []byte) (o []byte) {
zb0001Len--
zb0001Mask |= 0x200000
}
- if (*z).UpdateRound == 0 {
+ if (*z).LastProposed.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x400000
}
+ if (*z).LastHeartbeat.MsgIsZero() {
+ zb0001Len--
+ zb0001Mask |= 0x800000
+ }
+ if (*z).UpdateRound == 0 {
+ zb0001Len--
+ zb0001Mask |= 0x1000000
+ }
// variable map header, size zb0001Len
o = msgp.AppendMapHeader(o, zb0001Len)
if zb0001Len != 0 {
@@ -290,6 +298,16 @@ func (z *BaseAccountData) MarshalMsg(b []byte) (o []byte) {
o = msgp.AppendUint64(o, (*z).TotalBoxBytes)
}
if (zb0001Mask & 0x400000) == 0 { // if not empty
+ // string "o"
+ o = append(o, 0xa1, 0x6f)
+ o = (*z).LastProposed.MarshalMsg(o)
+ }
+ if (zb0001Mask & 0x800000) == 0 { // if not empty
+ // string "p"
+ o = append(o, 0xa1, 0x70)
+ o = (*z).LastHeartbeat.MarshalMsg(o)
+ }
+ if (zb0001Mask & 0x1000000) == 0 { // if not empty
// string "z"
o = append(o, 0xa1, 0x7a)
o = msgp.AppendUint64(o, (*z).UpdateRound)
@@ -433,6 +451,22 @@ func (z *BaseAccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalSta
return
}
}
+ if zb0001 > 0 {
+ zb0001--
+ bts, err = (*z).LastProposed.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "LastProposed")
+ return
+ }
+ }
+ if zb0001 > 0 {
+ zb0001--
+ bts, err = (*z).LastHeartbeat.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "LastHeartbeat")
+ return
+ }
+ }
if zb0001 > 0 {
zb0001--
bts, err = (*z).BaseVotingData.VoteID.UnmarshalMsgWithState(bts, st)
@@ -596,6 +630,18 @@ func (z *BaseAccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalSta
err = msgp.WrapError(err, "TotalBoxBytes")
return
}
+ case "o":
+ bts, err = (*z).LastProposed.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "LastProposed")
+ return
+ }
+ case "p":
+ bts, err = (*z).LastHeartbeat.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "LastHeartbeat")
+ return
+ }
case "A":
bts, err = (*z).BaseVotingData.VoteID.UnmarshalMsgWithState(bts, st)
if err != nil {
@@ -661,18 +707,18 @@ func (_ *BaseAccountData) CanUnmarshalMsg(z interface{}) bool {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *BaseAccountData) Msgsize() (s int) {
- s = 3 + 2 + (*z).Status.Msgsize() + 2 + (*z).MicroAlgos.Msgsize() + 2 + msgp.Uint64Size + 2 + (*z).RewardedMicroAlgos.Msgsize() + 2 + (*z).AuthAddr.Msgsize() + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint32Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + (*z).BaseVotingData.VoteID.Msgsize() + 2 + (*z).BaseVotingData.SelectionID.Msgsize() + 2 + (*z).BaseVotingData.VoteFirstValid.Msgsize() + 2 + (*z).BaseVotingData.VoteLastValid.Msgsize() + 2 + msgp.Uint64Size + 2 + (*z).BaseVotingData.StateProofID.Msgsize() + 2 + msgp.Uint64Size
+ s = 3 + 2 + (*z).Status.Msgsize() + 2 + (*z).MicroAlgos.Msgsize() + 2 + msgp.Uint64Size + 2 + (*z).RewardedMicroAlgos.Msgsize() + 2 + (*z).AuthAddr.Msgsize() + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint32Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + (*z).LastProposed.Msgsize() + 2 + (*z).LastHeartbeat.Msgsize() + 2 + (*z).BaseVotingData.VoteID.Msgsize() + 2 + (*z).BaseVotingData.SelectionID.Msgsize() + 2 + (*z).BaseVotingData.VoteFirstValid.Msgsize() + 2 + (*z).BaseVotingData.VoteLastValid.Msgsize() + 2 + msgp.Uint64Size + 2 + (*z).BaseVotingData.StateProofID.Msgsize() + 2 + msgp.Uint64Size
return
}
// MsgIsZero returns whether this is a zero value
func (z *BaseAccountData) MsgIsZero() bool {
- return ((*z).Status.MsgIsZero()) && ((*z).MicroAlgos.MsgIsZero()) && ((*z).RewardsBase == 0) && ((*z).RewardedMicroAlgos.MsgIsZero()) && ((*z).AuthAddr.MsgIsZero()) && ((*z).TotalAppSchemaNumUint == 0) && ((*z).TotalAppSchemaNumByteSlice == 0) && ((*z).TotalExtraAppPages == 0) && ((*z).TotalAssetParams == 0) && ((*z).TotalAssets == 0) && ((*z).TotalAppParams == 0) && ((*z).TotalAppLocalStates == 0) && ((*z).TotalBoxes == 0) && ((*z).TotalBoxBytes == 0) && ((*z).BaseVotingData.VoteID.MsgIsZero()) && ((*z).BaseVotingData.SelectionID.MsgIsZero()) && ((*z).BaseVotingData.VoteFirstValid.MsgIsZero()) && ((*z).BaseVotingData.VoteLastValid.MsgIsZero()) && ((*z).BaseVotingData.VoteKeyDilution == 0) && ((*z).BaseVotingData.StateProofID.MsgIsZero()) && ((*z).UpdateRound == 0)
+ return ((*z).Status.MsgIsZero()) && ((*z).MicroAlgos.MsgIsZero()) && ((*z).RewardsBase == 0) && ((*z).RewardedMicroAlgos.MsgIsZero()) && ((*z).AuthAddr.MsgIsZero()) && ((*z).TotalAppSchemaNumUint == 0) && ((*z).TotalAppSchemaNumByteSlice == 0) && ((*z).TotalExtraAppPages == 0) && ((*z).TotalAssetParams == 0) && ((*z).TotalAssets == 0) && ((*z).TotalAppParams == 0) && ((*z).TotalAppLocalStates == 0) && ((*z).TotalBoxes == 0) && ((*z).TotalBoxBytes == 0) && ((*z).LastProposed.MsgIsZero()) && ((*z).LastHeartbeat.MsgIsZero()) && ((*z).BaseVotingData.VoteID.MsgIsZero()) && ((*z).BaseVotingData.SelectionID.MsgIsZero()) && ((*z).BaseVotingData.VoteFirstValid.MsgIsZero()) && ((*z).BaseVotingData.VoteLastValid.MsgIsZero()) && ((*z).BaseVotingData.VoteKeyDilution == 0) && ((*z).BaseVotingData.StateProofID.MsgIsZero()) && ((*z).UpdateRound == 0)
}
// MaxSize returns a maximum valid message size for this message type
func BaseAccountDataMaxSize() (s int) {
- s = 3 + 2 + basics.StatusMaxSize() + 2 + basics.MicroAlgosMaxSize() + 2 + msgp.Uint64Size + 2 + basics.MicroAlgosMaxSize() + 2 + basics.AddressMaxSize() + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint32Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + crypto.OneTimeSignatureVerifierMaxSize() + 2 + crypto.VRFVerifierMaxSize() + 2 + basics.RoundMaxSize() + 2 + basics.RoundMaxSize() + 2 + msgp.Uint64Size + 2 + merklesignature.CommitmentMaxSize() + 2 + msgp.Uint64Size
+ s = 3 + 2 + basics.StatusMaxSize() + 2 + basics.MicroAlgosMaxSize() + 2 + msgp.Uint64Size + 2 + basics.MicroAlgosMaxSize() + 2 + basics.AddressMaxSize() + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint32Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + basics.RoundMaxSize() + 2 + basics.RoundMaxSize() + 2 + crypto.OneTimeSignatureVerifierMaxSize() + 2 + crypto.VRFVerifierMaxSize() + 2 + basics.RoundMaxSize() + 2 + basics.RoundMaxSize() + 2 + msgp.Uint64Size + 2 + merklesignature.CommitmentMaxSize() + 2 + msgp.Uint64Size
return
}
diff --git a/ledger/store/trackerdb/sqlitedriver/schema.go b/ledger/store/trackerdb/sqlitedriver/schema.go
index ea6f577868..66e4d9f220 100644
--- a/ledger/store/trackerdb/sqlitedriver/schema.go
+++ b/ledger/store/trackerdb/sqlitedriver/schema.go
@@ -734,8 +734,9 @@ func performOnlineAccountsTableMigration(ctx context.Context, e db.Executable, p
}
}
- // remove stateproofID field for offline accounts
- if ba.Status != basics.Online && !ba.StateProofID.IsEmpty() {
+ // We had a bug that didn't remove StateProofIDs when going offline.
+ // Tidy up such accounts.
+ if ba.VoteID.IsEmpty() && !ba.StateProofID.IsEmpty() {
// store old data for account hash update
state := acctState{old: ba, oldEnc: encodedAcctData}
ba.StateProofID = merklesignature.Commitment{}
diff --git a/ledger/store/trackerdb/sqlitedriver/schema_test.go b/ledger/store/trackerdb/sqlitedriver/schema_test.go
index 581082447b..df5a9b02bd 100644
--- a/ledger/store/trackerdb/sqlitedriver/schema_test.go
+++ b/ledger/store/trackerdb/sqlitedriver/schema_test.go
@@ -176,7 +176,7 @@ func TestRemoveOfflineStateProofID(t *testing.T) {
accts[addr] = acct
expectedAcct := acct
- if acct.Status != basics.Online {
+ if acct.Status != basics.Online && acct.Status != basics.Suspended {
expectedAcct.StateProofID = merklesignature.Commitment{}
}
expectedAccts[addr] = expectedAcct
@@ -211,7 +211,7 @@ func TestRemoveOfflineStateProofID(t *testing.T) {
defer dbs.Close()
defer tx.Rollback()
- // make second copy of DB to prepare exepected/fixed merkle trie
+ // make second copy of DB to prepare expected/fixed merkle trie
expectedDBs, expectedTx := buildDB(expectedAccts)
defer expectedDBs.Close()
defer expectedTx.Rollback()
@@ -237,7 +237,7 @@ func TestRemoveOfflineStateProofID(t *testing.T) {
var ba trackerdb.BaseAccountData
err = protocol.Decode(encodedAcctData, &ba)
require.NoError(t, err)
- if expected && ba.Status != basics.Online {
+ if expected && (ba.Status != basics.Online && ba.Status != basics.Suspended) {
require.Equal(t, merklesignature.Commitment{}, ba.StateProofID)
}
addHash := trackerdb.AccountHashBuilderV6(addr, &ba, encodedAcctData)
@@ -287,7 +287,7 @@ func TestRemoveOfflineStateProofID(t *testing.T) {
var ba trackerdb.BaseAccountData
err = protocol.Decode(encodedAcctData, &ba)
require.NoError(t, err)
- if ba.Status != basics.Online {
+ if ba.Status != basics.Online && ba.Status != basics.Suspended {
require.True(t, ba.StateProofID.IsEmpty())
}
}
diff --git a/ledger/testing/randomAccounts.go b/ledger/testing/randomAccounts.go
index fd4f3b4158..e9ef1b2da4 100644
--- a/ledger/testing/randomAccounts.go
+++ b/ledger/testing/randomAccounts.go
@@ -58,41 +58,60 @@ func RandomNote() []byte {
return note[:]
}
-// RandomAccountData generates a random AccountData
+// RandomAccountData generates a random AccountData with no associated resources.
func RandomAccountData(rewardsBase uint64) basics.AccountData {
var data basics.AccountData
// Avoid overflowing totals
data.MicroAlgos.Raw = crypto.RandUint64() % (1 << 32)
+ // 0 is an invalid round, but would be right if never proposed
+ data.LastProposed = basics.Round(crypto.RandUint64() % 10)
+ // 0 is an invalid round, but would be right if never needed a heartbeat
+ data.LastHeartbeat = basics.Round(crypto.RandUint64() % 10)
- switch crypto.RandUint64() % 3 {
+ switch crypto.RandUint64() % 4 {
case 0:
data.Status = basics.Online
- data.VoteLastValid = 10000
case 1:
data.Status = basics.Offline
- data.VoteLastValid = 0
- default:
+ case 2:
data.Status = basics.NotParticipating
+ case 3:
+ data.Status = basics.Suspended
+ }
+
+ switch data.Status {
+ case basics.Online, basics.Suspended:
+ crypto.RandBytes(data.VoteID[:])
+ crypto.RandBytes(data.SelectionID[:])
+ crypto.RandBytes(data.StateProofID[:])
+ data.VoteFirstValid = basics.Round(crypto.RandUint64())
+ data.VoteLastValid = basics.Round(crypto.RandUint64() % uint64(math.MaxInt64)) // int64 is the max sqlite can store
+ data.VoteKeyDilution = crypto.RandUint64()
+ case basics.Offline, basics.NotParticipating:
+ data.VoteID = crypto.OneTimeSignatureVerifier{}
+ data.SelectionID = crypto.VRFVerifier{}
+ data.StateProofID = merklesignature.Commitment{}
+ data.VoteFirstValid = 0
+ data.VoteLastValid = 0
+ data.VoteKeyDilution = 0
}
- data.VoteFirstValid = 0
data.RewardsBase = rewardsBase
return data
}
// RandomOnlineAccountData is similar to RandomAccountData but always creates online account
func RandomOnlineAccountData(rewardsBase uint64) basics.AccountData {
- var data basics.AccountData
- data.MicroAlgos.Raw = crypto.RandUint64() % (1 << 32)
- data.Status = basics.Online
- data.VoteLastValid = 1000
- data.VoteFirstValid = 0
- data.RewardsBase = rewardsBase
- return data
+ for {
+ data := RandomAccountData(rewardsBase)
+ if data.Status == basics.Online {
+ return data
+ }
+ }
}
-// RandomAssetParams creates a randim basics.AssetParams
+// RandomAssetParams creates a random basics.AssetParams
func RandomAssetParams() basics.AssetParams {
ap := basics.AssetParams{
Total: crypto.RandUint64(),
@@ -214,6 +233,7 @@ func RandomAppParams() basics.AppParams {
if len(ap.GlobalState) == 0 {
ap.GlobalState = nil
}
+ ap.ExtraProgramPages = uint32(crypto.RandUint64() % 4)
return ap
}
@@ -268,21 +288,6 @@ func RandomAppLocalState() basics.AppLocalState {
func RandomFullAccountData(rewardsLevel uint64, lastCreatableID *basics.CreatableIndex, assets map[basics.AssetIndex]struct{}, apps map[basics.AppIndex]struct{}) basics.AccountData {
data := RandomAccountData(rewardsLevel)
- if data.Status == basics.Online {
- crypto.RandBytes(data.VoteID[:])
- crypto.RandBytes(data.SelectionID[:])
- crypto.RandBytes(data.StateProofID[:])
- data.VoteFirstValid = basics.Round(crypto.RandUint64())
- data.VoteLastValid = basics.Round(crypto.RandUint64() % uint64(math.MaxInt64)) // int64 is the max sqlite can store
- data.VoteKeyDilution = crypto.RandUint64()
- } else {
- data.VoteID = crypto.OneTimeSignatureVerifier{}
- data.SelectionID = crypto.VRFVerifier{}
- data.StateProofID = merklesignature.Commitment{}
- data.VoteFirstValid = 0
- data.VoteLastValid = 0
- data.VoteKeyDilution = 0
- }
if (crypto.RandUint64() % 2) == 1 {
// if account has created assets, have these defined.
createdAssetsCount := crypto.RandUint64()%20 + 1
diff --git a/ledger/testing/testGenesis.go b/ledger/testing/testGenesis.go
index 98a41d06d5..9911af343a 100644
--- a/ledger/testing/testGenesis.go
+++ b/ledger/testing/testGenesis.go
@@ -25,17 +25,18 @@ import (
"github.com/algorand/go-algorand/protocol"
)
-// testGenesisCfg provides a configuration object for NewTestGenesis.
-type testGenesisCfg struct {
+// GenesisCfg provides a configuration object for NewTestGenesis.
+type GenesisCfg struct {
rewardsPoolAmount basics.MicroAlgos
+ OnlineCount int
}
// TestGenesisOption provides functional options for testGenesisCfg.
-type TestGenesisOption func(*testGenesisCfg)
+type TestGenesisOption func(*GenesisCfg)
// TestGenesisRewardsPoolSize configures the rewards pool size in the genesis block.
func TestGenesisRewardsPoolSize(amount basics.MicroAlgos) TestGenesisOption {
- return func(cfg *testGenesisCfg) { cfg.rewardsPoolAmount = amount }
+ return func(cfg *GenesisCfg) { cfg.rewardsPoolAmount = amount }
}
// NewTestGenesis creates a bunch of accounts, splits up 10B algos
@@ -43,7 +44,7 @@ func TestGenesisRewardsPoolSize(amount basics.MicroAlgos) TestGenesisOption {
// addresses and secrets it creates to enable tests. For special
// scenarios, manipulate these return values before using newTestLedger.
func NewTestGenesis(opts ...TestGenesisOption) (bookkeeping.GenesisBalances, []basics.Address, []*crypto.SignatureSecrets) {
- var cfg testGenesisCfg
+ var cfg GenesisCfg
for _, opt := range opts {
opt(&cfg)
}
@@ -75,6 +76,15 @@ func NewTestGenesis(opts ...TestGenesisOption) (bookkeeping.GenesisBalances, []b
adata := basics.AccountData{
MicroAlgos: basics.MicroAlgos{Raw: amount},
+ Status: basics.Offline,
+ }
+ if i < cfg.OnlineCount {
+ adata.Status = basics.Online
+ adata.VoteFirstValid = 0
+ adata.VoteLastValid = 1_000_000
+ crypto.RandBytes(adata.VoteID[:])
+ crypto.RandBytes(adata.SelectionID[:])
+ crypto.RandBytes(adata.StateProofID[:])
}
accts[addrs[i]] = adata
}
diff --git a/node/node.go b/node/node.go
index 4c18ad1d51..63815f08eb 100644
--- a/node/node.go
+++ b/node/node.go
@@ -1271,8 +1271,8 @@ type validatedBlock struct {
}
// WithSeed satisfies the agreement.ValidatedBlock interface.
-func (vb validatedBlock) WithSeed(s committee.Seed) agreement.ValidatedBlock {
- lvb := vb.vb.WithSeed(s)
+func (vb validatedBlock) WithSeed(s committee.Seed, proposer basics.Address) agreement.ValidatedBlock {
+ lvb := vb.vb.WithSeed(s, proposer)
return validatedBlock{vb: &lvb}
}
diff --git a/protocol/tags.go b/protocol/tags.go
index a9eb2a6bbc..c6d694c93d 100644
--- a/protocol/tags.go
+++ b/protocol/tags.go
@@ -73,7 +73,7 @@ const PingReplyTagMaxSize = 8
// ProposalPayloadTagMaxSize is the maximum size of a ProposalPayloadTag message
// This value is dominated by the MaxTxnBytesPerBlock
-const ProposalPayloadTagMaxSize = 5247980
+const ProposalPayloadTagMaxSize = 5250289
// StateProofSigTagMaxSize is the maximum size of a StateProofSigTag message
const StateProofSigTagMaxSize = 6378
diff --git a/test/scripts/e2e_client_runner.py b/test/scripts/e2e_client_runner.py
index 7b425ef925..15a877e043 100755
--- a/test/scripts/e2e_client_runner.py
+++ b/test/scripts/e2e_client_runner.py
@@ -114,7 +114,7 @@ def _script_thread_inner(runset, scriptname, timeout):
params = algod.suggested_params()
round = params.first
max_init_wait_rounds = 5
- txn = algosdk.transaction.PaymentTxn(sender=maxpubaddr, fee=params.min_fee, first=round, last=round+max_init_wait_rounds, gh=params.gh, receiver=addr, amt=1000000000000, flat_fee=True)
+ txn = algosdk.transaction.PaymentTxn(sender=maxpubaddr, fee=params.min_fee, first=round, last=round+max_init_wait_rounds, gh=params.gh, receiver=addr, amt=1_000_000_000_000, flat_fee=True)
stxn = kmd.sign_transaction(pubw, '', txn)
txid = algod.send_transaction(stxn)
ptxinfo = None
diff --git a/test/scripts/e2e_subs/absentee.py b/test/scripts/e2e_subs/absentee.py
new file mode 100755
index 0000000000..f889a4ff35
--- /dev/null
+++ b/test/scripts/e2e_subs/absentee.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+
+import base64
+import os
+import sys
+from goal import Goal
+import algosdk.encoding as enc
+
+from datetime import datetime
+
+stamp = datetime.now().strftime("%Y%m%d_%H%M%S")
+print(f"{os.path.basename(sys.argv[0])} start {stamp}")
+
+goal = Goal(sys.argv[1], autosend=True)
+
+joe = goal.new_account()
+
+txinfo, err = goal.pay(goal.account, joe, amt=500_000)
+assert not err, err
+
+# Joe is a brand new account, it has neither proposed nor heartbeat
+joe_info = goal.algod.account_info(joe)
+assert "last-proposed" not in joe_info, joe_info
+assert "last-heartbeat" not in joe_info, joe_info
+
+# Find info on the proposer of the pay block
+pblock = goal.algod.block_info(txinfo['confirmed-round'])['block']
+assert pblock["prp"] != "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ"
+prp_info = goal.algod.account_info(pblock["prp"])
+assert "last-proposed" in prp_info, prp_info # they just did!
+assert prp_info["last-proposed"] > 0
+assert "last-heartbeat" not in prp_info, prp_info # was a genesis account
+
+stamp = datetime.now().strftime("%Y%m%d_%H%M%S")
+print(f"{os.path.basename(sys.argv[0])} OK {stamp}")
diff --git a/test/scripts/e2e_subs/goal/goal.py b/test/scripts/e2e_subs/goal/goal.py
index d36241fd78..605f732eb7 100755
--- a/test/scripts/e2e_subs/goal/goal.py
+++ b/test/scripts/e2e_subs/goal/goal.py
@@ -229,19 +229,19 @@ def finish(self, tx, send):
def keyreg(self, sender, votekey=None, selkey=None, votefst=None,
votelst=None, votekd=None,
send=None, **kwargs):
- params = self.algod.suggested_params()
+ params = self.params(kwargs.pop("lifetime", 1000))
tx = txn.KeyregTxn(sender, params,
votekey, selkey, votefst, votelst, votekd,
**kwargs)
return self.finish(tx, send)
def pay(self, sender, receiver, amt: int, send=None, **kwargs):
- params = self.algod.suggested_params()
+ params = self.params(kwargs.pop("lifetime", 1000))
tx = txn.PaymentTxn(sender, params, receiver, amt, **kwargs)
return self.finish(tx, send)
def acfg(self, sender, send=None, **kwargs):
- params = self.algod.suggested_params()
+ params = self.params(kwargs.pop("lifetime", 1000))
tx = txn.AssetConfigTxn(
sender, params, **kwargs, strict_empty_address_check=False
)
@@ -252,7 +252,7 @@ def asset_create(self, sender, **kwargs):
return self.acfg(sender, **kwargs)
def axfer(self, sender, receiver, amt: int, index: int, send=None, **kwargs):
- params = self.algod.suggested_params()
+ params = self.params(kwargs.pop("lifetime", 1000))
tx = txn.AssetTransferTxn(
sender, params, receiver, amt, index, **kwargs
)
@@ -263,7 +263,7 @@ def asset_optin(self, sender, index: int, **kwargs):
return self.axfer(sender, sender, 0, index, **kwargs)
def afrz(self, sender, index: int, target, frozen, send=None, **kwargs):
- params = self.algod.suggested_params()
+ params = self.params(kwargs.pop("lifetime", 1000))
tx = txn.AssetFreezeTxn(sender, params, index, target, frozen, **kwargs)
return self.finish(tx, send)
@@ -274,9 +274,15 @@ def coerce_schema(self, values):
return values
return txn.StateSchema(num_uints=values[0], num_byte_slices=values[1])
+
+ def params(self, lifetime):
+ params = self.algod.suggested_params()
+ params.last = params.first + lifetime
+ return params
+
def appl(self, sender, index: int, on_complete=txn.OnComplete.NoOpOC,
send=None, **kwargs):
- params = self.algod.suggested_params()
+ params = self.params(kwargs.pop("lifetime", 1000))
local_schema = self.coerce_schema(kwargs.pop("local_schema", None))
global_schema = self.coerce_schema(kwargs.pop("global_schema", None))
tx = txn.ApplicationCallTxn(
diff --git a/test/scripts/e2e_subs/mining.py b/test/scripts/e2e_subs/mining.py
new file mode 100755
index 0000000000..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}")