Skip to content
Merged
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
2 changes: 1 addition & 1 deletion buildnumber.dat
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0
1
61 changes: 41 additions & 20 deletions data/transactions/logic/assembler.go
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,7 @@ func assembleTxn(ops *OpStream, spec *OpSpec, args []string) error {
}
ops.pending.WriteByte(spec.Opcode)
ops.pending.WriteByte(uint8(fs.field))
ops.returns(TxnFieldTypes[fs.field])
ops.returns(fs.ftype)
return nil
}

Expand Down Expand Up @@ -840,7 +840,7 @@ func assembleTxna(ops *OpStream, spec *OpSpec, args []string) error {
ops.pending.WriteByte(spec.Opcode)
ops.pending.WriteByte(uint8(fs.field))
ops.pending.WriteByte(uint8(arrayFieldIdx))
ops.returns(TxnFieldTypes[fs.field])
ops.returns(fs.ftype)
return nil
}

Expand Down Expand Up @@ -871,7 +871,7 @@ func assembleGtxn(ops *OpStream, spec *OpSpec, args []string) error {
ops.pending.WriteByte(spec.Opcode)
ops.pending.WriteByte(uint8(slot))
ops.pending.WriteByte(uint8(fs.field))
ops.returns(TxnFieldTypes[fs.field])
ops.returns(fs.ftype)
return nil
}

Expand Down Expand Up @@ -921,7 +921,7 @@ func assembleGtxna(ops *OpStream, spec *OpSpec, args []string) error {
ops.pending.WriteByte(uint8(slot))
ops.pending.WriteByte(uint8(fs.field))
ops.pending.WriteByte(uint8(arrayFieldIdx))
ops.returns(TxnFieldTypes[fs.field])
ops.returns(fs.ftype)
return nil
}

Expand All @@ -947,7 +947,7 @@ func assembleGtxns(ops *OpStream, spec *OpSpec, args []string) error {

ops.pending.WriteByte(spec.Opcode)
ops.pending.WriteByte(uint8(fs.field))
ops.returns(TxnFieldTypes[fs.field])
ops.returns(fs.ftype)
return nil
}

Expand Down Expand Up @@ -976,7 +976,7 @@ func assembleGtxnsa(ops *OpStream, spec *OpSpec, args []string) error {
ops.pending.WriteByte(spec.Opcode)
ops.pending.WriteByte(uint8(fs.field))
ops.pending.WriteByte(uint8(arrayFieldIdx))
ops.returns(TxnFieldTypes[fs.field])
ops.returns(fs.ftype)
return nil
}

Expand All @@ -989,57 +989,78 @@ func assembleGlobal(ops *OpStream, spec *OpSpec, args []string) error {
return ops.errorf("%s unknown field: %#v", spec.Name, args[0])
}
if fs.version > ops.Version {
// no return here. we may as well continue to maintain typestack
ops.errorf("global %s available in version %d. Missed #pragma version?", args[0], fs.version)
//nolint:errcheck // we continue to maintain typestack
ops.errorf("%s %s available in version %d. Missed #pragma version?", spec.Name, args[0], fs.version)
}

val := fs.gfield
val := fs.field
ops.pending.WriteByte(spec.Opcode)
ops.pending.WriteByte(uint8(val))
ops.trace("%s (%s)", GlobalFieldNames[val], GlobalFieldTypes[val].String())
ops.returns(GlobalFieldTypes[val])
ops.trace("%s (%s)", fs.field.String(), fs.ftype.String())
ops.returns(fs.ftype)
return nil
}

func assembleAssetHolding(ops *OpStream, spec *OpSpec, args []string) error {
if len(args) != 1 {
return ops.errorf("%s expects one argument", spec.Name)
}
val, ok := assetHoldingFields[args[0]]
fs, ok := assetHoldingFieldSpecByName[args[0]]
if !ok {
return ops.errorf("%s unknown arg: %#v", spec.Name, args[0])
return ops.errorf("%s unknown field: %#v", spec.Name, args[0])
}
if fs.version > ops.Version {
//nolint:errcheck // we continue to maintain typestack
ops.errorf("%s %s available in version %d. Missed #pragma version?", spec.Name, args[0], fs.version)
}

val := fs.field
ops.pending.WriteByte(spec.Opcode)
ops.pending.WriteByte(uint8(val))
ops.returns(AssetHoldingFieldTypes[val], StackUint64)
ops.trace("%s (%s)", fs.field.String(), fs.ftype.String())
ops.returns(fs.ftype, StackUint64)
return nil
}

