Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FOR REVIEW ONLY - go-algorand-sdk v1.19.0 #363

Merged
merged 5 commits into from
Aug 17, 2022
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 1.19.0
## Enhancements
* AVM: Consolidate TEAL and AVM versions ([#345](https://github.com/algorand/go-algorand-sdk/pull/345))
* Testing: Use Dev mode network for cucumber tests ([#349](https://github.com/algorand/go-algorand-sdk/pull/349))
* AVM: Use avm-abi repo ([#352](https://github.com/algorand/go-algorand-sdk/pull/352))

# 1.18.0

## What's Changed
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ unit:

integration:
go test $(TEST_SOURCES_NO_CUCUMBER)
cd test && go test -timeout 0s --godog.strict=true --godog.format=pretty --godog.tags="@algod,@assets,@auction,@kmd,@send,@indexer,@rekey,@send.keyregtxn,@dryrun,@compile,@applications.verified,@indexer.applications,@indexer.231,@abi,@c2c,@compile.sourcemap" --test.v .
cd test && go test -timeout 0s --godog.strict=true --godog.format=pretty --godog.tags="@algod,@assets,@auction,@kmd,@send,@indexer,@rekey_v1,@send.keyregtxn,@dryrun,@compile,@applications.verified,@indexer.applications,@indexer.231,@abi,@c2c,@compile.sourcemap" --test.v .

docker-test:
./test/docker/run_docker.sh
Expand Down
69 changes: 51 additions & 18 deletions abi/abi.go
Original file line number Diff line number Diff line change
@@ -1,33 +1,66 @@
package abi

import (
"fmt"
"math"

"github.com/algorand/go-algorand/data/abi"
avm_abi "github.com/algorand/avm-abi/abi"
)

type Type = abi.Type
type Type = avm_abi.Type

func TypeOf(str string) (Type, error) {
return abi.TypeOf(str)
return avm_abi.TypeOf(str)
}

// MakeTupleType makes tuple ABI type by taking an array of tuple element types as argument.
func MakeTupleType(argumentTypes []Type) (Type, error) {
if len(argumentTypes) == 0 {
return Type{}, fmt.Errorf("tuple must contain at least one type")
}
return avm_abi.MakeTupleType(argumentTypes)
}

// AnyTransactionType is the ABI argument type string for a nonspecific transaction argument
const AnyTransactionType = avm_abi.AnyTransactionType

// PaymentTransactionType is the ABI argument type string for a payment transaction argument
const PaymentTransactionType = avm_abi.PaymentTransactionType

// KeyRegistrationTransactionType is the ABI argument type string for a key registration transaction
// argument
const KeyRegistrationTransactionType = avm_abi.KeyRegistrationTransactionType

// AssetConfigTransactionType is the ABI argument type string for an asset configuration transaction
// argument
const AssetConfigTransactionType = avm_abi.AssetConfigTransactionType

// AssetTransferTransactionType is the ABI argument type string for an asset transfer transaction
// argument
const AssetTransferTransactionType = avm_abi.AssetTransferTransactionType

if len(argumentTypes) >= math.MaxUint16 {
return Type{}, fmt.Errorf("tuple type child type number larger than maximum uint16 error")
}
// AssetFreezeTransactionType is the ABI argument type string for an asset freeze transaction
// argument
const AssetFreezeTransactionType = avm_abi.AssetFreezeTransactionType

strTuple := "(" + argumentTypes[0].String()
for i := 1; i < len(argumentTypes); i++ {
strTuple += "," + argumentTypes[i].String()
}
strTuple += ")"
// ApplicationCallTransactionType is the ABI argument type string for an application call
// transaction argument
const ApplicationCallTransactionType = avm_abi.ApplicationCallTransactionType

return TypeOf(strTuple)
// IsTransactionType checks if a type string represents a transaction type
// argument, such as "txn", "pay", "keyreg", etc.
func IsTransactionType(typeStr string) bool {
return avm_abi.IsTransactionType(typeStr)
}

// AccountReferenceType is the ABI argument type string for account references
const AccountReferenceType = avm_abi.AccountReferenceType

// AssetReferenceType is the ABI argument type string for asset references
const AssetReferenceType = avm_abi.AssetReferenceType

// ApplicationReferenceType is the ABI argument type string for application references
const ApplicationReferenceType = avm_abi.ApplicationReferenceType

// IsReferenceType checks if a type string represents a reference type argument,
// such as "account", "asset", or "application".
func IsReferenceType(typeStr string) bool {
return avm_abi.IsReferenceType(typeStr)
}

// VoidReturnType is the ABI return type string for a method that does not return any value
const VoidReturnType = avm_abi.VoidReturnType
4 changes: 2 additions & 2 deletions abi/abi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import (
"github.com/stretchr/testify/require"
)

func TestGoAlgorandImportWorks(t *testing.T) {
func TestImportWorks(t *testing.T) {
// This test is not meant to be exhaustive. It's just a simple test to
// verify importing the ABI package from go-algorand is working
// verify importing the ABI package from avm-abi is working

abiType, err := TypeOf("uint64")
require.NoError(t, err)
Expand Down
123 changes: 9 additions & 114 deletions abi/interactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,53 +5,9 @@ import (
"fmt"
"strings"

"github.com/algorand/go-algorand-sdk/types"
avm_abi "github.com/algorand/avm-abi/abi"
)

// AnyTransactionType is the ABI argument type string for a nonspecific
// transaction argument
const AnyTransactionType = "txn"

var transactionArgTypes = map[string]interface{}{
AnyTransactionType: nil, // denotes a placeholder for any of the size types below
string(types.PaymentTx): nil,
string(types.KeyRegistrationTx): nil,
string(types.AssetConfigTx): nil,
string(types.AssetTransferTx): nil,
string(types.AssetFreezeTx): nil,
string(types.ApplicationCallTx): nil,
}

// IsTransactionType checks if a type string represents a transaction type
// argument, such as "txn", "pay", "keyreg", etc.
func IsTransactionType(typeStr string) bool {
_, ok := transactionArgTypes[typeStr]
return ok
}

// AccountReferenceType is the ABI argument type string for account references
const AccountReferenceType = "account"

// AssetReferenceType is the ABI argument type string for asset references
const AssetReferenceType = "asset"

// ApplicationReferenceType is the ABI argument type string for application
// references
const ApplicationReferenceType = "application"

var referenceArgTypes = map[string]interface{}{
AccountReferenceType: nil,
AssetReferenceType: nil,
ApplicationReferenceType: nil,
}

// IsReferenceType checks if a type string represents a reference type argument,
// such as "account", "asset", or "application".
func IsReferenceType(typeStr string) bool {
_, ok := referenceArgTypes[typeStr]
return ok
}

// Arg represents an ABI Method argument
type Arg struct {
// Optional, user-friendly name for the argument
Expand Down Expand Up @@ -95,10 +51,6 @@ func (a *Arg) GetTypeObject() (Type, error) {
return typeObject, err
}

// VoidReturnType is the ABI return type string for a method that does not have
// a return value
const VoidReturnType = "void"

// Return represents an ABI method return value
type Return struct {
// The type of the return value as a string. See the method GetTypeObject to
Expand Down Expand Up @@ -144,91 +96,34 @@ type Method struct {
Returns Return `json:"returns"`
}

// parseMethodArgs parses the arguments from a method signature string.
// trMethod is the complete method signature and startIdx is the index of the
// opening parenthesis of the arguments list. This function returns a list of
// the argument types from the method signature and the index of the closing
// parenthesis of the arguments list.
func parseMethodArgs(strMethod string, startIdx int) ([]string, int, error) {
// handle no args
if startIdx < len(strMethod)-1 && strMethod[startIdx+1] == ')' {
return []string{}, startIdx + 1, nil
}

var argTypes []string
parenCnt := 1
prevPos := startIdx + 1
closeIdx := -1
for curPos := prevPos; curPos < len(strMethod); curPos++ {
if strMethod[curPos] == '(' {
parenCnt++
} else if strMethod[curPos] == ')' {
parenCnt--
}

if parenCnt < 0 {
return nil, -1, fmt.Errorf("method signature parentheses mismatch")
} else if parenCnt > 1 {
continue
}

if strMethod[curPos] == ',' || parenCnt == 0 {
strArg := strMethod[prevPos:curPos]
argTypes = append(argTypes, strArg)
prevPos = curPos + 1
}

if parenCnt == 0 {
closeIdx = curPos
break
}
}

if closeIdx == -1 {
return nil, -1, fmt.Errorf("method signature parentheses mismatch")
}

return argTypes, closeIdx, nil
}

// MethodFromSignature decoded a method signature string into a Method object.
func MethodFromSignature(methodStr string) (Method, error) {
openIdx := strings.Index(methodStr, "(")
if openIdx == -1 {
return Method{}, fmt.Errorf("method signature is missing an open parenthesis")
}

name := methodStr[:openIdx]
if name == "" {
return Method{}, fmt.Errorf("method must have a non empty name")
}

argTypes, closeIdx, err := parseMethodArgs(methodStr, openIdx)
name, argTypesStr, retTypeStr, err := avm_abi.ParseMethodSignature(methodStr)
if err != nil {
return Method{}, err
}

returnType := Return{Type: methodStr[closeIdx+1:]}
returnType := Return{Type: retTypeStr}
if !returnType.IsVoid() {
// fill type object cache and catch any errors
_, err := returnType.GetTypeObject()
if err != nil {
return Method{}, err
return Method{}, fmt.Errorf("Could not parse method return type: %w", err)
}
}

args := make([]Arg, len(argTypes))
for i, argType := range argTypes {
args[i].Type = argType
args := make([]Arg, len(argTypesStr))
for i, argTypeStr := range argTypesStr {
args[i].Type = argTypeStr

if IsTransactionType(argType) || IsReferenceType(argType) {
if IsTransactionType(argTypeStr) || IsReferenceType(argTypeStr) {
continue
}

// fill type object cache and catch any errors
_, err := args[i].GetTypeObject()
if err != nil {
return Method{}, err
return Method{}, fmt.Errorf("Could not parse argument type at index %d: %w", i, err)
}
}

Expand Down
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/algorand/go-algorand-sdk
go 1.17

require (
github.com/algorand/go-algorand v0.0.0-20220323144801-17c0feef002f
github.com/algorand/avm-abi v0.1.0
github.com/algorand/go-codec/codec v1.1.8
github.com/cucumber/godog v0.8.1
github.com/google/go-querystring v1.0.0
Expand All @@ -13,7 +13,9 @@ require (

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
)
Loading