Skip to content

Commit

Permalink
Fix app_opted_in for resource sharing, and initial spec changes
Browse files Browse the repository at this point in the history
  • Loading branch information
jannotti committed Feb 22, 2023
1 parent 90284b2 commit 8d0b6a9
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 12 deletions.
34 changes: 34 additions & 0 deletions data/transactions/logic/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,40 @@ _available_.

* Since v7, the account associated with any contract present in the
`txn.ForeignApplications` field is _available_.

* Since v9, there is group-level resource sharing. Any resource that
is available in _some_ top-level transaction in a transaction group
is available in _all_ v9 or later application calls in the group,
whether those application calls are top-level or inner.

* When considering whether an asset holding or application local
state is available by group-level resource sharing, the holding or
local state must be available in a top-level transaction without
considering group sharing. For example, if account A is made
available in one transaction, and asset X is made available in
another, group resource sharing does _not_ make A's X holding
available.

* Top-level transactions that are not application calls also make
resources available to group-level resource sharing. The following
resources are made available other transaction types.

1. `pay` - `txn.Sender`, `txn.Receiver`, and `txn.CloseRemainderTo`

1. `keyreg` - `txn.Sender`

1. `acfg` - `txn.Sender`, `txn.ConfigAsset`, and the
`txn.ConfigAsset` holding of `txn.Sender`.

1. `axfer` - `txn.Sender`, `txn.AssetSender`, `txnAssetCloseTo`,
`txn.XferAsset` and the `txn.XferAsset` holding of each of
those accounts.

1. `afrz` - `txn.Sender`, `txn.FreezeAccount`, `txn.FreezeAsset`,
and the `txn.FreezeAsset` holding of `txn.FreezeAccount`. The
`txn.FreezeAsset` holding of `txn.Sender` is _not_ made
available.


* A Box is _available_ to an Approval Program if _any_ transaction in
the same group contains a box reference (`txn.Boxes`) that denotes
Expand Down
34 changes: 34 additions & 0 deletions data/transactions/logic/README_in.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,40 @@ _available_.

* Since v7, the account associated with any contract present in the
`txn.ForeignApplications` field is _available_.

* Since v9, there is group-level resource sharing. Any resource that
is available in _some_ top-level transaction in a transaction group
is available in _all_ v9 or later application calls in the group,
whether those application calls are top-level or inner.

* When considering whether an asset holding or application local
state is available by group-level resource sharing, the holding or
local state must be available in a top-level transaction without
considering group sharing. For example, if account A is made
available in one transaction, and asset X is made available in
another, group resource sharing does _not_ make A's X holding
available.

* Top-level transactions that are not application calls also make
resources available to group-level resource sharing. The following
resources are made available other transaction types.

1. `pay` - `txn.Sender`, `txn.Receiver`, and `txn.CloseRemainderTo`

1. `keyreg` - `txn.Sender`

1. `acfg` - `txn.Sender`, `txn.ConfigAsset`, and the
`txn.ConfigAsset` holding of `txn.Sender`.

1. `axfer` - `txn.Sender`, `txn.AssetSender`, `txnAssetCloseTo`,
`txn.XferAsset` and the `txn.XferAsset` holding of each of
those accounts.

1. `afrz` - `txn.Sender`, `txn.FreezeAccount`, `txn.FreezeAsset`,
and the `txn.FreezeAsset` holding of `txn.FreezeAccount`. The
`txn.FreezeAsset` holding of `txn.Sender` is _not_ made
available.


