Skip to content

Commit

Permalink
Fix langspec (and some assembly errors) for itxn_field
Browse files Browse the repository at this point in the history
  • Loading branch information
jannotti committed Apr 8, 2022
1 parent e58901a commit 4c95237
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 20 deletions.
6 changes: 5 additions & 1 deletion cmd/opdoc/opdoc.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,12 @@ func fieldsAndTypes(group logic.FieldGroup) ([]string, string) {

func argEnums(name string) ([]string, string) {
switch name {
case "txn", "gtxn", "gtxns", "itxn", "gitxn", "itxn_field":
case "txn", "gtxn", "gtxns", "itxn", "gitxn":
return fieldsAndTypes(logic.TxnFields)
case "itxn_field":
// itxn_field does not *return* a type depending on its immediate. It *takes* it.
// but until a consumer cares, ArgEnumTypes will be overloaded for that meaning.
return fieldsAndTypes(logic.ItxnSettableFields)
case "global":
return fieldsAndTypes(logic.GlobalFields)
case "txna", "gtxna", "gtxnsa", "txnas", "gtxnas", "gtxnsas", "itxna", "gitxna":
Expand Down
11 changes: 10 additions & 1 deletion cmd/opdoc/tmLanguage.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,18 @@ func buildSyntaxHighlight() *tmLanguage {
}
}

var seen = make(map[string]bool, len(allNamedFields))
var dedupe = make([]string, 0, len(allNamedFields))
for _, name := range allNamedFields {
if name != "" && !seen[name] {
dedupe = append(dedupe, name)
}
seen[name] = true
}

literals.Patterns = append(literals.Patterns, pattern{
Name: "variable.parameter.teal",
Match: fmt.Sprintf("\\b(%s)\\b", strings.Join(allNamedFields, "|")),
Match: fmt.Sprintf("\\b(%s)\\b", strings.Join(dedupe, "|")),
})
tm.Repository["literals"] = literals

Expand Down
6 changes: 5 additions & 1 deletion data/transactions/logic/assembler.go
Original file line number Diff line number Diff line change
Expand Up @@ -1869,7 +1869,11 @@ func disDefault(dis *disassembleState, spec *OpSpec) (string, error) {
if int(b) >= len(imm.Group.Names) {
return "", fmt.Errorf("invalid immediate %s for %s: %d", imm.Name, spec.Name, b)
}
out += imm.Group.Names[b]
name := imm.Group.Names[b]
if name == "" {
return "", fmt.Errorf("invalid immediate %s for %s: %d", imm.Name, spec.Name, b)
}
out += name
} else {
out += fmt.Sprintf("%d", b)
}
Expand Down
17 changes: 17 additions & 0 deletions data/transactions/logic/assembler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2404,3 +2404,20 @@ func TestTxTypes(t *testing.T) {
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)
}

func TestBadInnerFields(t *testing.T) {
testProg(t, "itxn_begin; int 1000; itxn_field FirstValid", 5, Expect{3, "...is not allowed."})
testProg(t, "itxn_begin; int 1000; itxn_field FirstValidTime", 5, Expect{3, "...is not allowed."})
testProg(t, "itxn_begin; int 1000; itxn_field LastValid", 5, Expect{3, "...is not allowed."})
testProg(t, "itxn_begin; int 32; bzero; itxn_field Lease", 5, Expect{4, "...is not allowed."})
testProg(t, "itxn_begin; byte 0x7263; itxn_field Note", 5, Expect{3, "...Note field was introduced in TEAL v6..."})
testProg(t, "itxn_begin; byte 0x7263; itxn_field VotePK", 5, Expect{3, "...VotePK field was introduced in TEAL v6..."})
testProg(t, "itxn_begin; int 32; bzero; itxn_field TxID", 5, Expect{4, "...is not allowed."})

testProg(t, "itxn_begin; int 1000; itxn_field FirstValid", 6, Expect{3, "...is not allowed."})
testProg(t, "itxn_begin; int 1000; itxn_field LastValid", 6, Expect{3, "...is not allowed."})
testProg(t, "itxn_begin; int 32; bzero; itxn_field Lease", 6, Expect{4, "...is not allowed."})
testProg(t, "itxn_begin; byte 0x7263; itxn_field Note", 6)
testProg(t, "itxn_begin; byte 0x7263; itxn_field VotePK", 6)
testProg(t, "itxn_begin; int 32; bzero; itxn_field TxID", 6, Expect{4, "...is not allowed."})
}
23 changes: 23 additions & 0 deletions data/transactions/logic/fields.go
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,29 @@ func txnaFieldNames() []string {
return names
}

// ItxnSettableFields collects info for itxn_field opcode
var ItxnSettableFields = FieldGroup{
"itxn_field", "",
itxnSettableFieldNames(),
txnFieldSpecByName,
}

// itxnSettableFieldNames are txn field names that can be set by
// itxn_field. Return value is a "sparse" slice, the names appear at their usual
// index, unsettable slots are set to "". They are laid out this way so that it is
// possible to get the name from the index value.
func itxnSettableFieldNames() []string {
names := make([]string, len(txnFieldSpecs))
for i, fs := range txnFieldSpecs {
if fs.itxVersion == 0 {
names[i] = ""
} else {
names[i] = fs.field.String()
}
}
return names
}

var innerTxnTypes = map[string]uint64{
string(protocol.PaymentTx): 5,
string(protocol.KeyRegistrationTx): 6,
Expand Down
17 changes: 1 addition & 16 deletions data/transactions/logic/langspec.json
Original file line number Diff line number Diff line change
Expand Up @@ -1842,11 +1842,7 @@
"ArgEnum": [
"Sender",
"Fee",
"FirstValid",
"FirstValidTime",
"LastValid",
"Note",
"Lease",
"Receiver",
"Amount",
"CloseRemainderTo",
Expand All @@ -1862,14 +1858,10 @@
"AssetSender",
"AssetReceiver",
"AssetCloseTo",
"GroupIndex",
"TxID",
"ApplicationID",
"OnCompletion",
"ApplicationArgs",
"NumAppArgs",
"Accounts",
"NumAccounts",
"ApprovalProgram",
"ClearStateProgram",
"RekeyTo",
Expand All @@ -1889,23 +1881,16 @@
"FreezeAssetAccount",
"FreezeAssetFrozen",
"Assets",
"NumAssets",
"Applications",
"NumApplications",
"GlobalNumUint",
"GlobalNumByteSlice",
"LocalNumUint",
"LocalNumByteSlice",
"ExtraProgramPages",
"Nonparticipation",
"Logs",
"NumLogs",
"CreatedAssetID",
"CreatedApplicationID",
"LastLog",
"StateProofPK"
],
"ArgEnumTypes": "BUUUUBBBUBBBUUUBUUUBBBUBUUBUBUBBBUUUUBBBBBBBBUBUUUUUUUUUUUBUUUBB",
"ArgEnumTypes": "BUBBUBBBUUUBUUUBBBUUBBBBBUUUUBBBBBBBBUBUUUUUUUUUB",
"Doc": "set field F of the current inner transaction to A",
"DocExtra": "`itxn_field` fails if A is of the wrong type for F, including a byte array of the wrong size for use as an address when F is an address field. `itxn_field` also fails if A is an account, asset, or app that is not _available_, or an attempt is made extend an array field beyond the limit imposed by consensus parameters. (Addresses set into asset params of acfg transactions need not be _available_.)",
"ImmediateNote": "{uint8 transaction field index}",
Expand Down
2 changes: 1 addition & 1 deletion data/transactions/logic/teal.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@
},
{
"name": "variable.parameter.teal",
"match": "\\b(unknown|pay|keyreg|acfg|axfer|afrz|appl|NoOp|OptIn|CloseOut|ClearState|UpdateApplication|DeleteApplication|Secp256k1|Secp256r1|Sender|Fee|FirstValid|FirstValidTime|LastValid|Note|Lease|Receiver|Amount|CloseRemainderTo|VotePK|SelectionPK|VoteFirst|VoteLast|VoteKeyDilution|Type|TypeEnum|XferAsset|AssetAmount|AssetSender|AssetReceiver|AssetCloseTo|GroupIndex|TxID|ApplicationID|OnCompletion|ApplicationArgs|NumAppArgs|Accounts|NumAccounts|ApprovalProgram|ClearStateProgram|RekeyTo|ConfigAsset|ConfigAssetTotal|ConfigAssetDecimals|ConfigAssetDefaultFrozen|ConfigAssetUnitName|ConfigAssetName|ConfigAssetURL|ConfigAssetMetadataHash|ConfigAssetManager|ConfigAssetReserve|ConfigAssetFreeze|ConfigAssetClawback|FreezeAsset|FreezeAssetAccount|FreezeAssetFrozen|Assets|NumAssets|Applications|NumApplications|GlobalNumUint|GlobalNumByteSlice|LocalNumUint|LocalNumByteSlice|ExtraProgramPages|Nonparticipation|Logs|NumLogs|CreatedAssetID|CreatedApplicationID|LastLog|StateProofPK|MinTxnFee|MinBalance|MaxTxnLife|ZeroAddress|GroupSize|LogicSigVersion|Round|LatestTimestamp|CurrentApplicationID|CreatorAddress|CurrentApplicationAddress|GroupID|OpcodeBudget|CallerApplicationID|CallerApplicationAddress|||||||||||||||||||||||||||ApplicationArgs||Accounts||||||||||||||||||||Assets||Applications||||||||Logs||||||URLEncoding|StdEncoding|JSONString|JSONUint64|JSONObject|AssetBalance|AssetFrozen|AssetTotal|AssetDecimals|AssetDefaultFrozen|AssetUnitName|AssetName|AssetURL|AssetMetadataHash|AssetManager|AssetReserve|AssetFreeze|AssetClawback|AssetCreator|AppApprovalProgram|AppClearStateProgram|AppGlobalNumUint|AppGlobalNumByteSlice|AppLocalNumUint|AppLocalNumByteSlice|AppExtraProgramPages|AppCreator|AppAddress|AcctBalance|AcctMinBalance|AcctAuthAddr)\\b"
"match": "\\b(unknown|pay|keyreg|acfg|axfer|afrz|appl|NoOp|OptIn|CloseOut|ClearState|UpdateApplication|DeleteApplication|Secp256k1|Secp256r1|Sender|Fee|FirstValid|FirstValidTime|LastValid|Note|Lease|Receiver|Amount|CloseRemainderTo|VotePK|SelectionPK|VoteFirst|VoteLast|VoteKeyDilution|Type|TypeEnum|XferAsset|AssetAmount|AssetSender|AssetReceiver|AssetCloseTo|GroupIndex|TxID|ApplicationID|OnCompletion|ApplicationArgs|NumAppArgs|Accounts|NumAccounts|ApprovalProgram|ClearStateProgram|RekeyTo|ConfigAsset|ConfigAssetTotal|ConfigAssetDecimals|ConfigAssetDefaultFrozen|ConfigAssetUnitName|ConfigAssetName|ConfigAssetURL|ConfigAssetMetadataHash|ConfigAssetManager|ConfigAssetReserve|ConfigAssetFreeze|ConfigAssetClawback|FreezeAsset|FreezeAssetAccount|FreezeAssetFrozen|Assets|NumAssets|Applications|NumApplications|GlobalNumUint|GlobalNumByteSlice|LocalNumUint|LocalNumByteSlice|ExtraProgramPages|Nonparticipation|Logs|NumLogs|CreatedAssetID|CreatedApplicationID|LastLog|StateProofPK|MinTxnFee|MinBalance|MaxTxnLife|ZeroAddress|GroupSize|LogicSigVersion|Round|LatestTimestamp|CurrentApplicationID|CreatorAddress|CurrentApplicationAddress|GroupID|OpcodeBudget|CallerApplicationID|CallerApplicationAddress|URLEncoding|StdEncoding|JSONString|JSONUint64|JSONObject|AssetBalance|AssetFrozen|AssetTotal|AssetDecimals|AssetDefaultFrozen|AssetUnitName|AssetName|AssetURL|AssetMetadataHash|AssetManager|AssetReserve|AssetFreeze|AssetClawback|AssetCreator|AppApprovalProgram|AppClearStateProgram|AppGlobalNumUint|AppGlobalNumByteSlice|AppLocalNumUint|AppLocalNumByteSlice|AppExtraProgramPages|AppCreator|AppAddress|AcctBalance|AcctMinBalance|AcctAuthAddr)\\b"
}
]
},
Expand Down

0 comments on commit 4c95237

Please sign in to comment.