diff --git a/agreement/abstractions.go b/agreement/abstractions.go
index a22a3a0526..ca640260c7 100644
--- a/agreement/abstractions.go
+++ b/agreement/abstractions.go
@@ -59,7 +59,7 @@ type ValidatedBlock interface {
//
// Calls to Seed() or to Digest() on the copy's Block must
// reflect the value of the new seed.
- WithSeed(committee.Seed) ValidatedBlock
+ WithSeed(committee.Seed, basics.Address) ValidatedBlock
// Block returns the underlying block that has been validated.
Block() bookkeeping.Block
diff --git a/agreement/agreementtest/simulate_test.go b/agreement/agreementtest/simulate_test.go
index a0afca4d46..fa1e4c1c5c 100644
--- a/agreement/agreementtest/simulate_test.go
+++ b/agreement/agreementtest/simulate_test.go
@@ -79,8 +79,9 @@ func (b testValidatedBlock) Block() bookkeeping.Block {
return b.Inside
}
-func (b testValidatedBlock) WithSeed(s committee.Seed) agreement.ValidatedBlock {
+func (b testValidatedBlock) WithSeed(s committee.Seed, proposer basics.Address) agreement.ValidatedBlock {
b.Inside.BlockHeader.Seed = s
+ b.Inside.BlockHeader.Proposer = proposer
return b
}
diff --git a/agreement/common_test.go b/agreement/common_test.go
index 9ec85618e8..11d6f5f90e 100644
--- a/agreement/common_test.go
+++ b/agreement/common_test.go
@@ -165,8 +165,9 @@ func (b testValidatedBlock) Block() bookkeeping.Block {
return b.Inside
}
-func (b testValidatedBlock) WithSeed(s committee.Seed) ValidatedBlock {
+func (b testValidatedBlock) WithSeed(s committee.Seed, proposer basics.Address) ValidatedBlock {
b.Inside.BlockHeader.Seed = s
+ b.Inside.BlockHeader.Proposer = proposer
return b
}
diff --git a/agreement/fuzzer/ledger_test.go b/agreement/fuzzer/ledger_test.go
index 00ba132294..91d261c6e7 100644
--- a/agreement/fuzzer/ledger_test.go
+++ b/agreement/fuzzer/ledger_test.go
@@ -93,8 +93,9 @@ func (b testValidatedBlock) Block() bookkeeping.Block {
return b.Inside
}
-func (b testValidatedBlock) WithSeed(s committee.Seed) agreement.ValidatedBlock {
+func (b testValidatedBlock) WithSeed(s committee.Seed, proposer basics.Address) agreement.ValidatedBlock {
b.Inside.BlockHeader.Seed = s
+ b.Inside.BlockHeader.Proposer = proposer
return b
}
diff --git a/agreement/msgp_gen.go b/agreement/msgp_gen.go
index 16679ce797..91f877042f 100644
--- a/agreement/msgp_gen.go
+++ b/agreement/msgp_gen.go
@@ -4493,123 +4493,131 @@ func PlayerMaxSize() (s int) {
func (z *proposal) MarshalMsg(b []byte) (o []byte) {
o = msgp.Require(b, z.Msgsize())
// omitempty: check for empty values
- zb0004Len := uint32(29)
- var zb0004Mask uint64 /* 38 bits */
+ zb0004Len := uint32(31)
+ var zb0004Mask uint64 /* 40 bits */
if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0 {
zb0004Len--
zb0004Mask |= 0x40
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero() {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x80
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0 {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x100
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "" {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0 {
zb0004Len--
zb0004Mask |= 0x200
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero() {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "" {
zb0004Len--
zb0004Mask |= 0x400
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x800
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero() {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x1000
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x2000
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0 {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x4000
}
- if (*z).unauthenticatedProposal.OriginalPeriod == 0 {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0 {
zb0004Len--
zb0004Mask |= 0x8000
}
- if (*z).unauthenticatedProposal.OriginalProposer.MsgIsZero() {
+ if (*z).unauthenticatedProposal.OriginalPeriod == 0 {
zb0004Len--
zb0004Mask |= 0x10000
}
- if len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 {
+ if (*z).unauthenticatedProposal.OriginalProposer.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x20000
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero() {
+ if len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 {
zb0004Len--
zb0004Mask |= 0x40000
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x80000
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0 {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x100000
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero() {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MsgIsZero() {
+ zb0004Len--
+ zb0004Mask |= 0x200000
+ }
+ if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0 {
zb0004Len--
zb0004Mask |= 0x400000
}
+ if (*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero() {
+ zb0004Len--
+ zb0004Mask |= 0x1000000
+ }
if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x800000
+ zb0004Mask |= 0x2000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x1000000
+ zb0004Mask |= 0x4000000
}
if (*z).unauthenticatedProposal.SeedProof.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x2000000
+ zb0004Mask |= 0x8000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x4000000
+ zb0004Mask |= 0x10000000
}
if len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0 {
zb0004Len--
- zb0004Mask |= 0x8000000
+ zb0004Mask |= 0x20000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0 {
zb0004Len--
- zb0004Mask |= 0x10000000
+ zb0004Mask |= 0x40000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0 {
zb0004Len--
- zb0004Mask |= 0x20000000
+ zb0004Mask |= 0x80000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x40000000
+ zb0004Mask |= 0x100000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x80000000
+ zb0004Mask |= 0x200000000
}
if (*z).unauthenticatedProposal.Block.Payset.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x100000000
+ zb0004Mask |= 0x400000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x200000000
+ zb0004Mask |= 0x800000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x400000000
+ zb0004Mask |= 0x1000000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false {
zb0004Len--
- zb0004Mask |= 0x800000000
+ zb0004Mask |= 0x2000000000
}
// variable map header, size zb0004Len
o = msgp.AppendMapHeader(o, zb0004Len)
@@ -4620,56 +4628,61 @@ func (z *proposal) MarshalMsg(b []byte) (o []byte) {
o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel)
}
if (zb0004Mask & 0x80) == 0 { // if not empty
+ // string "fc"
+ o = append(o, 0xa2, 0x66, 0x63)
+ o = (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MarshalMsg(o)
+ }
+ if (zb0004Mask & 0x100) == 0 { // if not empty
// string "fees"
o = append(o, 0xa4, 0x66, 0x65, 0x65, 0x73)
o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MarshalMsg(o)
}
- if (zb0004Mask & 0x100) == 0 { // if not empty
+ if (zb0004Mask & 0x200) == 0 { // if not empty
// string "frac"
o = append(o, 0xa4, 0x66, 0x72, 0x61, 0x63)
o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue)
}
- if (zb0004Mask & 0x200) == 0 { // if not empty
+ if (zb0004Mask & 0x400) == 0 { // if not empty
// string "gen"
o = append(o, 0xa3, 0x67, 0x65, 0x6e)
o = msgp.AppendString(o, (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID)
}
- if (zb0004Mask & 0x400) == 0 { // if not empty
+ if (zb0004Mask & 0x800) == 0 { // if not empty
// string "gh"
o = append(o, 0xa2, 0x67, 0x68)
o = (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MarshalMsg(o)
}
- if (zb0004Mask & 0x800) == 0 { // if not empty
+ if (zb0004Mask & 0x1000) == 0 { // if not empty
// string "nextbefore"
o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MarshalMsg(o)
}
- if (zb0004Mask & 0x1000) == 0 { // if not empty
+ if (zb0004Mask & 0x2000) == 0 { // if not empty
// string "nextproto"
o = append(o, 0xa9, 0x6e, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MarshalMsg(o)
}
- if (zb0004Mask & 0x2000) == 0 { // if not empty
+ if (zb0004Mask & 0x4000) == 0 { // if not empty
// string "nextswitch"
o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MarshalMsg(o)
}
- if (zb0004Mask & 0x4000) == 0 { // if not empty
+ if (zb0004Mask & 0x8000) == 0 { // if not empty
// string "nextyes"
o = append(o, 0xa7, 0x6e, 0x65, 0x78, 0x74, 0x79, 0x65, 0x73)
o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals)
}
- if (zb0004Mask & 0x8000) == 0 { // if not empty
+ if (zb0004Mask & 0x10000) == 0 { // if not empty
// string "oper"
o = append(o, 0xa4, 0x6f, 0x70, 0x65, 0x72)
o = msgp.AppendUint64(o, uint64((*z).unauthenticatedProposal.OriginalPeriod))
}
- if (zb0004Mask & 0x10000) == 0 { // if not empty
+ if (zb0004Mask & 0x20000) == 0 { // if not empty
// string "oprop"
o = append(o, 0xa5, 0x6f, 0x70, 0x72, 0x6f, 0x70)
o = (*z).unauthenticatedProposal.OriginalProposer.MarshalMsg(o)
}
- if (zb0004Mask & 0x20000) == 0 { // if not empty
+ if (zb0004Mask & 0x40000) == 0 { // if not empty
// string "partupdrmv"
o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76)
if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts == nil {
@@ -4681,47 +4694,52 @@ func (z *proposal) MarshalMsg(b []byte) (o []byte) {
o = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].MarshalMsg(o)
}
}
- if (zb0004Mask & 0x40000) == 0 { // if not empty
+ if (zb0004Mask & 0x80000) == 0 { // if not empty
// string "prev"
o = append(o, 0xa4, 0x70, 0x72, 0x65, 0x76)
o = (*z).unauthenticatedProposal.Block.BlockHeader.Branch.MarshalMsg(o)
}
- if (zb0004Mask & 0x80000) == 0 { // if not empty
+ if (zb0004Mask & 0x100000) == 0 { // if not empty
// string "proto"
o = append(o, 0xa5, 0x70, 0x72, 0x6f, 0x74, 0x6f)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MarshalMsg(o)
}
- if (zb0004Mask & 0x100000) == 0 { // if not empty
+ if (zb0004Mask & 0x200000) == 0 { // if not empty
+ // string "prp"
+ o = append(o, 0xa3, 0x70, 0x72, 0x70)
+ o = (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MarshalMsg(o)
+ }
+ if (zb0004Mask & 0x400000) == 0 { // if not empty
// string "rate"
o = append(o, 0xa4, 0x72, 0x61, 0x74, 0x65)
o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate)
}
- if (zb0004Mask & 0x400000) == 0 { // if not empty
+ if (zb0004Mask & 0x1000000) == 0 { // if not empty
// string "rnd"
o = append(o, 0xa3, 0x72, 0x6e, 0x64)
o = (*z).unauthenticatedProposal.Block.BlockHeader.Round.MarshalMsg(o)
}
- if (zb0004Mask & 0x800000) == 0 { // if not empty
+ if (zb0004Mask & 0x2000000) == 0 { // if not empty
// string "rwcalr"
o = append(o, 0xa6, 0x72, 0x77, 0x63, 0x61, 0x6c, 0x72)
o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MarshalMsg(o)
}
- if (zb0004Mask & 0x1000000) == 0 { // if not empty
+ if (zb0004Mask & 0x4000000) == 0 { // if not empty
// string "rwd"
o = append(o, 0xa3, 0x72, 0x77, 0x64)
o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MarshalMsg(o)
}
- if (zb0004Mask & 0x2000000) == 0 { // if not empty
+ if (zb0004Mask & 0x8000000) == 0 { // if not empty
// string "sdpf"
o = append(o, 0xa4, 0x73, 0x64, 0x70, 0x66)
o = (*z).unauthenticatedProposal.SeedProof.MarshalMsg(o)
}
- if (zb0004Mask & 0x4000000) == 0 { // if not empty
+ if (zb0004Mask & 0x10000000) == 0 { // if not empty
// string "seed"
o = append(o, 0xa4, 0x73, 0x65, 0x65, 0x64)
o = (*z).unauthenticatedProposal.Block.BlockHeader.Seed.MarshalMsg(o)
}
- if (zb0004Mask & 0x8000000) == 0 { // if not empty
+ if (zb0004Mask & 0x20000000) == 0 { // if not empty
// string "spt"
o = append(o, 0xa3, 0x73, 0x70, 0x74)
if (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking == nil {
@@ -4741,42 +4759,42 @@ func (z *proposal) MarshalMsg(b []byte) (o []byte) {
o = zb0002.MarshalMsg(o)
}
}
- if (zb0004Mask & 0x10000000) == 0 { // if not empty
+ if (zb0004Mask & 0x40000000) == 0 { // if not empty
// string "tc"
o = append(o, 0xa2, 0x74, 0x63)
o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter)
}
- if (zb0004Mask & 0x20000000) == 0 { // if not empty
+ if (zb0004Mask & 0x80000000) == 0 { // if not empty
// string "ts"
o = append(o, 0xa2, 0x74, 0x73)
o = msgp.AppendInt64(o, (*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp)
}
- if (zb0004Mask & 0x40000000) == 0 { // if not empty
+ if (zb0004Mask & 0x100000000) == 0 { // if not empty
// string "txn"
o = append(o, 0xa3, 0x74, 0x78, 0x6e)
o = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MarshalMsg(o)
}
- if (zb0004Mask & 0x80000000) == 0 { // if not empty
+ if (zb0004Mask & 0x200000000) == 0 { // if not empty
// string "txn256"
o = append(o, 0xa6, 0x74, 0x78, 0x6e, 0x32, 0x35, 0x36)
o = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MarshalMsg(o)
}
- if (zb0004Mask & 0x100000000) == 0 { // if not empty
+ if (zb0004Mask & 0x400000000) == 0 { // if not empty
// string "txns"
o = append(o, 0xa4, 0x74, 0x78, 0x6e, 0x73)
o = (*z).unauthenticatedProposal.Block.Payset.MarshalMsg(o)
}
- if (zb0004Mask & 0x200000000) == 0 { // if not empty
+ if (zb0004Mask & 0x800000000) == 0 { // if not empty
// string "upgradedelay"
o = append(o, 0xac, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x65, 0x6c, 0x61, 0x79)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MarshalMsg(o)
}
- if (zb0004Mask & 0x400000000) == 0 { // if not empty
+ if (zb0004Mask & 0x1000000000) == 0 { // if not empty
// string "upgradeprop"
o = append(o, 0xab, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x70, 0x72, 0x6f, 0x70)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MarshalMsg(o)
}
- if (zb0004Mask & 0x800000000) == 0 { // if not empty
+ if (zb0004Mask & 0x2000000000) == 0 { // if not empty
// string "upgradeyes"
o = append(o, 0xaa, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x65, 0x73)
o = msgp.AppendBool(o, (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove)
@@ -4882,6 +4900,22 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o
return
}
}
+ if zb0004 > 0 {
+ zb0004--
+ bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "Proposer")
+ return
+ }
+ }
+ if zb0004 > 0 {
+ zb0004--
+ bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "FeesCollected")
+ return
+ }
+ }
if zb0004 > 0 {
zb0004--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st)
@@ -5184,6 +5218,18 @@ func (z *proposal) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o
err = msgp.WrapError(err, "GenesisHash")
return
}
+ case "prp":
+ bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "Proposer")
+ return
+ }
+ case "fc":
+ bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "FeesCollected")
+ return
+ }
case "fees":
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st)
if err != nil {
@@ -5386,7 +5432,7 @@ func (_ *proposal) CanUnmarshalMsg(z interface{}) bool {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *proposal) Msgsize() (s int) {
- s = 3 + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.Round.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.Branch.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.Seed.Msgsize() + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.Msgsize() + 7 + (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.Msgsize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + len((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID) + 3 + (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.Msgsize() + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.Msgsize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.Msgsize() + 6 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.Msgsize() + 10 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.Msgsize() + 8 + msgp.Uint64Size + 11 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.Msgsize() + 11 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.Msgsize() + 12 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.Msgsize() + 13 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.Msgsize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + msgp.MapHeaderSize
+ s = 3 + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.Round.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.Branch.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.Seed.Msgsize() + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.Msgsize() + 7 + (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.Msgsize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + len((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID) + 3 + (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.Msgsize() + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.Msgsize() + 3 + (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.Msgsize() + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.Msgsize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.Msgsize() + 6 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.Msgsize() + 10 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.Msgsize() + 8 + msgp.Uint64Size + 11 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.Msgsize() + 11 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.Msgsize() + 12 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.Msgsize() + 13 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.Msgsize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + msgp.MapHeaderSize
if (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking != nil {
for zb0001, zb0002 := range (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking {
_ = zb0001
@@ -5404,12 +5450,12 @@ func (z *proposal) Msgsize() (s int) {
// MsgIsZero returns whether this is a zero value
func (z *proposal) MsgIsZero() bool {
- return ((*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "") && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).unauthenticatedProposal.Block.Payset.MsgIsZero()) && ((*z).unauthenticatedProposal.SeedProof.MsgIsZero()) && ((*z).unauthenticatedProposal.OriginalPeriod == 0) && ((*z).unauthenticatedProposal.OriginalProposer.MsgIsZero())
+ return ((*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "") && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).unauthenticatedProposal.Block.Payset.MsgIsZero()) && ((*z).unauthenticatedProposal.SeedProof.MsgIsZero()) && ((*z).unauthenticatedProposal.OriginalPeriod == 0) && ((*z).unauthenticatedProposal.OriginalProposer.MsgIsZero())
}
// MaxSize returns a maximum valid message size for this message type
func ProposalMaxSize() (s int) {
- s = 3 + 4 + basics.RoundMaxSize() + 5 + bookkeeping.BlockHashMaxSize() + 5 + committee.SeedMaxSize() + 4 + crypto.DigestMaxSize() + 7 + crypto.DigestMaxSize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + config.MaxGenesisIDLen + 3 + crypto.DigestMaxSize() + 5 + basics.AddressMaxSize() + 4 + basics.AddressMaxSize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + basics.RoundMaxSize() + 6 + protocol.ConsensusVersionMaxSize() + 10 + protocol.ConsensusVersionMaxSize() + 8 + msgp.Uint64Size + 11 + basics.RoundMaxSize() + 11 + basics.RoundMaxSize() + 12 + protocol.ConsensusVersionMaxSize() + 13 + basics.RoundMaxSize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4
+ s = 3 + 4 + basics.RoundMaxSize() + 5 + bookkeeping.BlockHashMaxSize() + 5 + committee.SeedMaxSize() + 4 + crypto.DigestMaxSize() + 7 + crypto.DigestMaxSize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + config.MaxGenesisIDLen + 3 + crypto.DigestMaxSize() + 4 + basics.AddressMaxSize() + 3 + basics.MicroAlgosMaxSize() + 5 + basics.AddressMaxSize() + 4 + basics.AddressMaxSize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + basics.RoundMaxSize() + 6 + protocol.ConsensusVersionMaxSize() + 10 + protocol.ConsensusVersionMaxSize() + 8 + msgp.Uint64Size + 11 + basics.RoundMaxSize() + 11 + basics.RoundMaxSize() + 12 + protocol.ConsensusVersionMaxSize() + 13 + basics.RoundMaxSize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4
s += msgp.MapHeaderSize
// Adding size of map keys for z.unauthenticatedProposal.Block.BlockHeader.StateProofTracking
s += protocol.NumStateProofTypes * (protocol.StateProofTypeMaxSize())
@@ -8856,127 +8902,135 @@ func ThresholdEventMaxSize() (s int) {
func (z *transmittedPayload) MarshalMsg(b []byte) (o []byte) {
o = msgp.Require(b, z.Msgsize())
// omitempty: check for empty values
- zb0004Len := uint32(30)
- var zb0004Mask uint64 /* 38 bits */
+ zb0004Len := uint32(32)
+ var zb0004Mask uint64 /* 40 bits */
if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0 {
zb0004Len--
zb0004Mask |= 0x80
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero() {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x100
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0 {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x200
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "" {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0 {
zb0004Len--
zb0004Mask |= 0x400
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero() {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "" {
zb0004Len--
zb0004Mask |= 0x800
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x1000
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero() {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x2000
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x4000
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0 {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x8000
}
- if (*z).unauthenticatedProposal.OriginalPeriod == 0 {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0 {
zb0004Len--
zb0004Mask |= 0x10000
}
- if (*z).unauthenticatedProposal.OriginalProposer.MsgIsZero() {
+ if (*z).unauthenticatedProposal.OriginalPeriod == 0 {
zb0004Len--
zb0004Mask |= 0x20000
}
- if len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 {
+ if (*z).unauthenticatedProposal.OriginalProposer.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x40000
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero() {
+ if len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 {
zb0004Len--
zb0004Mask |= 0x80000
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x100000
}
- if (*z).PriorVote.MsgIsZero() {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x200000
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0 {
+ if (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x400000
}
- if (*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero() {
+ if (*z).PriorVote.MsgIsZero() {
+ zb0004Len--
+ zb0004Mask |= 0x800000
+ }
+ if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0 {
zb0004Len--
zb0004Mask |= 0x1000000
}
+ if (*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero() {
+ zb0004Len--
+ zb0004Mask |= 0x4000000
+ }
if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x2000000
+ zb0004Mask |= 0x8000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x4000000
+ zb0004Mask |= 0x10000000
}
if (*z).unauthenticatedProposal.SeedProof.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x8000000
+ zb0004Mask |= 0x20000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x10000000
+ zb0004Mask |= 0x40000000
}
if len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0 {
zb0004Len--
- zb0004Mask |= 0x20000000
+ zb0004Mask |= 0x80000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0 {
zb0004Len--
- zb0004Mask |= 0x40000000
+ zb0004Mask |= 0x100000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0 {
zb0004Len--
- zb0004Mask |= 0x80000000
+ zb0004Mask |= 0x200000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x100000000
+ zb0004Mask |= 0x400000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x200000000
+ zb0004Mask |= 0x800000000
}
if (*z).unauthenticatedProposal.Block.Payset.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x400000000
+ zb0004Mask |= 0x1000000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x800000000
+ zb0004Mask |= 0x2000000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x1000000000
+ zb0004Mask |= 0x4000000000
}
if (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false {
zb0004Len--
- zb0004Mask |= 0x2000000000
+ zb0004Mask |= 0x8000000000
}
// variable map header, size zb0004Len
o = msgp.AppendMapHeader(o, zb0004Len)
@@ -8987,56 +9041,61 @@ func (z *transmittedPayload) MarshalMsg(b []byte) (o []byte) {
o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel)
}
if (zb0004Mask & 0x100) == 0 { // if not empty
+ // string "fc"
+ o = append(o, 0xa2, 0x66, 0x63)
+ o = (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MarshalMsg(o)
+ }
+ if (zb0004Mask & 0x200) == 0 { // if not empty
// string "fees"
o = append(o, 0xa4, 0x66, 0x65, 0x65, 0x73)
o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MarshalMsg(o)
}
- if (zb0004Mask & 0x200) == 0 { // if not empty
+ if (zb0004Mask & 0x400) == 0 { // if not empty
// string "frac"
o = append(o, 0xa4, 0x66, 0x72, 0x61, 0x63)
o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue)
}
- if (zb0004Mask & 0x400) == 0 { // if not empty
+ if (zb0004Mask & 0x800) == 0 { // if not empty
// string "gen"
o = append(o, 0xa3, 0x67, 0x65, 0x6e)
o = msgp.AppendString(o, (*z).unauthenticatedProposal.Block.BlockHeader.GenesisID)
}
- if (zb0004Mask & 0x800) == 0 { // if not empty
+ if (zb0004Mask & 0x1000) == 0 { // if not empty
// string "gh"
o = append(o, 0xa2, 0x67, 0x68)
o = (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MarshalMsg(o)
}
- if (zb0004Mask & 0x1000) == 0 { // if not empty
+ if (zb0004Mask & 0x2000) == 0 { // if not empty
// string "nextbefore"
o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MarshalMsg(o)
}
- if (zb0004Mask & 0x2000) == 0 { // if not empty
+ if (zb0004Mask & 0x4000) == 0 { // if not empty
// string "nextproto"
o = append(o, 0xa9, 0x6e, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MarshalMsg(o)
}
- if (zb0004Mask & 0x4000) == 0 { // if not empty
+ if (zb0004Mask & 0x8000) == 0 { // if not empty
// string "nextswitch"
o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MarshalMsg(o)
}
- if (zb0004Mask & 0x8000) == 0 { // if not empty
+ if (zb0004Mask & 0x10000) == 0 { // if not empty
// string "nextyes"
o = append(o, 0xa7, 0x6e, 0x65, 0x78, 0x74, 0x79, 0x65, 0x73)
o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals)
}
- if (zb0004Mask & 0x10000) == 0 { // if not empty
+ if (zb0004Mask & 0x20000) == 0 { // if not empty
// string "oper"
o = append(o, 0xa4, 0x6f, 0x70, 0x65, 0x72)
o = msgp.AppendUint64(o, uint64((*z).unauthenticatedProposal.OriginalPeriod))
}
- if (zb0004Mask & 0x20000) == 0 { // if not empty
+ if (zb0004Mask & 0x40000) == 0 { // if not empty
// string "oprop"
o = append(o, 0xa5, 0x6f, 0x70, 0x72, 0x6f, 0x70)
o = (*z).unauthenticatedProposal.OriginalProposer.MarshalMsg(o)
}
- if (zb0004Mask & 0x40000) == 0 { // if not empty
+ if (zb0004Mask & 0x80000) == 0 { // if not empty
// string "partupdrmv"
o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76)
if (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts == nil {
@@ -9048,52 +9107,57 @@ func (z *transmittedPayload) MarshalMsg(b []byte) (o []byte) {
o = (*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].MarshalMsg(o)
}
}
- if (zb0004Mask & 0x80000) == 0 { // if not empty
+ if (zb0004Mask & 0x100000) == 0 { // if not empty
// string "prev"
o = append(o, 0xa4, 0x70, 0x72, 0x65, 0x76)
o = (*z).unauthenticatedProposal.Block.BlockHeader.Branch.MarshalMsg(o)
}
- if (zb0004Mask & 0x100000) == 0 { // if not empty
+ if (zb0004Mask & 0x200000) == 0 { // if not empty
// string "proto"
o = append(o, 0xa5, 0x70, 0x72, 0x6f, 0x74, 0x6f)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MarshalMsg(o)
}
- if (zb0004Mask & 0x200000) == 0 { // if not empty
+ if (zb0004Mask & 0x400000) == 0 { // if not empty
+ // string "prp"
+ o = append(o, 0xa3, 0x70, 0x72, 0x70)
+ o = (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MarshalMsg(o)
+ }
+ if (zb0004Mask & 0x800000) == 0 { // if not empty
// string "pv"
o = append(o, 0xa2, 0x70, 0x76)
o = (*z).PriorVote.MarshalMsg(o)
}
- if (zb0004Mask & 0x400000) == 0 { // if not empty
+ if (zb0004Mask & 0x1000000) == 0 { // if not empty
// string "rate"
o = append(o, 0xa4, 0x72, 0x61, 0x74, 0x65)
o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate)
}
- if (zb0004Mask & 0x1000000) == 0 { // if not empty
+ if (zb0004Mask & 0x4000000) == 0 { // if not empty
// string "rnd"
o = append(o, 0xa3, 0x72, 0x6e, 0x64)
o = (*z).unauthenticatedProposal.Block.BlockHeader.Round.MarshalMsg(o)
}
- if (zb0004Mask & 0x2000000) == 0 { // if not empty
+ if (zb0004Mask & 0x8000000) == 0 { // if not empty
// string "rwcalr"
o = append(o, 0xa6, 0x72, 0x77, 0x63, 0x61, 0x6c, 0x72)
o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MarshalMsg(o)
}
- if (zb0004Mask & 0x4000000) == 0 { // if not empty
+ if (zb0004Mask & 0x10000000) == 0 { // if not empty
// string "rwd"
o = append(o, 0xa3, 0x72, 0x77, 0x64)
o = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MarshalMsg(o)
}
- if (zb0004Mask & 0x8000000) == 0 { // if not empty
+ if (zb0004Mask & 0x20000000) == 0 { // if not empty
// string "sdpf"
o = append(o, 0xa4, 0x73, 0x64, 0x70, 0x66)
o = (*z).unauthenticatedProposal.SeedProof.MarshalMsg(o)
}
- if (zb0004Mask & 0x10000000) == 0 { // if not empty
+ if (zb0004Mask & 0x40000000) == 0 { // if not empty
// string "seed"
o = append(o, 0xa4, 0x73, 0x65, 0x65, 0x64)
o = (*z).unauthenticatedProposal.Block.BlockHeader.Seed.MarshalMsg(o)
}
- if (zb0004Mask & 0x20000000) == 0 { // if not empty
+ if (zb0004Mask & 0x80000000) == 0 { // if not empty
// string "spt"
o = append(o, 0xa3, 0x73, 0x70, 0x74)
if (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking == nil {
@@ -9113,42 +9177,42 @@ func (z *transmittedPayload) MarshalMsg(b []byte) (o []byte) {
o = zb0002.MarshalMsg(o)
}
}
- if (zb0004Mask & 0x40000000) == 0 { // if not empty
+ if (zb0004Mask & 0x100000000) == 0 { // if not empty
// string "tc"
o = append(o, 0xa2, 0x74, 0x63)
o = msgp.AppendUint64(o, (*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter)
}
- if (zb0004Mask & 0x80000000) == 0 { // if not empty
+ if (zb0004Mask & 0x200000000) == 0 { // if not empty
// string "ts"
o = append(o, 0xa2, 0x74, 0x73)
o = msgp.AppendInt64(o, (*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp)
}
- if (zb0004Mask & 0x100000000) == 0 { // if not empty
+ if (zb0004Mask & 0x400000000) == 0 { // if not empty
// string "txn"
o = append(o, 0xa3, 0x74, 0x78, 0x6e)
o = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MarshalMsg(o)
}
- if (zb0004Mask & 0x200000000) == 0 { // if not empty
+ if (zb0004Mask & 0x800000000) == 0 { // if not empty
// string "txn256"
o = append(o, 0xa6, 0x74, 0x78, 0x6e, 0x32, 0x35, 0x36)
o = (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MarshalMsg(o)
}
- if (zb0004Mask & 0x400000000) == 0 { // if not empty
+ if (zb0004Mask & 0x1000000000) == 0 { // if not empty
// string "txns"
o = append(o, 0xa4, 0x74, 0x78, 0x6e, 0x73)
o = (*z).unauthenticatedProposal.Block.Payset.MarshalMsg(o)
}
- if (zb0004Mask & 0x800000000) == 0 { // if not empty
+ if (zb0004Mask & 0x2000000000) == 0 { // if not empty
// string "upgradedelay"
o = append(o, 0xac, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x65, 0x6c, 0x61, 0x79)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MarshalMsg(o)
}
- if (zb0004Mask & 0x1000000000) == 0 { // if not empty
+ if (zb0004Mask & 0x4000000000) == 0 { // if not empty
// string "upgradeprop"
o = append(o, 0xab, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x70, 0x72, 0x6f, 0x70)
o = (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MarshalMsg(o)
}
- if (zb0004Mask & 0x2000000000) == 0 { // if not empty
+ if (zb0004Mask & 0x8000000000) == 0 { // if not empty
// string "upgradeyes"
o = append(o, 0xaa, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x65, 0x73)
o = msgp.AppendBool(o, (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove)
@@ -9254,6 +9318,22 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal
return
}
}
+ if zb0004 > 0 {
+ zb0004--
+ bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "Proposer")
+ return
+ }
+ }
+ if zb0004 > 0 {
+ zb0004--
+ bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "FeesCollected")
+ return
+ }
+ }
if zb0004 > 0 {
zb0004--
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st)
@@ -9564,6 +9644,18 @@ func (z *transmittedPayload) UnmarshalMsgWithState(bts []byte, st msgp.Unmarshal
err = msgp.WrapError(err, "GenesisHash")
return
}
+ case "prp":
+ bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "Proposer")
+ return
+ }
+ case "fc":
+ bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "FeesCollected")
+ return
+ }
case "fees":
bts, err = (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st)
if err != nil {
@@ -9772,7 +9864,7 @@ func (_ *transmittedPayload) CanUnmarshalMsg(z interface{}) bool {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *transmittedPayload) Msgsize() (s int) {
- s = 3 + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.Round.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.Branch.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.Seed.Msgsize() + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.Msgsize() + 7 + (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.Msgsize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + len((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID) + 3 + (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.Msgsize() + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.Msgsize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.Msgsize() + 6 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.Msgsize() + 10 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.Msgsize() + 8 + msgp.Uint64Size + 11 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.Msgsize() + 11 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.Msgsize() + 12 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.Msgsize() + 13 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.Msgsize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + msgp.MapHeaderSize
+ s = 3 + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.Round.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.Branch.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.Seed.Msgsize() + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.Msgsize() + 7 + (*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.Msgsize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + len((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID) + 3 + (*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.Msgsize() + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.Proposer.Msgsize() + 3 + (*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.Msgsize() + 5 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.Msgsize() + 4 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.Msgsize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + (*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.Msgsize() + 6 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.Msgsize() + 10 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.Msgsize() + 8 + msgp.Uint64Size + 11 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.Msgsize() + 11 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.Msgsize() + 12 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.Msgsize() + 13 + (*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.Msgsize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + msgp.MapHeaderSize
if (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking != nil {
for zb0001, zb0002 := range (*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking {
_ = zb0001
@@ -9790,12 +9882,12 @@ func (z *transmittedPayload) Msgsize() (s int) {
// MsgIsZero returns whether this is a zero value
func (z *transmittedPayload) MsgIsZero() bool {
- return ((*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "") && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).unauthenticatedProposal.Block.Payset.MsgIsZero()) && ((*z).unauthenticatedProposal.SeedProof.MsgIsZero()) && ((*z).unauthenticatedProposal.OriginalPeriod == 0) && ((*z).unauthenticatedProposal.OriginalProposer.MsgIsZero()) && ((*z).PriorVote.MsgIsZero())
+ return ((*z).unauthenticatedProposal.Block.BlockHeader.Round.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Branch.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Seed.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.TimeStamp == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisID == "") && ((*z).unauthenticatedProposal.Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.Proposer.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.FeesCollected.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).unauthenticatedProposal.Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).unauthenticatedProposal.Block.BlockHeader.TxnCounter == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.StateProofTracking) == 0) && (len((*z).unauthenticatedProposal.Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).unauthenticatedProposal.Block.Payset.MsgIsZero()) && ((*z).unauthenticatedProposal.SeedProof.MsgIsZero()) && ((*z).unauthenticatedProposal.OriginalPeriod == 0) && ((*z).unauthenticatedProposal.OriginalProposer.MsgIsZero()) && ((*z).PriorVote.MsgIsZero())
}
// MaxSize returns a maximum valid message size for this message type
func TransmittedPayloadMaxSize() (s int) {
- s = 3 + 4 + basics.RoundMaxSize() + 5 + bookkeeping.BlockHashMaxSize() + 5 + committee.SeedMaxSize() + 4 + crypto.DigestMaxSize() + 7 + crypto.DigestMaxSize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + config.MaxGenesisIDLen + 3 + crypto.DigestMaxSize() + 5 + basics.AddressMaxSize() + 4 + basics.AddressMaxSize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + basics.RoundMaxSize() + 6 + protocol.ConsensusVersionMaxSize() + 10 + protocol.ConsensusVersionMaxSize() + 8 + msgp.Uint64Size + 11 + basics.RoundMaxSize() + 11 + basics.RoundMaxSize() + 12 + protocol.ConsensusVersionMaxSize() + 13 + basics.RoundMaxSize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4
+ s = 3 + 4 + basics.RoundMaxSize() + 5 + bookkeeping.BlockHashMaxSize() + 5 + committee.SeedMaxSize() + 4 + crypto.DigestMaxSize() + 7 + crypto.DigestMaxSize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + config.MaxGenesisIDLen + 3 + crypto.DigestMaxSize() + 4 + basics.AddressMaxSize() + 3 + basics.MicroAlgosMaxSize() + 5 + basics.AddressMaxSize() + 4 + basics.AddressMaxSize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + basics.RoundMaxSize() + 6 + protocol.ConsensusVersionMaxSize() + 10 + protocol.ConsensusVersionMaxSize() + 8 + msgp.Uint64Size + 11 + basics.RoundMaxSize() + 11 + basics.RoundMaxSize() + 12 + protocol.ConsensusVersionMaxSize() + 13 + basics.RoundMaxSize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4
s += msgp.MapHeaderSize
// Adding size of map keys for z.unauthenticatedProposal.Block.BlockHeader.StateProofTracking
s += protocol.NumStateProofTypes * (protocol.StateProofTypeMaxSize())
@@ -10516,123 +10608,131 @@ func UnauthenticatedEquivocationVoteMaxSize() (s int) {
func (z *unauthenticatedProposal) MarshalMsg(b []byte) (o []byte) {
o = msgp.Require(b, z.Msgsize())
// omitempty: check for empty values
- zb0004Len := uint32(29)
- var zb0004Mask uint64 /* 36 bits */
+ zb0004Len := uint32(31)
+ var zb0004Mask uint64 /* 38 bits */
if (*z).Block.BlockHeader.RewardsState.RewardsLevel == 0 {
zb0004Len--
zb0004Mask |= 0x40
}
- if (*z).Block.BlockHeader.RewardsState.FeeSink.MsgIsZero() {
+ if (*z).Block.BlockHeader.FeesCollected.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x80
}
- if (*z).Block.BlockHeader.RewardsState.RewardsResidue == 0 {
+ if (*z).Block.BlockHeader.RewardsState.FeeSink.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x100
}
- if (*z).Block.BlockHeader.GenesisID == "" {
+ if (*z).Block.BlockHeader.RewardsState.RewardsResidue == 0 {
zb0004Len--
zb0004Mask |= 0x200
}
- if (*z).Block.BlockHeader.GenesisHash.MsgIsZero() {
+ if (*z).Block.BlockHeader.GenesisID == "" {
zb0004Len--
zb0004Mask |= 0x400
}
- if (*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() {
+ if (*z).Block.BlockHeader.GenesisHash.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x800
}
- if (*z).Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero() {
+ if (*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x1000
}
- if (*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() {
+ if (*z).Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x2000
}
- if (*z).Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0 {
+ if (*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x4000
}
- if (*z).OriginalPeriod == 0 {
+ if (*z).Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0 {
zb0004Len--
zb0004Mask |= 0x8000
}
- if (*z).OriginalProposer.MsgIsZero() {
+ if (*z).OriginalPeriod == 0 {
zb0004Len--
zb0004Mask |= 0x10000
}
- if len((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 {
+ if (*z).OriginalProposer.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x20000
}
- if (*z).Block.BlockHeader.Branch.MsgIsZero() {
+ if len((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 {
zb0004Len--
zb0004Mask |= 0x40000
}
- if (*z).Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() {
+ if (*z).Block.BlockHeader.Branch.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x80000
}
- if (*z).Block.BlockHeader.RewardsState.RewardsRate == 0 {
+ if (*z).Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x100000
}
- if (*z).Block.BlockHeader.Round.MsgIsZero() {
+ if (*z).Block.BlockHeader.Proposer.MsgIsZero() {
+ zb0004Len--
+ zb0004Mask |= 0x200000
+ }
+ if (*z).Block.BlockHeader.RewardsState.RewardsRate == 0 {
zb0004Len--
zb0004Mask |= 0x400000
}
+ if (*z).Block.BlockHeader.Round.MsgIsZero() {
+ zb0004Len--
+ zb0004Mask |= 0x1000000
+ }
if (*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x800000
+ zb0004Mask |= 0x2000000
}
if (*z).Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x1000000
+ zb0004Mask |= 0x4000000
}
if (*z).SeedProof.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x2000000
+ zb0004Mask |= 0x8000000
}
if (*z).Block.BlockHeader.Seed.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x4000000
+ zb0004Mask |= 0x10000000
}
if len((*z).Block.BlockHeader.StateProofTracking) == 0 {
zb0004Len--
- zb0004Mask |= 0x8000000
+ zb0004Mask |= 0x20000000
}
if (*z).Block.BlockHeader.TxnCounter == 0 {
zb0004Len--
- zb0004Mask |= 0x10000000
+ zb0004Mask |= 0x40000000
}
if (*z).Block.BlockHeader.TimeStamp == 0 {
zb0004Len--
- zb0004Mask |= 0x20000000
+ zb0004Mask |= 0x80000000
}
if (*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x40000000
+ zb0004Mask |= 0x100000000
}
if (*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x80000000
+ zb0004Mask |= 0x200000000
}
if (*z).Block.Payset.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x100000000
+ zb0004Mask |= 0x400000000
}
if (*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x200000000
+ zb0004Mask |= 0x800000000
}
if (*z).Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero() {
zb0004Len--
- zb0004Mask |= 0x400000000
+ zb0004Mask |= 0x1000000000
}
if (*z).Block.BlockHeader.UpgradeVote.UpgradeApprove == false {
zb0004Len--
- zb0004Mask |= 0x800000000
+ zb0004Mask |= 0x2000000000
}
// variable map header, size zb0004Len
o = msgp.AppendMapHeader(o, zb0004Len)
@@ -10643,56 +10743,61 @@ func (z *unauthenticatedProposal) MarshalMsg(b []byte) (o []byte) {
o = msgp.AppendUint64(o, (*z).Block.BlockHeader.RewardsState.RewardsLevel)
}
if (zb0004Mask & 0x80) == 0 { // if not empty
+ // string "fc"
+ o = append(o, 0xa2, 0x66, 0x63)
+ o = (*z).Block.BlockHeader.FeesCollected.MarshalMsg(o)
+ }
+ if (zb0004Mask & 0x100) == 0 { // if not empty
// string "fees"
o = append(o, 0xa4, 0x66, 0x65, 0x65, 0x73)
o = (*z).Block.BlockHeader.RewardsState.FeeSink.MarshalMsg(o)
}
- if (zb0004Mask & 0x100) == 0 { // if not empty
+ if (zb0004Mask & 0x200) == 0 { // if not empty
// string "frac"
o = append(o, 0xa4, 0x66, 0x72, 0x61, 0x63)
o = msgp.AppendUint64(o, (*z).Block.BlockHeader.RewardsState.RewardsResidue)
}
- if (zb0004Mask & 0x200) == 0 { // if not empty
+ if (zb0004Mask & 0x400) == 0 { // if not empty
// string "gen"
o = append(o, 0xa3, 0x67, 0x65, 0x6e)
o = msgp.AppendString(o, (*z).Block.BlockHeader.GenesisID)
}
- if (zb0004Mask & 0x400) == 0 { // if not empty
+ if (zb0004Mask & 0x800) == 0 { // if not empty
// string "gh"
o = append(o, 0xa2, 0x67, 0x68)
o = (*z).Block.BlockHeader.GenesisHash.MarshalMsg(o)
}
- if (zb0004Mask & 0x800) == 0 { // if not empty
+ if (zb0004Mask & 0x1000) == 0 { // if not empty
// string "nextbefore"
o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65)
o = (*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MarshalMsg(o)
}
- if (zb0004Mask & 0x1000) == 0 { // if not empty
+ if (zb0004Mask & 0x2000) == 0 { // if not empty
// string "nextproto"
o = append(o, 0xa9, 0x6e, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f)
o = (*z).Block.BlockHeader.UpgradeState.NextProtocol.MarshalMsg(o)
}
- if (zb0004Mask & 0x2000) == 0 { // if not empty
+ if (zb0004Mask & 0x4000) == 0 { // if not empty
// string "nextswitch"
o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68)
o = (*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MarshalMsg(o)
}
- if (zb0004Mask & 0x4000) == 0 { // if not empty
+ if (zb0004Mask & 0x8000) == 0 { // if not empty
// string "nextyes"
o = append(o, 0xa7, 0x6e, 0x65, 0x78, 0x74, 0x79, 0x65, 0x73)
o = msgp.AppendUint64(o, (*z).Block.BlockHeader.UpgradeState.NextProtocolApprovals)
}
- if (zb0004Mask & 0x8000) == 0 { // if not empty
+ if (zb0004Mask & 0x10000) == 0 { // if not empty
// string "oper"
o = append(o, 0xa4, 0x6f, 0x70, 0x65, 0x72)
o = msgp.AppendUint64(o, uint64((*z).OriginalPeriod))
}
- if (zb0004Mask & 0x10000) == 0 { // if not empty
+ if (zb0004Mask & 0x20000) == 0 { // if not empty
// string "oprop"
o = append(o, 0xa5, 0x6f, 0x70, 0x72, 0x6f, 0x70)
o = (*z).OriginalProposer.MarshalMsg(o)
}
- if (zb0004Mask & 0x20000) == 0 { // if not empty
+ if (zb0004Mask & 0x40000) == 0 { // if not empty
// string "partupdrmv"
o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76)
if (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts == nil {
@@ -10704,47 +10809,52 @@ func (z *unauthenticatedProposal) MarshalMsg(b []byte) (o []byte) {
o = (*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].MarshalMsg(o)
}
}
- if (zb0004Mask & 0x40000) == 0 { // if not empty
+ if (zb0004Mask & 0x80000) == 0 { // if not empty
// string "prev"
o = append(o, 0xa4, 0x70, 0x72, 0x65, 0x76)
o = (*z).Block.BlockHeader.Branch.MarshalMsg(o)
}
- if (zb0004Mask & 0x80000) == 0 { // if not empty
+ if (zb0004Mask & 0x100000) == 0 { // if not empty
// string "proto"
o = append(o, 0xa5, 0x70, 0x72, 0x6f, 0x74, 0x6f)
o = (*z).Block.BlockHeader.UpgradeState.CurrentProtocol.MarshalMsg(o)
}
- if (zb0004Mask & 0x100000) == 0 { // if not empty
+ if (zb0004Mask & 0x200000) == 0 { // if not empty
+ // string "prp"
+ o = append(o, 0xa3, 0x70, 0x72, 0x70)
+ o = (*z).Block.BlockHeader.Proposer.MarshalMsg(o)
+ }
+ if (zb0004Mask & 0x400000) == 0 { // if not empty
// string "rate"
o = append(o, 0xa4, 0x72, 0x61, 0x74, 0x65)
o = msgp.AppendUint64(o, (*z).Block.BlockHeader.RewardsState.RewardsRate)
}
- if (zb0004Mask & 0x400000) == 0 { // if not empty
+ if (zb0004Mask & 0x1000000) == 0 { // if not empty
// string "rnd"
o = append(o, 0xa3, 0x72, 0x6e, 0x64)
o = (*z).Block.BlockHeader.Round.MarshalMsg(o)
}
- if (zb0004Mask & 0x800000) == 0 { // if not empty
+ if (zb0004Mask & 0x2000000) == 0 { // if not empty
// string "rwcalr"
o = append(o, 0xa6, 0x72, 0x77, 0x63, 0x61, 0x6c, 0x72)
o = (*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.MarshalMsg(o)
}
- if (zb0004Mask & 0x1000000) == 0 { // if not empty
+ if (zb0004Mask & 0x4000000) == 0 { // if not empty
// string "rwd"
o = append(o, 0xa3, 0x72, 0x77, 0x64)
o = (*z).Block.BlockHeader.RewardsState.RewardsPool.MarshalMsg(o)
}
- if (zb0004Mask & 0x2000000) == 0 { // if not empty
+ if (zb0004Mask & 0x8000000) == 0 { // if not empty
// string "sdpf"
o = append(o, 0xa4, 0x73, 0x64, 0x70, 0x66)
o = (*z).SeedProof.MarshalMsg(o)
}
- if (zb0004Mask & 0x4000000) == 0 { // if not empty
+ if (zb0004Mask & 0x10000000) == 0 { // if not empty
// string "seed"
o = append(o, 0xa4, 0x73, 0x65, 0x65, 0x64)
o = (*z).Block.BlockHeader.Seed.MarshalMsg(o)
}
- if (zb0004Mask & 0x8000000) == 0 { // if not empty
+ if (zb0004Mask & 0x20000000) == 0 { // if not empty
// string "spt"
o = append(o, 0xa3, 0x73, 0x70, 0x74)
if (*z).Block.BlockHeader.StateProofTracking == nil {
@@ -10764,42 +10874,42 @@ func (z *unauthenticatedProposal) MarshalMsg(b []byte) (o []byte) {
o = zb0002.MarshalMsg(o)
}
}
- if (zb0004Mask & 0x10000000) == 0 { // if not empty
+ if (zb0004Mask & 0x40000000) == 0 { // if not empty
// string "tc"
o = append(o, 0xa2, 0x74, 0x63)
o = msgp.AppendUint64(o, (*z).Block.BlockHeader.TxnCounter)
}
- if (zb0004Mask & 0x20000000) == 0 { // if not empty
+ if (zb0004Mask & 0x80000000) == 0 { // if not empty
// string "ts"
o = append(o, 0xa2, 0x74, 0x73)
o = msgp.AppendInt64(o, (*z).Block.BlockHeader.TimeStamp)
}
- if (zb0004Mask & 0x40000000) == 0 { // if not empty
+ if (zb0004Mask & 0x100000000) == 0 { // if not empty
// string "txn"
o = append(o, 0xa3, 0x74, 0x78, 0x6e)
o = (*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MarshalMsg(o)
}
- if (zb0004Mask & 0x80000000) == 0 { // if not empty
+ if (zb0004Mask & 0x200000000) == 0 { // if not empty
// string "txn256"
o = append(o, 0xa6, 0x74, 0x78, 0x6e, 0x32, 0x35, 0x36)
o = (*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.MarshalMsg(o)
}
- if (zb0004Mask & 0x100000000) == 0 { // if not empty
+ if (zb0004Mask & 0x400000000) == 0 { // if not empty
// string "txns"
o = append(o, 0xa4, 0x74, 0x78, 0x6e, 0x73)
o = (*z).Block.Payset.MarshalMsg(o)
}
- if (zb0004Mask & 0x200000000) == 0 { // if not empty
+ if (zb0004Mask & 0x800000000) == 0 { // if not empty
// string "upgradedelay"
o = append(o, 0xac, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x65, 0x6c, 0x61, 0x79)
o = (*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.MarshalMsg(o)
}
- if (zb0004Mask & 0x400000000) == 0 { // if not empty
+ if (zb0004Mask & 0x1000000000) == 0 { // if not empty
// string "upgradeprop"
o = append(o, 0xab, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x70, 0x72, 0x6f, 0x70)
o = (*z).Block.BlockHeader.UpgradeVote.UpgradePropose.MarshalMsg(o)
}
- if (zb0004Mask & 0x800000000) == 0 { // if not empty
+ if (zb0004Mask & 0x2000000000) == 0 { // if not empty
// string "upgradeyes"
o = append(o, 0xaa, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x65, 0x73)
o = msgp.AppendBool(o, (*z).Block.BlockHeader.UpgradeVote.UpgradeApprove)
@@ -10905,6 +11015,22 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma
return
}
}
+ if zb0004 > 0 {
+ zb0004--
+ bts, err = (*z).Block.BlockHeader.Proposer.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "Proposer")
+ return
+ }
+ }
+ if zb0004 > 0 {
+ zb0004--
+ bts, err = (*z).Block.BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "FeesCollected")
+ return
+ }
+ }
if zb0004 > 0 {
zb0004--
bts, err = (*z).Block.BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st)
@@ -11207,6 +11333,18 @@ func (z *unauthenticatedProposal) UnmarshalMsgWithState(bts []byte, st msgp.Unma
err = msgp.WrapError(err, "GenesisHash")
return
}
+ case "prp":
+ bts, err = (*z).Block.BlockHeader.Proposer.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "Proposer")
+ return
+ }
+ case "fc":
+ bts, err = (*z).Block.BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "FeesCollected")
+ return
+ }
case "fees":
bts, err = (*z).Block.BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st)
if err != nil {
@@ -11409,7 +11547,7 @@ func (_ *unauthenticatedProposal) CanUnmarshalMsg(z interface{}) bool {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *unauthenticatedProposal) Msgsize() (s int) {
- s = 3 + 4 + (*z).Block.BlockHeader.Round.Msgsize() + 5 + (*z).Block.BlockHeader.Branch.Msgsize() + 5 + (*z).Block.BlockHeader.Seed.Msgsize() + 4 + (*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.Msgsize() + 7 + (*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.Msgsize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + len((*z).Block.BlockHeader.GenesisID) + 3 + (*z).Block.BlockHeader.GenesisHash.Msgsize() + 5 + (*z).Block.BlockHeader.RewardsState.FeeSink.Msgsize() + 4 + (*z).Block.BlockHeader.RewardsState.RewardsPool.Msgsize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + (*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.Msgsize() + 6 + (*z).Block.BlockHeader.UpgradeState.CurrentProtocol.Msgsize() + 10 + (*z).Block.BlockHeader.UpgradeState.NextProtocol.Msgsize() + 8 + msgp.Uint64Size + 11 + (*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.Msgsize() + 11 + (*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.Msgsize() + 12 + (*z).Block.BlockHeader.UpgradeVote.UpgradePropose.Msgsize() + 13 + (*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.Msgsize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + msgp.MapHeaderSize
+ s = 3 + 4 + (*z).Block.BlockHeader.Round.Msgsize() + 5 + (*z).Block.BlockHeader.Branch.Msgsize() + 5 + (*z).Block.BlockHeader.Seed.Msgsize() + 4 + (*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.Msgsize() + 7 + (*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.Msgsize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + len((*z).Block.BlockHeader.GenesisID) + 3 + (*z).Block.BlockHeader.GenesisHash.Msgsize() + 4 + (*z).Block.BlockHeader.Proposer.Msgsize() + 3 + (*z).Block.BlockHeader.FeesCollected.Msgsize() + 5 + (*z).Block.BlockHeader.RewardsState.FeeSink.Msgsize() + 4 + (*z).Block.BlockHeader.RewardsState.RewardsPool.Msgsize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + (*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.Msgsize() + 6 + (*z).Block.BlockHeader.UpgradeState.CurrentProtocol.Msgsize() + 10 + (*z).Block.BlockHeader.UpgradeState.NextProtocol.Msgsize() + 8 + msgp.Uint64Size + 11 + (*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.Msgsize() + 11 + (*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.Msgsize() + 12 + (*z).Block.BlockHeader.UpgradeVote.UpgradePropose.Msgsize() + 13 + (*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.Msgsize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + msgp.MapHeaderSize
if (*z).Block.BlockHeader.StateProofTracking != nil {
for zb0001, zb0002 := range (*z).Block.BlockHeader.StateProofTracking {
_ = zb0001
@@ -11427,12 +11565,12 @@ func (z *unauthenticatedProposal) Msgsize() (s int) {
// MsgIsZero returns whether this is a zero value
func (z *unauthenticatedProposal) MsgIsZero() bool {
- return ((*z).Block.BlockHeader.Round.MsgIsZero()) && ((*z).Block.BlockHeader.Branch.MsgIsZero()) && ((*z).Block.BlockHeader.Seed.MsgIsZero()) && ((*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).Block.BlockHeader.TimeStamp == 0) && ((*z).Block.BlockHeader.GenesisID == "") && ((*z).Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).Block.BlockHeader.TxnCounter == 0) && (len((*z).Block.BlockHeader.StateProofTracking) == 0) && (len((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).Block.Payset.MsgIsZero()) && ((*z).SeedProof.MsgIsZero()) && ((*z).OriginalPeriod == 0) && ((*z).OriginalProposer.MsgIsZero())
+ return ((*z).Block.BlockHeader.Round.MsgIsZero()) && ((*z).Block.BlockHeader.Branch.MsgIsZero()) && ((*z).Block.BlockHeader.Seed.MsgIsZero()) && ((*z).Block.BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).Block.BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).Block.BlockHeader.TimeStamp == 0) && ((*z).Block.BlockHeader.GenesisID == "") && ((*z).Block.BlockHeader.GenesisHash.MsgIsZero()) && ((*z).Block.BlockHeader.Proposer.MsgIsZero()) && ((*z).Block.BlockHeader.FeesCollected.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).Block.BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsRate == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).Block.BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).Block.BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).Block.BlockHeader.TxnCounter == 0) && (len((*z).Block.BlockHeader.StateProofTracking) == 0) && (len((*z).Block.BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).Block.Payset.MsgIsZero()) && ((*z).SeedProof.MsgIsZero()) && ((*z).OriginalPeriod == 0) && ((*z).OriginalProposer.MsgIsZero())
}
// MaxSize returns a maximum valid message size for this message type
func UnauthenticatedProposalMaxSize() (s int) {
- s = 3 + 4 + basics.RoundMaxSize() + 5 + bookkeeping.BlockHashMaxSize() + 5 + committee.SeedMaxSize() + 4 + crypto.DigestMaxSize() + 7 + crypto.DigestMaxSize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + config.MaxGenesisIDLen + 3 + crypto.DigestMaxSize() + 5 + basics.AddressMaxSize() + 4 + basics.AddressMaxSize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + basics.RoundMaxSize() + 6 + protocol.ConsensusVersionMaxSize() + 10 + protocol.ConsensusVersionMaxSize() + 8 + msgp.Uint64Size + 11 + basics.RoundMaxSize() + 11 + basics.RoundMaxSize() + 12 + protocol.ConsensusVersionMaxSize() + 13 + basics.RoundMaxSize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4
+ s = 3 + 4 + basics.RoundMaxSize() + 5 + bookkeeping.BlockHashMaxSize() + 5 + committee.SeedMaxSize() + 4 + crypto.DigestMaxSize() + 7 + crypto.DigestMaxSize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + config.MaxGenesisIDLen + 3 + crypto.DigestMaxSize() + 4 + basics.AddressMaxSize() + 3 + basics.MicroAlgosMaxSize() + 5 + basics.AddressMaxSize() + 4 + basics.AddressMaxSize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + basics.RoundMaxSize() + 6 + protocol.ConsensusVersionMaxSize() + 10 + protocol.ConsensusVersionMaxSize() + 8 + msgp.Uint64Size + 11 + basics.RoundMaxSize() + 11 + basics.RoundMaxSize() + 12 + protocol.ConsensusVersionMaxSize() + 13 + basics.RoundMaxSize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4
s += msgp.MapHeaderSize
// Adding size of map keys for z.Block.BlockHeader.StateProofTracking
s += protocol.NumStateProofTypes * (protocol.StateProofTypeMaxSize())
diff --git a/agreement/proposal.go b/agreement/proposal.go
index ac29970b16..852006952c 100644
--- a/agreement/proposal.go
+++ b/agreement/proposal.go
@@ -197,6 +197,12 @@ func verifyNewSeed(p unauthenticatedProposal, ledger LedgerReader) error {
return fmt.Errorf("failed to obtain consensus parameters in round %d: %v", ParamsRound(rnd), err)
}
+ if cparams.EnableMining {
+ if p.BlockHeader.Proposer != value.OriginalProposer {
+ return fmt.Errorf("payload has wrong proposer (%v != %v)", p.Proposer, value.OriginalProposer)
+ }
+ }
+
balanceRound := balanceRound(rnd, cparams)
proposerRecord, err := ledger.LookupAgreement(balanceRound, value.OriginalProposer)
if err != nil {
@@ -251,7 +257,7 @@ func proposalForBlock(address basics.Address, vrf *crypto.VRFSecrets, ve Validat
return proposal{}, proposalValue{}, fmt.Errorf("proposalForBlock: could not derive new seed: %v", err)
}
- ve = ve.WithSeed(newSeed)
+ ve = ve.WithSeed(newSeed, address)
proposal := makeProposal(ve, seedProof, period, address)
value := proposalValue{
OriginalPeriod: period,
diff --git a/config/consensus.go b/config/consensus.go
index fc08e2990e..81c6afc84a 100644
--- a/config/consensus.go
+++ b/config/consensus.go
@@ -529,6 +529,13 @@ type ConsensusParams struct {
// arrival times or is set to a static value. Even if this flag disables the
// dynamic filter, it will be calculated and logged (but not used).
DynamicFilterTimeout bool
+
+ // EnableMining means that the proposer should be included in the BlockHeader.
+ EnableMining bool
+
+ // MiningPercent specifies the percent of fees paid in a block that go to
+ // the proposer instead of the FeeSink.
+ MiningPercent uint64
}
// PaysetCommitType enumerates possible ways for the block header to commit to
@@ -1412,6 +1419,9 @@ func initConsensusProtocols() {
vFuture.LogicSigVersion = 11 // When moving this to a release, put a new higher LogicSigVersion here
+ vFuture.EnableMining = true
+ vFuture.MiningPercent = 75
+
Consensus[protocol.ConsensusFuture] = vFuture
// vAlphaX versions are an separate series of consensus parameters and versions for alphanet
diff --git a/daemon/algod/api/algod.oas2.json b/daemon/algod/api/algod.oas2.json
index e327e0e3be..23f835e908 100644
--- a/daemon/algod/api/algod.oas2.json
+++ b/daemon/algod/api/algod.oas2.json
@@ -2983,6 +2983,10 @@
"participation": {
"$ref": "#/definitions/AccountParticipation"
},
+ "incentive-eligible": {
+ "description": "Whether or not the account can receive block incentives if its balance is in range at proposal time.",
+ "type": "boolean"
+ },
"pending-rewards": {
"description": "amount of MicroAlgos of pending rewards in this account.",
"type": "integer"
diff --git a/daemon/algod/api/algod.oas3.yml b/daemon/algod/api/algod.oas3.yml
index be9237b90e..96e4a670d9 100644
--- a/daemon/algod/api/algod.oas3.yml
+++ b/daemon/algod/api/algod.oas3.yml
@@ -1067,6 +1067,10 @@
},
"type": "array"
},
+ "incentive-eligible": {
+ "description": "Whether or not the account can receive block incentives if its balance is in range at proposal time.",
+ "type": "boolean"
+ },
"min-balance": {
"description": "MicroAlgo balance required by the account.\n\nThe requirement grows based on asset and application usage.",
"type": "integer"
diff --git a/daemon/algod/api/server/v2/account.go b/daemon/algod/api/server/v2/account.go
index addb81b432..732d85133c 100644
--- a/daemon/algod/api/server/v2/account.go
+++ b/daemon/algod/api/server/v2/account.go
@@ -24,6 +24,7 @@ import (
"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/crypto"
+ "github.com/algorand/go-algorand/crypto/merklesignature"
"github.com/algorand/go-algorand/daemon/algod/api/server/v2/generated/model"
"github.com/algorand/go-algorand/data/basics"
"golang.org/x/exp/slices"
@@ -123,6 +124,7 @@ func AccountDataToAccount(
Status: record.Status.String(),
RewardBase: &record.RewardsBase,
Participation: apiParticipation,
+ IncentiveEligible: omitEmpty(record.IncentiveEligible),
CreatedAssets: &createdAssets,
TotalCreatedAssets: uint64(len(createdAssets)),
CreatedApps: &createdApps,
@@ -199,12 +201,16 @@ func AccountToAccountData(a *model.Account) (basics.AccountData, error) {
var voteFirstValid basics.Round
var voteLastValid basics.Round
var voteKeyDilution uint64
+ var stateProofID merklesignature.Commitment
if a.Participation != nil {
copy(voteID[:], a.Participation.VoteParticipationKey)
copy(selID[:], a.Participation.SelectionParticipationKey)
voteFirstValid = basics.Round(a.Participation.VoteFirstValid)
voteLastValid = basics.Round(a.Participation.VoteLastValid)
voteKeyDilution = a.Participation.VoteKeyDilution
+ if a.Participation.StateProofKey != nil {
+ copy(stateProofID[:], *a.Participation.StateProofKey)
+ }
}
var rewardsBase uint64
@@ -350,11 +356,13 @@ func AccountToAccountData(a *model.Account) (basics.AccountData, error) {
MicroAlgos: basics.MicroAlgos{Raw: a.Amount},
RewardsBase: rewardsBase,
RewardedMicroAlgos: basics.MicroAlgos{Raw: a.Rewards},
+ IncentiveEligible: nilToZero(a.IncentiveEligible),
VoteID: voteID,
SelectionID: selID,
VoteFirstValid: voteFirstValid,
VoteLastValid: voteLastValid,
VoteKeyDilution: voteKeyDilution,
+ StateProofID: stateProofID,
Assets: assets,
AppLocalStates: appLocalStates,
AppParams: appParams,
diff --git a/daemon/algod/api/server/v2/account_test.go b/daemon/algod/api/server/v2/account_test.go
index cd3c67499a..29d668f6e2 100644
--- a/daemon/algod/api/server/v2/account_test.go
+++ b/daemon/algod/api/server/v2/account_test.go
@@ -25,12 +25,15 @@ import (
"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/daemon/algod/api/server/v2/generated/model"
"github.com/algorand/go-algorand/data/basics"
+ ledgertesting "github.com/algorand/go-algorand/ledger/testing"
"github.com/algorand/go-algorand/protocol"
"github.com/algorand/go-algorand/test/partitiontest"
)
func TestAccount(t *testing.T) {
partitiontest.PartitionTest(t)
+ t.Parallel()
+
proto := config.Consensus[protocol.ConsensusFuture]
appIdx1 := basics.AppIndex(1)
appIdx2 := basics.AppIndex(2)
@@ -203,3 +206,21 @@ func TestAccount(t *testing.T) {
}
})
}
+
+func TestAccountRandomRoundTrip(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ t.Parallel()
+
+ for _, simple := range []bool{true, false} {
+ accts := ledgertesting.RandomAccounts(20, simple)
+ for addr, acct := range accts {
+ round := basics.Round(2)
+ proto := config.Consensus[protocol.ConsensusFuture]
+ conv, err := AccountDataToAccount(addr.String(), &acct, round, &proto, acct.MicroAlgos)
+ require.NoError(t, err)
+ c, err := AccountToAccountData(&conv)
+ require.NoError(t, err)
+ require.Equal(t, acct, c)
+ }
+ }
+}
diff --git a/daemon/algod/api/server/v2/generated/data/routes.go b/daemon/algod/api/server/v2/generated/data/routes.go
index 4a3438b8ff..0507c856e2 100644
--- a/daemon/algod/api/server/v2/generated/data/routes.go
+++ b/daemon/algod/api/server/v2/generated/data/routes.go
@@ -192,134 +192,135 @@ var swaggerSpec = []string{
"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",
- "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",
- "npw8mnz8/wEAAP//6aRdnSH5AAA=",
+ "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",
+ "r0Zkc775AAA=",
}
// GetSwagger returns the content of the embedded swagger specification file
diff --git a/daemon/algod/api/server/v2/generated/experimental/routes.go b/daemon/algod/api/server/v2/generated/experimental/routes.go
index e7e56520a4..760f86cc7a 100644
--- a/daemon/algod/api/server/v2/generated/experimental/routes.go
+++ b/daemon/algod/api/server/v2/generated/experimental/routes.go
@@ -168,134 +168,135 @@ var swaggerSpec = []string{
"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",
- "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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/model/types.go b/daemon/algod/api/server/v2/generated/model/types.go
index b9fc3b1baa..2565f762a9 100644
--- a/daemon/algod/api/server/v2/generated/model/types.go
+++ b/daemon/algod/api/server/v2/generated/model/types.go
@@ -185,6 +185,9 @@ type Account struct {
// Note: the raw account uses `map[int] -> Asset` for this type.
CreatedAssets *[]Asset `json:"created-assets,omitempty"`
+ // IncentiveEligible Whether or not the account can receive block incentives if its balance is in range at proposal time.
+ IncentiveEligible *bool `json:"incentive-eligible,omitempty"`
+
// MinBalance MicroAlgo balance required by the account.
//
// The requirement grows based on asset and application usage.
diff --git a/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go b/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go
index b866cc9f42..697e544f8d 100644
--- a/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go
+++ b/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go
@@ -139,215 +139,216 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
// Base64 encoded, gzipped, json marshaled Swagger object
var swaggerSpec = []string{
- "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",
- "nUw+/v8AAAD//31f+lNw+wAA",
+ "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",
+ "6a4N/AAA",
}
// GetSwagger returns the content of the embedded swagger specification file
diff --git a/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go b/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go
index 713e5cd7b0..49eb954d27 100644
--- a/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go
+++ b/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go
@@ -802,211 +802,212 @@ var swaggerSpec = []string{
"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",
- "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",
- "bwAAAP//bsB3VeaoAQA=",
+ "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",
+ "AQA=",
}
// GetSwagger returns the content of the embedded swagger specification file
diff --git a/daemon/algod/api/server/v2/generated/participating/private/routes.go b/daemon/algod/api/server/v2/generated/participating/private/routes.go
index c0e0c71fe2..84000d35dd 100644
--- a/daemon/algod/api/server/v2/generated/participating/private/routes.go
+++ b/daemon/algod/api/server/v2/generated/participating/private/routes.go
@@ -281,140 +281,141 @@ var swaggerSpec = []string{
"7Fe+SFh8CfgItxDfMeJG6/i/6X4Fub033q5efvBgl2q9zMzZjq5KGRL3O9PUDloYIctHYyi2QG3VlVma",
"AcmXkF+7+jewqvRu2vncB/w4QdOzDqZsZSSbmYe1OdBBMQNSVwV1ojjlu36RBAVa+7Dit3ANu0vRlvY4",
"pipCN0lfpQ4qUmogXRpiDY+tG6O/+S6qDBX7qvK57pj06MniRUMX/pv0QbYi7x0c4hhRdJLIU4igMoII",
- "S/wJFNxgoWa8W5F+bHlGy5jZmy9SJcnzfuJeaZUnFwAWrgat7vb5CrDMmtgoMqNGbheuQphNRA+4WK3o",
- "AhIScugjGpnu3fEr4SCH7r3oTSfm/QttcN9EQbYvZ2bNUUoB88SQCiozvbA/P5N1QzrPBBb+dAiblSgm",
- "NfGRlulQ2fHV2UqGKdDiBAyStwKHB6OLkVCyWVLli5dhjTd/lkfJAH9gYYV95XTOg4i1oJBbUyzH89z+",
- "OR1ol66ojq+k48vnhKrliFI4RsLHIPnYdgiOAlABJSzswu3LnlDaIg/tBhk4fpzPS8aBZLHgt8AMGlwz",
- "bg4w8vFDQqwFnoweIUbGAdjoXseByQ8iPJt8cQyQ3BWpoH5sdMwHf0M8fcyGgxuRR1SGhbOEVyv3HIC6",
- "iMnm/urF7eIwhPEpMWxuTUvD5pzG1w4yqOqCYmuvhosL8HiQEmf3OEDsxXLUmuxVdJPVhDKTBzou0O2B",
- "eCa2mc0fjUq8s+3M0Hs0Qh6zWWMH09bPuafITGwxaAivFhuRfQCWNBwejEDD3zKF9IrfpW5zC8y+afdL",
- "UzEqVEgyzpzXkEtKnBgzdUKCSZHL/aAkzo0A6Bk72vrSTvk9qKR2xZPhZd7eatO21JtPPood/9QRiu5S",
- "An9DK0xTxOZNX2KJ2im6sS/d+j2BCBkjesMmhk6aoStIQQmoFGQdISq7jnlOjW4DeONc+M8C4wVWCaJ8",
- "9yAIqJKwYEpDa0T3cRKfwzxJsTihEPP06nQl52Z9b4VorinrRsQPO8v85CvAiOQ5k0pn6IGILsG89I1C",
- "pfob82pcVuqGbNlSvqyI8wac9hp2WcHKOk6vbt7vXplpf2hYoqpnyG8ZtwErMyw9HQ3k3DO1jfXdu+DX",
- "dsGv6Z2td9xpMK+aiaUhl+4c/yLnosd597GDCAHGiGO4a0mU7mGQQQLukDsGclPg4z/ZZ30dHKbCj30w",
- "asenAafuKDtSdC2BwWDvKhi6iYxYwnRQuXmYGZs4A7SqWLHt2ULtqEmNmR5l8PD17npYwN11gx3AQDcu",
- "Lxrm3KkV6KL/nM3nFAXkUyPC2XBAF+sGErUcmxNa1BKNap1gu2FhykawG7n2736+0ELSBTjDaGZButUQ",
- "uJxj0BCUfVREM+vhLNh8DqFBUN3EmNUBrm/2iTZ3GEFkcathzbj+4lmMjA5QTwvjYZTFKSZCCyk30eXQ",
- "8OrFqkDvbDqXBFtzA+tpNIP0O9hlPxsNhVSUSdVGjDlLaJf/HbHr69V3sMORDwZiGcAO7AqqqW8BaTBm",
- "Fmwe2cSJRgUKa5hi0YfOFh6xU2fxXbqjrXFVZ9PE34Zld6qydpdym4PR+u0MLGN24yLuLjOnB7qI75Py",
- "oU1gCWNcSI6ByBVOxZTv0TO8ipr06EO0ewm09MSLy5l8nE5u55yK3WZuxAO4ftNcoFE8Y/CTdVZ0fM1H",
- "opxWlRRrWmbOhZe6/KVYu8sfX/cev08sTMYp+/Lrs9dvHPgfp5O8BCqzRhlLrgrfq/5lVmXr1O6/SlBi",
- "8VYRq6wHm98U1wzdfpsluGYKgb4/qPrcunSDo+jcgPN4DOZB3ue8z3aJe7zQUDVO6NZBYn3QXb8zXVNW",
- "es+EhzYRL4mLG1c6PMoVwgFu7b8OwhCyO2U3g9MdPx0tdR3gSTjXj1gtLa5xcFdLDVmR80fTO5eevhGy",
- "w/xdskzUn/3HiVVGyLZ4TIQP+gY9fWHqhFjB69fFr+Y0PnwYHrWHD6fk19I9CADE32fud9QvHj6Muhqi",
- "lgTDJNBQwOkKHjSBv8mN+LRmJw6bcRf02XrVSJYiTYYNhVrHtEf3xmFvI5nDZ+F+KaAE89Ph3Lreplt0",
- "h8CMOUEXqeSYJu5pZXsCKSJ4P8wP87IMaSGzX1Gsem49N8MjxOsVejsyVbI87gfmM2XYK7fxPeZlgi8n",
- "DGZmxJolwsV4zYKxzGtjyvj1gAzmiCJTRSsJtribCXe8a85+q4Gwwmg1cwYS77XeVeeVAxx1IJAa1XM4",
- "lxvYRhG0w9/GDhJW/O/LjAjEfiNIGE00APdVY9b3C228Zq3OdGxQYjjjgHHvCSh09OGo2SZYLLtRQeP0",
- "mDG9IT2jc60HEnNEez0ylc2l+B3itmg04Udys32PA4aRuL9DqJ6FHc46LKXxQLUtK9vZD233eN04tfG3",
- "1oX9opu2Cje5TOOn+riNvInSq+IVRB2SU0pY6I7sRqsmWAseryA+Cyva+1AFyu15sonJnaSH+KkM04tO",
- "7fjtqXQwD1KySrqZ0Vi5f6MLGZiC7e0EVWhB/Md+A1STdmtnJ0FQYfMus8WNKpBtbYphocQb6jV22tEa",
- "TavAIEWFqsvUBoKVSkSGqfmGctsm0Xxn+ZX7WoH1gpqvNkJiaTIVj/8oIGerqDn26updkQ99/QVbMNsB",
- "sFYQtJhzA9nuqpaKXJu+JpncoeZ8Th5Ngz6XbjcKtmaKzUrANx7bN2ZU4XXZeCSbT8zygOulwtefjHh9",
- "WfNCQqGXyiJWCdLonijkNVFMM9AbAE4e4XuPvyT3MX5LsTU8MFh0QtDkxeMv0ftu/3gUu2VdB8d9LLtA",
- "nv13x7PjdIwBbHYMwyTdqCfRKk62hXP6dthzmuynY84SvukulMNnaUU5XUA8ZHh1ACb7Le4melR7eOHW",
- "GwBKS7EjTMfnB00Nf0qkIRr2Z8EguVitmF65KB8lVoae2v5xdlI/nG1m6lp/eLj8QwyWq3ysUM/W9YnV",
- "GLpKpBFgSOMPdAVdtE4JtfXoStaGsfqGROTcl7vEXihNCxSLGzOXWTrKkhjVOieVZFyj/aPW8+wvRi2W",
- "NDfs7yQFbjb74lmkp0i37D4/DvBPjncJCuQ6jnqZIHsvs7hvyX0ueLYyHKV40Kb9BqcyGdUXj99KBZHt",
- "H3qs5GtGyZLkVnfIjQac+laEx/cMeEtSbNZzFD0evbJPTpm1jJMHrc0O/fT2tZMyVkLGali3x91JHBK0",
- "ZLDGJI74Jpkxb7kXshy1C7eB/vOGoHiRMxDL/FmOKgKBR3Nf/qaR4n/+vi3Gi45VmxzTswEKGbF2Orvd",
- "Jw74Os7q1vff2pgdfJbA3Gi02U7vA6wkQnVtLG7zzSdO542ae+2edwyOj38l0ujgKMc/fIhAP3w4dWLw",
- "r0+6jy17f/gwXhMzanIzv7ZYuI1GjN/G9vArETGA+QZUTUCRS9mNGCBTl5R5YJjgzA01Jd1mP59eirib",
- "ZJB4wF/8FFxdvcMnHg/4Rx8Rn5lZ4ga2Ic3pw95tdhYlmaJ5HoQaU/KV2I4lnN4d5InnnwBFCZSMNM/h",
- "SgbN3KLu+oPxIgGNmlFnUAqjZIZ9KkJ7/r8Ons3ip3uwXbOy+LktN9S7SCTl+TIaqDkzH/7SNl1vlmhZ",
- "ZbT0/ZJyDmV0OKvb/uJ14IiW/g8xdp4V4yPf7TcTtMvtLa4FvAumB8pPaNDLdGkmCLHareTSZAqXC1EQ",
- "nKets94yx2FXzqBV2G81KB07GvjAZiuhs8swX9upigAv0Pp1Qr7FmgoGlk4RXbQ6+fKE3VJddVUKWkyx",
- "bOLl12eviZ3VfmNbB9tOWQs0unRXEbWSjy9d1nQBjufkjx9nf5KwWbXSWdPYKlb1yLzRtt5ivdAJNMeE",
- "2Dkhr6wlTHk7i52EYPFNuYIi6KNldTGkCfMfrWm+RBNT5yJLk/z4Fm+eKlsDfNAvuumrgOfOwO26vNkm",
- "b1Mi9BLkhinALExYQ7fQUlN1zJk4feGl7vJkzbmllJMjZIqmi8KxaPfAWYHE+4ajkPUQf6SBwXZIPLbj",
- "3QV+FS3z3G+f13Pe+rI9TR/g752NOKdccJZjkeWYQIRFYcZ5m0bUo467idTEndDI4Yo27WvyvxwWk238",
- "PCN0iBt6boOnZlMtddg/NWxdM5cFaOU4GxRT33vS+TUYV+D6ZBgiCvmkkJHYlGg8e+MHP5KMsN5DwlD1",
- "jXn2gzNjYiL0NeNosHBoc2K29TyUiqGDkROmyUKAcuvpFr1S78w3J1j/qYDt+5PXYsHyC7bAMWw0lFm2",
- "Df0bDnXmAwFd4J1596V511XlbX7uRPXYSc+qyk2a7kwab8e85UkEx8JPfDxAgNxm/HC0PeS2N4IX71ND",
- "aLDG4COo8B4eEEbTpbPXEtuoCJai8A1ic5OipfkYj4DxmnHvCYtfEHn0SsCNwfOa+E7lkmorAo7iaZdA",
- "y0QcO+b6WVfqbYfq1yQ2KME1+jnS29g2GE0wjuaFVnCjfEf8oTDUHQgTL2nZRMBG2oWiVOWEqAJzRHoN",
- "RGOMwzBu36K4ewEc6Eo+bT/HOt/H3kSp6kezuliAzmhRxNqWfIVPCT71uT6whbxu2ltUFcmx2Ge3+umQ",
- "2txEueCqXu2Zy79wy+mCjrwRagi7AvsdxuoKsx3+e0y/+Cb29ej8Nh/oWhxX8neYrxeTeg1NZ4otsvGY",
- "wDvl9uhop74Zobff3ymll2LRBeRzGEkTXC7coxh/+9pcHGFJwEGYsb1amop9GNIr8LkvctHUmupyJbzK",
- "Bh1M0Hnd9Gnfb4ZId1yf4uWXyCkNTd72frVm4FRmaZ5MhKbalWTRlOxlQckyFzbks2dEH3qCUmGeNsrz",
- "7ozPbq17EZp2wXzXcbjYUJ+WWSQdLTfzhbQbfKwz5Lt1KtnYVwDH5/2OzNfg6rRVEtZM1D6IxoeyepXQ",
- "/trpb9yke0fXHw0Q/9zG56Sp/NJ1xrPLdDr5dz9bZxoBruXun8BwPtj0Qa/nobRrzVPtK6RpqjSqyVLn",
- "VhxTHT9WiN3Jhp1u0wd6ZQ/I6tUYcWDY+3o6OS+OujBjxfwndpTYsYt3sk7XOm7rG+MRq4RibW+zWIvr",
- "kTHjl9ilOqjVPBzLxxKuIdfY0K6NkZIAx1RuNpN52/2fNY/T6nQTWu9KHe+rbzzsYnfgjh+UIAnK6NgO",
- "YCfjq/meNZGwNpFnQxXWvpdo4+6mvo5OwJvPIddsfaDky9+XwINyIlNvl0FY5kEFGNako2DF0OOtji1A",
- "+yqy7IUnqNx/a3BS6cjXsLunSIcaoi3JmlysmxSLRAwgd8gMiQgVizSzhmQX/MNUQxmIBR/ZaT+Htux2",
- "sptxUMDohnN5kjQXR1vUaM+U8Xaqo+Yynx5V6gszK1JVYYbdGNP6xytsfqlcnBNtik2GWjo5H5bk37hi",
- "lVigp/Gd+LKVoPxvvhqXnaVk1xD2W0ZP1YbKwr8RNb14q0625z4alHLxnQT7QM+bmVkbhz/0VUeKPGNK",
- "S14KI0Zkqbygbuh7Ezd2T9kAv7YOC8I1B+n60qP8WwoFmRY+bn8fHPtQYaMYb4QElWysYIFLljt929Zz",
- "xQYzFMubUhe8GC6QSFhRA50Mqq6m59yH7Jf2uc+l9g1GDlqYGno93OnOZ2AwNUBiSPVz4m7LwznaNzE2",
- "Mc5BZt7z1C/BykF2vSGVFEWd2ws6PBiNQW50CZQ9rCRqp8mHq+zpCEGu8zXsTq0S5FsE+h0MgbaSkwU9",
- "KN3X2+Q7Nb+pGNyLOwHvc1quppNKiDJLODvOh3Vj+xR/zfJrKIi5KXykcqL7K7mPNvbGm71Z7nyd1KoC",
- "DsWDE0LOuM0N8Y7tbuOi3uT8nt43/xZnLWpbytkZ1U6ueDzIHossy1tyMz/Mfh6mwLC6W05lBzlQlXSb",
- "qFkr6SbSC/lkrFY+dDX3+9O2RGWhiMkkF9Zj9RIPesxwhJnsQckFdGRS4jxdRJUiFpJ5k2x7M1QcU+Fk",
- "CJAGPibpu4HCDR5FQLTjauQU2gpmrnaZmBMJrRP5pkXchs1hYxp9f+Zmli6/mwsJnTav5mshCy/yMNX2",
- "Y6ZyxrSkcneTUmuD5rQD60kSywfDsZpIrHYhbTTWEIdlKTYZMqusqW0eU23Ne6p7Gft2Lu135lTPIIjr",
- "osoJajuypAXJhZSQh1/E0/YsVCshISsFhnnFPNBzbeTuFebqcFKKBRFVLgqwPQLiFJSaq+acotgEQVRN",
- "FAWWdjDp034T0PHIKe+qM7ItzmMXnVlfZiLwFJQrxuMwZF8ewrunq/BR1fnP52gRYhjr0s29ttJn2FsZ",
- "jmytzMrSGwxS3ZXJT6rGcCRMvDFTPCMrobTT7OxIqhmqDfG6nwuupSjLrhHIisQLZ9n+nm7P8ly/FuJ6",
- "RvPrB6hHcqGblRZTn5baD8ZrZ5K9ikwj20BfLiN2XpzFn7qjez07znF0i9YAzPeHOdZhG/dZrJV1d139",
- "3uw8UTtTixXL4zT8rxXdloxJi7GEaKkn2yXJJufja8iow8uhCWZAljREM3BDsLH9cjzNOXWReZj/osTb",
- "H5fMwV0SiYtpyCed1JLlSdmqBwBCajNGdS1ta6VQ8mm4iljYDHN0SfcBHcnFMfLndrCZEe4cKA23AmoQ",
- "bdgAeN8q+1NbkstGLs7E1j9/0NbsuhHwH/dTeawdfeQUN6TluuX7+h4JjhCvDLw3/ggbh/sb9HAUUtMG",
- "b+SNGgCQjkvqwDAqOulYMOaUlVBkVCcud7QJTQPN1mW09JubMuU4eU7thb0EYsauJbh6E1ak7jVDr6gh",
- "JdG8PrTc8gK2oLAYhO3oTJX1M3h/B5S2rVRP+RZVVsIaOuFarghGjaIdW4P/VjUfkwKgQu9f3yYVi0MK",
- "7/KeocKtPQsiWcZgN2q5sIi1O0UOmCWiRpQtz+wxUWOPkoFozYqadvCnjhU5umY3c5QjqBrI5JnX28ZO",
- "85Md4a0f4Mx/HxNlPCbej+NDR7OgOOr2MaCDcYm1Sp16Hg9LDCu8NA4NnK1oHJ+WxFu+oSq64WkD4JDk",
- "W/Vm5D4xwQPEfr2FHKWabtzd7XFCcDCietWbkiK4bHb45obkz0LDe0k4OV5M1VCADHavpcbThRPY8QVs",
- "Z8mN2GukZmwh5fi/439T7MBvBzJ6te1oFWpwr8B77LCgdOOscAItay40H184dfUE+0o5CyKrV3RHhMR/",
- "jL72W01LNt/hCbXg+8+IWlJDQs5FaH3XLl7RTLxfMJl6wLxdQPip7LrZ2DGD4XZmlABocwU64xRWBrqG",
- "cBvQLW85T64Ny1H1bMWUwsuut51DLLjF+5oQK1qEOjJWpuu2EvW1Ss3X/3+btRVO5QtKVSXNff8yIIqu",
- "egZx26PQE5dewmp/Wt9QPfYk0PQ9bIlW+nTe4gbGvSMjN2Kx8ql+Dx2wB/3gBq0ubrWMYxoUt5nRexIi",
- "Ry3lrndhbHzIAGh0MvuqXgfAt9UYfQWwT4H/aNHI1DLGgP/PgvdEG70QXtsx7xNguZPyH4HV2lVnYptJ",
- "mKtDoRDWsGoUYdkWC/DGScZzCVTZ2JDzH53K1tZEZNyokDZ6sfG+NaMUMGe8ZZaMV7WOaABYGpHvAoSF",
- "5mlEa8LZk5ISjBi2puWPa5CSFamNM6fDtvEKa9J7k7z7NqL8N3fqcACmWu0HMwmhzVQLXjMXuO16YwML",
- "laa8oLIIX2ec5CDNvU82dKdu7vsw0MrayBcHvB80kGa6+e2BHwRJ2wJS7pz78paeiQZAeocuihGuBYxg",
- "jbgVrFFEi4QnYQhDvKwC3WalWGB+WYIAXfFJ9P1YZUVwNNhaeei4eRT7HfZPg3W33cHXAmcdM8X+c/Yj",
- "og4Vnp8403tPmrWm9RP+bESmPQie/vmiDQu3mzOk/1iO5iUmMXTyNPtN5/1e2/AQOx8kPBldC25iF9FB",
- "7hJ8Q3Pt+H5GXR98LBPU6rAZ6rZqT+A3qDbImeYucGdo9BkoxRYpU5dHe6RNyFqS/T2QAM92qnVnqztt",
- "E0xhxjmmCdT+zNmsElWWj4kGtKX5C2fQdpB2YUzQR2CuTqy7CZxQTbOKTmGTTteKY/tgJbtmHPLLVPk+",
- "JTtl0Ehw0K6xXMyRl+ERtmYczPFojBfTfvZR12DTMAlCiYS8lmjQ3NDd4b5CiZKwF387e/74yS9Pnn9B",
- "zAukYAtQbVnhXl+eNmKM8b6d5dPGiA2Wp+Ob4PPSLeK8p8yn2zSb4s6a5baqrRk46Ep0jCU0cgFEjmOk",
- "H8yN9grHaYO+/7m2K7bIO9+xGAr++D2ToizjZd0b0S1i6o/tVmDsNxJ/BVIxpQ0j7PrqmG5jZdUSzXFY",
- "3HNt64wInrvq6w0VMJ0IxoktJBVqifwMs36df4PAtiodr7I+iX3rcnqRtYhhcAbGb8yAVKJyojSbkxhE",
- "mFsig5xLZ2jE8M4gerJhtjaOMkaILiY5Tnpn3GmeYk72c/tut0Yd5/RmEyPihT+UNyDNlCU9ndF+E07S",
- "mtL/afhHJEX/zrhGs9w/gldE9YObNT4eBdowXTtCHghAIg+zk0EX9kVvK41Ka5VH+713dfbFj+9bF+jB",
- "hAGExH9wALwwsbJ9r4lxd+B85pKd3zdICZbyPkUJneUfytX0rLe5SIItckYKrUFZtiSGYmGQiKteNvmt",
- "Ca1kkAaLTdCNZlqWkfRZazfBMxUSjlEJ5JqWn55rYHf8M8QHFG/TSTNhDmWIZItKdbMKbq/pqLmDfMm7",
- "m5q/wZTdv4PZo+g954Zy7uLBbYZWL2xJvfC3gs0CJhsc04YDPf6CzFw1/UpCzlTfDb3xwkmTMgiSzV3o",
- "JWz1gRzFQ+v8WehbkPHcx4yQHwJ3kkCzXQthe0Q/M1NJnNwolceob0AWEfzFeFTYffPAdXHLyus3KwgS",
- "lPY6siDIsK/o2OXZohfm0qkVDNc5+rbu4DZyUbdrG1vNZnQB96urd3o2pghNvNi6+Ryr4NxJ1fWjaq7/",
- "AfVvLI7cGG7eGMX8nKqIaqt+Jorv9vajZuXBAJFOKeWP08kCOCimsFjwL645xKe9Sz0ENid/eFQtrLcp",
- "JGIRE1lrZ/JgqqBI8oj6yO6zSDVkzHfLa8n0DhuDegMa+yVaqefbpuqDqxrS+K7c3afFNTTNmdsaEbXy",
- "t+u3gpZ4H1mXGje3kChPyNdbuqpKZw4mf703+w94+pdnxaOnj/9j9pdHzx/l8Oz5l48e0S+f0cdfPn0M",
- "T/7y/NkjeDz/4svZk+LJsyezZ0+effH8y/zps8ezZ198+R/3DB8yIFtAfe3uF5P/nZ2VC5GdvTnPLg2w",
- "LU5oxb4DszeoK88FNq4zSM3xJMKKsnLywv/0v/wJO8nFqh3e/zpxDVgmS60r9eL0dLPZnISfnC4wKTzT",
- "os6Xp34ebCfWkVfenDfR5DbuBXe0tR7jpjpSOMNnb7++uCRnb85PWoKZvJg8Onl08tj1ruW0YpMXk6f4",
- "E56eJe77qSO2yYsPH6eT0yXQEmuomD9WoCXL/SMJtNi5/6sNXSxAnmDCgP1p/eTUixWnH1xy/Md9z07D",
- "kIrTD50aAsWBLzEc4PSD72C5/+1O90IXiRV8MBKKfa+dzrBrxdhXQQUvp5eCyoY6/YDicvL3U2fziD9E",
- "tcWeh1NfaCP+ZgdLH/TWwHrgiy0rgpXkVOfLujr9gP9B6g2AtkUYT/WWn6Ln9PRDZ63u8WCt3d/bz8M3",
- "1itRgAdOzOe2s+e+x6cf7L/BRLCtQDIjFmLhE/erLVB1ig2edsOfdzyP/jhcR6c4jzl3US/0W1sRnpKS",
- "KR9O0K3po8Lmz+cF8mfdLxRkXvKhhHjInzx65Dmb0xsCqjx1h3jStoIfV3agX55oeOMNWdu+lX2cTp4d",
- "Cehe21CnqGMEmK9oQXwOKs79+NPNfc5tWKPh9fZOQgiefToIOttHvoMd+UFo8g0qTx+nk+efcifOuRHl",
- "aEnwzaDB5vCI/MSvudhw/6YRZurVisrd6OOj6UKh31OyNXWiZPMaX0zeYw0Gm5fcPWpnRTEgeivUgdJf",
- "CbwdUxhbqUXl3CYt0lqZlnGzhKFSPEDVpe0z26v0ZevReOc5FwVMQmlTyxo+3pIn9AIuqNTnERsPGisx",
- "0nnuW+IGoEbLVvXd0XbkoT5yiITbrs1tgPCfPOVPntLwlOePnn666S9ArlkO5BJWlZBUsnJHfuJN5PmN",
- "edxZUURr/XWP/kEeN51ss1wUsACeOQaWzUSx853pOxNcg1VfB4LMqVf3OhJ/gnt6RTImrbTxkJMX72J+",
- "StdGtapnJcuJNXWhrmcUmUAVa4qvdZnfNNjWAfuJFPglBSvrJhFYb4RLtBteKOR+mB6vfrMd1vEgMr0j",
- "G8YLscH20gjubzUgn3fw+mkmEQCDoLthL4vWgm8AHICVmg9N/2Ows2fy1/Rmc5f02Knf3/LKOniZNsWN",
- "/uvixx+CdBybQmw99JgMYkkXI3elwIjUDcUQLamhOCEvreml3BEu0Mhfq067nZM/76E/ef/tef+3TbVL",
- "22hHYweNIUsK7oKTUQJvlLd/6PzpTBMTGx8Zq1FpfieULLBJ2vCCmu3I+auB9mo/618JX+3w1d6tEOH3",
- "fRCPYvwJ9rJPpDELWQjdRInaRf0pZP4pZN5KcR19eMborlHLkm1dSAf62NR3IYz106Z6CMoY+9NnPb53",
- "svFD21bMlmXr4UJBggc2PbuP5j9ZxJ8s4nYs4luIHEY8tY5pRIjuOFvXWIaBVTiKTsyTlzr863VJZZAR",
- "d8iEfYYjxlXBP4RrfGqDXRRX1l6HgbzMRrBFNvBubXh/srw/Wd6/Dss7O8xouoLJra1e17Bb0aqxdall",
- "rQuxCTzcCIuNPh36+Kzi3//7dEOZzuZCuu4KdK5BDj/WQMtT10q192vbvWzwBFuyBT+GdYyiv57SrtOy",
- "6xs3rDf14cBxHnvqHMeJl3wSsX/cBtGEQSnI9ptwlHfvDctWINf+RmhjLF6cnmJViaVQ+nTycfqhF38R",
- "PnzfkMeH5h5xZPIR6UJItmCclpmLbWj7QU+enDyafPx/AQAA//+o0sPPZwkBAA==",
+ "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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 0938833520..c4e4a8de10 100644
--- a/daemon/algod/api/server/v2/generated/participating/public/routes.go
+++ b/daemon/algod/api/server/v2/generated/participating/public/routes.go
@@ -255,146 +255,146 @@ var swaggerSpec = []string{
"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",
- "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",
- "/G1EEgEA",
+ "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",
}
// GetSwagger returns the content of the embedded swagger specification file
diff --git a/daemon/algod/api/server/v2/handlers.go b/daemon/algod/api/server/v2/handlers.go
index 69201ca848..5663f429ba 100644
--- a/daemon/algod/api/server/v2/handlers.go
+++ b/daemon/algod/api/server/v2/handlers.go
@@ -525,6 +525,7 @@ func (v2 *Handlers) basicAccountInformation(ctx echo.Context, addr basics.Addres
Status: record.Status.String(),
RewardBase: &record.RewardsBase,
Participation: apiParticipation,
+ IncentiveEligible: omitEmpty(record.IncentiveEligible),
TotalCreatedAssets: record.TotalAssetParams,
TotalCreatedApps: record.TotalAppParams,
TotalAssetsOptedIn: record.TotalAssets,
@@ -1401,10 +1402,7 @@ func (v2 *Handlers) getPendingTransactions(ctx echo.Context, max *uint64, format
}
// MatchAddress uses this to check FeeSink, we don't care about that here.
- spec := transactions.SpecialAddresses{
- FeeSink: basics.Address{},
- RewardsPool: basics.Address{},
- }
+ spec := transactions.SpecialAddresses{}
txnLimit := uint64(math.MaxUint64)
if max != nil && *max != 0 {
diff --git a/data/basics/fraction.go b/data/basics/fraction.go
new file mode 100644
index 0000000000..8a643f2520
--- /dev/null
+++ b/data/basics/fraction.go
@@ -0,0 +1,69 @@
+// Copyright (C) 2019-2024 Algorand, Inc.
+// This file is part of go-algorand
+//
+// go-algorand is free software: you can redistribute it and/or modify
+// 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..bc6a639c29
--- /dev/null
+++ b/data/basics/fraction_test.go
@@ -0,0 +1,76 @@
+// Copyright (C) 2019-2024 Algorand, Inc.
+// This file is part of go-algorand
+//
+// go-algorand is free software: you can redistribute it and/or modify
+// 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..f51e6e503b 100644
--- a/data/basics/msgp_gen.go
+++ b/data/basics/msgp_gen.go
@@ -250,8 +250,8 @@ import (
func (z *AccountData) MarshalMsg(b []byte) (o []byte) {
o = msgp.Require(b, z.Msgsize())
// omitempty: check for empty values
- zb0009Len := uint32(19)
- var zb0009Mask uint32 /* 20 bits */
+ zb0009Len := uint32(20)
+ var zb0009Mask uint32 /* 21 bits */
if (*z).MicroAlgos.MsgIsZero() {
zb0009Len--
zb0009Mask |= 0x2
@@ -280,54 +280,58 @@ func (z *AccountData) MarshalMsg(b []byte) (o []byte) {
zb0009Len--
zb0009Mask |= 0x80
}
- if (*z).Status == 0 {
+ if (*z).IncentiveEligible == false {
zb0009Len--
zb0009Mask |= 0x100
}
- if (*z).SelectionID.MsgIsZero() {
+ if (*z).Status == 0 {
zb0009Len--
zb0009Mask |= 0x200
}
- if (*z).AuthAddr.MsgIsZero() {
+ if (*z).SelectionID.MsgIsZero() {
zb0009Len--
zb0009Mask |= 0x400
}
- if (*z).StateProofID.MsgIsZero() {
+ if (*z).AuthAddr.MsgIsZero() {
zb0009Len--
zb0009Mask |= 0x800
}
- if (*z).TotalBoxes == 0 {
+ if (*z).StateProofID.MsgIsZero() {
zb0009Len--
zb0009Mask |= 0x1000
}
- if (*z).TotalBoxBytes == 0 {
+ if (*z).TotalBoxes == 0 {
zb0009Len--
zb0009Mask |= 0x2000
}
- if (*z).TotalExtraAppPages == 0 {
+ if (*z).TotalBoxBytes == 0 {
zb0009Len--
zb0009Mask |= 0x4000
}
- if ((*z).TotalAppSchema.NumUint == 0) && ((*z).TotalAppSchema.NumByteSlice == 0) {
+ if (*z).TotalExtraAppPages == 0 {
zb0009Len--
zb0009Mask |= 0x8000
}
- if (*z).VoteID.MsgIsZero() {
+ if ((*z).TotalAppSchema.NumUint == 0) && ((*z).TotalAppSchema.NumByteSlice == 0) {
zb0009Len--
zb0009Mask |= 0x10000
}
- if (*z).VoteFirstValid == 0 {
+ if (*z).VoteID.MsgIsZero() {
zb0009Len--
zb0009Mask |= 0x20000
}
- if (*z).VoteKeyDilution == 0 {
+ if (*z).VoteFirstValid == 0 {
zb0009Len--
zb0009Mask |= 0x40000
}
- if (*z).VoteLastValid == 0 {
+ if (*z).VoteKeyDilution == 0 {
zb0009Len--
zb0009Mask |= 0x80000
}
+ if (*z).VoteLastValid == 0 {
+ zb0009Len--
+ zb0009Mask |= 0x100000
+ }
// variable map header, size zb0009Len
o = msgp.AppendMapHeader(o, zb0009Len)
if zb0009Len != 0 {
@@ -451,41 +455,46 @@ func (z *AccountData) MarshalMsg(b []byte) (o []byte) {
o = (*z).RewardedMicroAlgos.MarshalMsg(o)
}
if (zb0009Mask & 0x100) == 0 { // if not empty
+ // string "ie"
+ o = append(o, 0xa2, 0x69, 0x65)
+ o = msgp.AppendBool(o, (*z).IncentiveEligible)
+ }
+ if (zb0009Mask & 0x200) == 0 { // if not empty
// string "onl"
o = append(o, 0xa3, 0x6f, 0x6e, 0x6c)
o = msgp.AppendByte(o, byte((*z).Status))
}
- if (zb0009Mask & 0x200) == 0 { // if not empty
+ if (zb0009Mask & 0x400) == 0 { // if not empty
// string "sel"
o = append(o, 0xa3, 0x73, 0x65, 0x6c)
o = (*z).SelectionID.MarshalMsg(o)
}
- if (zb0009Mask & 0x400) == 0 { // if not empty
+ if (zb0009Mask & 0x800) == 0 { // if not empty
// string "spend"
o = append(o, 0xa5, 0x73, 0x70, 0x65, 0x6e, 0x64)
o = (*z).AuthAddr.MarshalMsg(o)
}
- if (zb0009Mask & 0x800) == 0 { // if not empty
+ if (zb0009Mask & 0x1000) == 0 { // if not empty
// string "stprf"
o = append(o, 0xa5, 0x73, 0x74, 0x70, 0x72, 0x66)
o = (*z).StateProofID.MarshalMsg(o)
}
- if (zb0009Mask & 0x1000) == 0 { // if not empty
+ if (zb0009Mask & 0x2000) == 0 { // if not empty
// string "tbx"
o = append(o, 0xa3, 0x74, 0x62, 0x78)
o = msgp.AppendUint64(o, (*z).TotalBoxes)
}
- if (zb0009Mask & 0x2000) == 0 { // if not empty
+ if (zb0009Mask & 0x4000) == 0 { // if not empty
// string "tbxb"
o = append(o, 0xa4, 0x74, 0x62, 0x78, 0x62)
o = msgp.AppendUint64(o, (*z).TotalBoxBytes)
}
- if (zb0009Mask & 0x4000) == 0 { // if not empty
+ if (zb0009Mask & 0x8000) == 0 { // if not empty
// string "teap"
o = append(o, 0xa4, 0x74, 0x65, 0x61, 0x70)
o = msgp.AppendUint32(o, (*z).TotalExtraAppPages)
}
- if (zb0009Mask & 0x8000) == 0 { // if not empty
+ if (zb0009Mask & 0x10000) == 0 { // if not empty
// string "tsch"
o = append(o, 0xa4, 0x74, 0x73, 0x63, 0x68)
// omitempty: check for empty values
@@ -512,22 +521,22 @@ func (z *AccountData) MarshalMsg(b []byte) (o []byte) {
o = msgp.AppendUint64(o, (*z).TotalAppSchema.NumUint)
}
}
- if (zb0009Mask & 0x10000) == 0 { // if not empty
+ if (zb0009Mask & 0x20000) == 0 { // if not empty
// string "vote"
o = append(o, 0xa4, 0x76, 0x6f, 0x74, 0x65)
o = (*z).VoteID.MarshalMsg(o)
}
- if (zb0009Mask & 0x20000) == 0 { // if not empty
+ if (zb0009Mask & 0x40000) == 0 { // if not empty
// string "voteFst"
o = append(o, 0xa7, 0x76, 0x6f, 0x74, 0x65, 0x46, 0x73, 0x74)
o = msgp.AppendUint64(o, uint64((*z).VoteFirstValid))
}
- if (zb0009Mask & 0x40000) == 0 { // if not empty
+ if (zb0009Mask & 0x80000) == 0 { // if not empty
// string "voteKD"
o = append(o, 0xa6, 0x76, 0x6f, 0x74, 0x65, 0x4b, 0x44)
o = msgp.AppendUint64(o, (*z).VoteKeyDilution)
}
- if (zb0009Mask & 0x80000) == 0 { // if not empty
+ if (zb0009Mask & 0x100000) == 0 { // if not empty
// string "voteLst"
o = append(o, 0xa7, 0x76, 0x6f, 0x74, 0x65, 0x4c, 0x73, 0x74)
o = msgp.AppendUint64(o, uint64((*z).VoteLastValid))
@@ -795,6 +804,14 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
return
}
}
+ if zb0009 > 0 {
+ zb0009--
+ (*z).IncentiveEligible, bts, err = msgp.ReadBoolBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "IncentiveEligible")
+ return
+ }
+ }
if zb0009 > 0 {
zb0009--
var zb0020 int
@@ -1196,6 +1213,12 @@ func (z *AccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
err = msgp.WrapError(err, "AuthAddr")
return
}
+ case "ie":
+ (*z).IncentiveEligible, bts, err = msgp.ReadBoolBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "IncentiveEligible")
+ return
+ }
case "appl":
var zb0035 int
var zb0036 bool
@@ -1391,7 +1414,7 @@ func (z *AccountData) Msgsize() (s int) {
s += 0 + zb0003.Msgsize() + 1 + 2 + msgp.Uint64Size + 2 + msgp.BoolSize
}
}
- s += 6 + (*z).AuthAddr.Msgsize() + 5 + msgp.MapHeaderSize
+ s += 6 + (*z).AuthAddr.Msgsize() + 3 + msgp.BoolSize + 5 + msgp.MapHeaderSize
if (*z).AppLocalStates != nil {
for zb0005, zb0006 := range (*z).AppLocalStates {
_ = zb0005
@@ -1413,7 +1436,7 @@ func (z *AccountData) Msgsize() (s int) {
// MsgIsZero returns whether this is a zero value
func (z *AccountData) MsgIsZero() bool {
- return ((*z).Status == 0) && ((*z).MicroAlgos.MsgIsZero()) && ((*z).RewardsBase == 0) && ((*z).RewardedMicroAlgos.MsgIsZero()) && ((*z).VoteID.MsgIsZero()) && ((*z).SelectionID.MsgIsZero()) && ((*z).StateProofID.MsgIsZero()) && ((*z).VoteFirstValid == 0) && ((*z).VoteLastValid == 0) && ((*z).VoteKeyDilution == 0) && (len((*z).AssetParams) == 0) && (len((*z).Assets) == 0) && ((*z).AuthAddr.MsgIsZero()) && (len((*z).AppLocalStates) == 0) && (len((*z).AppParams) == 0) && (((*z).TotalAppSchema.NumUint == 0) && ((*z).TotalAppSchema.NumByteSlice == 0)) && ((*z).TotalExtraAppPages == 0) && ((*z).TotalBoxes == 0) && ((*z).TotalBoxBytes == 0)
+ return ((*z).Status == 0) && ((*z).MicroAlgos.MsgIsZero()) && ((*z).RewardsBase == 0) && ((*z).RewardedMicroAlgos.MsgIsZero()) && ((*z).VoteID.MsgIsZero()) && ((*z).SelectionID.MsgIsZero()) && ((*z).StateProofID.MsgIsZero()) && ((*z).VoteFirstValid == 0) && ((*z).VoteLastValid == 0) && ((*z).VoteKeyDilution == 0) && (len((*z).AssetParams) == 0) && (len((*z).Assets) == 0) && ((*z).AuthAddr.MsgIsZero()) && ((*z).IncentiveEligible == false) && (len((*z).AppLocalStates) == 0) && (len((*z).AppParams) == 0) && (((*z).TotalAppSchema.NumUint == 0) && ((*z).TotalAppSchema.NumByteSlice == 0)) && ((*z).TotalExtraAppPages == 0) && ((*z).TotalBoxes == 0) && ((*z).TotalBoxBytes == 0)
}
// MaxSize returns a maximum valid message size for this message type
@@ -1431,7 +1454,7 @@ func AccountDataMaxSize() (s int) {
// Adding size of map values for z.Assets
s += encodedMaxAssetsPerAccount * (1)
s += 2 + msgp.Uint64Size + 2 + msgp.BoolSize
- s += 6 + AddressMaxSize() + 5
+ s += 6 + AddressMaxSize() + 3 + msgp.BoolSize + 5
s += msgp.MapHeaderSize
// Adding size of map keys for z.AppLocalStates
s += EncodedMaxAppLocalStates * (AppIndexMaxSize())
@@ -3199,8 +3222,8 @@ func AssetParamsMaxSize() (s int) {
func (z *BalanceRecord) MarshalMsg(b []byte) (o []byte) {
o = msgp.Require(b, z.Msgsize())
// omitempty: check for empty values
- zb0009Len := uint32(20)
- var zb0009Mask uint32 /* 22 bits */
+ zb0009Len := uint32(21)
+ var zb0009Mask uint32 /* 23 bits */
if (*z).Addr.MsgIsZero() {
zb0009Len--
zb0009Mask |= 0x4
@@ -3233,54 +3256,58 @@ func (z *BalanceRecord) MarshalMsg(b []byte) (o []byte) {
zb0009Len--
zb0009Mask |= 0x200
}
- if (*z).AccountData.Status == 0 {
+ if (*z).AccountData.IncentiveEligible == false {
zb0009Len--
zb0009Mask |= 0x400
}
- if (*z).AccountData.SelectionID.MsgIsZero() {
+ if (*z).AccountData.Status == 0 {
zb0009Len--
zb0009Mask |= 0x800
}
- if (*z).AccountData.AuthAddr.MsgIsZero() {
+ if (*z).AccountData.SelectionID.MsgIsZero() {
zb0009Len--
zb0009Mask |= 0x1000
}
- if (*z).AccountData.StateProofID.MsgIsZero() {
+ if (*z).AccountData.AuthAddr.MsgIsZero() {
zb0009Len--
zb0009Mask |= 0x2000
}
- if (*z).AccountData.TotalBoxes == 0 {
+ if (*z).AccountData.StateProofID.MsgIsZero() {
zb0009Len--
zb0009Mask |= 0x4000
}
- if (*z).AccountData.TotalBoxBytes == 0 {
+ if (*z).AccountData.TotalBoxes == 0 {
zb0009Len--
zb0009Mask |= 0x8000
}
- if (*z).AccountData.TotalExtraAppPages == 0 {
+ if (*z).AccountData.TotalBoxBytes == 0 {
zb0009Len--
zb0009Mask |= 0x10000
}
- if ((*z).AccountData.TotalAppSchema.NumUint == 0) && ((*z).AccountData.TotalAppSchema.NumByteSlice == 0) {
+ if (*z).AccountData.TotalExtraAppPages == 0 {
zb0009Len--
zb0009Mask |= 0x20000
}
- if (*z).AccountData.VoteID.MsgIsZero() {
+ if ((*z).AccountData.TotalAppSchema.NumUint == 0) && ((*z).AccountData.TotalAppSchema.NumByteSlice == 0) {
zb0009Len--
zb0009Mask |= 0x40000
}
- if (*z).AccountData.VoteFirstValid == 0 {
+ if (*z).AccountData.VoteID.MsgIsZero() {
zb0009Len--
zb0009Mask |= 0x80000
}
- if (*z).AccountData.VoteKeyDilution == 0 {
+ if (*z).AccountData.VoteFirstValid == 0 {
zb0009Len--
zb0009Mask |= 0x100000
}
- if (*z).AccountData.VoteLastValid == 0 {
+ if (*z).AccountData.VoteKeyDilution == 0 {
zb0009Len--
zb0009Mask |= 0x200000
}
+ if (*z).AccountData.VoteLastValid == 0 {
+ zb0009Len--
+ zb0009Mask |= 0x400000
+ }
// variable map header, size zb0009Len
o = msgp.AppendMapHeader(o, zb0009Len)
if zb0009Len != 0 {
@@ -3409,41 +3436,46 @@ func (z *BalanceRecord) MarshalMsg(b []byte) (o []byte) {
o = (*z).AccountData.RewardedMicroAlgos.MarshalMsg(o)
}
if (zb0009Mask & 0x400) == 0 { // if not empty
+ // string "ie"
+ o = append(o, 0xa2, 0x69, 0x65)
+ o = msgp.AppendBool(o, (*z).AccountData.IncentiveEligible)
+ }
+ if (zb0009Mask & 0x800) == 0 { // if not empty
// string "onl"
o = append(o, 0xa3, 0x6f, 0x6e, 0x6c)
o = msgp.AppendByte(o, byte((*z).AccountData.Status))
}
- if (zb0009Mask & 0x800) == 0 { // if not empty
+ if (zb0009Mask & 0x1000) == 0 { // if not empty
// string "sel"
o = append(o, 0xa3, 0x73, 0x65, 0x6c)
o = (*z).AccountData.SelectionID.MarshalMsg(o)
}
- if (zb0009Mask & 0x1000) == 0 { // if not empty
+ if (zb0009Mask & 0x2000) == 0 { // if not empty
// string "spend"
o = append(o, 0xa5, 0x73, 0x70, 0x65, 0x6e, 0x64)
o = (*z).AccountData.AuthAddr.MarshalMsg(o)
}
- if (zb0009Mask & 0x2000) == 0 { // if not empty
+ if (zb0009Mask & 0x4000) == 0 { // if not empty
// string "stprf"
o = append(o, 0xa5, 0x73, 0x74, 0x70, 0x72, 0x66)
o = (*z).AccountData.StateProofID.MarshalMsg(o)
}
- if (zb0009Mask & 0x4000) == 0 { // if not empty
+ if (zb0009Mask & 0x8000) == 0 { // if not empty
// string "tbx"
o = append(o, 0xa3, 0x74, 0x62, 0x78)
o = msgp.AppendUint64(o, (*z).AccountData.TotalBoxes)
}
- if (zb0009Mask & 0x8000) == 0 { // if not empty
+ if (zb0009Mask & 0x10000) == 0 { // if not empty
// string "tbxb"
o = append(o, 0xa4, 0x74, 0x62, 0x78, 0x62)
o = msgp.AppendUint64(o, (*z).AccountData.TotalBoxBytes)
}
- if (zb0009Mask & 0x10000) == 0 { // if not empty
+ if (zb0009Mask & 0x20000) == 0 { // if not empty
// string "teap"
o = append(o, 0xa4, 0x74, 0x65, 0x61, 0x70)
o = msgp.AppendUint32(o, (*z).AccountData.TotalExtraAppPages)
}
- if (zb0009Mask & 0x20000) == 0 { // if not empty
+ if (zb0009Mask & 0x40000) == 0 { // if not empty
// string "tsch"
o = append(o, 0xa4, 0x74, 0x73, 0x63, 0x68)
// omitempty: check for empty values
@@ -3470,22 +3502,22 @@ func (z *BalanceRecord) MarshalMsg(b []byte) (o []byte) {
o = msgp.AppendUint64(o, (*z).AccountData.TotalAppSchema.NumUint)
}
}
- if (zb0009Mask & 0x40000) == 0 { // if not empty
+ if (zb0009Mask & 0x80000) == 0 { // if not empty
// string "vote"
o = append(o, 0xa4, 0x76, 0x6f, 0x74, 0x65)
o = (*z).AccountData.VoteID.MarshalMsg(o)
}
- if (zb0009Mask & 0x80000) == 0 { // if not empty
+ if (zb0009Mask & 0x100000) == 0 { // if not empty
// string "voteFst"
o = append(o, 0xa7, 0x76, 0x6f, 0x74, 0x65, 0x46, 0x73, 0x74)
o = msgp.AppendUint64(o, uint64((*z).AccountData.VoteFirstValid))
}
- if (zb0009Mask & 0x100000) == 0 { // if not empty
+ if (zb0009Mask & 0x200000) == 0 { // if not empty
// string "voteKD"
o = append(o, 0xa6, 0x76, 0x6f, 0x74, 0x65, 0x4b, 0x44)
o = msgp.AppendUint64(o, (*z).AccountData.VoteKeyDilution)
}
- if (zb0009Mask & 0x200000) == 0 { // if not empty
+ if (zb0009Mask & 0x400000) == 0 { // if not empty
// string "voteLst"
o = append(o, 0xa7, 0x76, 0x6f, 0x74, 0x65, 0x4c, 0x73, 0x74)
o = msgp.AppendUint64(o, uint64((*z).AccountData.VoteLastValid))
@@ -3761,6 +3793,14 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState
return
}
}
+ if zb0009 > 0 {
+ zb0009--
+ (*z).AccountData.IncentiveEligible, bts, err = msgp.ReadBoolBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "IncentiveEligible")
+ return
+ }
+ }
if zb0009 > 0 {
zb0009--
var zb0020 int
@@ -4168,6 +4208,12 @@ func (z *BalanceRecord) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState
err = msgp.WrapError(err, "AuthAddr")
return
}
+ case "ie":
+ (*z).AccountData.IncentiveEligible, bts, err = msgp.ReadBoolBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "IncentiveEligible")
+ return
+ }
case "appl":
var zb0035 int
var zb0036 bool
@@ -4363,7 +4409,7 @@ func (z *BalanceRecord) Msgsize() (s int) {
s += 0 + zb0003.Msgsize() + 1 + 2 + msgp.Uint64Size + 2 + msgp.BoolSize
}
}
- s += 6 + (*z).AccountData.AuthAddr.Msgsize() + 5 + msgp.MapHeaderSize
+ s += 6 + (*z).AccountData.AuthAddr.Msgsize() + 3 + msgp.BoolSize + 5 + msgp.MapHeaderSize
if (*z).AccountData.AppLocalStates != nil {
for zb0005, zb0006 := range (*z).AccountData.AppLocalStates {
_ = zb0005
@@ -4385,7 +4431,7 @@ func (z *BalanceRecord) Msgsize() (s int) {
// MsgIsZero returns whether this is a zero value
func (z *BalanceRecord) MsgIsZero() bool {
- return ((*z).Addr.MsgIsZero()) && ((*z).AccountData.Status == 0) && ((*z).AccountData.MicroAlgos.MsgIsZero()) && ((*z).AccountData.RewardsBase == 0) && ((*z).AccountData.RewardedMicroAlgos.MsgIsZero()) && ((*z).AccountData.VoteID.MsgIsZero()) && ((*z).AccountData.SelectionID.MsgIsZero()) && ((*z).AccountData.StateProofID.MsgIsZero()) && ((*z).AccountData.VoteFirstValid == 0) && ((*z).AccountData.VoteLastValid == 0) && ((*z).AccountData.VoteKeyDilution == 0) && (len((*z).AccountData.AssetParams) == 0) && (len((*z).AccountData.Assets) == 0) && ((*z).AccountData.AuthAddr.MsgIsZero()) && (len((*z).AccountData.AppLocalStates) == 0) && (len((*z).AccountData.AppParams) == 0) && (((*z).AccountData.TotalAppSchema.NumUint == 0) && ((*z).AccountData.TotalAppSchema.NumByteSlice == 0)) && ((*z).AccountData.TotalExtraAppPages == 0) && ((*z).AccountData.TotalBoxes == 0) && ((*z).AccountData.TotalBoxBytes == 0)
+ return ((*z).Addr.MsgIsZero()) && ((*z).AccountData.Status == 0) && ((*z).AccountData.MicroAlgos.MsgIsZero()) && ((*z).AccountData.RewardsBase == 0) && ((*z).AccountData.RewardedMicroAlgos.MsgIsZero()) && ((*z).AccountData.VoteID.MsgIsZero()) && ((*z).AccountData.SelectionID.MsgIsZero()) && ((*z).AccountData.StateProofID.MsgIsZero()) && ((*z).AccountData.VoteFirstValid == 0) && ((*z).AccountData.VoteLastValid == 0) && ((*z).AccountData.VoteKeyDilution == 0) && (len((*z).AccountData.AssetParams) == 0) && (len((*z).AccountData.Assets) == 0) && ((*z).AccountData.AuthAddr.MsgIsZero()) && ((*z).AccountData.IncentiveEligible == false) && (len((*z).AccountData.AppLocalStates) == 0) && (len((*z).AccountData.AppParams) == 0) && (((*z).AccountData.TotalAppSchema.NumUint == 0) && ((*z).AccountData.TotalAppSchema.NumByteSlice == 0)) && ((*z).AccountData.TotalExtraAppPages == 0) && ((*z).AccountData.TotalBoxes == 0) && ((*z).AccountData.TotalBoxBytes == 0)
}
// MaxSize returns a maximum valid message size for this message type
@@ -4403,7 +4449,7 @@ func BalanceRecordMaxSize() (s int) {
// Adding size of map values for z.AccountData.Assets
s += encodedMaxAssetsPerAccount * (1)
s += 2 + msgp.Uint64Size + 2 + msgp.BoolSize
- s += 6 + AddressMaxSize() + 5
+ s += 6 + AddressMaxSize() + 3 + msgp.BoolSize + 5
s += msgp.MapHeaderSize
// Adding size of map keys for z.AccountData.AppLocalStates
s += EncodedMaxAppLocalStates * (AppIndexMaxSize())
diff --git a/data/basics/units.go b/data/basics/units.go
index af8743ee40..09bee7b8a8 100644
--- a/data/basics/units.go
+++ b/data/basics/units.go
@@ -17,6 +17,8 @@
package basics
import (
+ "math"
+
"github.com/algorand/go-codec/codec"
"github.com/algorand/msgp/msgp"
@@ -43,6 +45,11 @@ func (a MicroAlgos) GreaterThan(b MicroAlgos) bool {
return a.Raw > b.Raw
}
+// GTE implements arithmetic comparison for MicroAlgos
+func (a MicroAlgos) GTE(b MicroAlgos) bool {
+ return a.Raw >= b.Raw
+}
+
// IsZero implements arithmetic comparison for MicroAlgos
func (a MicroAlgos) IsZero() bool {
return a.Raw == 0
@@ -122,6 +129,17 @@ func MicroAlgosMaxSize() (s int) {
return msgp.Uint64Size
}
+// Algos is a convenience function so that whole Algos can be written easily. It
+// panics on overflow because it should only be used constants - things that are
+// best human-readable in source code - not used on arbitrary values from, say,
+// transactions.
+func Algos(algos uint64) MicroAlgos {
+ if algos > math.MaxUint64/1_000_000 {
+ panic(algos)
+ }
+ return MicroAlgos{Raw: algos * 1_000_000}
+}
+
// Round represents a protocol round index
type Round uint64
diff --git a/data/basics/userBalance.go b/data/basics/userBalance.go
index 398147bb6d..48af4348e2 100644
--- a/data/basics/userBalance.go
+++ b/data/basics/userBalance.go
@@ -209,6 +209,11 @@ type AccountData struct {
// This allows key rotation, changing the members in a multisig, etc.
AuthAddr Address `codec:"spend"`
+ // IncentiveEligible indicates whether the account came online with the
+ // extra fee required to be eligible for block incentives. At proposal time,
+ // balance limits must also be met to receive incentives.
+ IncentiveEligible bool `codec:"ie"`
+
// AppLocalStates stores the local states associated with any applications
// that this account has opted in to.
AppLocalStates map[AppIndex]AppLocalState `codec:"appl,allocbound=EncodedMaxAppLocalStates"`
diff --git a/data/bookkeeping/block.go b/data/bookkeeping/block.go
index d67621b343..987b44e867 100644
--- a/data/bookkeeping/block.go
+++ b/data/bookkeeping/block.go
@@ -58,6 +58,16 @@ type (
// Genesis hash to which this block belongs.
GenesisHash crypto.Digest `codec:"gh"`
+ // Proposer is the proposer of this block. Like the Seed, algod adds
+ // this after the block is built, so that the same block can be prepared
+ // for multiple Players in the same node. Therefore, it can not be used
+ // to influence block evaluation. Populated if proto.EnableMining
+ Proposer basics.Address `codec:"prp"`
+
+ // FeesCollected is the sum of all fees paid by transactions in this
+ // block. Populated if proto.EnableMining.
+ FeesCollected basics.MicroAlgos `codec:"fc"`
+
// Rewards.
//
// When a block is applied, some amount of rewards are accrued to
@@ -275,9 +285,13 @@ func (block Block) GenesisHash() crypto.Digest {
}
// WithSeed returns a copy of the Block with the seed set to s.
-func (block Block) WithSeed(s committee.Seed) Block {
+func (block Block) WithSeed(s committee.Seed, proposer basics.Address) Block {
c := block
c.BlockHeader.Seed = s
+ if !c.BlockHeader.Proposer.IsZero() {
+ panic("Attempt to re-set the proposer.")
+ }
+ c.BlockHeader.Proposer = proposer
return c
}
diff --git a/data/bookkeeping/msgp_gen.go b/data/bookkeeping/msgp_gen.go
index cb3a63ad2e..e020a7c7bf 100644
--- a/data/bookkeeping/msgp_gen.go
+++ b/data/bookkeeping/msgp_gen.go
@@ -143,112 +143,120 @@ import (
func (z *Block) MarshalMsg(b []byte) (o []byte) {
o = msgp.Require(b, z.Msgsize())
// omitempty: check for empty values
- zb0004Len := uint32(26)
- var zb0004Mask uint32 /* 31 bits */
+ zb0004Len := uint32(28)
+ var zb0004Mask uint64 /* 33 bits */
if (*z).BlockHeader.RewardsState.RewardsLevel == 0 {
zb0004Len--
zb0004Mask |= 0x20
}
- if (*z).BlockHeader.RewardsState.FeeSink.MsgIsZero() {
+ if (*z).BlockHeader.FeesCollected.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x40
}
- if (*z).BlockHeader.RewardsState.RewardsResidue == 0 {
+ if (*z).BlockHeader.RewardsState.FeeSink.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x80
}
- if (*z).BlockHeader.GenesisID == "" {
+ if (*z).BlockHeader.RewardsState.RewardsResidue == 0 {
zb0004Len--
zb0004Mask |= 0x100
}
- if (*z).BlockHeader.GenesisHash.MsgIsZero() {
+ if (*z).BlockHeader.GenesisID == "" {
zb0004Len--
zb0004Mask |= 0x200
}
- if (*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() {
+ if (*z).BlockHeader.GenesisHash.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x400
}
- if (*z).BlockHeader.UpgradeState.NextProtocol.MsgIsZero() {
+ if (*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x800
}
- if (*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() {
+ if (*z).BlockHeader.UpgradeState.NextProtocol.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x1000
}
- if (*z).BlockHeader.UpgradeState.NextProtocolApprovals == 0 {
+ if (*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x2000
}
- if len((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 {
+ if (*z).BlockHeader.UpgradeState.NextProtocolApprovals == 0 {
zb0004Len--
zb0004Mask |= 0x4000
}
- if (*z).BlockHeader.Branch.MsgIsZero() {
+ if len((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0 {
zb0004Len--
zb0004Mask |= 0x8000
}
- if (*z).BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() {
+ if (*z).BlockHeader.Branch.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x10000
}
- if (*z).BlockHeader.RewardsState.RewardsRate == 0 {
+ if (*z).BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x20000
}
- if (*z).BlockHeader.Round.MsgIsZero() {
+ if (*z).BlockHeader.Proposer.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x40000
}
- if (*z).BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero() {
+ if (*z).BlockHeader.RewardsState.RewardsRate == 0 {
zb0004Len--
zb0004Mask |= 0x80000
}
- if (*z).BlockHeader.RewardsState.RewardsPool.MsgIsZero() {
+ if (*z).BlockHeader.Round.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x100000
}
- if (*z).BlockHeader.Seed.MsgIsZero() {
+ if (*z).BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x200000
}
- if len((*z).BlockHeader.StateProofTracking) == 0 {
+ if (*z).BlockHeader.RewardsState.RewardsPool.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x400000
}
- if (*z).BlockHeader.TxnCounter == 0 {
+ if (*z).BlockHeader.Seed.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x800000
}
- if (*z).BlockHeader.TimeStamp == 0 {
+ if len((*z).BlockHeader.StateProofTracking) == 0 {
zb0004Len--
zb0004Mask |= 0x1000000
}
- if (*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero() {
+ if (*z).BlockHeader.TxnCounter == 0 {
zb0004Len--
zb0004Mask |= 0x2000000
}
- if (*z).BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero() {
+ if (*z).BlockHeader.TimeStamp == 0 {
zb0004Len--
zb0004Mask |= 0x4000000
}
- if (*z).Payset.MsgIsZero() {
+ if (*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x8000000
}
- if (*z).BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero() {
+ if (*z).BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x10000000
}
- if (*z).BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero() {
+ if (*z).Payset.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x20000000
}
- if (*z).BlockHeader.UpgradeVote.UpgradeApprove == false {
+ if (*z).BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x40000000
}
+ if (*z).BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero() {
+ zb0004Len--
+ zb0004Mask |= 0x80000000
+ }
+ if (*z).BlockHeader.UpgradeVote.UpgradeApprove == false {
+ zb0004Len--
+ zb0004Mask |= 0x100000000
+ }
// variable map header, size zb0004Len
o = msgp.AppendMapHeader(o, zb0004Len)
if zb0004Len != 0 {
@@ -258,46 +266,51 @@ func (z *Block) MarshalMsg(b []byte) (o []byte) {
o = msgp.AppendUint64(o, (*z).BlockHeader.RewardsState.RewardsLevel)
}
if (zb0004Mask & 0x40) == 0 { // if not empty
+ // string "fc"
+ o = append(o, 0xa2, 0x66, 0x63)
+ o = (*z).BlockHeader.FeesCollected.MarshalMsg(o)
+ }
+ if (zb0004Mask & 0x80) == 0 { // if not empty
// string "fees"
o = append(o, 0xa4, 0x66, 0x65, 0x65, 0x73)
o = (*z).BlockHeader.RewardsState.FeeSink.MarshalMsg(o)
}
- if (zb0004Mask & 0x80) == 0 { // if not empty
+ if (zb0004Mask & 0x100) == 0 { // if not empty
// string "frac"
o = append(o, 0xa4, 0x66, 0x72, 0x61, 0x63)
o = msgp.AppendUint64(o, (*z).BlockHeader.RewardsState.RewardsResidue)
}
- if (zb0004Mask & 0x100) == 0 { // if not empty
+ if (zb0004Mask & 0x200) == 0 { // if not empty
// string "gen"
o = append(o, 0xa3, 0x67, 0x65, 0x6e)
o = msgp.AppendString(o, (*z).BlockHeader.GenesisID)
}
- if (zb0004Mask & 0x200) == 0 { // if not empty
+ if (zb0004Mask & 0x400) == 0 { // if not empty
// string "gh"
o = append(o, 0xa2, 0x67, 0x68)
o = (*z).BlockHeader.GenesisHash.MarshalMsg(o)
}
- if (zb0004Mask & 0x400) == 0 { // if not empty
+ if (zb0004Mask & 0x800) == 0 { // if not empty
// string "nextbefore"
o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65)
o = (*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.MarshalMsg(o)
}
- if (zb0004Mask & 0x800) == 0 { // if not empty
+ if (zb0004Mask & 0x1000) == 0 { // if not empty
// string "nextproto"
o = append(o, 0xa9, 0x6e, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f)
o = (*z).BlockHeader.UpgradeState.NextProtocol.MarshalMsg(o)
}
- if (zb0004Mask & 0x1000) == 0 { // if not empty
+ if (zb0004Mask & 0x2000) == 0 { // if not empty
// string "nextswitch"
o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68)
o = (*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.MarshalMsg(o)
}
- if (zb0004Mask & 0x2000) == 0 { // if not empty
+ if (zb0004Mask & 0x4000) == 0 { // if not empty
// string "nextyes"
o = append(o, 0xa7, 0x6e, 0x65, 0x78, 0x74, 0x79, 0x65, 0x73)
o = msgp.AppendUint64(o, (*z).BlockHeader.UpgradeState.NextProtocolApprovals)
}
- if (zb0004Mask & 0x4000) == 0 { // if not empty
+ if (zb0004Mask & 0x8000) == 0 { // if not empty
// string "partupdrmv"
o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76)
if (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts == nil {
@@ -309,42 +322,47 @@ func (z *Block) MarshalMsg(b []byte) (o []byte) {
o = (*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts[zb0003].MarshalMsg(o)
}
}
- if (zb0004Mask & 0x8000) == 0 { // if not empty
+ if (zb0004Mask & 0x10000) == 0 { // if not empty
// string "prev"
o = append(o, 0xa4, 0x70, 0x72, 0x65, 0x76)
o = (*z).BlockHeader.Branch.MarshalMsg(o)
}
- if (zb0004Mask & 0x10000) == 0 { // if not empty
+ if (zb0004Mask & 0x20000) == 0 { // if not empty
// string "proto"
o = append(o, 0xa5, 0x70, 0x72, 0x6f, 0x74, 0x6f)
o = (*z).BlockHeader.UpgradeState.CurrentProtocol.MarshalMsg(o)
}
- if (zb0004Mask & 0x20000) == 0 { // if not empty
+ if (zb0004Mask & 0x40000) == 0 { // if not empty
+ // string "prp"
+ o = append(o, 0xa3, 0x70, 0x72, 0x70)
+ o = (*z).BlockHeader.Proposer.MarshalMsg(o)
+ }
+ if (zb0004Mask & 0x80000) == 0 { // if not empty
// string "rate"
o = append(o, 0xa4, 0x72, 0x61, 0x74, 0x65)
o = msgp.AppendUint64(o, (*z).BlockHeader.RewardsState.RewardsRate)
}
- if (zb0004Mask & 0x40000) == 0 { // if not empty
+ if (zb0004Mask & 0x100000) == 0 { // if not empty
// string "rnd"
o = append(o, 0xa3, 0x72, 0x6e, 0x64)
o = (*z).BlockHeader.Round.MarshalMsg(o)
}
- if (zb0004Mask & 0x80000) == 0 { // if not empty
+ if (zb0004Mask & 0x200000) == 0 { // if not empty
// string "rwcalr"
o = append(o, 0xa6, 0x72, 0x77, 0x63, 0x61, 0x6c, 0x72)
o = (*z).BlockHeader.RewardsState.RewardsRecalculationRound.MarshalMsg(o)
}
- if (zb0004Mask & 0x100000) == 0 { // if not empty
+ if (zb0004Mask & 0x400000) == 0 { // if not empty
// string "rwd"
o = append(o, 0xa3, 0x72, 0x77, 0x64)
o = (*z).BlockHeader.RewardsState.RewardsPool.MarshalMsg(o)
}
- if (zb0004Mask & 0x200000) == 0 { // if not empty
+ if (zb0004Mask & 0x800000) == 0 { // if not empty
// string "seed"
o = append(o, 0xa4, 0x73, 0x65, 0x65, 0x64)
o = (*z).BlockHeader.Seed.MarshalMsg(o)
}
- if (zb0004Mask & 0x400000) == 0 { // if not empty
+ if (zb0004Mask & 0x1000000) == 0 { // if not empty
// string "spt"
o = append(o, 0xa3, 0x73, 0x70, 0x74)
if (*z).BlockHeader.StateProofTracking == nil {
@@ -364,42 +382,42 @@ func (z *Block) MarshalMsg(b []byte) (o []byte) {
o = zb0002.MarshalMsg(o)
}
}
- if (zb0004Mask & 0x800000) == 0 { // if not empty
+ if (zb0004Mask & 0x2000000) == 0 { // if not empty
// string "tc"
o = append(o, 0xa2, 0x74, 0x63)
o = msgp.AppendUint64(o, (*z).BlockHeader.TxnCounter)
}
- if (zb0004Mask & 0x1000000) == 0 { // if not empty
+ if (zb0004Mask & 0x4000000) == 0 { // if not empty
// string "ts"
o = append(o, 0xa2, 0x74, 0x73)
o = msgp.AppendInt64(o, (*z).BlockHeader.TimeStamp)
}
- if (zb0004Mask & 0x2000000) == 0 { // if not empty
+ if (zb0004Mask & 0x8000000) == 0 { // if not empty
// string "txn"
o = append(o, 0xa3, 0x74, 0x78, 0x6e)
o = (*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.MarshalMsg(o)
}
- if (zb0004Mask & 0x4000000) == 0 { // if not empty
+ if (zb0004Mask & 0x10000000) == 0 { // if not empty
// string "txn256"
o = append(o, 0xa6, 0x74, 0x78, 0x6e, 0x32, 0x35, 0x36)
o = (*z).BlockHeader.TxnCommitments.Sha256Commitment.MarshalMsg(o)
}
- if (zb0004Mask & 0x8000000) == 0 { // if not empty
+ if (zb0004Mask & 0x20000000) == 0 { // if not empty
// string "txns"
o = append(o, 0xa4, 0x74, 0x78, 0x6e, 0x73)
o = (*z).Payset.MarshalMsg(o)
}
- if (zb0004Mask & 0x10000000) == 0 { // if not empty
+ if (zb0004Mask & 0x40000000) == 0 { // if not empty
// string "upgradedelay"
o = append(o, 0xac, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x65, 0x6c, 0x61, 0x79)
o = (*z).BlockHeader.UpgradeVote.UpgradeDelay.MarshalMsg(o)
}
- if (zb0004Mask & 0x20000000) == 0 { // if not empty
+ if (zb0004Mask & 0x80000000) == 0 { // if not empty
// string "upgradeprop"
o = append(o, 0xab, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x70, 0x72, 0x6f, 0x70)
o = (*z).BlockHeader.UpgradeVote.UpgradePropose.MarshalMsg(o)
}
- if (zb0004Mask & 0x40000000) == 0 { // if not empty
+ if (zb0004Mask & 0x100000000) == 0 { // if not empty
// string "upgradeyes"
o = append(o, 0xaa, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x65, 0x73)
o = msgp.AppendBool(o, (*z).BlockHeader.UpgradeVote.UpgradeApprove)
@@ -505,6 +523,22 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b
return
}
}
+ if zb0004 > 0 {
+ zb0004--
+ bts, err = (*z).BlockHeader.Proposer.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "Proposer")
+ return
+ }
+ }
+ if zb0004 > 0 {
+ zb0004--
+ bts, err = (*z).BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "FeesCollected")
+ return
+ }
+ }
if zb0004 > 0 {
zb0004--
bts, err = (*z).BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st)
@@ -779,6 +813,18 @@ func (z *Block) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState) (o []b
err = msgp.WrapError(err, "GenesisHash")
return
}
+ case "prp":
+ bts, err = (*z).BlockHeader.Proposer.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "Proposer")
+ return
+ }
+ case "fc":
+ bts, err = (*z).BlockHeader.FeesCollected.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "FeesCollected")
+ return
+ }
case "fees":
bts, err = (*z).BlockHeader.RewardsState.FeeSink.UnmarshalMsgWithState(bts, st)
if err != nil {
@@ -959,7 +1005,7 @@ func (_ *Block) CanUnmarshalMsg(z interface{}) bool {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *Block) Msgsize() (s int) {
- s = 3 + 4 + (*z).BlockHeader.Round.Msgsize() + 5 + (*z).BlockHeader.Branch.Msgsize() + 5 + (*z).BlockHeader.Seed.Msgsize() + 4 + (*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.Msgsize() + 7 + (*z).BlockHeader.TxnCommitments.Sha256Commitment.Msgsize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + len((*z).BlockHeader.GenesisID) + 3 + (*z).BlockHeader.GenesisHash.Msgsize() + 5 + (*z).BlockHeader.RewardsState.FeeSink.Msgsize() + 4 + (*z).BlockHeader.RewardsState.RewardsPool.Msgsize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + (*z).BlockHeader.RewardsState.RewardsRecalculationRound.Msgsize() + 6 + (*z).BlockHeader.UpgradeState.CurrentProtocol.Msgsize() + 10 + (*z).BlockHeader.UpgradeState.NextProtocol.Msgsize() + 8 + msgp.Uint64Size + 11 + (*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.Msgsize() + 11 + (*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.Msgsize() + 12 + (*z).BlockHeader.UpgradeVote.UpgradePropose.Msgsize() + 13 + (*z).BlockHeader.UpgradeVote.UpgradeDelay.Msgsize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + msgp.MapHeaderSize
+ s = 3 + 4 + (*z).BlockHeader.Round.Msgsize() + 5 + (*z).BlockHeader.Branch.Msgsize() + 5 + (*z).BlockHeader.Seed.Msgsize() + 4 + (*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.Msgsize() + 7 + (*z).BlockHeader.TxnCommitments.Sha256Commitment.Msgsize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + len((*z).BlockHeader.GenesisID) + 3 + (*z).BlockHeader.GenesisHash.Msgsize() + 4 + (*z).BlockHeader.Proposer.Msgsize() + 3 + (*z).BlockHeader.FeesCollected.Msgsize() + 5 + (*z).BlockHeader.RewardsState.FeeSink.Msgsize() + 4 + (*z).BlockHeader.RewardsState.RewardsPool.Msgsize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + (*z).BlockHeader.RewardsState.RewardsRecalculationRound.Msgsize() + 6 + (*z).BlockHeader.UpgradeState.CurrentProtocol.Msgsize() + 10 + (*z).BlockHeader.UpgradeState.NextProtocol.Msgsize() + 8 + msgp.Uint64Size + 11 + (*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.Msgsize() + 11 + (*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.Msgsize() + 12 + (*z).BlockHeader.UpgradeVote.UpgradePropose.Msgsize() + 13 + (*z).BlockHeader.UpgradeVote.UpgradeDelay.Msgsize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + msgp.MapHeaderSize
if (*z).BlockHeader.StateProofTracking != nil {
for zb0001, zb0002 := range (*z).BlockHeader.StateProofTracking {
_ = zb0001
@@ -977,12 +1023,12 @@ func (z *Block) Msgsize() (s int) {
// MsgIsZero returns whether this is a zero value
func (z *Block) MsgIsZero() bool {
- return ((*z).BlockHeader.Round.MsgIsZero()) && ((*z).BlockHeader.Branch.MsgIsZero()) && ((*z).BlockHeader.Seed.MsgIsZero()) && ((*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).BlockHeader.TimeStamp == 0) && ((*z).BlockHeader.GenesisID == "") && ((*z).BlockHeader.GenesisHash.MsgIsZero()) && ((*z).BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).BlockHeader.RewardsState.RewardsRate == 0) && ((*z).BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).BlockHeader.TxnCounter == 0) && (len((*z).BlockHeader.StateProofTracking) == 0) && (len((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).Payset.MsgIsZero())
+ return ((*z).BlockHeader.Round.MsgIsZero()) && ((*z).BlockHeader.Branch.MsgIsZero()) && ((*z).BlockHeader.Seed.MsgIsZero()) && ((*z).BlockHeader.TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).BlockHeader.TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).BlockHeader.TimeStamp == 0) && ((*z).BlockHeader.GenesisID == "") && ((*z).BlockHeader.GenesisHash.MsgIsZero()) && ((*z).BlockHeader.Proposer.MsgIsZero()) && ((*z).BlockHeader.FeesCollected.MsgIsZero()) && ((*z).BlockHeader.RewardsState.FeeSink.MsgIsZero()) && ((*z).BlockHeader.RewardsState.RewardsPool.MsgIsZero()) && ((*z).BlockHeader.RewardsState.RewardsLevel == 0) && ((*z).BlockHeader.RewardsState.RewardsRate == 0) && ((*z).BlockHeader.RewardsState.RewardsResidue == 0) && ((*z).BlockHeader.RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocol.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocolApprovals == 0) && ((*z).BlockHeader.UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).BlockHeader.UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).BlockHeader.UpgradeVote.UpgradeApprove == false) && ((*z).BlockHeader.TxnCounter == 0) && (len((*z).BlockHeader.StateProofTracking) == 0) && (len((*z).BlockHeader.ParticipationUpdates.ExpiredParticipationAccounts) == 0) && ((*z).Payset.MsgIsZero())
}
// MaxSize returns a maximum valid message size for this message type
func BlockMaxSize() (s int) {
- s = 3 + 4 + basics.RoundMaxSize() + 5 + BlockHashMaxSize() + 5 + committee.SeedMaxSize() + 4 + crypto.DigestMaxSize() + 7 + crypto.DigestMaxSize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + config.MaxGenesisIDLen + 3 + crypto.DigestMaxSize() + 5 + basics.AddressMaxSize() + 4 + basics.AddressMaxSize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + basics.RoundMaxSize() + 6 + protocol.ConsensusVersionMaxSize() + 10 + protocol.ConsensusVersionMaxSize() + 8 + msgp.Uint64Size + 11 + basics.RoundMaxSize() + 11 + basics.RoundMaxSize() + 12 + protocol.ConsensusVersionMaxSize() + 13 + basics.RoundMaxSize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4
+ s = 3 + 4 + basics.RoundMaxSize() + 5 + BlockHashMaxSize() + 5 + committee.SeedMaxSize() + 4 + crypto.DigestMaxSize() + 7 + crypto.DigestMaxSize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + config.MaxGenesisIDLen + 3 + crypto.DigestMaxSize() + 4 + basics.AddressMaxSize() + 3 + basics.MicroAlgosMaxSize() + 5 + basics.AddressMaxSize() + 4 + basics.AddressMaxSize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + basics.RoundMaxSize() + 6 + protocol.ConsensusVersionMaxSize() + 10 + protocol.ConsensusVersionMaxSize() + 8 + msgp.Uint64Size + 11 + basics.RoundMaxSize() + 11 + basics.RoundMaxSize() + 12 + protocol.ConsensusVersionMaxSize() + 13 + basics.RoundMaxSize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4
s += msgp.MapHeaderSize
// Adding size of map keys for z.BlockHeader.StateProofTracking
s += protocol.NumStateProofTypes * (protocol.StateProofTypeMaxSize())
@@ -1037,108 +1083,116 @@ func BlockHashMaxSize() int {
func (z *BlockHeader) MarshalMsg(b []byte) (o []byte) {
o = msgp.Require(b, z.Msgsize())
// omitempty: check for empty values
- zb0004Len := uint32(25)
- var zb0004Mask uint32 /* 30 bits */
+ zb0004Len := uint32(27)
+ var zb0004Mask uint32 /* 32 bits */
if (*z).RewardsState.RewardsLevel == 0 {
zb0004Len--
zb0004Mask |= 0x20
}
- if (*z).RewardsState.FeeSink.MsgIsZero() {
+ if (*z).FeesCollected.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x40
}
- if (*z).RewardsState.RewardsResidue == 0 {
+ if (*z).RewardsState.FeeSink.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x80
}
- if (*z).GenesisID == "" {
+ if (*z).RewardsState.RewardsResidue == 0 {
zb0004Len--
zb0004Mask |= 0x100
}
- if (*z).GenesisHash.MsgIsZero() {
+ if (*z).GenesisID == "" {
zb0004Len--
zb0004Mask |= 0x200
}
- if (*z).UpgradeState.NextProtocolVoteBefore.MsgIsZero() {
+ if (*z).GenesisHash.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x400
}
- if (*z).UpgradeState.NextProtocol.MsgIsZero() {
+ if (*z).UpgradeState.NextProtocolVoteBefore.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x800
}
- if (*z).UpgradeState.NextProtocolSwitchOn.MsgIsZero() {
+ if (*z).UpgradeState.NextProtocol.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x1000
}
- if (*z).UpgradeState.NextProtocolApprovals == 0 {
+ if (*z).UpgradeState.NextProtocolSwitchOn.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x2000
}
- if len((*z).ParticipationUpdates.ExpiredParticipationAccounts) == 0 {
+ if (*z).UpgradeState.NextProtocolApprovals == 0 {
zb0004Len--
zb0004Mask |= 0x4000
}
- if (*z).Branch.MsgIsZero() {
+ if len((*z).ParticipationUpdates.ExpiredParticipationAccounts) == 0 {
zb0004Len--
zb0004Mask |= 0x8000
}
- if (*z).UpgradeState.CurrentProtocol.MsgIsZero() {
+ if (*z).Branch.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x10000
}
- if (*z).RewardsState.RewardsRate == 0 {
+ if (*z).UpgradeState.CurrentProtocol.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x20000
}
- if (*z).Round.MsgIsZero() {
+ if (*z).Proposer.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x40000
}
- if (*z).RewardsState.RewardsRecalculationRound.MsgIsZero() {
+ if (*z).RewardsState.RewardsRate == 0 {
zb0004Len--
zb0004Mask |= 0x80000
}
- if (*z).RewardsState.RewardsPool.MsgIsZero() {
+ if (*z).Round.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x100000
}
- if (*z).Seed.MsgIsZero() {
+ if (*z).RewardsState.RewardsRecalculationRound.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x200000
}
- if len((*z).StateProofTracking) == 0 {
+ if (*z).RewardsState.RewardsPool.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x400000
}
- if (*z).TxnCounter == 0 {
+ if (*z).Seed.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x800000
}
- if (*z).TimeStamp == 0 {
+ if len((*z).StateProofTracking) == 0 {
zb0004Len--
zb0004Mask |= 0x1000000
}
- if (*z).TxnCommitments.NativeSha512_256Commitment.MsgIsZero() {
+ if (*z).TxnCounter == 0 {
zb0004Len--
zb0004Mask |= 0x2000000
}
- if (*z).TxnCommitments.Sha256Commitment.MsgIsZero() {
+ if (*z).TimeStamp == 0 {
zb0004Len--
zb0004Mask |= 0x4000000
}
- if (*z).UpgradeVote.UpgradeDelay.MsgIsZero() {
+ if (*z).TxnCommitments.NativeSha512_256Commitment.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x8000000
}
- if (*z).UpgradeVote.UpgradePropose.MsgIsZero() {
+ if (*z).TxnCommitments.Sha256Commitment.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x10000000
}
- if (*z).UpgradeVote.UpgradeApprove == false {
+ if (*z).UpgradeVote.UpgradeDelay.MsgIsZero() {
zb0004Len--
zb0004Mask |= 0x20000000
}
+ if (*z).UpgradeVote.UpgradePropose.MsgIsZero() {
+ zb0004Len--
+ zb0004Mask |= 0x40000000
+ }
+ if (*z).UpgradeVote.UpgradeApprove == false {
+ zb0004Len--
+ zb0004Mask |= 0x80000000
+ }
// variable map header, size zb0004Len
o = msgp.AppendMapHeader(o, zb0004Len)
if zb0004Len != 0 {
@@ -1148,46 +1202,51 @@ func (z *BlockHeader) MarshalMsg(b []byte) (o []byte) {
o = msgp.AppendUint64(o, (*z).RewardsState.RewardsLevel)
}
if (zb0004Mask & 0x40) == 0 { // if not empty
+ // string "fc"
+ o = append(o, 0xa2, 0x66, 0x63)
+ o = (*z).FeesCollected.MarshalMsg(o)
+ }
+ if (zb0004Mask & 0x80) == 0 { // if not empty
// string "fees"
o = append(o, 0xa4, 0x66, 0x65, 0x65, 0x73)
o = (*z).RewardsState.FeeSink.MarshalMsg(o)
}
- if (zb0004Mask & 0x80) == 0 { // if not empty
+ if (zb0004Mask & 0x100) == 0 { // if not empty
// string "frac"
o = append(o, 0xa4, 0x66, 0x72, 0x61, 0x63)
o = msgp.AppendUint64(o, (*z).RewardsState.RewardsResidue)
}
- if (zb0004Mask & 0x100) == 0 { // if not empty
+ if (zb0004Mask & 0x200) == 0 { // if not empty
// string "gen"
o = append(o, 0xa3, 0x67, 0x65, 0x6e)
o = msgp.AppendString(o, (*z).GenesisID)
}
- if (zb0004Mask & 0x200) == 0 { // if not empty
+ if (zb0004Mask & 0x400) == 0 { // if not empty
// string "gh"
o = append(o, 0xa2, 0x67, 0x68)
o = (*z).GenesisHash.MarshalMsg(o)
}
- if (zb0004Mask & 0x400) == 0 { // if not empty
+ if (zb0004Mask & 0x800) == 0 { // if not empty
// string "nextbefore"
o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65)
o = (*z).UpgradeState.NextProtocolVoteBefore.MarshalMsg(o)
}
- if (zb0004Mask & 0x800) == 0 { // if not empty
+ if (zb0004Mask & 0x1000) == 0 { // if not empty
// string "nextproto"
o = append(o, 0xa9, 0x6e, 0x65, 0x78, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f)
o = (*z).UpgradeState.NextProtocol.MarshalMsg(o)
}
- if (zb0004Mask & 0x1000) == 0 { // if not empty
+ if (zb0004Mask & 0x2000) == 0 { // if not empty
// string "nextswitch"
o = append(o, 0xaa, 0x6e, 0x65, 0x78, 0x74, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68)
o = (*z).UpgradeState.NextProtocolSwitchOn.MarshalMsg(o)
}
- if (zb0004Mask & 0x2000) == 0 { // if not empty
+ if (zb0004Mask & 0x4000) == 0 { // if not empty
// string "nextyes"
o = append(o, 0xa7, 0x6e, 0x65, 0x78, 0x74, 0x79, 0x65, 0x73)
o = msgp.AppendUint64(o, (*z).UpgradeState.NextProtocolApprovals)
}
- if (zb0004Mask & 0x4000) == 0 { // if not empty
+ if (zb0004Mask & 0x8000) == 0 { // if not empty
// string "partupdrmv"
o = append(o, 0xaa, 0x70, 0x61, 0x72, 0x74, 0x75, 0x70, 0x64, 0x72, 0x6d, 0x76)
if (*z).ParticipationUpdates.ExpiredParticipationAccounts == nil {
@@ -1199,42 +1258,47 @@ func (z *BlockHeader) MarshalMsg(b []byte) (o []byte) {
o = (*z).ParticipationUpdates.ExpiredParticipationAccounts[zb0003].MarshalMsg(o)
}
}
- if (zb0004Mask & 0x8000) == 0 { // if not empty
+ if (zb0004Mask & 0x10000) == 0 { // if not empty
// string "prev"
o = append(o, 0xa4, 0x70, 0x72, 0x65, 0x76)
o = (*z).Branch.MarshalMsg(o)
}
- if (zb0004Mask & 0x10000) == 0 { // if not empty
+ if (zb0004Mask & 0x20000) == 0 { // if not empty
// string "proto"
o = append(o, 0xa5, 0x70, 0x72, 0x6f, 0x74, 0x6f)
o = (*z).UpgradeState.CurrentProtocol.MarshalMsg(o)
}
- if (zb0004Mask & 0x20000) == 0 { // if not empty
+ if (zb0004Mask & 0x40000) == 0 { // if not empty
+ // string "prp"
+ o = append(o, 0xa3, 0x70, 0x72, 0x70)
+ o = (*z).Proposer.MarshalMsg(o)
+ }
+ if (zb0004Mask & 0x80000) == 0 { // if not empty
// string "rate"
o = append(o, 0xa4, 0x72, 0x61, 0x74, 0x65)
o = msgp.AppendUint64(o, (*z).RewardsState.RewardsRate)
}
- if (zb0004Mask & 0x40000) == 0 { // if not empty
+ if (zb0004Mask & 0x100000) == 0 { // if not empty
// string "rnd"
o = append(o, 0xa3, 0x72, 0x6e, 0x64)
o = (*z).Round.MarshalMsg(o)
}
- if (zb0004Mask & 0x80000) == 0 { // if not empty
+ if (zb0004Mask & 0x200000) == 0 { // if not empty
// string "rwcalr"
o = append(o, 0xa6, 0x72, 0x77, 0x63, 0x61, 0x6c, 0x72)
o = (*z).RewardsState.RewardsRecalculationRound.MarshalMsg(o)
}
- if (zb0004Mask & 0x100000) == 0 { // if not empty
+ if (zb0004Mask & 0x400000) == 0 { // if not empty
// string "rwd"
o = append(o, 0xa3, 0x72, 0x77, 0x64)
o = (*z).RewardsState.RewardsPool.MarshalMsg(o)
}
- if (zb0004Mask & 0x200000) == 0 { // if not empty
+ if (zb0004Mask & 0x800000) == 0 { // if not empty
// string "seed"
o = append(o, 0xa4, 0x73, 0x65, 0x65, 0x64)
o = (*z).Seed.MarshalMsg(o)
}
- if (zb0004Mask & 0x400000) == 0 { // if not empty
+ if (zb0004Mask & 0x1000000) == 0 { // if not empty
// string "spt"
o = append(o, 0xa3, 0x73, 0x70, 0x74)
if (*z).StateProofTracking == nil {
@@ -1254,37 +1318,37 @@ func (z *BlockHeader) MarshalMsg(b []byte) (o []byte) {
o = zb0002.MarshalMsg(o)
}
}
- if (zb0004Mask & 0x800000) == 0 { // if not empty
+ if (zb0004Mask & 0x2000000) == 0 { // if not empty
// string "tc"
o = append(o, 0xa2, 0x74, 0x63)
o = msgp.AppendUint64(o, (*z).TxnCounter)
}
- if (zb0004Mask & 0x1000000) == 0 { // if not empty
+ if (zb0004Mask & 0x4000000) == 0 { // if not empty
// string "ts"
o = append(o, 0xa2, 0x74, 0x73)
o = msgp.AppendInt64(o, (*z).TimeStamp)
}
- if (zb0004Mask & 0x2000000) == 0 { // if not empty
+ if (zb0004Mask & 0x8000000) == 0 { // if not empty
// string "txn"
o = append(o, 0xa3, 0x74, 0x78, 0x6e)
o = (*z).TxnCommitments.NativeSha512_256Commitment.MarshalMsg(o)
}
- if (zb0004Mask & 0x4000000) == 0 { // if not empty
+ if (zb0004Mask & 0x10000000) == 0 { // if not empty
// string "txn256"
o = append(o, 0xa6, 0x74, 0x78, 0x6e, 0x32, 0x35, 0x36)
o = (*z).TxnCommitments.Sha256Commitment.MarshalMsg(o)
}
- if (zb0004Mask & 0x8000000) == 0 { // if not empty
+ if (zb0004Mask & 0x20000000) == 0 { // if not empty
// string "upgradedelay"
o = append(o, 0xac, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x65, 0x6c, 0x61, 0x79)
o = (*z).UpgradeVote.UpgradeDelay.MarshalMsg(o)
}
- if (zb0004Mask & 0x10000000) == 0 { // if not empty
+ if (zb0004Mask & 0x40000000) == 0 { // if not empty
// string "upgradeprop"
o = append(o, 0xab, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x70, 0x72, 0x6f, 0x70)
o = (*z).UpgradeVote.UpgradePropose.MarshalMsg(o)
}
- if (zb0004Mask & 0x20000000) == 0 { // if not empty
+ if (zb0004Mask & 0x80000000) == 0 { // if not empty
// string "upgradeyes"
o = append(o, 0xaa, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x65, 0x73)
o = msgp.AppendBool(o, (*z).UpgradeVote.UpgradeApprove)
@@ -1390,6 +1454,22 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
return
}
}
+ if zb0004 > 0 {
+ zb0004--
+ bts, err = (*z).Proposer.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "Proposer")
+ return
+ }
+ }
+ if zb0004 > 0 {
+ zb0004--
+ bts, err = (*z).FeesCollected.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "FeesCollected")
+ return
+ }
+ }
if zb0004 > 0 {
zb0004--
bts, err = (*z).RewardsState.FeeSink.UnmarshalMsgWithState(bts, st)
@@ -1656,6 +1736,18 @@ func (z *BlockHeader) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalState)
err = msgp.WrapError(err, "GenesisHash")
return
}
+ case "prp":
+ bts, err = (*z).Proposer.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "Proposer")
+ return
+ }
+ case "fc":
+ bts, err = (*z).FeesCollected.UnmarshalMsgWithState(bts, st)
+ if err != nil {
+ err = msgp.WrapError(err, "FeesCollected")
+ return
+ }
case "fees":
bts, err = (*z).RewardsState.FeeSink.UnmarshalMsgWithState(bts, st)
if err != nil {
@@ -1830,7 +1922,7 @@ func (_ *BlockHeader) CanUnmarshalMsg(z interface{}) bool {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *BlockHeader) Msgsize() (s int) {
- s = 3 + 4 + (*z).Round.Msgsize() + 5 + (*z).Branch.Msgsize() + 5 + (*z).Seed.Msgsize() + 4 + (*z).TxnCommitments.NativeSha512_256Commitment.Msgsize() + 7 + (*z).TxnCommitments.Sha256Commitment.Msgsize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + len((*z).GenesisID) + 3 + (*z).GenesisHash.Msgsize() + 5 + (*z).RewardsState.FeeSink.Msgsize() + 4 + (*z).RewardsState.RewardsPool.Msgsize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + (*z).RewardsState.RewardsRecalculationRound.Msgsize() + 6 + (*z).UpgradeState.CurrentProtocol.Msgsize() + 10 + (*z).UpgradeState.NextProtocol.Msgsize() + 8 + msgp.Uint64Size + 11 + (*z).UpgradeState.NextProtocolVoteBefore.Msgsize() + 11 + (*z).UpgradeState.NextProtocolSwitchOn.Msgsize() + 12 + (*z).UpgradeVote.UpgradePropose.Msgsize() + 13 + (*z).UpgradeVote.UpgradeDelay.Msgsize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + msgp.MapHeaderSize
+ s = 3 + 4 + (*z).Round.Msgsize() + 5 + (*z).Branch.Msgsize() + 5 + (*z).Seed.Msgsize() + 4 + (*z).TxnCommitments.NativeSha512_256Commitment.Msgsize() + 7 + (*z).TxnCommitments.Sha256Commitment.Msgsize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + len((*z).GenesisID) + 3 + (*z).GenesisHash.Msgsize() + 4 + (*z).Proposer.Msgsize() + 3 + (*z).FeesCollected.Msgsize() + 5 + (*z).RewardsState.FeeSink.Msgsize() + 4 + (*z).RewardsState.RewardsPool.Msgsize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + (*z).RewardsState.RewardsRecalculationRound.Msgsize() + 6 + (*z).UpgradeState.CurrentProtocol.Msgsize() + 10 + (*z).UpgradeState.NextProtocol.Msgsize() + 8 + msgp.Uint64Size + 11 + (*z).UpgradeState.NextProtocolVoteBefore.Msgsize() + 11 + (*z).UpgradeState.NextProtocolSwitchOn.Msgsize() + 12 + (*z).UpgradeVote.UpgradePropose.Msgsize() + 13 + (*z).UpgradeVote.UpgradeDelay.Msgsize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4 + msgp.MapHeaderSize
if (*z).StateProofTracking != nil {
for zb0001, zb0002 := range (*z).StateProofTracking {
_ = zb0001
@@ -1847,12 +1939,12 @@ func (z *BlockHeader) Msgsize() (s int) {
// MsgIsZero returns whether this is a zero value
func (z *BlockHeader) MsgIsZero() bool {
- return ((*z).Round.MsgIsZero()) && ((*z).Branch.MsgIsZero()) && ((*z).Seed.MsgIsZero()) && ((*z).TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).TimeStamp == 0) && ((*z).GenesisID == "") && ((*z).GenesisHash.MsgIsZero()) && ((*z).RewardsState.FeeSink.MsgIsZero()) && ((*z).RewardsState.RewardsPool.MsgIsZero()) && ((*z).RewardsState.RewardsLevel == 0) && ((*z).RewardsState.RewardsRate == 0) && ((*z).RewardsState.RewardsResidue == 0) && ((*z).RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).UpgradeState.NextProtocol.MsgIsZero()) && ((*z).UpgradeState.NextProtocolApprovals == 0) && ((*z).UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).UpgradeVote.UpgradeApprove == false) && ((*z).TxnCounter == 0) && (len((*z).StateProofTracking) == 0) && (len((*z).ParticipationUpdates.ExpiredParticipationAccounts) == 0)
+ return ((*z).Round.MsgIsZero()) && ((*z).Branch.MsgIsZero()) && ((*z).Seed.MsgIsZero()) && ((*z).TxnCommitments.NativeSha512_256Commitment.MsgIsZero()) && ((*z).TxnCommitments.Sha256Commitment.MsgIsZero()) && ((*z).TimeStamp == 0) && ((*z).GenesisID == "") && ((*z).GenesisHash.MsgIsZero()) && ((*z).Proposer.MsgIsZero()) && ((*z).FeesCollected.MsgIsZero()) && ((*z).RewardsState.FeeSink.MsgIsZero()) && ((*z).RewardsState.RewardsPool.MsgIsZero()) && ((*z).RewardsState.RewardsLevel == 0) && ((*z).RewardsState.RewardsRate == 0) && ((*z).RewardsState.RewardsResidue == 0) && ((*z).RewardsState.RewardsRecalculationRound.MsgIsZero()) && ((*z).UpgradeState.CurrentProtocol.MsgIsZero()) && ((*z).UpgradeState.NextProtocol.MsgIsZero()) && ((*z).UpgradeState.NextProtocolApprovals == 0) && ((*z).UpgradeState.NextProtocolVoteBefore.MsgIsZero()) && ((*z).UpgradeState.NextProtocolSwitchOn.MsgIsZero()) && ((*z).UpgradeVote.UpgradePropose.MsgIsZero()) && ((*z).UpgradeVote.UpgradeDelay.MsgIsZero()) && ((*z).UpgradeVote.UpgradeApprove == false) && ((*z).TxnCounter == 0) && (len((*z).StateProofTracking) == 0) && (len((*z).ParticipationUpdates.ExpiredParticipationAccounts) == 0)
}
// MaxSize returns a maximum valid message size for this message type
func BlockHeaderMaxSize() (s int) {
- s = 3 + 4 + basics.RoundMaxSize() + 5 + BlockHashMaxSize() + 5 + committee.SeedMaxSize() + 4 + crypto.DigestMaxSize() + 7 + crypto.DigestMaxSize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + config.MaxGenesisIDLen + 3 + crypto.DigestMaxSize() + 5 + basics.AddressMaxSize() + 4 + basics.AddressMaxSize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + basics.RoundMaxSize() + 6 + protocol.ConsensusVersionMaxSize() + 10 + protocol.ConsensusVersionMaxSize() + 8 + msgp.Uint64Size + 11 + basics.RoundMaxSize() + 11 + basics.RoundMaxSize() + 12 + protocol.ConsensusVersionMaxSize() + 13 + basics.RoundMaxSize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4
+ s = 3 + 4 + basics.RoundMaxSize() + 5 + BlockHashMaxSize() + 5 + committee.SeedMaxSize() + 4 + crypto.DigestMaxSize() + 7 + crypto.DigestMaxSize() + 3 + msgp.Int64Size + 4 + msgp.StringPrefixSize + config.MaxGenesisIDLen + 3 + crypto.DigestMaxSize() + 4 + basics.AddressMaxSize() + 3 + basics.MicroAlgosMaxSize() + 5 + basics.AddressMaxSize() + 4 + basics.AddressMaxSize() + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 5 + msgp.Uint64Size + 7 + basics.RoundMaxSize() + 6 + protocol.ConsensusVersionMaxSize() + 10 + protocol.ConsensusVersionMaxSize() + 8 + msgp.Uint64Size + 11 + basics.RoundMaxSize() + 11 + basics.RoundMaxSize() + 12 + protocol.ConsensusVersionMaxSize() + 13 + basics.RoundMaxSize() + 11 + msgp.BoolSize + 3 + msgp.Uint64Size + 4
s += msgp.MapHeaderSize
// Adding size of map keys for z.StateProofTracking
s += protocol.NumStateProofTypes * (protocol.StateProofTypeMaxSize())
diff --git a/data/datatest/impls.go b/data/datatest/impls.go
index 7c9462d40d..67bdefbb8c 100644
--- a/data/datatest/impls.go
+++ b/data/datatest/impls.go
@@ -65,8 +65,8 @@ func (i entryFactoryImpl) AssembleBlock(round basics.Round) (agreement.Validated
}
// WithSeed implements the agreement.ValidatedBlock interface.
-func (ve validatedBlock) WithSeed(s committee.Seed) agreement.ValidatedBlock {
- newblock := ve.blk.WithSeed(s)
+func (ve validatedBlock) WithSeed(s committee.Seed, proposer basics.Address) agreement.ValidatedBlock {
+ newblock := ve.blk.WithSeed(s, proposer)
return validatedBlock{blk: &newblock}
}
diff --git a/data/transactions/logic/assembler_test.go b/data/transactions/logic/assembler_test.go
index 3f609fd7ee..0d2ae828ce 100644
--- a/data/transactions/logic/assembler_test.go
+++ b/data/transactions/logic/assembler_test.go
@@ -1707,6 +1707,10 @@ block BlkSeed
global AssetCreateMinBalance
global AssetOptInMinBalance
global GenesisHash
+pushint 1
+block BlkProposer
+pushint 1
+block BlkFeesCollected
`, AssemblerMaxVersion)
for _, names := range [][]string{GlobalFieldNames[:], TxnFieldNames[:], blockFieldNames[:]} {
for _, f := range names {
diff --git a/data/transactions/logic/eval.go b/data/transactions/logic/eval.go
index 210d7a3164..8d85a15772 100644
--- a/data/transactions/logic/eval.go
+++ b/data/transactions/logic/eval.go
@@ -5700,17 +5700,20 @@ func opBlock(cx *EvalContext) error {
switch fs.field {
case BlkSeed:
cx.Stack[last].Bytes = hdr.Seed[:]
- return nil
case BlkTimestamp:
cx.Stack[last].Bytes = nil
if hdr.TimeStamp < 0 {
return fmt.Errorf("block(%d) timestamp %d < 0", round, hdr.TimeStamp)
}
cx.Stack[last].Uint = uint64(hdr.TimeStamp)
- return nil
+ case BlkProposer:
+ cx.Stack[last].Bytes = hdr.Proposer[:]
+ case BlkFeesCollected:
+ cx.Stack[last].Uint = hdr.FeesCollected.Raw
default:
return fmt.Errorf("invalid block field %s", fs.field)
}
+ return nil
}
// pcDetails return PC and disassembled instructions at PC up to 2 opcodes back
diff --git a/data/transactions/logic/fields.go b/data/transactions/logic/fields.go
index a2f971f7b7..7f962125b5 100644
--- a/data/transactions/logic/fields.go
+++ b/data/transactions/logic/fields.go
@@ -965,6 +965,10 @@ const (
BlkSeed BlockField = iota
// BlkTimestamp is the Block's timestamp, seconds from epoch
BlkTimestamp
+ // BlkProposer is the Block's proposer, or ZeroAddress, pre EnableMining
+ BlkProposer
+ // BlkFeesCollected is the sum of fees for the block, or 0, pre EnableMining
+ BlkFeesCollected
invalidBlockField // compile-time constant for number of fields
)
@@ -980,6 +984,8 @@ type blockFieldSpec struct {
var blockFieldSpecs = [...]blockFieldSpec{
{BlkSeed, StackBytes, randomnessVersion},
{BlkTimestamp, StackUint64, randomnessVersion},
+ {BlkProposer, StackAddress, incentiveVersion},
+ {BlkFeesCollected, StackUint64, incentiveVersion},
}
func blockFieldSpecByField(r BlockField) (blockFieldSpec, bool) {
diff --git a/data/transactions/logic/fields_string.go b/data/transactions/logic/fields_string.go
index 37bfeb9bcc..70f74fe11e 100644
--- a/data/transactions/logic/fields_string.go
+++ b/data/transactions/logic/fields_string.go
@@ -352,12 +352,14 @@ func _() {
var x [1]struct{}
_ = x[BlkSeed-0]
_ = x[BlkTimestamp-1]
- _ = x[invalidBlockField-2]
+ _ = x[BlkProposer-2]
+ _ = x[BlkFeesCollected-3]
+ _ = x[invalidBlockField-4]
}
-const _BlockField_name = "BlkSeedBlkTimestampinvalidBlockField"
+const _BlockField_name = "BlkSeedBlkTimestampBlkProposerBlkFeesCollectedinvalidBlockField"
-var _BlockField_index = [...]uint8{0, 7, 19, 36}
+var _BlockField_index = [...]uint8{0, 7, 19, 30, 46, 63}
func (i BlockField) String() string {
if i < 0 || i >= BlockField(len(_BlockField_index)-1) {
diff --git a/data/transactions/logic/opcodes.go b/data/transactions/logic/opcodes.go
index b8ecd76cac..ae152bf919 100644
--- a/data/transactions/logic/opcodes.go
+++ b/data/transactions/logic/opcodes.go
@@ -71,11 +71,13 @@ const fpVersion = 8 // changes for frame pointers and simpler function d
const sharedResourcesVersion = 9 // apps can access resources from other transactions.
+const pairingVersion = 10 // bn256 opcodes. will add bls12-381, and unify the available opcodes.
+const spliceVersion = 10 // box splicing/resizing
+
// EXPERIMENTAL. These should be revisited whenever a new LogicSigVersion is
// moved from vFuture to a new consensus version. If they remain unready, bump
// their version, and fixup TestAssemble() in assembler_test.go.
-const pairingVersion = 10 // bn256 opcodes. will add bls12-381, and unify the available opcodes.
-const spliceVersion = 10 // box splicing/resizing
+const incentiveVersion = 11 // block fields, heartbeat
const spOpcodesVersion = 11 // falcon_verify, sumhash512
diff --git a/data/transactions/payment.go b/data/transactions/payment.go
index 62eafdb1e9..d3c1432e7c 100644
--- a/data/transactions/payment.go
+++ b/data/transactions/payment.go
@@ -42,8 +42,11 @@ func (payment PaymentTxnFields) checkSpender(header Header, spec SpecialAddresse
return fmt.Errorf("transaction cannot close account to its sender %v", header.Sender)
}
- // the FeeSink account may only spend to the IncentivePool
+ // the FeeSink account may only spend to the IncentivePool (not at all, if EnableMining)
if header.Sender == spec.FeeSink {
+ if proto.EnableMining {
+ return fmt.Errorf("cannot spend from fee sink address %v", header.Sender)
+ }
if payment.Receiver != spec.RewardsPool {
return fmt.Errorf("cannot spend from fee sink's address %v to non incentive pool address %v", header.Sender, payment.Receiver)
}
diff --git a/data/transactions/transaction_test.go b/data/transactions/transaction_test.go
index e3a25619bb..dfec67c558 100644
--- a/data/transactions/transaction_test.go
+++ b/data/transactions/transaction_test.go
@@ -101,13 +101,13 @@ func TestGoOnlineGoNonparticipatingContradiction(t *testing.T) {
tx.KeyregTxnFields = KeyregTxnFields{
VotePK: v.OneTimeSignatureVerifier,
SelectionPK: vrf.PK,
+ VoteKeyDilution: 1,
Nonparticipation: true,
}
// this tx tries to both register keys to go online, and mark an account as non-participating.
// it is not well-formed.
- feeSink := basics.Address{0x7, 0xda, 0xcb, 0x4b, 0x6d, 0x9e, 0xd1, 0x41, 0xb1, 0x75, 0x76, 0xbd, 0x45, 0x9a, 0xe6, 0x42, 0x1d, 0x48, 0x6d, 0xa3, 0xd4, 0xef, 0x22, 0x47, 0xc4, 0x9, 0xa3, 0x96, 0xb8, 0x2e, 0xa2, 0x21}
- err = tx.WellFormed(SpecialAddresses{FeeSink: feeSink}, config.Consensus[protocol.ConsensusCurrentVersion])
- require.Error(t, err)
+ err = tx.WellFormed(SpecialAddresses{}, config.Consensus[protocol.ConsensusCurrentVersion])
+ require.ErrorContains(t, err, "go online, but vote last is set to zero")
}
func TestGoNonparticipatingWellFormed(t *testing.T) {
@@ -125,19 +125,17 @@ func TestGoNonparticipatingWellFormed(t *testing.T) {
}
// this tx is well-formed
- feeSink := basics.Address{0x7, 0xda, 0xcb, 0x4b, 0x6d, 0x9e, 0xd1, 0x41, 0xb1, 0x75, 0x76, 0xbd, 0x45, 0x9a, 0xe6, 0x42, 0x1d, 0x48, 0x6d, 0xa3, 0xd4, 0xef, 0x22, 0x47, 0xc4, 0x9, 0xa3, 0x96, 0xb8, 0x2e, 0xa2, 0x21}
- err = tx.WellFormed(SpecialAddresses{FeeSink: feeSink}, curProto)
+ err = tx.WellFormed(SpecialAddresses{}, curProto)
require.NoError(t, err)
// but it should stop being well-formed if the protocol does not support it
curProto.SupportBecomeNonParticipatingTransactions = false
- err = tx.WellFormed(SpecialAddresses{FeeSink: feeSink}, curProto)
- require.Error(t, err)
+ err = tx.WellFormed(SpecialAddresses{}, curProto)
+ require.ErrorContains(t, err, "mark an account as nonparticipating, but")
}
func TestAppCallCreateWellFormed(t *testing.T) {
partitiontest.PartitionTest(t)
- feeSink := basics.Address{0x7, 0xda, 0xcb, 0x4b, 0x6d, 0x9e, 0xd1, 0x41, 0xb1, 0x75, 0x76, 0xbd, 0x45, 0x9a, 0xe6, 0x42, 0x1d, 0x48, 0x6d, 0xa3, 0xd4, 0xef, 0x22, 0x47, 0xc4, 0x9, 0xa3, 0x96, 0xb8, 0x2e, 0xa2, 0x21}
curProto := config.Consensus[protocol.ConsensusCurrentVersion]
futureProto := config.Consensus[protocol.ConsensusFuture]
addr1, err := basics.UnmarshalChecksumAddress("NDQCJNNY5WWWFLP4GFZ7MEF2QJSMZYK6OWIV2AQ7OMAVLEFCGGRHFPKJJA")
@@ -253,7 +251,7 @@ func TestAppCallCreateWellFormed(t *testing.T) {
}
for i, usecase := range usecases {
t.Run(fmt.Sprintf("i=%d", i), func(t *testing.T) {
- err := usecase.tx.WellFormed(SpecialAddresses{FeeSink: feeSink}, usecase.proto)
+ err := usecase.tx.WellFormed(SpecialAddresses{}, usecase.proto)
if usecase.expectedError != "" {
require.Error(t, err)
require.Contains(t, err.Error(), usecase.expectedError)
@@ -267,8 +265,6 @@ func TestAppCallCreateWellFormed(t *testing.T) {
func TestWellFormedErrors(t *testing.T) {
partitiontest.PartitionTest(t)
- feeSink := basics.Address{0x7, 0xda, 0xcb, 0x4b, 0x6d, 0x9e, 0xd1, 0x41, 0xb1, 0x75, 0x76, 0xbd, 0x45, 0x9a, 0xe6, 0x42, 0x1d, 0x48, 0x6d, 0xa3, 0xd4, 0xef, 0x22, 0x47, 0xc4, 0x9, 0xa3, 0x96, 0xb8, 0x2e, 0xa2, 0x21}
- specialAddr := SpecialAddresses{FeeSink: feeSink}
curProto := config.Consensus[protocol.ConsensusCurrentVersion]
futureProto := config.Consensus[protocol.ConsensusFuture]
protoV27 := config.Consensus[protocol.ConsensusV27]
@@ -595,7 +591,7 @@ func TestWellFormedErrors(t *testing.T) {
},
}
for _, usecase := range usecases {
- err := usecase.tx.WellFormed(specialAddr, usecase.proto)
+ err := usecase.tx.WellFormed(SpecialAddresses{}, usecase.proto)
require.Equal(t, usecase.expectedError, err)
}
}
@@ -632,14 +628,12 @@ func TestWellFormedKeyRegistrationTx(t *testing.T) {
tx := generateDummyGoNonparticpatingTransaction(addr)
curProto := config.Consensus[protocol.ConsensusCurrentVersion]
- feeSink := basics.Address{0x7, 0xda, 0xcb, 0x4b, 0x6d, 0x9e, 0xd1, 0x41, 0xb1, 0x75, 0x76, 0xbd, 0x45, 0x9a, 0xe6, 0x42, 0x1d, 0x48, 0x6d, 0xa3, 0xd4, 0xef, 0x22, 0x47, 0xc4, 0x9, 0xa3, 0x96, 0xb8, 0x2e, 0xa2, 0x21}
- spec := SpecialAddresses{FeeSink: feeSink}
if !curProto.SupportBecomeNonParticipatingTransactions {
t.Skipf("Skipping rest of test because current protocol version %v does not support become-nonparticipating transactions", protocol.ConsensusCurrentVersion)
}
// this tx is well-formed
- err = tx.WellFormed(spec, curProto)
+ err = tx.WellFormed(SpecialAddresses{}, curProto)
require.NoError(t, err)
type keyRegTestCase struct {
@@ -677,7 +671,7 @@ func TestWellFormedKeyRegistrationTx(t *testing.T) {
curProto.EnableKeyregCoherencyCheck = testCase.enableKeyregCoherencyCheck
curProto.EnableStateProofKeyregCheck = testCase.enableStateProofKeyregCheck
curProto.MaxKeyregValidPeriod = maxValidPeriod // TODO: remove this when MaxKeyregValidPeriod is in CurrentVersion
- return tx.WellFormed(spec, curProto)
+ return tx.WellFormed(SpecialAddresses{}, curProto)
}
if *generateFlag == true {
diff --git a/data/txntest/txn.go b/data/txntest/txn.go
index 515c9df458..26553d6b97 100644
--- a/data/txntest/txn.go
+++ b/data/txntest/txn.go
@@ -23,6 +23,7 @@ import (
"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/crypto"
+ "github.com/algorand/go-algorand/crypto/merklesignature"
"github.com/algorand/go-algorand/crypto/stateproof"
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/data/stateproofmsg"
@@ -55,6 +56,7 @@ type Txn struct {
VoteLast basics.Round
VoteKeyDilution uint64
Nonparticipation bool
+ StateProofPK merklesignature.Commitment
Receiver basics.Address
Amount uint64
@@ -228,6 +230,7 @@ func (tx Txn) Txn() transactions.Transaction {
VoteLast: tx.VoteLast,
VoteKeyDilution: tx.VoteKeyDilution,
Nonparticipation: tx.Nonparticipation,
+ StateProofPK: tx.StateProofPK,
},
PaymentTxnFields: transactions.PaymentTxnFields{
Receiver: tx.Receiver,
diff --git a/ledger/acctonline_expired_test.go b/ledger/acctonline_expired_test.go
index ac7986a78b..e51494d184 100644
--- a/ledger/acctonline_expired_test.go
+++ b/ledger/acctonline_expired_test.go
@@ -244,9 +244,8 @@ type doubleLedgerAcctModel struct {
}
func newDoubleLedgerAcctModel(t testing.TB, proto protocol.ConsensusVersion, inMem bool) *doubleLedgerAcctModel {
- // set 1 Algo for rewards pool size -- rewards math not supported by newMapOnlineAcctModel
- genesisOpt := ledgertesting.TestGenesisRewardsPoolSize(basics.MicroAlgos{Raw: 1_000_000})
- genBalances, genAddrs, genSecrets := ledgertesting.NewTestGenesis(genesisOpt)
+ // rewards math not supported by newMapOnlineAcctModel
+ genBalances, genAddrs, genSecrets := ledgertesting.NewTestGenesis(ledgertesting.TurnOffRewards)
cfg := config.GetDefaultLocal()
opts := []simpleLedgerOption{simpleLedgerNotArchival()}
if !inMem {
diff --git a/ledger/apply/asset_test.go b/ledger/apply/asset_test.go
index eddc15757e..0280ecdb60 100644
--- a/ledger/apply/asset_test.go
+++ b/ledger/apply/asset_test.go
@@ -90,7 +90,7 @@ func TestAssetTransfer(t *testing.T) {
}
var ad transactions.ApplyData
- err := AssetTransfer(tx.AssetTransferTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, &ad)
+ err := AssetTransfer(tx.AssetTransferTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, &ad)
require.NoError(t, err)
if config.Consensus[protocol.ConsensusCurrentVersion].EnableAssetCloseAmount {
diff --git a/ledger/apply/keyreg.go b/ledger/apply/keyreg.go
index 4fe0f0a326..6a83eab316 100644
--- a/ledger/apply/keyreg.go
+++ b/ledger/apply/keyreg.go
@@ -31,7 +31,7 @@ var errKeyregGoingOnlineFirstVotingInFuture = errors.New("transaction tries to m
// Keyreg applies a KeyRegistration transaction using the Balances interface.
func Keyreg(keyreg transactions.KeyregTxnFields, header transactions.Header, balances Balances, spec transactions.SpecialAddresses, ad *transactions.ApplyData, round basics.Round) error {
if header.Sender == spec.FeeSink {
- return fmt.Errorf("cannot register participation key for fee sink's address %v ", header.Sender)
+ return fmt.Errorf("cannot register participation key for fee sink's address %v", header.Sender)
}
// Get the user's balance entry
@@ -67,6 +67,7 @@ func Keyreg(keyreg transactions.KeyregTxnFields, header transactions.Header, bal
record.VoteFirstValid = 0
record.VoteLastValid = 0
record.VoteKeyDilution = 0
+ record.IncentiveEligible = false
} else {
if params.EnableKeyregCoherencyCheck {
if keyreg.VoteLast <= round {
@@ -80,6 +81,9 @@ func Keyreg(keyreg transactions.KeyregTxnFields, header transactions.Header, bal
record.VoteFirstValid = keyreg.VoteFirst
record.VoteLastValid = keyreg.VoteLast
record.VoteKeyDilution = keyreg.VoteKeyDilution
+ if header.Fee.GTE(incentiveFeeForEligibility) && params.EnableMining {
+ record.IncentiveEligible = true
+ }
}
// Write the updated entry
@@ -90,3 +94,9 @@ func Keyreg(keyreg transactions.KeyregTxnFields, header transactions.Header, bal
return nil
}
+
+// incentiveFeeForEligibility imparts a small cost on moving from offline to
+// online. This will impose a cost to running unreliable nodes that get
+// suspended and then come back online. Becomes a consensus param if ever
+// changed.
+var incentiveFeeForEligibility = basics.Algos(2)
diff --git a/ledger/apply/keyreg_test.go b/ledger/apply/keyreg_test.go
index e64beea4b4..41976257ea 100644
--- a/ledger/apply/keyreg_test.go
+++ b/ledger/apply/keyreg_test.go
@@ -136,20 +136,20 @@ func TestKeyregApply(t *testing.T) {
// Going from offline to online should be okay
mockBal.addrs[src] = basics.AccountData{Status: basics.Offline}
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0))
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0))
require.NoError(t, err)
// Going from online to nonparticipatory should be okay, if the protocol supports that
if mockBal.ConsensusParams().SupportBecomeNonParticipatingTransactions {
tx.KeyregTxnFields = transactions.KeyregTxnFields{}
tx.KeyregTxnFields.Nonparticipation = true
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0))
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0))
require.NoError(t, err)
// Nonparticipatory accounts should not be able to change status
mockBal.addrs[src] = basics.AccountData{Status: basics.NotParticipating}
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0))
- require.Error(t, err)
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0))
+ require.ErrorContains(t, err, "cannot change online/offline status of non-participating account")
}
mockBal.version = "future"
@@ -171,25 +171,25 @@ func TestKeyregApply(t *testing.T) {
},
}
mockBal.addrs[src] = basics.AccountData{Status: basics.Offline}
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(999))
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(999))
require.NoError(t, err)
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(1000))
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(1000))
require.Equal(t, errKeyregGoingOnlineExpiredParticipationKey, err)
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(1001))
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(1001))
require.Equal(t, errKeyregGoingOnlineExpiredParticipationKey, err)
tx.KeyregTxnFields.VoteFirst = basics.Round(1100)
tx.KeyregTxnFields.VoteLast = basics.Round(1200)
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(1098))
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(1098))
require.Equal(t, errKeyregGoingOnlineFirstVotingInFuture, err)
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(1099))
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(1099))
require.NoError(t, err)
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(1100))
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(1100))
require.NoError(t, err)
testStateProofPKBeingStored(t, tx, mockBal)
@@ -197,7 +197,7 @@ func TestKeyregApply(t *testing.T) {
}
func testStateProofPKBeingStored(t *testing.T, tx transactions.Transaction, mockBal *keyregTestBalances) {
- err := Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(1100))
+ err := Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(1100))
require.NoError(t, err) // expects no error with empty keyRegistration attempt
rec, err := mockBal.Get(tx.Header.Sender, false)
@@ -215,7 +215,7 @@ func TestStateProofPKKeyReg(t *testing.T) {
tx := createTestTxn(t, src, secretParticipation, vrfSecrets)
mockBal := makeMockBalances(protocol.ConsensusV30)
- err := Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0))
+ err := Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0))
require.NoError(t, err)
acct, err := mockBal.Get(tx.Src(), false)
@@ -223,7 +223,7 @@ func TestStateProofPKKeyReg(t *testing.T) {
require.True(t, acct.StateProofID.IsEmpty())
mockBal = makeMockBalances(protocol.ConsensusCurrentVersion)
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0))
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0))
require.NoError(t, err)
acct, err = mockBal.Get(tx.Src(), false)
@@ -232,7 +232,7 @@ func TestStateProofPKKeyReg(t *testing.T) {
// go offline in current consensus version: StateProofID should be empty
emptyKeyreg := transactions.KeyregTxnFields{}
- err = Keyreg(emptyKeyreg, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0))
+ err = Keyreg(emptyKeyreg, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0))
require.NoError(t, err)
acct, err = mockBal.Get(tx.Src(), false)
@@ -241,7 +241,7 @@ func TestStateProofPKKeyReg(t *testing.T) {
// run same test using vFuture
mockBal = makeMockBalances(protocol.ConsensusFuture)
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0))
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0))
require.NoError(t, err)
acct, err = mockBal.Get(tx.Src(), false)
@@ -249,7 +249,7 @@ func TestStateProofPKKeyReg(t *testing.T) {
require.False(t, acct.StateProofID.IsEmpty())
// go offline in vFuture: StateProofID should be empty
- err = Keyreg(emptyKeyreg, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, nil, basics.Round(0))
+ err = Keyreg(emptyKeyreg, tx.Header, mockBal, transactions.SpecialAddresses{}, nil, basics.Round(0))
require.NoError(t, err)
acct, err = mockBal.Get(tx.Src(), false)
diff --git a/ledger/apply/payment_test.go b/ledger/apply/payment_test.go
index d377211a17..a0b5976d70 100644
--- a/ledger/apply/payment_test.go
+++ b/ledger/apply/payment_test.go
@@ -104,7 +104,7 @@ func TestPaymentApply(t *testing.T) {
},
}
var ad transactions.ApplyData
- err := Payment(tx.PaymentTxnFields, tx.Header, mockBalV0, transactions.SpecialAddresses{FeeSink: feeSink}, &ad)
+ err := Payment(tx.PaymentTxnFields, tx.Header, mockBalV0, transactions.SpecialAddresses{}, &ad)
require.NoError(t, err)
}
diff --git a/ledger/apptxn_test.go b/ledger/apptxn_test.go
index 167d22f2dc..0e193e3eb2 100644
--- a/ledger/apptxn_test.go
+++ b/ledger/apptxn_test.go
@@ -26,6 +26,7 @@ import (
"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/crypto"
+ "github.com/algorand/go-algorand/crypto/merklesignature"
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/data/transactions"
"github.com/algorand/go-algorand/data/transactions/logic"
@@ -35,7 +36,7 @@ import (
"github.com/algorand/go-algorand/test/partitiontest"
)
-// TestPayAction ensures a pay in teal affects balances
+// TestPayAction ensures a inner pay transaction affects balances
func TestPayAction(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()
@@ -58,6 +59,23 @@ 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.
+ proposer := basics.Address{0x01, 0x02, 0x03}
+ dl.txns(&txntest.Txn{
+ Type: "pay",
+ Sender: addrs[7],
+ Receiver: proposer,
+ Amount: 1_000_000 * 1_000_000, // 1 million algos is surely an eligible amount
+ }, &txntest.Txn{
+ Type: "keyreg",
+ Sender: proposer,
+ Fee: 3_000_000,
+ VotePK: crypto.OneTimeSignatureVerifier{0x01},
+ SelectionPK: crypto.VRFVerifier{0x02},
+ StateProofPK: merklesignature.Commitment{0x03},
+ VoteFirst: 1, VoteLast: 1000,
+ })
+
payout1 := txntest.Txn{
Type: "appl",
Sender: addrs[1],
@@ -65,7 +83,39 @@ func TestPayAction(t *testing.T) {
Accounts: []basics.Address{addrs[1]}, // pay self
}
- dl.fullBlock(&payout1)
+ 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 >= 40 {
+ require.True(t, dl.generator.GenesisProto().EnableMining)
+ require.EqualValues(t, proposer, vb.Block().BlockHeader.Proposer)
+ require.EqualValues(t, 2000, vb.Block().BlockHeader.FeesCollected.Raw)
+ } 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 >= 40 {
+ 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 +140,7 @@ func TestPayAction(t *testing.T) {
ApplicationID: ai,
Accounts: []basics.Address{addrs[2]}, // pay other
}
- vb := dl.fullBlock(&payout2)
+ vb = dl.fullBlock(&payout2)
// confirm that modifiedAccounts can see account in inner txn
deltas := vb.Delta()
diff --git a/ledger/double_test.go b/ledger/double_test.go
index c08212e373..00ae863399 100644
--- a/ledger/double_test.go
+++ b/ledger/double_test.go
@@ -48,6 +48,9 @@ type DoubleLedger struct {
validator *Ledger
eval *eval.BlockEvaluator
+
+ // proposer is the default proposer unless one is supplied to endBlock.
+ proposer basics.Address
}
func (dl DoubleLedger) Close() {
@@ -59,7 +62,7 @@ func (dl DoubleLedger) Close() {
func NewDoubleLedger(t testing.TB, balances bookkeeping.GenesisBalances, cv protocol.ConsensusVersion, cfg config.Local, opts ...simpleLedgerOption) DoubleLedger {
g := newSimpleLedgerWithConsensusVersion(t, balances, cv, cfg, opts...)
v := newSimpleLedgerFull(t, balances, cv, g.GenesisHash(), cfg, opts...)
- return DoubleLedger{t, g, v, nil}
+ return DoubleLedger{t, g, v, nil, balances.FeeSink} // FeeSink as proposer will make old code work as expected
}
func (dl *DoubleLedger) beginBlock() *eval.BlockEvaluator {
@@ -134,8 +137,12 @@ func (dl *DoubleLedger) fullBlock(txs ...*txntest.Txn) *ledgercore.ValidatedBloc
return dl.endBlock()
}
-func (dl *DoubleLedger) endBlock() *ledgercore.ValidatedBlock {
- vb := endBlock(dl.t, dl.generator, dl.eval)
+func (dl *DoubleLedger) endBlock(proposer ...basics.Address) *ledgercore.ValidatedBlock {
+ prp := dl.proposer
+ if len(proposer) > 0 {
+ prp = proposer[0]
+ }
+ vb := endBlock(dl.t, dl.generator, dl.eval, prp)
if dl.validator != nil { // Allows setting to nil while debugging, to simplify
checkBlock(dl.t, dl.validator, vb)
}
@@ -195,7 +202,7 @@ func checkBlock(t testing.TB, checkLedger *Ledger, vb *ledgercore.ValidatedBlock
require.NoError(t, err, "%+v", reconstituted.Payset)
}
check.SetGenerateForTesting(true)
- cb := endBlock(t, checkLedger, check)
+ cb := endBlock(t, checkLedger, check, vb.Block().Proposer)
check.SetGenerateForTesting(false)
require.Equal(t, vb.Block(), cb.Block())
diff --git a/ledger/eval/applications.go b/ledger/eval/applications.go
index 8be898e05c..3aa7bd3905 100644
--- a/ledger/eval/applications.go
+++ b/ledger/eval/applications.go
@@ -290,8 +290,7 @@ func (cs *roundCowState) DelBox(appIdx basics.AppIndex, key string, appAddr basi
func (cs *roundCowState) Perform(gi int, ep *logic.EvalParams) error {
txn := &ep.TxnGroup[gi]
- // move fee to pool
- err := cs.Move(txn.Txn.Sender, ep.Specials.FeeSink, txn.Txn.Fee, &txn.ApplyData.SenderRewards, nil)
+ err := cs.takeFee(&txn.Txn, &txn.ApplyData.SenderRewards, ep)
if err != nil {
return err
}
diff --git a/ledger/eval/cow.go b/ledger/eval/cow.go
index 269ce570ff..1e8f3c1a50 100644
--- a/ledger/eval/cow.go
+++ b/ledger/eval/cow.go
@@ -95,6 +95,8 @@ type roundCowState struct {
// prevTotals contains the accounts totals for the previous round. It's being used to calculate the totals for the new round
// so that we could perform the validation test on these to ensure the block evaluator generate a valid changeset.
prevTotals ledgercore.AccountTotals
+
+ feesCollected basics.MicroAlgos
}
var childPool = sync.Pool{
@@ -299,6 +301,8 @@ func (cb *roundCowState) commitToParent() {
cb.commitParent.mods.Txids[txid] = ledgercore.IncludedTransactions{LastValid: incTxn.LastValid, Intra: commitParentBaseIdx + incTxn.Intra}
}
cb.commitParent.txnCount += cb.txnCount
+ // no overflow because of 10B algo cap
+ cb.commitParent.feesCollected, _ = basics.OAddA(cb.commitParent.feesCollected, cb.feesCollected)
for txl, expires := range cb.mods.Txleases {
cb.commitParent.mods.AddTxLease(txl, expires)
@@ -342,6 +346,7 @@ func (cb *roundCowState) reset() {
cb.compatibilityMode = false
maps.Clear(cb.compatibilityGetKeyCache)
cb.prevTotals = ledgercore.AccountTotals{}
+ cb.feesCollected = basics.MicroAlgos{}
}
// recycle resets the roundcowstate and returns it to the sync.Pool
diff --git a/ledger/eval/cow_test.go b/ledger/eval/cow_test.go
index 06d600d58a..81224a8d0b 100644
--- a/ledger/eval/cow_test.go
+++ b/ledger/eval/cow_test.go
@@ -282,6 +282,7 @@ func TestCowChildReflect(t *testing.T) {
"compatibilityMode": {},
"compatibilityGetKeyCache": {},
"prevTotals": {},
+ "feesCollected": {},
}
cow := roundCowState{}
@@ -289,7 +290,7 @@ func TestCowChildReflect(t *testing.T) {
st := v.Type()
for i := 0; i < v.NumField(); i++ {
reflectedCowName := st.Field(i).Name
- require.Containsf(t, cowFieldNames, reflectedCowName, "new field:\"%v\" added to roundCowState, please update roundCowState.reset() to handle it before fixing the test", reflectedCowName)
+ require.Containsf(t, cowFieldNames, reflectedCowName, "new field:\"%v\" added to roundCowState, please update roundCowState.reset() to handle it before fixing this test", reflectedCowName)
}
}
diff --git a/ledger/eval/eval.go b/ledger/eval/eval.go
index de1304988a..fd4f65fa77 100644
--- a/ledger/eval/eval.go
+++ b/ledger/eval/eval.go
@@ -788,6 +788,15 @@ func StartEvaluator(l LedgerForEvaluator, hdr bookkeeping.BlockHeader, evalOpts
return nil, fmt.Errorf("overflowed subtracting rewards for block %v", hdr.Round)
}
+ if eval.eligibleForIncentives(prevHeader.Proposer) {
+ miningIncentive, _ := basics.NewPercent(proto.MiningPercent).DivvyAlgos(prevHeader.FeesCollected)
+ err = eval.state.Move(prevHeader.FeeSink, prevHeader.Proposer, miningIncentive, nil, nil)
+ if err != nil {
+ // This should be impossible. The fees were just collected, and the FeeSink cannot be emptied.
+ return nil, fmt.Errorf("unable to Move mining incentive")
+ }
+ }
+
if eval.Tracer != nil {
eval.Tracer.BeforeBlock(&eval.block.BlockHeader)
}
@@ -795,6 +804,44 @@ func StartEvaluator(l LedgerForEvaluator, hdr bookkeeping.BlockHeader, evalOpts
return eval, nil
}
+var (
+ // these would become ConsensusParameters if we ever wanted to change them
+
+ // incentiveMinBalance is the minimum balance an account must have to be
+ // eligible for incentives. It serves a couple purposes. First, it sets a
+ // manageable upper bound on the total number of incentivized participating
+ // accounts. This means it is possible to track these accounts in memory,
+ // which is required to ensure absenteeism checking time is bounded. Second,
+ // it ensures that smaller accounts continue to operate for the same
+ // motivations they had before block incentives were introduced. Without
+ // that assurance, it is difficult to model their behaviour - might many
+ // participants join for the hope of easy financial rewards, but without
+ // caring enough to run a high-quality node?
+ incentiveMinBalance = basics.Algos(100_000)
+
+ // incentiveMaxBalance is the maximum balance an account might have to be
+ // eligible for incentives. It encourages large accounts to split their
+ // stake to add resilience to consensus in the case of outages. Of course,
+ // nothing in protocol can prevent such accounts from running nodes that
+ // share fate (same machine, same data center, etc), but this serves as a
+ // gentle reminder.
+ incentiveMaxBalance = basics.Algos(100_000_000)
+)
+
+func (eval *BlockEvaluator) eligibleForIncentives(proposer basics.Address) bool {
+ proposerState, err := eval.state.Get(proposer, true)
+ if err != nil {
+ return false
+ }
+ if proposerState.MicroAlgos.LessThan(incentiveMinBalance) {
+ return false
+ }
+ if proposerState.MicroAlgos.GreaterThan(incentiveMaxBalance) {
+ return false
+ }
+ return proposerState.IncentiveEligible
+}
+
// hotfix for testnet stall 08/26/2019; move some algos from testnet bank to rewards pool to give it enough time until protocol upgrade occur.
// hotfix for testnet stall 11/07/2019; do the same thing
func (eval *BlockEvaluator) workaroundOverspentRewards(rewardPoolBalance ledgercore.AccountData, headerRound basics.Round) (poolOld ledgercore.AccountData, err error) {
@@ -1165,12 +1212,27 @@ func (eval *BlockEvaluator) transaction(txn transactions.SignedTxn, evalParams *
return nil
}
+func (cs *roundCowState) takeFee(tx *transactions.Transaction, senderRewards *basics.MicroAlgos, ep *logic.EvalParams) error {
+ err := cs.Move(tx.Sender, ep.Specials.FeeSink, tx.Fee, senderRewards, nil)
+ if err != nil {
+ return err
+ }
+ // transactions from FeeSink should be exceedingly rare. But we can't count
+ // them in feesCollected because there are no net algos added to the Sink
+ if tx.Sender == ep.Specials.FeeSink {
+ return nil
+ }
+ // overflow impossible, since these sum the fees actually paid. 10B algo limit
+ cs.feesCollected, _ = basics.OAddA(cs.feesCollected, tx.Fee)
+ return nil
+
+}
+
// applyTransaction changes the balances according to this transaction.
func (eval *BlockEvaluator) applyTransaction(tx transactions.Transaction, cow *roundCowState, evalParams *logic.EvalParams, gi int, ctr uint64) (ad transactions.ApplyData, err error) {
params := cow.ConsensusParams()
- // move fee to pool
- err = cow.Move(tx.Sender, eval.specials.FeeSink, tx.Fee, &ad.SenderRewards, nil)
+ err = cow.takeFee(&tx, &ad.SenderRewards, evalParams)
if err != nil {
return
}
@@ -1272,6 +1334,10 @@ func (eval *BlockEvaluator) endOfBlock() error {
eval.block.TxnCounter = 0
}
+ if eval.proto.EnableMining {
+ eval.block.FeesCollected = eval.state.feesCollected
+ }
+
eval.generateExpiredOnlineAccountsList()
if eval.proto.StateProofInterval > 0 {
@@ -1316,6 +1382,14 @@ func (eval *BlockEvaluator) endOfBlock() error {
return fmt.Errorf("txn count wrong: %d != %d", eval.block.TxnCounter, expectedTxnCount)
}
+ var expectedFeesCollected basics.MicroAlgos
+ if eval.proto.EnableMining {
+ expectedFeesCollected = eval.state.feesCollected
+ }
+ if eval.block.FeesCollected != expectedFeesCollected {
+ return fmt.Errorf("fees collected wrong: %v != %v", eval.block.FeesCollected, expectedFeesCollected)
+ }
+
expectedVoters, expectedVotersWeight, err2 := eval.stateProofVotersAndTotal()
if err2 != nil {
return err2
diff --git a/ledger/eval/prefetcher/prefetcher_alignment_test.go b/ledger/eval/prefetcher/prefetcher_alignment_test.go
index 57f4c5d92b..2f79cd45d4 100644
--- a/ledger/eval/prefetcher/prefetcher_alignment_test.go
+++ b/ledger/eval/prefetcher/prefetcher_alignment_test.go
@@ -58,6 +58,10 @@ func rewardsPool() basics.Address {
return makeAddress(101)
}
+func proposer() basics.Address {
+ return basics.Address{}
+}
+
func genesisBlock() (bookkeeping.Block, error) {
block, err := bookkeeping.MakeGenesisBlock(
proto,
@@ -261,6 +265,18 @@ type ledgerData struct {
Creators map[creatable]struct{}
}
+// pretend adds the `before` addresses to the Accounts. It "pretends" that the
+// addresses were prefetched, so we can get agreement with what was actually
+// requested. We do this to include two addresses that are going to end up
+// requested *before* prefetch is even attempted. So there's no point in
+// PrefetchAccounts being modified to return them, they have been "prefetched"
+// simply by accessing them.
+func (ld *ledgerData) pretend(before ...basics.Address) {
+ for _, a := range before {
+ ld.Accounts[a] = struct{}{}
+ }
+}
+
func prefetch(t *testing.T, l prefetcher.Ledger, txn transactions.Transaction) ledgerData {
group := makeGroupFromTxn(txn)
@@ -361,7 +377,7 @@ func TestEvaluatorPrefetcherAlignmentPayment(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -393,7 +409,7 @@ func TestEvaluatorPrefetcherAlignmentCreateAsset(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
// Only one (non-existing) asset is requested. Ignore it.
require.Len(t, requested.Assets, 1)
require.Len(t, requested.Assets[makeAddress(1)], 1)
@@ -449,7 +465,7 @@ func TestEvaluatorPrefetcherAlignmentReconfigAsset(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -504,7 +520,7 @@ func TestEvaluatorPrefetcherAlignmentAssetOptIn(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -570,7 +586,7 @@ func TestEvaluatorPrefetcherAlignmentAssetOptInCloseTo(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -641,7 +657,7 @@ func TestEvaluatorPrefetcherAlignmentAssetTransfer(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
// zero transfer of any asset
@@ -660,7 +676,7 @@ func TestEvaluatorPrefetcherAlignmentAssetTransfer(t *testing.T) {
requested, prefetched = run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -741,7 +757,7 @@ func TestEvaluatorPrefetcherAlignmentAssetClawback(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -811,7 +827,7 @@ func TestEvaluatorPrefetcherAlignmentAssetFreeze(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -858,7 +874,7 @@ func TestEvaluatorPrefetcherAlignmentKeyreg(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -895,7 +911,7 @@ func TestEvaluatorPrefetcherAlignmentCreateApplication(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
// Only one (non-existing) asset is requested. Ignore it.
require.Len(t, requested.Apps, 1)
require.Len(t, requested.Apps[makeAddress(1)], 1)
@@ -953,7 +969,7 @@ func TestEvaluatorPrefetcherAlignmentDeleteApplication(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -1011,7 +1027,7 @@ func TestEvaluatorPrefetcherAlignmentApplicationOptIn(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -1075,7 +1091,7 @@ func TestEvaluatorPrefetcherAlignmentApplicationCloseOut(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -1139,7 +1155,7 @@ func TestEvaluatorPrefetcherAlignmentApplicationClearState(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
@@ -1203,7 +1219,7 @@ func TestEvaluatorPrefetcherAlignmentApplicationCallAccountsDeclaration(t *testi
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
// Foreign accounts are not loaded, ensure they are not prefetched
require.NotContains(t, prefetched.Accounts, makeAddress(5))
require.NotContains(t, prefetched.Accounts, makeAddress(3))
@@ -1271,7 +1287,7 @@ func TestEvaluatorPrefetcherAlignmentApplicationCallForeignAppsDeclaration(t *te
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
// Foreign apps are not loaded, ensure they are not prefetched
require.NotContains(t, prefetched.Creators, creatable{cindex: 6, ctype: basics.AppCreatable})
require.NotContains(t, prefetched.Creators, creatable{cindex: 8, ctype: basics.AppCreatable})
@@ -1338,7 +1354,7 @@ func TestEvaluatorPrefetcherAlignmentApplicationCallForeignAssetsDeclaration(t *
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
// Foreign apps are not loaded, ensure they are not prefetched
require.NotContains(t, prefetched.Creators, creatable{cindex: 6, ctype: basics.AssetCreatable})
require.NotContains(t, prefetched.Creators, creatable{cindex: 8, ctype: basics.AssetCreatable})
@@ -1385,6 +1401,6 @@ func TestEvaluatorPrefetcherAlignmentStateProof(t *testing.T) {
requested, prefetched := run(t, l, txn)
- prefetched.Accounts[rewardsPool()] = struct{}{}
+ prefetched.pretend(rewardsPool(), proposer())
require.Equal(t, requested, prefetched)
}
diff --git a/ledger/eval_simple_test.go b/ledger/eval_simple_test.go
index 7354b4a567..ee9a097b06 100644
--- a/ledger/eval_simple_test.go
+++ b/ledger/eval_simple_test.go
@@ -29,6 +29,7 @@ import (
"github.com/algorand/go-algorand/agreement"
"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/crypto"
+ "github.com/algorand/go-algorand/crypto/merklesignature"
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/data/bookkeeping"
"github.com/algorand/go-algorand/data/transactions"
@@ -211,6 +212,166 @@ 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
+func TestMiningFees(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ t.Parallel()
+
+ // Lots of balance checks that would be messed up by rewards
+ genBalances, addrs, _ := ledgertesting.NewTestGenesis(ledgertesting.TurnOffRewards)
+ miningBegins := 40
+ ledgertesting.TestConsensusRange(t, miningBegins-1, 0, func(t *testing.T, ver int, cv protocol.ConsensusVersion, cfg config.Local) {
+ dl := NewDoubleLedger(t, genBalances, cv, cfg)
+ defer dl.Close()
+
+ tooBig := basics.Address{0x01, 0x011}
+ tooSmall := basics.Address{0x01, 0x022}
+ smallest := basics.Address{0x01, 0x033}
+ biggest := basics.Address{0x01, 0x044}
+
+ const eFee = 3_000_000
+ dl.txns(
+ &txntest.Txn{Type: "pay", Sender: addrs[1],
+ Receiver: tooBig, Amount: eFee + 100_000_000*1_000_000 + 1},
+ &txntest.Txn{Type: "pay", Sender: addrs[1],
+ Receiver: tooSmall, Amount: eFee + 100_000*1_000_000 - 1},
+ &txntest.Txn{Type: "pay", Sender: addrs[1],
+ Receiver: smallest, Amount: eFee + 100_000*1_000_000},
+ &txntest.Txn{Type: "pay", Sender: addrs[1],
+ Receiver: biggest, Amount: eFee + 100_000_000*1_000_000},
+ )
+
+ for _, proposer := range []basics.Address{tooBig, tooSmall, smallest, biggest} {
+ t.Log(proposer)
+
+ dl.txn(&txntest.Txn{
+ Type: "keyreg",
+ Sender: proposer,
+ Fee: eFee,
+ VotePK: crypto.OneTimeSignatureVerifier{0x01},
+ SelectionPK: crypto.VRFVerifier{0x02},
+ StateProofPK: merklesignature.Commitment{0x03},
+ VoteFirst: 1, VoteLast: 1000,
+ })
+
+ dl.fullBlock() // start with an empty block, so no mining fees are paid at start of next one
+
+ presink := micros(dl.t, dl.generator, genBalances.FeeSink)
+ preprop := micros(dl.t, dl.generator, proposer)
+ t.Log(" presink", presink)
+ t.Log(" preprop", preprop)
+ dl.beginBlock()
+ pay := txntest.Txn{
+ Type: "pay",
+ Sender: addrs[1],
+ Receiver: addrs[2],
+ Amount: 100000,
+ }
+ dl.txns(&pay, pay.Args("again"))
+ vb := dl.endBlock(proposer)
+
+ if ver >= miningBegins {
+ require.True(t, dl.generator.GenesisProto().EnableMining) // version sanity check
+ require.NotZero(t, dl.generator.GenesisProto().MiningPercent) // version sanity check
+ // new fields are in the header
+ require.EqualValues(t, proposer, vb.Block().BlockHeader.Proposer)
+ require.EqualValues(t, 2000, vb.Block().BlockHeader.FeesCollected.Raw)
+ } else {
+ require.False(t, dl.generator.GenesisProto().EnableMining)
+ require.Zero(t, dl.generator.GenesisProto().MiningPercent) // version sanity check
+ // new fields are not in the header
+ require.Zero(t, vb.Block().BlockHeader.Proposer)
+ require.Zero(t, vb.Block().BlockHeader.FeesCollected)
+ }
+
+ postsink := micros(dl.t, dl.generator, genBalances.FeeSink)
+ postprop := micros(dl.t, dl.generator, proposer)
+ t.Log(" postsink", postsink)
+ t.Log(" postprop", postprop)
+
+ // At the end of the block, all fees are still in the sink.
+ require.EqualValues(t, 2000, postsink-presink)
+ //require.EqualValues(t, 0, postprop-preprop)
+
+ // Do the next block, which moves part of the fees to proposer
+ dl.fullBlock()
+ postsink = micros(dl.t, dl.generator, genBalances.FeeSink)
+ postprop = micros(dl.t, dl.generator, proposer)
+
+ if ver >= miningBegins && (proposer == smallest || proposer == biggest) {
+ require.EqualValues(t, 500, postsink-presink) // based on 75% in config/consensus.go
+ require.EqualValues(t, 1500, postprop-preprop)
+ } else {
+ // stayed in the feesink
+ require.EqualValues(t, 0, postprop-preprop, "%v", proposer)
+ require.EqualValues(t, 2000, postsink-presink)
+ }
+ }
+ })
+}
+
+// TestIncentiveEligible checks that keyreg with extra fee turns on the incentive eligible flag
+func TestIncentiveEligible(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ t.Parallel()
+
+ genBalances, addrs, _ := ledgertesting.NewTestGenesis()
+ miningBegins := 40
+ ledgertesting.TestConsensusRange(t, miningBegins-1, 0, func(t *testing.T, ver int, cv protocol.ConsensusVersion, cfg config.Local) {
+ dl := NewDoubleLedger(t, genBalances, cv, cfg)
+ defer dl.Close()
+
+ tooSmall := basics.Address{0x01, 0x011}
+ smallest := basics.Address{0x01, 0x022}
+
+ // They begin ineligible
+ for _, addr := range []basics.Address{tooSmall, smallest} {
+ acct, _, _, err := dl.generator.LookupLatest(addr)
+ require.NoError(t, err)
+ require.False(t, acct.IncentiveEligible)
+ }
+
+ // Fund everyone
+ dl.txns(&txntest.Txn{Type: "pay", Sender: addrs[1], Receiver: tooSmall, Amount: 10_000_000},
+ &txntest.Txn{Type: "pay", Sender: addrs[1], Receiver: smallest, Amount: 10_000_000},
+ )
+
+ // Keyreg (but offline) with various fees. No effect on incentive eligible
+ dl.txns(&txntest.Txn{Type: "keyreg", Sender: tooSmall, Fee: 2_000_000 - 1},
+ &txntest.Txn{Type: "keyreg", Sender: smallest, Fee: 2_000_000},
+ )
+
+ for _, addr := range []basics.Address{tooSmall, smallest} {
+ acct, _, _, err := dl.generator.LookupLatest(addr)
+ require.NoError(t, err)
+ require.False(t, acct.IncentiveEligible)
+ }
+
+ // Keyreg to get online with various fees. Sufficient fee gets `smallest` eligible
+ keyreg := txntest.Txn{
+ Type: "keyreg",
+ VotePK: crypto.OneTimeSignatureVerifier{0x01},
+ SelectionPK: crypto.VRFVerifier{0x02},
+ StateProofPK: merklesignature.Commitment{0x03},
+ VoteFirst: 1, VoteLast: 1000,
+ }
+ tooSmallKR := keyreg
+ tooSmallKR.Sender = tooSmall
+ tooSmallKR.Fee = 2_000_000 - 1
+
+ smallKR := keyreg
+ smallKR.Sender = smallest
+ smallKR.Fee = 2_000_000
+ dl.txns(&tooSmallKR, &smallKR)
+ a, _, _, err := dl.generator.LookupLatest(tooSmall)
+ require.NoError(t, err)
+ require.False(t, a.IncentiveEligible)
+ a, _, _, err = dl.generator.LookupLatest(smallest)
+ require.NoError(t, err)
+ require.Equal(t, a.IncentiveEligible, ver >= miningBegins)
+ })
+}
+
// TestHoldingGet tests some of the corner cases for the asset_holding_get
// opcode: the asset doesn't exist, the account doesn't exist, account not opted
// in, vs it has none of the asset. This is tested here, even though it should
diff --git a/ledger/ledger_test.go b/ledger/ledger_test.go
index ab5bc293a3..0305ccc9c0 100644
--- a/ledger/ledger_test.go
+++ b/ledger/ledger_test.go
@@ -173,6 +173,9 @@ func (l *Ledger) appendUnvalidatedSignedTx(t *testing.T, initAccounts map[basics
if proto.TxnCounter {
blk.TxnCounter = blk.TxnCounter + 1
}
+ if proto.EnableMining {
+ blk.FeesCollected = stx.Txn.Fee
+ }
blk.Payset = append(blk.Payset, txib)
blk.TxnCommitments, err = blk.PaysetCommit()
require.NoError(t, err)
diff --git a/ledger/ledgercore/accountdata.go b/ledger/ledgercore/accountdata.go
index 3685d16909..7fde54c0aa 100644
--- a/ledger/ledgercore/accountdata.go
+++ b/ledger/ledgercore/accountdata.go
@@ -39,6 +39,7 @@ type AccountBaseData struct {
RewardsBase uint64
RewardedMicroAlgos basics.MicroAlgos
AuthAddr basics.Address
+ IncentiveEligible bool
TotalAppSchema basics.StateSchema // Totals across created globals, and opted in locals.
TotalExtraAppPages uint32 // Total number of extra pages across all created apps
@@ -75,8 +76,8 @@ func ToAccountData(acct basics.AccountData) AccountData {
MicroAlgos: acct.MicroAlgos,
RewardsBase: acct.RewardsBase,
RewardedMicroAlgos: acct.RewardedMicroAlgos,
-
- AuthAddr: acct.AuthAddr,
+ AuthAddr: acct.AuthAddr,
+ IncentiveEligible: acct.IncentiveEligible,
TotalAppSchema: acct.TotalAppSchema,
TotalExtraAppPages: acct.TotalExtraAppPages,
@@ -105,6 +106,8 @@ func AssignAccountData(a *basics.AccountData, acct AccountData) {
a.MicroAlgos = acct.MicroAlgos
a.RewardsBase = acct.RewardsBase
a.RewardedMicroAlgos = acct.RewardedMicroAlgos
+ a.AuthAddr = acct.AuthAddr
+ a.IncentiveEligible = acct.IncentiveEligible
a.VoteID = acct.VoteID
a.SelectionID = acct.SelectionID
@@ -113,7 +116,6 @@ func AssignAccountData(a *basics.AccountData, acct AccountData) {
a.VoteLastValid = acct.VoteLastValid
a.VoteKeyDilution = acct.VoteKeyDilution
- a.AuthAddr = acct.AuthAddr
a.TotalAppSchema = acct.TotalAppSchema
a.TotalExtraAppPages = acct.TotalExtraAppPages
a.TotalBoxes = acct.TotalBoxes
diff --git a/ledger/ledgercore/validatedBlock.go b/ledger/ledgercore/validatedBlock.go
index 541a3a54f8..3bfef32649 100644
--- a/ledger/ledgercore/validatedBlock.go
+++ b/ledger/ledgercore/validatedBlock.go
@@ -17,6 +17,7 @@
package ledgercore
import (
+ "github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/data/bookkeeping"
"github.com/algorand/go-algorand/data/committee"
)
@@ -39,11 +40,15 @@ func (vb ValidatedBlock) Delta() StateDelta {
return vb.delta
}
-// WithSeed returns a copy of the ValidatedBlock with a modified seed.
-func (vb ValidatedBlock) WithSeed(s committee.Seed) ValidatedBlock {
+// WithSeed returns a copy of the ValidatedBlock with a modified seed and associated proposer
+func (vb ValidatedBlock) WithSeed(s committee.Seed, proposer basics.Address) ValidatedBlock {
newblock := vb.blk
newblock.BlockHeader.Seed = s
+ if vb.blk.ConsensusProtocol().EnableMining {
+ newblock.BlockHeader.Proposer = proposer
+ }
+
return ValidatedBlock{
blk: newblock,
delta: vb.delta,
diff --git a/ledger/simple_test.go b/ledger/simple_test.go
index 10b87f9378..b42d3a53f2 100644
--- a/ledger/simple_test.go
+++ b/ledger/simple_test.go
@@ -26,6 +26,7 @@ import (
"github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/data/bookkeeping"
+ "github.com/algorand/go-algorand/data/committee"
"github.com/algorand/go-algorand/data/transactions"
"github.com/algorand/go-algorand/data/txntest"
"github.com/algorand/go-algorand/ledger/eval"
@@ -136,11 +137,20 @@ func txgroup(t testing.TB, ledger *Ledger, eval *eval.BlockEvaluator, txns ...*t
return eval.TransactionGroup(transactions.WrapSignedTxnsWithAD(txgroup))
}
-// endBlock completes the block being created, returns the ValidatedBlock for inspection
-func endBlock(t testing.TB, ledger *Ledger, eval *eval.BlockEvaluator) *ledgercore.ValidatedBlock {
- validatedBlock, err := eval.GenerateBlock()
+// endBlock completes the block being created, returns the ValidatedBlock for
+// inspection. Proposer is optional - if unset, blocks will be finished with
+// ZeroAddress proposer.
+func endBlock(t testing.TB, ledger *Ledger, eval *eval.BlockEvaluator, proposer ...basics.Address) *ledgercore.ValidatedBlock {
+ vb, err := eval.GenerateBlock()
require.NoError(t, err)
- err = ledger.AddValidatedBlock(*validatedBlock, agreement.Certificate{})
+
+ var prp basics.Address
+ if len(proposer) > 0 {
+ prp = proposer[0]
+ }
+ *vb = vb.WithSeed(committee.Seed{}, prp)
+
+ err = ledger.AddValidatedBlock(*vb, agreement.Certificate{})
require.NoError(t, err)
// `rndBQ` gives the latest known block round added to the ledger
// we should wait until `rndBQ` block to be committed to blockQueue,
@@ -152,7 +162,7 @@ func endBlock(t testing.TB, ledger *Ledger, eval *eval.BlockEvaluator) *ledgerco
// then we return the result and continue the execution.
rndBQ := ledger.Latest()
ledger.WaitForCommit(rndBQ)
- return validatedBlock
+ return vb
}
// main wraps up some TEAL source in a header and footer so that it is
diff --git a/ledger/store/trackerdb/data.go b/ledger/store/trackerdb/data.go
index fc243b2b92..2e9ee4778e 100644
--- a/ledger/store/trackerdb/data.go
+++ b/ledger/store/trackerdb/data.go
@@ -47,6 +47,7 @@ type BaseAccountData struct {
TotalAppLocalStates uint64 `codec:"l"`
TotalBoxes uint64 `codec:"m"`
TotalBoxBytes uint64 `codec:"n"`
+ IncentiveEligible bool `codec:"o"`
BaseVotingData
@@ -286,6 +287,7 @@ func (ba *BaseAccountData) SetCoreAccountData(ad *ledgercore.AccountData) {
ba.TotalAppLocalStates = ad.TotalAppLocalStates
ba.TotalBoxes = ad.TotalBoxes
ba.TotalBoxBytes = ad.TotalBoxBytes
+ ba.IncentiveEligible = ad.IncentiveEligible
ba.BaseVotingData.SetCoreAccountData(ad)
}
@@ -306,6 +308,7 @@ func (ba *BaseAccountData) SetAccountData(ad *basics.AccountData) {
ba.TotalAppLocalStates = uint64(len(ad.AppLocalStates))
ba.TotalBoxes = ad.TotalBoxes
ba.TotalBoxBytes = ad.TotalBoxBytes
+ ba.IncentiveEligible = ad.IncentiveEligible
ba.BaseVotingData.VoteID = ad.VoteID
ba.BaseVotingData.SelectionID = ad.SelectionID
@@ -342,6 +345,7 @@ func (ba *BaseAccountData) GetLedgerCoreAccountBaseData() ledgercore.AccountBase
TotalAssets: ba.TotalAssets,
TotalBoxes: ba.TotalBoxes,
TotalBoxBytes: ba.TotalBoxBytes,
+ IncentiveEligible: ba.IncentiveEligible,
}
}
@@ -365,6 +369,7 @@ func (ba *BaseAccountData) GetAccountData() basics.AccountData {
RewardsBase: ba.RewardsBase,
RewardedMicroAlgos: ba.RewardedMicroAlgos,
AuthAddr: ba.AuthAddr,
+ IncentiveEligible: ba.IncentiveEligible,
TotalAppSchema: basics.StateSchema{
NumUint: ba.TotalAppSchemaNumUint,
NumByteSlice: ba.TotalAppSchemaNumByteSlice,
@@ -389,6 +394,7 @@ func (ba *BaseAccountData) IsEmpty() bool {
ba.RewardsBase == 0 &&
ba.RewardedMicroAlgos.Raw == 0 &&
ba.AuthAddr.IsZero() &&
+ !ba.IncentiveEligible &&
ba.TotalAppSchemaNumUint == 0 &&
ba.TotalAppSchemaNumByteSlice == 0 &&
ba.TotalExtraAppPages == 0 &&
diff --git a/ledger/store/trackerdb/data_test.go b/ledger/store/trackerdb/data_test.go
index e329a84e74..8c91b028de 100644
--- a/ledger/store/trackerdb/data_test.go
+++ b/ledger/store/trackerdb/data_test.go
@@ -1105,7 +1105,7 @@ func TestBaseAccountDataIsEmpty(t *testing.T) {
structureTesting := func(t *testing.T) {
encoding, err := json.Marshal(&empty)
zeros32 := "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
- expectedEncoding := `{"Status":0,"MicroAlgos":{"Raw":0},"RewardsBase":0,"RewardedMicroAlgos":{"Raw":0},"AuthAddr":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ","TotalAppSchemaNumUint":0,"TotalAppSchemaNumByteSlice":0,"TotalExtraAppPages":0,"TotalAssetParams":0,"TotalAssets":0,"TotalAppParams":0,"TotalAppLocalStates":0,"TotalBoxes":0,"TotalBoxBytes":0,"VoteID":[` + zeros32 + `],"SelectionID":[` + zeros32 + `],"VoteFirstValid":0,"VoteLastValid":0,"VoteKeyDilution":0,"StateProofID":[` + zeros32 + `,` + zeros32 + `],"UpdateRound":0}`
+ expectedEncoding := `{"Status":0,"MicroAlgos":{"Raw":0},"RewardsBase":0,"RewardedMicroAlgos":{"Raw":0},"AuthAddr":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ","TotalAppSchemaNumUint":0,"TotalAppSchemaNumByteSlice":0,"TotalExtraAppPages":0,"TotalAssetParams":0,"TotalAssets":0,"TotalAppParams":0,"TotalAppLocalStates":0,"TotalBoxes":0,"TotalBoxBytes":0,"IncentiveEligible":false,"VoteID":[` + zeros32 + `],"SelectionID":[` + zeros32 + `],"VoteFirstValid":0,"VoteLastValid":0,"VoteKeyDilution":0,"StateProofID":[` + zeros32 + `,` + zeros32 + `],"UpdateRound":0}`
require.NoError(t, err)
require.Equal(t, expectedEncoding, string(encoding))
}
diff --git a/ledger/store/trackerdb/msgp_gen.go b/ledger/store/trackerdb/msgp_gen.go
index a13469c0ab..8b0092f4c1 100644
--- a/ledger/store/trackerdb/msgp_gen.go
+++ b/ledger/store/trackerdb/msgp_gen.go
@@ -100,8 +100,8 @@ import (
func (z *BaseAccountData) MarshalMsg(b []byte) (o []byte) {
o = msgp.Require(b, z.Msgsize())
// omitempty: check for empty values
- zb0001Len := uint32(21)
- var zb0001Mask uint32 /* 23 bits */
+ zb0001Len := uint32(22)
+ var zb0001Mask uint32 /* 24 bits */
if (*z).BaseVotingData.VoteID.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x1
@@ -182,10 +182,14 @@ func (z *BaseAccountData) MarshalMsg(b []byte) (o []byte) {
zb0001Len--
zb0001Mask |= 0x200000
}
- if (*z).UpdateRound == 0 {
+ if (*z).IncentiveEligible == false {
zb0001Len--
zb0001Mask |= 0x400000
}
+ if (*z).UpdateRound == 0 {
+ zb0001Len--
+ zb0001Mask |= 0x800000
+ }
// variable map header, size zb0001Len
o = msgp.AppendMapHeader(o, zb0001Len)
if zb0001Len != 0 {
@@ -290,6 +294,11 @@ func (z *BaseAccountData) MarshalMsg(b []byte) (o []byte) {
o = msgp.AppendUint64(o, (*z).TotalBoxBytes)
}
if (zb0001Mask & 0x400000) == 0 { // if not empty
+ // string "o"
+ o = append(o, 0xa1, 0x6f)
+ o = msgp.AppendBool(o, (*z).IncentiveEligible)
+ }
+ if (zb0001Mask & 0x800000) == 0 { // if not empty
// string "z"
o = append(o, 0xa1, 0x7a)
o = msgp.AppendUint64(o, (*z).UpdateRound)
@@ -433,6 +442,14 @@ func (z *BaseAccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalSta
return
}
}
+ if zb0001 > 0 {
+ zb0001--
+ (*z).IncentiveEligible, bts, err = msgp.ReadBoolBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "IncentiveEligible")
+ return
+ }
+ }
if zb0001 > 0 {
zb0001--
bts, err = (*z).BaseVotingData.VoteID.UnmarshalMsgWithState(bts, st)
@@ -596,6 +613,12 @@ func (z *BaseAccountData) UnmarshalMsgWithState(bts []byte, st msgp.UnmarshalSta
err = msgp.WrapError(err, "TotalBoxBytes")
return
}
+ case "o":
+ (*z).IncentiveEligible, bts, err = msgp.ReadBoolBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "IncentiveEligible")
+ return
+ }
case "A":
bts, err = (*z).BaseVotingData.VoteID.UnmarshalMsgWithState(bts, st)
if err != nil {
@@ -661,18 +684,18 @@ func (_ *BaseAccountData) CanUnmarshalMsg(z interface{}) bool {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *BaseAccountData) Msgsize() (s int) {
- s = 3 + 2 + (*z).Status.Msgsize() + 2 + (*z).MicroAlgos.Msgsize() + 2 + msgp.Uint64Size + 2 + (*z).RewardedMicroAlgos.Msgsize() + 2 + (*z).AuthAddr.Msgsize() + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint32Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + (*z).BaseVotingData.VoteID.Msgsize() + 2 + (*z).BaseVotingData.SelectionID.Msgsize() + 2 + (*z).BaseVotingData.VoteFirstValid.Msgsize() + 2 + (*z).BaseVotingData.VoteLastValid.Msgsize() + 2 + msgp.Uint64Size + 2 + (*z).BaseVotingData.StateProofID.Msgsize() + 2 + msgp.Uint64Size
+ s = 3 + 2 + (*z).Status.Msgsize() + 2 + (*z).MicroAlgos.Msgsize() + 2 + msgp.Uint64Size + 2 + (*z).RewardedMicroAlgos.Msgsize() + 2 + (*z).AuthAddr.Msgsize() + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint32Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.BoolSize + 2 + (*z).BaseVotingData.VoteID.Msgsize() + 2 + (*z).BaseVotingData.SelectionID.Msgsize() + 2 + (*z).BaseVotingData.VoteFirstValid.Msgsize() + 2 + (*z).BaseVotingData.VoteLastValid.Msgsize() + 2 + msgp.Uint64Size + 2 + (*z).BaseVotingData.StateProofID.Msgsize() + 2 + msgp.Uint64Size
return
}
// MsgIsZero returns whether this is a zero value
func (z *BaseAccountData) MsgIsZero() bool {
- return ((*z).Status.MsgIsZero()) && ((*z).MicroAlgos.MsgIsZero()) && ((*z).RewardsBase == 0) && ((*z).RewardedMicroAlgos.MsgIsZero()) && ((*z).AuthAddr.MsgIsZero()) && ((*z).TotalAppSchemaNumUint == 0) && ((*z).TotalAppSchemaNumByteSlice == 0) && ((*z).TotalExtraAppPages == 0) && ((*z).TotalAssetParams == 0) && ((*z).TotalAssets == 0) && ((*z).TotalAppParams == 0) && ((*z).TotalAppLocalStates == 0) && ((*z).TotalBoxes == 0) && ((*z).TotalBoxBytes == 0) && ((*z).BaseVotingData.VoteID.MsgIsZero()) && ((*z).BaseVotingData.SelectionID.MsgIsZero()) && ((*z).BaseVotingData.VoteFirstValid.MsgIsZero()) && ((*z).BaseVotingData.VoteLastValid.MsgIsZero()) && ((*z).BaseVotingData.VoteKeyDilution == 0) && ((*z).BaseVotingData.StateProofID.MsgIsZero()) && ((*z).UpdateRound == 0)
+ return ((*z).Status.MsgIsZero()) && ((*z).MicroAlgos.MsgIsZero()) && ((*z).RewardsBase == 0) && ((*z).RewardedMicroAlgos.MsgIsZero()) && ((*z).AuthAddr.MsgIsZero()) && ((*z).TotalAppSchemaNumUint == 0) && ((*z).TotalAppSchemaNumByteSlice == 0) && ((*z).TotalExtraAppPages == 0) && ((*z).TotalAssetParams == 0) && ((*z).TotalAssets == 0) && ((*z).TotalAppParams == 0) && ((*z).TotalAppLocalStates == 0) && ((*z).TotalBoxes == 0) && ((*z).TotalBoxBytes == 0) && ((*z).IncentiveEligible == false) && ((*z).BaseVotingData.VoteID.MsgIsZero()) && ((*z).BaseVotingData.SelectionID.MsgIsZero()) && ((*z).BaseVotingData.VoteFirstValid.MsgIsZero()) && ((*z).BaseVotingData.VoteLastValid.MsgIsZero()) && ((*z).BaseVotingData.VoteKeyDilution == 0) && ((*z).BaseVotingData.StateProofID.MsgIsZero()) && ((*z).UpdateRound == 0)
}
// MaxSize returns a maximum valid message size for this message type
func BaseAccountDataMaxSize() (s int) {
- s = 3 + 2 + basics.StatusMaxSize() + 2 + basics.MicroAlgosMaxSize() + 2 + msgp.Uint64Size + 2 + basics.MicroAlgosMaxSize() + 2 + basics.AddressMaxSize() + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint32Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + crypto.OneTimeSignatureVerifierMaxSize() + 2 + crypto.VRFVerifierMaxSize() + 2 + basics.RoundMaxSize() + 2 + basics.RoundMaxSize() + 2 + msgp.Uint64Size + 2 + merklesignature.CommitmentMaxSize() + 2 + msgp.Uint64Size
+ s = 3 + 2 + basics.StatusMaxSize() + 2 + basics.MicroAlgosMaxSize() + 2 + msgp.Uint64Size + 2 + basics.MicroAlgosMaxSize() + 2 + basics.AddressMaxSize() + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint32Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.Uint64Size + 2 + msgp.BoolSize + 2 + crypto.OneTimeSignatureVerifierMaxSize() + 2 + crypto.VRFVerifierMaxSize() + 2 + basics.RoundMaxSize() + 2 + basics.RoundMaxSize() + 2 + msgp.Uint64Size + 2 + merklesignature.CommitmentMaxSize() + 2 + msgp.Uint64Size
return
}
diff --git a/ledger/testing/randomAccounts.go b/ledger/testing/randomAccounts.go
index 2d5f79c82a..bd079605a3 100644
--- a/ledger/testing/randomAccounts.go
+++ b/ledger/testing/randomAccounts.go
@@ -68,15 +68,16 @@ func RandomAccountData(rewardsBase uint64) basics.AccountData {
switch crypto.RandUint64() % 3 {
case 0:
data.Status = basics.Online
+ data.VoteID = crypto.OneTimeSignatureVerifier{0x01}
+ data.IncentiveEligible = crypto.RandUint64()%5 == 0
+ data.VoteFirstValid = 1
data.VoteLastValid = 10000
case 1:
data.Status = basics.Offline
- data.VoteLastValid = 0
default:
data.Status = basics.NotParticipating
}
- data.VoteFirstValid = 0
data.RewardsBase = rewardsBase
return data
}
@@ -99,6 +100,10 @@ func RandomAssetParams() basics.AssetParams {
Decimals: uint32(crypto.RandUint64() % 20),
DefaultFrozen: crypto.RandUint64()%2 == 0,
}
+ // Since 0 and 1 Total assets seem extra interesting, make them more often.
+ if crypto.RandUint64()%5 != 0 {
+ ap.Total = crypto.RandUint64() % 2
+ }
if crypto.RandUint64()%5 != 0 {
ap.UnitName = fmt.Sprintf("un%x", uint32(crypto.RandUint64()%0x7fffff))
}
diff --git a/ledger/testing/randomAccounts_test.go b/ledger/testing/randomAccounts_test.go
index 9f69321aaa..f59f704129 100644
--- a/ledger/testing/randomAccounts_test.go
+++ b/ledger/testing/randomAccounts_test.go
@@ -87,7 +87,6 @@ func TestAccounts(t *testing.T) {
zeroValueExceptions := []reflectionhelpers.TypePath{
reflectionhelpers.TypePath{}.AddField("MicroAlgos").AddField("Raw"),
reflectionhelpers.TypePath{}.AddField("AssetParams").AddMapKey(),
- reflectionhelpers.TypePath{}.AddField("AssetParams").AddValue().AddField("Total"),
reflectionhelpers.TypePath{}.AddField("Assets").AddMapKey(),
reflectionhelpers.TypePath{}.AddField("AppLocalStates").AddMapKey(),
reflectionhelpers.TypePath{}.AddField("AppLocalStates").AddValue().AddField("KeyValue").AddValue().AddField("Type"),
diff --git a/ledger/testing/testGenesis.go b/ledger/testing/testGenesis.go
index a2d469dcf0..06b50be977 100644
--- a/ledger/testing/testGenesis.go
+++ b/ledger/testing/testGenesis.go
@@ -33,10 +33,9 @@ type testGenesisCfg struct {
// TestGenesisOption provides functional options for testGenesisCfg.
type TestGenesisOption func(*testGenesisCfg)
-// TestGenesisRewardsPoolSize configures the rewards pool size in the genesis block.
-func TestGenesisRewardsPoolSize(amount basics.MicroAlgos) TestGenesisOption {
- return func(cfg *testGenesisCfg) { cfg.rewardsPoolAmount = amount }
-}
+// TurnOffRewards turns off the rewards pool for tests that are sensistive to
+// "surprise" balance changes.
+var TurnOffRewards = func(cfg *testGenesisCfg) { cfg.rewardsPoolAmount = basics.MicroAlgos{Raw: 100_000} }
// NewTestGenesis creates a bunch of accounts, splits up 10B algos
// between them and the rewardspool and feesink, and gives out the
diff --git a/node/node.go b/node/node.go
index f59bd67dab..2c1e675e1b 100644
--- a/node/node.go
+++ b/node/node.go
@@ -1291,8 +1291,8 @@ type validatedBlock struct {
}
// WithSeed satisfies the agreement.ValidatedBlock interface.
-func (vb validatedBlock) WithSeed(s committee.Seed) agreement.ValidatedBlock {
- lvb := vb.vb.WithSeed(s)
+func (vb validatedBlock) WithSeed(s committee.Seed, proposer basics.Address) agreement.ValidatedBlock {
+ lvb := vb.vb.WithSeed(s, proposer)
return validatedBlock{vb: &lvb}
}
diff --git a/protocol/tags.go b/protocol/tags.go
index e980454674..1e2ef3b148 100644
--- a/protocol/tags.go
+++ b/protocol/tags.go
@@ -73,7 +73,7 @@ const PingReplyTagMaxSize = 8
// ProposalPayloadTagMaxSize is the maximum size of a ProposalPayloadTag message
// This value is dominated by the MaxTxnBytesPerBlock
-const ProposalPayloadTagMaxSize = 5247980
+const ProposalPayloadTagMaxSize = 5248065
// StateProofSigTagMaxSize is the maximum size of a StateProofSigTag message
const StateProofSigTagMaxSize = 6378
diff --git a/test/scripts/e2e_subs/eligible.py b/test/scripts/e2e_subs/eligible.py
new file mode 100755
index 0000000000..ddac9a3515
--- /dev/null
+++ b/test/scripts/e2e_subs/eligible.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+
+import base64
+import os
+import sys
+from goal import Goal
+import algosdk.encoding as enc
+
+from datetime import datetime
+
+stamp = datetime.now().strftime("%Y%m%d_%H%M%S")
+print(f"{os.path.basename(sys.argv[0])} start {stamp}")
+
+goal = Goal(sys.argv[1], autosend=True)
+
+joe = goal.new_account()
+
+txinfo, err = goal.pay(goal.account, joe, amt=10_000_000)
+assert not err, err
+
+# Joe is a brand new account, it is not incentive eligible
+joe_info = goal.algod.account_info(joe)
+assert "incentive-eligible" not in joe_info, joe_info
+
+# Go online, but without paying enough to be incentive eligible
+txinfo, err = goal.keyreg(joe, votekey=base64.b64encode(b'1'*32),
+ selkey=base64.b64encode(b'1'*32),
+ sprfkey=base64.b64encode(b'1'*64),
+ votekd=1,
+ votefst=1, votelst=2000)
+assert not err, err
+
+# No extra fee paid, so not eligible
+joe_info = goal.algod.account_info(joe)
+assert "incentive-eligible" not in joe_info, joe_info
+
+# Pay the extra fee to become eligible
+txinfo, err = goal.keyreg(joe, fee=3_000_000,
+ votekey=base64.b64encode(b'1'*32),
+ selkey=base64.b64encode(b'1'*32),
+ sprfkey=base64.b64encode(b'1'*64),
+ votekd=2,
+ votefst=1, votelst=2000)
+assert not err, err
+joe_info = goal.algod.account_info(joe)
+assert joe_info.get("incentive-eligible", None) == True, joe_info
+
+
+
+stamp = datetime.now().strftime("%Y%m%d_%H%M%S")
+print(f"{os.path.basename(sys.argv[0])} OK {stamp}")
diff --git a/test/scripts/e2e_subs/goal/goal.py b/test/scripts/e2e_subs/goal/goal.py
index 5d0dd7db0f..57d8b0acb5 100755
--- a/test/scripts/e2e_subs/goal/goal.py
+++ b/test/scripts/e2e_subs/goal/goal.py
@@ -240,21 +240,21 @@ def finish(self, tx, send):
return tx
def keyreg(self, sender, votekey=None, selkey=None, votefst=None,
- votelst=None, votekd=None,
+ votelst=None, votekd=None, sprfkey=None,
send=None, **kwargs):
- params = self.algod.suggested_params()
+ params = self.params(kwargs.pop("lifetime", 1000), kwargs.pop("fee", None))
tx = txn.KeyregTxn(sender, params,
- votekey, selkey, votefst, votelst, votekd,
+ votekey, selkey, votefst, votelst, votekd, sprfkey=sprfkey,
**kwargs)
return self.finish(tx, send)
def pay(self, sender, receiver, amt: int, send=None, **kwargs):
- params = self.algod.suggested_params()
+ params = self.params(kwargs.pop("lifetime", 1000), kwargs.pop("fee", None))
tx = txn.PaymentTxn(sender, params, receiver, amt, **kwargs)
return self.finish(tx, send)
def acfg(self, sender, send=None, **kwargs):
- params = self.algod.suggested_params()
+ params = self.params(kwargs.pop("lifetime", 1000), kwargs.pop("fee", None))
tx = txn.AssetConfigTxn(
sender, params, **kwargs, strict_empty_address_check=False
)
@@ -265,7 +265,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), kwargs.pop("fee", None))
tx = txn.AssetTransferTxn(
sender, params, receiver, amt, index, **kwargs
)
@@ -276,7 +276,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), kwargs.pop("fee", None))
tx = txn.AssetFreezeTxn(sender, params, index, target, frozen, **kwargs)
return self.finish(tx, send)
@@ -287,9 +287,19 @@ def coerce_schema(self, values):
return values
return txn.StateSchema(num_uints=values[0], num_byte_slices=values[1])
+
+ def params(self, lifetime=None, fee=None):
+ params = self.algod.suggested_params()
+ if lifetime is not None:
+ params.last = params.first + lifetime
+ if fee is not None:
+ params.flat_fee = True
+ params.fee = fee
+ return params
+
def appl(self, sender, index: int, on_complete=txn.OnComplete.NoOpOC,
send=None, **kwargs):
- params = self.algod.suggested_params()
+ params = self.params(kwargs.pop("lifetime", 1000), kwargs.pop("fee", None))
local_schema = self.coerce_schema(kwargs.pop("local_schema", None))
global_schema = self.coerce_schema(kwargs.pop("global_schema", None))
tx = txn.ApplicationCallTxn(
diff --git a/test/scripts/e2e_subs/mining.py b/test/scripts/e2e_subs/mining.py
new file mode 100755
index 0000000000..216ecc93ef
--- /dev/null
+++ b/test/scripts/e2e_subs/mining.py
@@ -0,0 +1,84 @@
+#!/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 11
+ 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().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")
+
+# We can not do checks on whether the proposer actually gets paid here
+# because in our e2e tests, the proposers _won't_ get paid. Their
+# accounts have too many algos.
+
+stamp = datetime.now().strftime("%Y%m%d_%H%M%S")
+print(f"{os.path.basename(sys.argv[0])} OK {stamp}")