func assembleAssetParams(ops *OpStream, spec *OpSpec, args []string) error {
if len(args) != 1 {
return ops.errorf("%s expects one argument", spec.Name)
}
val, ok := assetParamsFields[args[0]]
fs, ok := assetParamsFieldSpecByName[args[0]]
if !ok {
return ops.errorf("%s unknown arg: %#v", spec.Name, args[0])
return ops.errorf("%s unknown field: %#v", spec.Name, args[0])
}
if fs.version > ops.Version {
//nolint:errcheck // we continue to maintain typestack
ops.errorf("%s %s available in version %d. Missed #pragma version?", spec.Name, args[0], fs.version)
}

val := fs.field
ops.pending.WriteByte(spec.Opcode)
ops.pending.WriteByte(uint8(val))
ops.returns(AssetParamsFieldTypes[val], StackUint64)
ops.trace("%s (%s)", fs.field.String(), fs.ftype.String())
ops.returns(fs.ftype, StackUint64)
return nil
}

func assembleAppParams(ops *OpStream, spec *OpSpec, args []string) error {
if len(args) != 1 {
return ops.errorf("%s expects one argument", spec.Name)
}
val, ok := appParamsFields[args[0]]
fs, ok := appParamsFieldSpecByName[args[0]]
if !ok {
return ops.errorf("%s unknown arg: %#v", spec.Name, args[0])
return ops.errorf("%s unknown field: %#v", spec.Name, args[0])
}
if fs.version > ops.Version {
//nolint:errcheck // we continue to maintain typestack
ops.errorf("%s %s available in version %d. Missed #pragma version?", spec.Name, args[0], fs.version)
}

val := fs.field
ops.pending.WriteByte(spec.Opcode)
ops.pending.WriteByte(uint8(val))
ops.returns(AppParamsFieldTypes[val], StackUint64)
ops.trace("%s (%s)", fs.field.String(), fs.ftype.String())
ops.returns(fs.ftype, StackUint64)
return nil
}

Expand Down
4 changes: 2 additions & 2 deletions data/transactions/logic/assembler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1578,13 +1578,13 @@ func TestAssembleAsset(t *testing.T) {
testProg(t, "int 1; int 1; asset_holding_get ABC 1", v,
expect{3, "asset_holding_get expects one argument"})
testProg(t, "int 1; int 1; asset_holding_get ABC", v,
expect{3, "asset_holding_get unknown arg: \"ABC\""})
expect{3, "asset_holding_get unknown field: \"ABC\""})

testProg(t, "byte 0x1234; asset_params_get ABC 1", v,
expect{2, "asset_params_get ABC 1 arg 0 wanted type uint64..."})

testLine(t, "asset_params_get ABC 1", v, "asset_params_get expects one argument")
testLine(t, "asset_params_get ABC", v, "asset_params_get unknown arg: \"ABC\"")
testLine(t, "asset_params_get ABC", v, "asset_params_get unknown field: \"ABC\"")
}
}

Expand Down
8 changes: 4 additions & 4 deletions data/transactions/logic/debugger.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,13 @@ func makeDebugState(cx *evalContext) DebugState {
Proto: cx.Proto,
}