* A Box is _available_ to an Approval Program if _any_ transaction in
the same group contains a box reference (`txn.Boxes`) that denotes
Expand Down
4 changes: 2 additions & 2 deletions data/transactions/logic/TEAL_opcodes.md
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,7 @@ Almost all smart contracts should use simpler and smaller methods (such as the [
- Availability: v2
- Mode: Application

params: Txn.Accounts offset (or, since v4, an _available_ account address), _available_ application id (or, since v4, a Txn.ForeignApps offset). Return: value.
params: Txn.Accounts offset (or, since v4, an _available_ account address). Return: value.

## app_opted_in

Expand Down Expand Up @@ -1037,7 +1037,7 @@ params: Txn.ForeignApps offset or an _available_ app id. Return: did_exist flag
- Availability: v3
- Mode: Application

params: Txn.Accounts offset (or, since v4, an _available_ account address), _available_ application id (or, since v4, a Txn.ForeignApps offset). Return: value.
params: Txn.Accounts offset (or, since v4, an _available_ account address). Return: value.

## pushbytes bytes

Expand Down
4 changes: 2 additions & 2 deletions data/transactions/logic/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,8 @@ var opDocExtras = map[string]string{
"pushints": "pushints args are not added to the intcblock during assembly processes",
"getbit": "see explanation of bit ordering in setbit",
"setbit": "When A is a uint64, index 0 is the least significant bit. Setting bit 3 to 1 on the integer 0 yields 8, or 2^3. When A is a byte array, index 0 is the leftmost bit of the leftmost byte. Setting bits 0 through 11 to 1 in a 4-byte-array of 0s yields the byte array 0xfff00000. Setting bit 3 to 1 on the 1-byte-array 0x00 yields the byte array 0x10.",
"balance": "params: Txn.Accounts offset (or, since v4, an _available_ account address), _available_ application id (or, since v4, a Txn.ForeignApps offset). Return: value.",
"min_balance": "params: Txn.Accounts offset (or, since v4, an _available_ account address), _available_ application id (or, since v4, a Txn.ForeignApps offset). Return: value.",
"balance": "params: Txn.Accounts offset (or, since v4, an _available_ account address). Return: value.",
"min_balance": "params: Txn.Accounts offset (or, since v4, an _available_ account address). Return: value.",
"app_opted_in": "params: Txn.Accounts offset (or, since v4, an _available_ account address), _available_ application id (or, since v4, a Txn.ForeignApps offset). Return: 1 if opted in and 0 otherwise.",
"app_local_get": "params: Txn.Accounts offset (or, since v4, an _available_ account address), state key. Return: value. The value is zero (of type uint64) if the key does not exist.",
"app_local_get_ex": "params: Txn.Accounts offset (or, since v4, an _available_ account address), _available_ application id (or, since v4, a Txn.ForeignApps offset), state key. Return: did_exist flag (top of the stack, 1 if the application and key existed and 0 otherwise), value. The value is zero (of type uint64) if the key does not exist.",
Expand Down
7 changes: 1 addition & 6 deletions data/transactions/logic/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -4108,12 +4108,7 @@ func opAppOptedIn(cx *EvalContext) error {
last := len(cx.stack) - 1 // app
prev := last - 1 // account

addr, _, err := cx.accountReference(cx.stack[prev])
if err != nil {
return err
}

app, err := cx.appReference(cx.stack[last].Uint, false)
addr, app, _, err := cx.localsReference(cx.stack[prev], cx.stack[last].Uint)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions data/transactions/logic/langspec.json
Original file line number Diff line number Diff line change
Expand Up @@ -1462,7 +1462,7 @@
"Returns": "U",
"Size": 1,
"Doc": "balance for account A, in microalgos. The balance is observed after the effects of previous transactions in the group, and after the fee for the current transaction is deducted. Changes caused by inner transactions are observable immediately following `itxn_submit`",
"DocExtra": "params: Txn.Accounts offset (or, since v4, an _available_ account address), _available_ application id (or, since v4, a Txn.ForeignApps offset). Return: value.",
"DocExtra": "params: Txn.Accounts offset (or, since v4, an _available_ account address). Return: value.",
"IntroducedVersion": 2,
"Groups": [
"State Access"
Expand Down Expand Up @@ -1689,7 +1689,7 @@
"Returns": "U",
"Size": 1,
"Doc": "minimum required balance for account A, in microalgos. Required balance is affected by ASA, App, and Box usage. When creating or opting into an app, the minimum balance grows before the app code runs, therefore the increase is visible there. When deleting or closing out, the minimum balance decreases after the app executes. Changes caused by inner transactions or box usage are observable immediately following the opcode effecting the change.",
"DocExtra": "params: Txn.Accounts offset (or, since v4, an _available_ account address), _available_ application id (or, since v4, a Txn.ForeignApps offset). Return: value.",
"DocExtra": "params: Txn.Accounts offset (or, since v4, an _available_ account address). Return: value.",
"IntroducedVersion": 3,
"Groups": [
"State Access"
Expand Down
30 changes: 30 additions & 0 deletions data/transactions/logic/resources_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ pop; pop; int 1

_, _, ledger := logic.MakeSampleEnv()
ledger.NewAccount(appl0.Sender, 100_000)
ledger.NewAccount(appl1.Sender, 100_000)
ledger.NewApp(appl0.Sender, 500, basics.AppParams{})
ledger.NewLocals(appl0.Sender, 500) // opt in
// Now txn0 passes, but txn1 has an error because it can't see app 500
Expand All @@ -96,6 +97,27 @@ pop; pop; int 1
// is the one from tx0.
logic.TestApps(t, sources, txntest.Group(&appl0, &appl2), 9, ledger)

// Checking if an account is opted in has pretty much the same rules
optInCheck := `
int 0 // Sender
int 500
app_opted_in
`

sources = []string{optInCheck, optInCheck}
// app_opted_in requires the address and the app exist, else the program fails
logic.TestApps(t, sources, txntest.Group(&appl0, &appl1), 8, nil,
logic.NewExpect(0, "no account"))

// Now txn0 passes, but txn1 has an error because it can't see app 500
logic.TestApps(t, sources, txntest.Group(&appl0, &appl1), 9, ledger,
logic.NewExpect(1, "invalid Local State access"))

// But it's ok in appl2, because appl2 uses the same Sender, even though the
// foreign-app is not repeated in appl2 because the holding being accessed
// is the one from tx0.
logic.TestApps(t, sources, txntest.Group(&appl0, &appl2), 9, ledger)

// Now, confirm that *setting* a local state in tx1 that was made available
// in tx0 works. The extra check here is that the change is recorded
// properly in EvalDelta.
Expand Down Expand Up @@ -706,6 +728,14 @@ func TestAccessMyLocals(t *testing.T) {
app_local_get
int 7
==
`
logic.TestApp(t, source, ep)

// They can also see that they are opted in, though it's a weird question to ask.
source = `
int 0
int 0
app_opted_in
`
logic.TestApp(t, source, ep)
})
Expand Down

0 comments on commit 8d0b6a9

Please sign in to comment.