Skip to content

Commit

Permalink
Consider the current auth addr for each inner txn (algorand#83)
Browse files Browse the repository at this point in the history
  • Loading branch information
jannotti authored Mar 5, 2024
1 parent 3905154 commit 3e50c3b
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 10 deletions.
21 changes: 11 additions & 10 deletions data/transactions/logic/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -5509,18 +5509,15 @@ func opItxnSubmit(cx *EvalContext) (err error) {
parent = cx.currentTxID()
}
for itx := range cx.subtxns {
// The goal is to follow the same invariants used by the
// transaction pool. Namely that any transaction that makes it
// to Perform (which is equivalent to eval.applyTransaction)
// is authorized, and WellFormed.
txnErr := authorizedSender(cx, cx.subtxns[itx].Txn.Sender)
if txnErr != nil {
return txnErr
}
// The goal is to follow the same invariants used by the transaction
// pool. Namely that any transaction that makes it to Perform (which is
// equivalent to eval.applyTransaction) is WellFormed. Authorization
// must be checked later, to take state changes from earlier in the
// group into account.

// Recall that WellFormed does not care about individual
// transaction fees because of fee pooling. Checked above.
txnErr = cx.subtxns[itx].Txn.WellFormed(*cx.Specials, *cx.Proto)
txnErr := cx.subtxns[itx].Txn.WellFormed(*cx.Specials, *cx.Proto)
if txnErr != nil {
return txnErr
}
Expand Down Expand Up @@ -5639,7 +5636,11 @@ func opItxnSubmit(cx *EvalContext) (err error) {
ep.Tracer.BeforeTxn(ep, i)
}

err := cx.Ledger.Perform(i, ep)
err := authorizedSender(cx, ep.TxnGroup[i].Txn.Sender)
if err != nil {
return err
}
err = cx.Ledger.Perform(i, ep)

if ep.Tracer != nil {
ep.Tracer.AfterTxn(ep, i, ep.TxnGroup[i].ApplyData, err)
Expand Down
28 changes: 28 additions & 0 deletions data/transactions/logic/evalAppTxn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,34 @@ func TestRekeyBack(t *testing.T) {
})
}

// TestRekeyInnerGroup ensures that in an inner group, if an account is
// rekeyed, it can not be used (by the previously owning app) later in the
// group.
func TestRekeyInnerGroup(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()

rekeyAndUse := `
itxn_begin
// pay 0 to the zero address, and rekey a junk addr
int pay; itxn_field TypeEnum
global ZeroAddress; byte 0x01; b|; itxn_field RekeyTo
itxn_next
// try to perform the same 0 pay, but fail because tx0 gave away control
int pay; itxn_field TypeEnum
itxn_submit
int 1
`

// v6 added inner rekey
TestLogicRange(t, 6, 0, func(t *testing.T, ep *EvalParams, tx *transactions.Transaction, ledger *Ledger) {
ledger.NewApp(tx.Receiver, 888, basics.AppParams{})
// fund the app account
ledger.NewAccount(basics.AppIndex(888).Address(), 1_000_000)
TestApp(t, rekeyAndUse, ep, "unauthorized AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVIOOBQA")
})
}

func TestDefaultSender(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()
Expand Down

0 comments on commit 3e50c3b

Please sign in to comment.