globals := make([]basics.TealValue, len(GlobalFieldNames))
for fieldIdx := range GlobalFieldNames {
sv, err := cx.globalFieldToStack(GlobalField(fieldIdx))
globals := make([]basics.TealValue, len(globalFieldSpecs))
for _, fs := range globalFieldSpecs {
sv, err := cx.globalFieldToValue(fs)
if err != nil {
sv = stackValue{Bytes: []byte(err.Error())}
}
globals[fieldIdx] = stackValueToTealValue(&sv)
globals[fs.field] = stackValueToTealValue(&sv)
}
ds.Globals = globals

Expand Down
87 changes: 47 additions & 40 deletions data/transactions/logic/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -1751,27 +1751,25 @@ func opUncover(cx *evalContext) {
cx.stack[topIdx] = sv
}

func (cx *evalContext) assetHoldingEnumToValue(holding *basics.AssetHolding, field uint64) (sv stackValue, err error) {
switch AssetHoldingField(field) {
func (cx *evalContext) assetHoldingToValue(holding *basics.AssetHolding, fs assetHoldingFieldSpec) (sv stackValue, err error) {
switch fs.field {
case AssetBalance:
sv.Uint = holding.Amount
case AssetFrozen:
sv.Uint = boolToUint(holding.Frozen)
default:
err = fmt.Errorf("invalid asset holding field %d", field)
err = fmt.Errorf("invalid asset_holding_get field %d", fs.field)
return
}

assetHoldingField := AssetHoldingField(field)
assetHoldingFieldType := AssetHoldingFieldTypes[assetHoldingField]
if !typecheck(assetHoldingFieldType, sv.argType()) {
err = fmt.Errorf("%s expected field type is %s but got %s", assetHoldingField.String(), assetHoldingFieldType.String(), sv.argType().String())
if !typecheck(fs.ftype, sv.argType()) {
err = fmt.Errorf("%s expected field type is %s but got %s", fs.field.String(), fs.ftype.String(), sv.argType().String())
}
return
}

func (cx *evalContext) assetParamsEnumToValue(params *basics.AssetParams, creator basics.Address, field uint64) (sv stackValue, err error) {
switch AssetParamsField(field) {
func (cx *evalContext) assetParamsToValue(params *basics.AssetParams, creator basics.Address, fs assetParamsFieldSpec) (sv stackValue, err error) {
switch fs.field {
case AssetTotal:
sv.Uint = params.Total
case AssetDecimals:
Expand All @@ -1797,20 +1795,18 @@ func (cx *evalContext) assetParamsEnumToValue(params *basics.AssetParams, creato
case AssetCreator:
sv.Bytes = creator[:]
default:
err = fmt.Errorf("invalid asset params field %d", field)
err = fmt.Errorf("invalid asset_params_get field %d", fs.field)
return
}

assetParamsField := AssetParamsField(field)
assetParamsFieldType := AssetParamsFieldTypes[assetParamsField]
if !typecheck(assetParamsFieldType, sv.argType()) {
err = fmt.Errorf("%s expected field type is %s but got %s", assetParamsField.String(), assetParamsFieldType.String(), sv.argType().String())
if !typecheck(fs.ftype, sv.argType()) {
err = fmt.Errorf("%s expected field type is %s but got %s", fs.field.String(), fs.ftype.String(), sv.argType().String())
}
return
}

func (cx *evalContext) appParamsEnumToValue(params *basics.AppParams, creator basics.Address, field uint64) (sv stackValue, err error) {
switch AppParamsField(field) {
func (cx *evalContext) appParamsToValue(params *basics.AppParams, creator basics.Address, fs appParamsFieldSpec) (sv stackValue, err error) {
switch fs.field {
case AppApprovalProgram:
sv.Bytes = params.ApprovalProgram[:]
case AppClearStateProgram:
Expand All @@ -1828,14 +1824,12 @@ func (cx *evalContext) appParamsEnumToValue(params *basics.AppParams, creator ba
case AppCreator:
sv.Bytes = creator[:]
default:
err = fmt.Errorf("invalid app params field %d", field)
err = fmt.Errorf("invalid app_params_get field %d", fs.field)
return
}

appParamsField := AppParamsField(field)
appParamsFieldType := AppParamsFieldTypes[appParamsField]
if !typecheck(appParamsFieldType, sv.argType()) {
err = fmt.Errorf("%s expected field type is %s but got %s", appParamsField.String(), appParamsFieldType.String(), sv.argType().String())
if !typecheck(fs.ftype, sv.argType()) {
err = fmt.Errorf("%s expected field type is %s but got %s", fs.field.String(), fs.ftype.String(), sv.argType().String())
}
return
}
Expand Down Expand Up @@ -2285,8 +2279,8 @@ func (cx *evalContext) getCreatorAddress() ([]byte, error) {

var zeroAddress basics.Address

func (cx *evalContext) globalFieldToStack(field GlobalField) (sv stackValue, err error) {
switch field {
func (cx *evalContext) globalFieldToValue(fs globalFieldSpec) (sv stackValue, err error) {
switch fs.field {
case MinTxnFee:
sv.Uint = cx.Proto.MinTxnFee
case MinBalance:
Expand All @@ -2308,36 +2302,34 @@ func (cx *evalContext) globalFieldToStack(field GlobalField) (sv stackValue, err
case CreatorAddress:
sv.Bytes, err = cx.getCreatorAddress()
default:
err = fmt.Errorf("invalid global[%d]", field)
err = fmt.Errorf("invalid global field %d", fs.field)
}

if !typecheck(fs.ftype, sv.argType()) {
err = fmt.Errorf("%s expected field type is %s but got %s", fs.field.String(), fs.ftype.String(), sv.argType().String())
}

return sv, err
}

func opGlobal(cx *evalContext) {
gindex := uint64(cx.program[cx.pc+1])
globalField := GlobalField(gindex)
globalField := GlobalField(cx.program[cx.pc+1])
fs, ok := globalFieldSpecByField[globalField]
if !ok || fs.version > cx.version {
cx.err = fmt.Errorf("invalid global[%d]", globalField)
cx.err = fmt.Errorf("invalid global field %d", globalField)
return
}
if (cx.runModeFlags & fs.mode) == 0 {
cx.err = fmt.Errorf("global[%d] not allowed in current mode", globalField)
return
}

sv, err := cx.globalFieldToStack(globalField)
sv, err := cx.globalFieldToValue(fs)
if err != nil {
cx.err = err
return
}

globalFieldType := GlobalFieldTypes[globalField]
if !typecheck(globalFieldType, sv.argType()) {
cx.err = fmt.Errorf("%s expected field type is %s but got %s", globalField.String(), globalFieldType.String(), sv.argType().String())
return
}

cx.stack = append(cx.stack, sv)
}

Expand Down Expand Up @@ -3082,7 +3074,12 @@ func opAssetHoldingGet(cx *evalContext) {
return
}

fieldIdx := uint64(cx.program[cx.pc+1])
holdingField := AssetHoldingField(cx.program[cx.pc+1])
fs, ok := assetHoldingFieldSpecByField[holdingField]
if !ok || fs.version > cx.version {
cx.err = fmt.Errorf("invalid asset_holding_get field %d", holdingField)
return
}

addr, _, err := accountReference(cx, cx.stack[prev])
if err != nil {
Expand All @@ -3101,7 +3098,7 @@ func opAssetHoldingGet(cx *evalContext) {
if holding, err := cx.Ledger.AssetHolding(addr, asset); err == nil {
// the holding exist, read the value
exist = 1
value, err = cx.assetHoldingEnumToValue(&holding, fieldIdx)
value, err = cx.assetHoldingToValue(&holding, fs)
if err != nil {
cx.err = err
return
Expand All @@ -3120,7 +3117,12 @@ func opAssetParamsGet(cx *evalContext) {
return
}

paramIdx := uint64(cx.program[cx.pc+1])
paramField := AssetParamsField(cx.program[cx.pc+1])
fs, ok := assetParamsFieldSpecByField[paramField]
if !ok || fs.version > cx.version {
cx.err = fmt.Errorf("invalid asset_params_get field %d", paramField)
return
}

asset, err := asaReference(cx, cx.stack[last].Uint, true)
if err != nil {
Expand All @@ -3133,7 +3135,7 @@ func opAssetParamsGet(cx *evalContext) {
if params, creator, err := cx.Ledger.AssetParams(asset); err == nil {
// params exist, read the value
exist = 1
value, err = cx.assetParamsEnumToValue(&params, creator, paramIdx)
value, err = cx.assetParamsToValue(&params, creator, fs)
if err != nil {
cx.err = err
return
Expand All @@ -3152,7 +3154,12 @@ func opAppParamsGet(cx *evalContext) {
return
}

paramIdx := uint64(cx.program[cx.pc+1])
paramField := AppParamsField(cx.program[cx.pc+1])
fs, ok := appParamsFieldSpecByField[paramField]
if !ok || fs.version > cx.version {
cx.err = fmt.Errorf("invalid app_params_get field %d", paramField)
return
}

app, err := appReference(cx, cx.stack[last].Uint, true)
if err != nil {
Expand All @@ -3165,7 +3172,7 @@ func opAppParamsGet(cx *evalContext) {
if params, creator, err := cx.Ledger.AppParams(app); err == nil {
// params exist, read the value
exist = 1
value, err = cx.appParamsEnumToValue(&params, creator, paramIdx)
value, err = cx.appParamsToValue(&params, creator, fs)
if err != nil {
cx.err = err
return
Expand Down
Loading