Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions config/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,11 @@ func initConsensusProtocols() {

// Enable App calls to pool budget in grouped transactions
vFuture.EnableAppCostPooling = true

// Enable Inner Transactions, and set maximum number. 0 value is
// disabled. Value > 0 also activates storage of creatable IDs in
// ApplyData, as that is required to support REST API when inner
// transactions are activated.
vFuture.MaxInnerTransactions = 16

// Allow 50 app opt ins
Expand Down
22 changes: 20 additions & 2 deletions daemon/algod/api/server/v1/handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ func computeCreatableIndexInPayset(tx node.TxnWithStatus, txnCounter uint64, pay
// computeAssetIndexFromTxn returns the created asset index given a confirmed
// transaction whose confirmation block is available in the ledger. Note that
// 0 is an invalid asset index (they start at 1).
func computeAssetIndexFromTxn(tx node.TxnWithStatus, l *data.Ledger) (aidx uint64) {
func computeAssetIndexFromTxn(tx node.TxnWithStatus, l *data.Ledger) uint64 {
// Must have ledger
if l == nil {
return 0
Expand All @@ -413,6 +413,15 @@ func computeAssetIndexFromTxn(tx node.TxnWithStatus, l *data.Ledger) (aidx uint6
return 0
}

aidx := uint64(tx.ApplyData.ConfigAsset)
if aidx > 0 {
return aidx
}
// If there is no ConfigAsset in the ApplyData, it must be a
// transaction before inner transactions were activated. Therefore
// the computeCreatableIndexInPayset function will work properly
// to deduce the aid. Proceed.

// Look up block where transaction was confirmed
blk, err := l.Block(tx.ConfirmedRound)
if err != nil {
Expand All @@ -430,7 +439,7 @@ func computeAssetIndexFromTxn(tx node.TxnWithStatus, l *data.Ledger) (aidx uint6
// computeAppIndexFromTxn returns the created app index given a confirmed
// transaction whose confirmation block is available in the ledger. Note that
// 0 is an invalid asset index (they start at 1).
func computeAppIndexFromTxn(tx node.TxnWithStatus, l *data.Ledger) (aidx uint64) {
func computeAppIndexFromTxn(tx node.TxnWithStatus, l *data.Ledger) uint64 {
// Must have ledger
if l == nil {
return 0
Expand All @@ -448,6 +457,15 @@ func computeAppIndexFromTxn(tx node.TxnWithStatus, l *data.Ledger) (aidx uint64)
return 0
}

aidx := uint64(tx.ApplyData.ApplicationID)
if aidx > 0 {
return aidx
}
// If there is no ApplicationID in the ApplyData, it must be a
// transaction before inner transactions were activated. Therefore
// the computeCreatableIndexInPayset function will work properly
// to deduce the aidx. Proceed.

// Look up block where transaction was confirmed
blk, err := l.Block(tx.ConfirmedRound)
if err != nil {
Expand Down
33 changes: 26 additions & 7 deletions daemon/algod/api/server/v2/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func computeCreatableIndexInPayset(tx node.TxnWithStatus, txnCounter uint64, pay
// computeAssetIndexFromTxn returns the created asset index given a confirmed
// transaction whose confirmation block is available in the ledger. Note that
// 0 is an invalid asset index (they start at 1).
func computeAssetIndexFromTxn(tx node.TxnWithStatus, l *data.Ledger) (aidx *uint64) {
func computeAssetIndexFromTxn(tx node.TxnWithStatus, l *data.Ledger) *uint64 {
// Must have ledger
if l == nil {
return nil
Expand All @@ -128,6 +128,15 @@ func computeAssetIndexFromTxn(tx node.TxnWithStatus, l *data.Ledger) (aidx *uint
return nil
}

aid := uint64(tx.ApplyData.ConfigAsset)
if aid > 0 {
return &aid
}
// If there is no ConfigAsset in the ApplyData, it must be a
// transaction before inner transactions were activated. Therefore
// the computeCreatableIndexInPayset function will work properly
// to deduce the aid. Proceed.

// Look up block where transaction was confirmed
blk, err := l.Block(tx.ConfirmedRound)
if err != nil {
Expand All @@ -145,7 +154,7 @@ func computeAssetIndexFromTxn(tx node.TxnWithStatus, l *data.Ledger) (aidx *uint
// computeAppIndexFromTxn returns the created app index given a confirmed
// transaction whose confirmation block is available in the ledger. Note that
// 0 is an invalid asset index (they start at 1).
func computeAppIndexFromTxn(tx node.TxnWithStatus, l *data.Ledger) (aidx *uint64) {
func computeAppIndexFromTxn(tx node.TxnWithStatus, l *data.Ledger) *uint64 {
// Must have ledger
if l == nil {
return nil
Expand All @@ -163,6 +172,15 @@ func computeAppIndexFromTxn(tx node.TxnWithStatus, l *data.Ledger) (aidx *uint64
return nil
}

aid := uint64(tx.ApplyData.ApplicationID)
if aid > 0 {
return &aid
}
// If there is no ApplicationID in the ApplyData, it must be a
// transaction before inner transactions were activated. Therefore
// the computeCreatableIndexInPayset function will work properly
// to deduce the aid. Proceed.

// Look up block where transaction was confirmed
blk, err := l.Block(tx.ConfirmedRound)
if err != nil {
Expand Down Expand Up @@ -283,12 +301,12 @@ func convertLogs(txn node.TxnWithStatus) *[][]byte {
func convertInners(txn *node.TxnWithStatus) *[]preEncodedTxInfo {
inner := make([]preEncodedTxInfo, len(txn.ApplyData.EvalDelta.InnerTxns))
for i, itxn := range txn.ApplyData.EvalDelta.InnerTxns {
inner[i] = convertTxn(&itxn)
inner[i] = convertInnerTxn(&itxn)
}
return &inner
}

func convertTxn(txn *transactions.SignedTxnWithAD) preEncodedTxInfo {
func convertInnerTxn(txn *transactions.SignedTxnWithAD) preEncodedTxInfo {
// This copies from handlers.PendingTransactionInformation, with
// simplifications because we have a SignedTxnWithAD rather than
// TxnWithStatus, and we know this txn has committed.
Expand All @@ -301,9 +319,10 @@ func convertTxn(txn *transactions.SignedTxnWithAD) preEncodedTxInfo {
response.ReceiverRewards = &txn.ApplyData.ReceiverRewards.Raw
response.CloseRewards = &txn.ApplyData.CloseRewards.Raw

// Indexes can't be set until we allow acfg or appl
// response.AssetIndex = computeAssetIndexFromTxn(txn, v2.Node.Ledger())
// response.ApplicationIndex = computeAppIndexFromTxn(txn, v2.Node.Ledger())
// Since this is an inner txn, we know these indexes will be populated. No
// need to search payset for IDs
response.AssetIndex = numOrNil(uint64(txn.ApplyData.ConfigAsset))
response.ApplicationIndex = numOrNil(uint64(txn.ApplyData.ApplicationID))

// Deltas, Logs, and Inners can not be set until we allow appl
// response.LocalStateDelta, response.GlobalStateDelta = convertToDeltas(txn)
Expand Down
2 changes: 1 addition & 1 deletion data/pools/transactionPool.go
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ func (pool *TransactionPool) isAssemblyTimedOut() bool {
// we have no deadline, so no reason to timeout.
return false
}
generateBlockDuration := generateBlockBaseDuration + time.Duration(pool.pendingBlockEvaluator.TxnCounter())*generateBlockTransactionDuration
generateBlockDuration := generateBlockBaseDuration + time.Duration(pool.pendingBlockEvaluator.PaySetSize())*generateBlockTransactionDuration
return time.Now().After(pool.assemblyDeadline.Add(-generateBlockDuration))
}

Expand Down
6 changes: 3 additions & 3 deletions data/transactions/logic/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,9 @@ The following opcodes allow for the construction and submission of

| Op | Description |
| --- | --- |
| `tx_begin` | Begin preparation of a new inner transaction |
| `tx_field f` | Set field F of the current inner transaction to X |
| `tx_submit` | Execute the current inner transaction. Panic on any failure. |
| `itxn_begin` | Begin preparation of a new inner transaction |
| `itxn_field f` | Set field F of the current inner transaction to X |
| `itxn_submit` | Execute the current inner transaction. Panic on any failure. |


### Loading Values
Expand Down
6 changes: 3 additions & 3 deletions data/transactions/logic/TEAL_opcodes.md
Original file line number Diff line number Diff line change
Expand Up @@ -1233,7 +1233,7 @@ bitlen interprets arrays as big-endian integers, unlike setbit/getbit

`log` can be called up to MaxLogCalls times in a program, and log up to a total of 1k bytes.

## tx_begin
## itxn_begin

- Opcode: 0xb1
- Pops: _None_
Expand All @@ -1242,7 +1242,7 @@ bitlen interprets arrays as big-endian integers, unlike setbit/getbit
- LogicSigVersion >= 5
- Mode: Application

## tx_field f
## itxn_field f

- Opcode: 0xb2 {uint8 transaction field index}
- Pops: *... stack*, any
Expand All @@ -1251,7 +1251,7 @@ bitlen interprets arrays as big-endian integers, unlike setbit/getbit
- LogicSigVersion >= 5
- Mode: Application

## tx_submit
## itxn_submit

- Opcode: 0xb3
- Pops: _None_
Expand Down
18 changes: 9 additions & 9 deletions data/transactions/logic/assembler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,9 @@ extract16bits
log
txn Nonparticipation
gtxn 0 Nonparticipation
tx_begin
tx_field Sender
tx_submit
itxn_begin
itxn_field Sender
itxn_submit
int 1
txnas ApplicationArgs
int 0
Expand Down Expand Up @@ -2250,11 +2250,11 @@ func TestUncoverAsm(t *testing.T) {
}

func TestTxTypes(t *testing.T) {
testProg(t, "tx_begin; tx_field Sender", 5, expect{2, "tx_field Sender expects 1 stack argument..."})
testProg(t, "tx_begin; int 1; tx_field Sender", 5, expect{3, "...wanted type []byte got uint64"})
testProg(t, "tx_begin; byte 0x56127823; tx_field Sender", 5)
testProg(t, "itxn_begin; itxn_field Sender", 5, expect{2, "itxn_field Sender expects 1 stack argument..."})
testProg(t, "itxn_begin; int 1; itxn_field Sender", 5, expect{3, "...wanted type []byte got uint64"})
testProg(t, "itxn_begin; byte 0x56127823; itxn_field Sender", 5)

testProg(t, "tx_begin; tx_field Amount", 5, expect{2, "tx_field Amount expects 1 stack argument..."})
testProg(t, "tx_begin; byte 0x87123376; tx_field Amount", 5, expect{3, "...wanted type uint64 got []byte"})
testProg(t, "tx_begin; int 1; tx_field Amount", 5)
testProg(t, "itxn_begin; itxn_field Amount", 5, expect{2, "itxn_field Amount expects 1 stack argument..."})
testProg(t, "itxn_begin; byte 0x87123376; itxn_field Amount", 5, expect{3, "...wanted type uint64 got []byte"})
testProg(t, "itxn_begin; int 1; itxn_field Amount", 5)
}
12 changes: 6 additions & 6 deletions data/transactions/logic/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,10 @@ var opDocByName = map[string]string{
"b^": "A bitwise-xor B, where A and B are byte-arrays, zero-left extended to the greater of their lengths",
"b~": "X with all bits inverted",

"log": "write bytes to log state of the current application",
"tx_begin": "Begin preparation of a new inner transaction",
"tx_field": "Set field F of the current inner transaction to X",
"tx_submit": "Execute the current inner transaction. Panic on any failure.",
"log": "write bytes to log state of the current application",
"itxn_begin": "Begin preparation of a new inner transaction",
"itxn_field": "Set field F of the current inner transaction to X",
"itxn_submit": "Execute the current inner transaction. Panic on any failure.",

"txnas": "push Xth value of the array field F of the current transaction",
"gtxnas": "push Xth value of the array field F from the Tth transaction in the current group",
Expand Down Expand Up @@ -201,7 +201,7 @@ var opcodeImmediateNotes = map[string]string{
"asset_holding_get": "{uint8 asset holding field index}",
"asset_params_get": "{uint8 asset params field index}",
"app_params_get": "{uint8 app params field index}",
"tx_field": "{uint8 transaction field index}",
"itxn_field": "{uint8 transaction field index}",
"txnas": "{uint8 transaction field index}",
"gtxnas": "{uint8 transaction group index} {uint8 transaction field index}",
"gtxnsas": "{uint8 transaction field index}",
Expand Down Expand Up @@ -269,7 +269,7 @@ var OpGroups = map[string][]string{
"Loading Values": {"intcblock", "intc", "intc_0", "intc_1", "intc_2", "intc_3", "pushint", "bytecblock", "bytec", "bytec_0", "bytec_1", "bytec_2", "bytec_3", "pushbytes", "bzero", "arg", "arg_0", "arg_1", "arg_2", "arg_3", "txn", "gtxn", "txna", "txnas", "gtxna", "gtxnas", "gtxns", "gtxnsa", "gtxnsas", "global", "load", "loads", "store", "stores", "gload", "gloads", "gaid", "gaids", "args"},
"Flow Control": {"err", "bnz", "bz", "b", "return", "pop", "dup", "dup2", "dig", "cover", "uncover", "swap", "select", "assert", "callsub", "retsub"},
"State Access": {"balance", "min_balance", "app_opted_in", "app_local_get", "app_local_get_ex", "app_global_get", "app_global_get_ex", "app_local_put", "app_global_put", "app_local_del", "app_global_del", "asset_holding_get", "asset_params_get", "app_params_get", "log"},
"Inner Transactions": {"tx_begin", "tx_field", "tx_submit"},
"Inner Transactions": {"itxn_begin", "itxn_field", "itxn_submit"},
}

// OpCost indicates the cost of an operation over the range of
Expand Down
Loading