From 555bcc8698348767e8ac750581fd5eda108e9352 Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Wed, 21 Aug 2024 12:11:45 -0400 Subject: [PATCH 1/4] Provide access to some more block header values --- data/transactions/logic/assembler_test.go | 10 ++++++++++ data/transactions/logic/eval.go | 12 ++++++++++++ data/transactions/logic/fields.go | 21 ++++++++++++++++++++- data/transactions/logic/fields_string.go | 17 +++++++++++------ 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/data/transactions/logic/assembler_test.go b/data/transactions/logic/assembler_test.go index 32101dbcbc..10d86f476a 100644 --- a/data/transactions/logic/assembler_test.go +++ b/data/transactions/logic/assembler_test.go @@ -1700,11 +1700,21 @@ global AssetCreateMinBalance global AssetOptInMinBalance global GenesisHash pushint 1 +block BlkBranch +pushint 1 +block BlkFeeSink +pushint 1 +block BlkProtocol +pushint 1 +block BlkTxnCounter +pushint 1 block BlkProposer pushint 1 block BlkFeesCollected pushint 1 block BlkBonus +pushint 1 +block BlkProposerPayout global PayoutsEnabled global PayoutsGoOnlineFee global PayoutsPercent diff --git a/data/transactions/logic/eval.go b/data/transactions/logic/eval.go index 3201877ed9..4da436a1b6 100644 --- a/data/transactions/logic/eval.go +++ b/data/transactions/logic/eval.go @@ -5771,12 +5771,24 @@ func opBlock(cx *EvalContext) error { return fmt.Errorf("block(%d) timestamp %d < 0", round, hdr.TimeStamp) } cx.Stack[last] = stackValue{Uint: uint64(hdr.TimeStamp)} + + case BlkBranch: + cx.Stack[last].Bytes = hdr.Branch[:] + case BlkFeeSink: + cx.Stack[last].Bytes = hdr.FeeSink[:] + case BlkProtocol: + cx.Stack[last].Bytes = []byte(hdr.CurrentProtocol) + case BlkTxnCounter: + cx.Stack[last] = stackValue{Uint: hdr.TxnCounter} + case BlkProposer: cx.Stack[last].Bytes = hdr.Proposer[:] case BlkFeesCollected: cx.Stack[last] = stackValue{Uint: hdr.FeesCollected.Raw} case BlkBonus: cx.Stack[last] = stackValue{Uint: hdr.Bonus.Raw} + case BlkProposerPayout: + cx.Stack[last] = stackValue{Uint: hdr.ProposerPayout.Raw} default: return fmt.Errorf("invalid block field %s", fs.field) } diff --git a/data/transactions/logic/fields.go b/data/transactions/logic/fields.go index 99cc08bad2..5ecb6d4ea3 100644 --- a/data/transactions/logic/fields.go +++ b/data/transactions/logic/fields.go @@ -991,12 +991,24 @@ const ( BlkSeed BlockField = iota // BlkTimestamp is the Block's timestamp, seconds from epoch BlkTimestamp + + // BlkBranch is the hash of the previous block + BlkBranch + // BlkFeeSink is the fee sink for the given round + BlkFeeSink + // BlkProtocol is the ConsensusVersion of the block. + BlkProtocol + // BlkTxnCounter is the number of the next transaction after the block + BlkTxnCounter + // BlkProposer is the Block's proposer, or ZeroAddress, pre Payouts.Enabled BlkProposer // BlkFeesCollected is the sum of fees for the block, or 0, pre Payouts.Enabled BlkFeesCollected // BlkBonus is the extra amount to be paid for the given block (from FeeSink) BlkBonus + // BlkProposerPayout is the actual amount moved from feesink to proposer + BlkProposerPayout invalidBlockField // compile-time constant for number of fields ) @@ -1010,11 +1022,18 @@ type blockFieldSpec struct { } var blockFieldSpecs = [...]blockFieldSpec{ - {BlkSeed, StackBytes, randomnessVersion}, + {BlkSeed, StackBytes32, randomnessVersion}, {BlkTimestamp, StackUint64, randomnessVersion}, + + {BlkBranch, StackBytes32, 11}, + {BlkFeeSink, StackAddress, 11}, + {BlkProtocol, StackBytes, 11}, + {BlkTxnCounter, StackUint64, 11}, + {BlkProposer, StackAddress, incentiveVersion}, {BlkFeesCollected, StackUint64, incentiveVersion}, {BlkBonus, StackUint64, incentiveVersion}, + {BlkProposerPayout, 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 3463da269c..bed5095221 100644 --- a/data/transactions/logic/fields_string.go +++ b/data/transactions/logic/fields_string.go @@ -379,15 +379,20 @@ func _() { var x [1]struct{} _ = x[BlkSeed-0] _ = x[BlkTimestamp-1] - _ = x[BlkProposer-2] - _ = x[BlkFeesCollected-3] - _ = x[BlkBonus-4] - _ = x[invalidBlockField-5] + _ = x[BlkBranch-2] + _ = x[BlkFeeSink-3] + _ = x[BlkProtocol-4] + _ = x[BlkTxnCounter-5] + _ = x[BlkProposer-6] + _ = x[BlkFeesCollected-7] + _ = x[BlkBonus-8] + _ = x[BlkProposerPayout-9] + _ = x[invalidBlockField-10] } -const _BlockField_name = "BlkSeedBlkTimestampBlkProposerBlkFeesCollectedBlkBonusinvalidBlockField" +const _BlockField_name = "BlkSeedBlkTimestampBlkBranchBlkFeeSinkBlkProtocolBlkTxnCounterBlkProposerBlkFeesCollectedBlkBonusBlkProposerPayoutinvalidBlockField" -var _BlockField_index = [...]uint8{0, 7, 19, 30, 46, 54, 71} +var _BlockField_index = [...]uint8{0, 7, 19, 28, 38, 49, 62, 73, 89, 97, 114, 131} func (i BlockField) String() string { if i < 0 || i >= BlockField(len(_BlockField_index)-1) { From 9ea381a34e01af52abc14a6e357cdb1a3fe15fd5 Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Wed, 21 Aug 2024 13:13:15 -0400 Subject: [PATCH 2/4] update spec --- data/transactions/logic/TEAL_opcodes_v10.md | 2 +- data/transactions/logic/TEAL_opcodes_v7.md | 2 +- data/transactions/logic/TEAL_opcodes_v8.md | 2 +- data/transactions/logic/TEAL_opcodes_v9.md | 2 +- data/transactions/logic/langspec_v10.json | 2 +- data/transactions/logic/langspec_v7.json | 2 +- data/transactions/logic/langspec_v8.json | 2 +- data/transactions/logic/langspec_v9.json | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/data/transactions/logic/TEAL_opcodes_v10.md b/data/transactions/logic/TEAL_opcodes_v10.md index b90801521b..4e4491e095 100644 --- a/data/transactions/logic/TEAL_opcodes_v10.md +++ b/data/transactions/logic/TEAL_opcodes_v10.md @@ -1638,7 +1638,7 @@ Fields | Index | Name | Type | Notes | | - | ------ | -- | --------- | -| 0 | BlkSeed | []byte | | +| 0 | BlkSeed | [32]byte | | | 1 | BlkTimestamp | uint64 | | diff --git a/data/transactions/logic/TEAL_opcodes_v7.md b/data/transactions/logic/TEAL_opcodes_v7.md index 3a0c678b00..74314af059 100644 --- a/data/transactions/logic/TEAL_opcodes_v7.md +++ b/data/transactions/logic/TEAL_opcodes_v7.md @@ -1476,6 +1476,6 @@ Fields | Index | Name | Type | Notes | | - | ------ | -- | --------- | -| 0 | BlkSeed | []byte | | +| 0 | BlkSeed | [32]byte | | | 1 | BlkTimestamp | uint64 | | diff --git a/data/transactions/logic/TEAL_opcodes_v8.md b/data/transactions/logic/TEAL_opcodes_v8.md index f06e087e5e..a1059bc50e 100644 --- a/data/transactions/logic/TEAL_opcodes_v8.md +++ b/data/transactions/logic/TEAL_opcodes_v8.md @@ -1635,6 +1635,6 @@ Fields | Index | Name | Type | Notes | | - | ------ | -- | --------- | -| 0 | BlkSeed | []byte | | +| 0 | BlkSeed | [32]byte | | | 1 | BlkTimestamp | uint64 | | diff --git a/data/transactions/logic/TEAL_opcodes_v9.md b/data/transactions/logic/TEAL_opcodes_v9.md index e14f4d7d76..ac4482ce3e 100644 --- a/data/transactions/logic/TEAL_opcodes_v9.md +++ b/data/transactions/logic/TEAL_opcodes_v9.md @@ -1635,6 +1635,6 @@ Fields | Index | Name | Type | Notes | | - | ------ | -- | --------- | -| 0 | BlkSeed | []byte | | +| 0 | BlkSeed | [32]byte | | | 1 | BlkTimestamp | uint64 | | diff --git a/data/transactions/logic/langspec_v10.json b/data/transactions/logic/langspec_v10.json index f59103f0f6..1a8986436a 100644 --- a/data/transactions/logic/langspec_v10.json +++ b/data/transactions/logic/langspec_v10.json @@ -4601,7 +4601,7 @@ "BlkTimestamp" ], "ArgEnumTypes": [ - "[]byte", + "[32]byte", "uint64" ], "DocCost": "1", diff --git a/data/transactions/logic/langspec_v7.json b/data/transactions/logic/langspec_v7.json index a7b4df95b3..12d2594194 100644 --- a/data/transactions/logic/langspec_v7.json +++ b/data/transactions/logic/langspec_v7.json @@ -4249,7 +4249,7 @@ "BlkTimestamp" ], "ArgEnumTypes": [ - "[]byte", + "[32]byte", "uint64" ], "DocCost": "1", diff --git a/data/transactions/logic/langspec_v8.json b/data/transactions/logic/langspec_v8.json index 186f9cdfe2..c5fcdbf58d 100644 --- a/data/transactions/logic/langspec_v8.json +++ b/data/transactions/logic/langspec_v8.json @@ -4595,7 +4595,7 @@ "BlkTimestamp" ], "ArgEnumTypes": [ - "[]byte", + "[32]byte", "uint64" ], "DocCost": "1", diff --git a/data/transactions/logic/langspec_v9.json b/data/transactions/logic/langspec_v9.json index cab0aa6d91..01e951cc3c 100644 --- a/data/transactions/logic/langspec_v9.json +++ b/data/transactions/logic/langspec_v9.json @@ -4595,7 +4595,7 @@ "BlkTimestamp" ], "ArgEnumTypes": [ - "[]byte", + "[32]byte", "uint64" ], "DocCost": "1", From 004eefec5aa21a6f63aef088864ef03619b2e219 Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Mon, 26 Aug 2024 11:42:48 -0400 Subject: [PATCH 3/4] e2e test for `block FeeSink` --- test/scripts/e2e_subs/hdr-access.py | 46 ++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/test/scripts/e2e_subs/hdr-access.py b/test/scripts/e2e_subs/hdr-access.py index bb6c0ad650..32739e91b2 100755 --- a/test/scripts/e2e_subs/hdr-access.py +++ b/test/scripts/e2e_subs/hdr-access.py @@ -1,8 +1,10 @@ #!/usr/bin/env python +import base64 import os import sys from goal import Goal +import algosdk.encoding as enc from datetime import datetime @@ -43,13 +45,10 @@ txinfo, err = goal.app_create(joe, goal.assemble(teal)) assert "not available" in str(err), err -# We want to manipulate lastvalid, so we need to turn off autosend -goal.autosend = False - -# We will be able to access two blocks, by setting lv explcitly. So we -# test that the block timestamp from two blocks ago is between 2 and 5 -# (inclusive) seconds before the previous block timestamp. devMode -# might mess this test up. +# We will be able to access more than one previous block by using a +# shorter tx liftetime. So we test that the block timestamp from two +# blocks ago is between 2 and 5 (inclusive) seconds before the +# previous block timestamp. devMode might mess this test up. teal = """ #pragma version 7 txn FirstValid @@ -73,10 +72,7 @@ int 6 < """ -checktimes = goal.assemble(teal) -tx = goal.app_create(joe, goal.assemble(teal)) -tx.last_valid_round = tx.last_valid_round - 800 -txinfo, err = goal.send(tx) +txinfo, err = goal.app_create(joe, goal.assemble(teal), lifetime=100) assert not err, err # block 0 is not accessible even with a low LastValid @@ -85,11 +81,33 @@ int 0 block BlkTimestamp """ -tx = goal.app_create(joe, goal.assemble(teal)) -tx.last_valid_round = tx.last_valid_round - 800 -txinfo, err = goal.send(tx) +txinfo, err = goal.app_create(joe, goal.assemble(teal), lifetime=100) assert "round 0 is not available" in str(err), err assert "outside [1-" in str(err), err # confirms that we can look back to 1 + +# Get FeeSink from `block` opcode, compare to REST API +teal = """ +#pragma version 11 + txn FirstValid + int 2 + - + block BlkFeeSink + log + int 1 + return +""" +txinfo, err = goal.app_create(joe, goal.assemble(teal), lifetime=100) +assert not err, err +assert len(txinfo["logs"]) == 1 +opcode = txinfo["logs"][0] + +block = goal.algod.block_info(txinfo['confirmed-round']-2)['block'] +api = base64.b64encode(enc.decode_address(block['fees'])).decode("utf-8") + +print(opcode, api) + +assert opcode == api + stamp = datetime.now().strftime("%Y%m%d_%H%M%S") print(f"{os.path.basename(sys.argv[0])} OK {stamp}") From 4fdcff6713147d27aae29331e2f6424ca908efbf Mon Sep 17 00:00:00 2001 From: John Jannotti Date: Wed, 28 Aug 2024 10:11:58 -0400 Subject: [PATCH 4/4] keep existing order, even though "unreleased" --- data/transactions/logic/fields.go | 24 ++++++++++-------------- data/transactions/logic/fields_string.go | 18 +++++++++--------- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/data/transactions/logic/fields.go b/data/transactions/logic/fields.go index 5ecb6d4ea3..b2f384c259 100644 --- a/data/transactions/logic/fields.go +++ b/data/transactions/logic/fields.go @@ -991,7 +991,12 @@ const ( BlkSeed BlockField = iota // BlkTimestamp is the Block's timestamp, seconds from epoch BlkTimestamp - + // BlkProposer is the Block's proposer, or ZeroAddress, pre Payouts.Enabled + BlkProposer + // BlkFeesCollected is the sum of fees for the block, or 0, pre Payouts.Enabled + BlkFeesCollected + // BlkBonus is the extra amount to be paid for the given block (from FeeSink) + BlkBonus // BlkBranch is the hash of the previous block BlkBranch // BlkFeeSink is the fee sink for the given round @@ -1000,13 +1005,6 @@ const ( BlkProtocol // BlkTxnCounter is the number of the next transaction after the block BlkTxnCounter - - // BlkProposer is the Block's proposer, or ZeroAddress, pre Payouts.Enabled - BlkProposer - // BlkFeesCollected is the sum of fees for the block, or 0, pre Payouts.Enabled - BlkFeesCollected - // BlkBonus is the extra amount to be paid for the given block (from FeeSink) - BlkBonus // BlkProposerPayout is the actual amount moved from feesink to proposer BlkProposerPayout @@ -1024,15 +1022,13 @@ type blockFieldSpec struct { var blockFieldSpecs = [...]blockFieldSpec{ {BlkSeed, StackBytes32, randomnessVersion}, {BlkTimestamp, StackUint64, randomnessVersion}, - - {BlkBranch, StackBytes32, 11}, - {BlkFeeSink, StackAddress, 11}, - {BlkProtocol, StackBytes, 11}, - {BlkTxnCounter, StackUint64, 11}, - {BlkProposer, StackAddress, incentiveVersion}, {BlkFeesCollected, StackUint64, incentiveVersion}, {BlkBonus, StackUint64, incentiveVersion}, + {BlkBranch, StackBytes32, incentiveVersion}, + {BlkFeeSink, StackAddress, incentiveVersion}, + {BlkProtocol, StackBytes, incentiveVersion}, + {BlkTxnCounter, StackUint64, incentiveVersion}, {BlkProposerPayout, StackUint64, incentiveVersion}, } diff --git a/data/transactions/logic/fields_string.go b/data/transactions/logic/fields_string.go index bed5095221..df9922abf2 100644 --- a/data/transactions/logic/fields_string.go +++ b/data/transactions/logic/fields_string.go @@ -379,20 +379,20 @@ func _() { var x [1]struct{} _ = x[BlkSeed-0] _ = x[BlkTimestamp-1] - _ = x[BlkBranch-2] - _ = x[BlkFeeSink-3] - _ = x[BlkProtocol-4] - _ = x[BlkTxnCounter-5] - _ = x[BlkProposer-6] - _ = x[BlkFeesCollected-7] - _ = x[BlkBonus-8] + _ = x[BlkProposer-2] + _ = x[BlkFeesCollected-3] + _ = x[BlkBonus-4] + _ = x[BlkBranch-5] + _ = x[BlkFeeSink-6] + _ = x[BlkProtocol-7] + _ = x[BlkTxnCounter-8] _ = x[BlkProposerPayout-9] _ = x[invalidBlockField-10] } -const _BlockField_name = "BlkSeedBlkTimestampBlkBranchBlkFeeSinkBlkProtocolBlkTxnCounterBlkProposerBlkFeesCollectedBlkBonusBlkProposerPayoutinvalidBlockField" +const _BlockField_name = "BlkSeedBlkTimestampBlkProposerBlkFeesCollectedBlkBonusBlkBranchBlkFeeSinkBlkProtocolBlkTxnCounterBlkProposerPayoutinvalidBlockField" -var _BlockField_index = [...]uint8{0, 7, 19, 28, 38, 49, 62, 73, 89, 97, 114, 131} +var _BlockField_index = [...]uint8{0, 7, 19, 30, 46, 54, 63, 73, 84, 97, 114, 131} func (i BlockField) String() string { if i < 0 || i >= BlockField(len(_BlockField_index)-1) {