Skip to content

Commit

Permalink
Merge branch 'master' into jack/upgrade-golang-version-to-1.16.7
Browse files Browse the repository at this point in the history
  • Loading branch information
algojack authored Dec 7, 2021
2 parents 32b0b38 + 850f7c7 commit 6c39870
Show file tree
Hide file tree
Showing 47 changed files with 1,564 additions and 711 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,6 @@ commands:
export PACKAGE_NAMES=$(echo $PACKAGES | tr -d '\n')
export PARTITION_TOTAL=${CIRCLE_NODE_TOTAL}
export PARTITION_ID=${CIRCLE_NODE_INDEX}
export PARALLEL_FLAG="-p 1"
gotestsum --format testname --junitfile << parameters.result_path >>/<< parameters.result_subdir >>/${CIRCLE_NODE_INDEX}/results.xml --jsonfile << parameters.result_path >>/<< parameters.result_subdir >>/${CIRCLE_NODE_INDEX}/testresults.json -- --tags "sqlite_unlock_notify sqlite_omit_load_extension" << parameters.short_test_flag >> -race -timeout 1h -coverprofile=coverage.txt -covermode=atomic -p 1 $PACKAGE_NAMES
- store_artifacts:
path: << parameters.result_path >>
Expand Down Expand Up @@ -432,6 +431,7 @@ commands:
export TEST_RESULTS=<< parameters.result_path >>/<< parameters.result_subdir >>/${CIRCLE_NODE_INDEX}
export PARTITION_TOTAL=${CIRCLE_NODE_TOTAL}
export PARTITION_ID=${CIRCLE_NODE_INDEX}
export PARALLEL_FLAG="-p 1"
test/scripts/run_integration_tests.sh
- store_artifacts:
path: << parameters.result_path >>
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[![Build Status](https://travis-ci.com/algorand/go-algorand.svg?branch=master)](https://travis-ci.com/algorand/go-algorand)
| rel/stable <br> [![CircleCI](https://circleci.com/gh/algorand/go-algorand/tree/rel%2Fstable.svg?style=svg)](https://circleci.com/gh/algorand/go-algorand/tree/rel%2Fstable) | rel/beta <br> [![CircleCI](https://circleci.com/gh/algorand/go-algorand/tree/rel%2Fbeta.svg?style=svg)](https://circleci.com/gh/algorand/go-algorand/tree/rel%2Fbeta) | rel/nightly <br> [![CircleCI](https://circleci.com/gh/algorand/go-algorand/tree/rel%2Fnightly.svg?style=svg)](https://circleci.com/gh/algorand/go-algorand/tree/rel%2Fnightly) |
| --- | --- | --- |

go-algorand
====================
Expand Down
193 changes: 158 additions & 35 deletions cmd/goal/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ var (

extraPages uint32

createOnCompletion string
onCompletion string

localSchemaUints uint64
localSchemaByteSlices uint64
Expand Down Expand Up @@ -106,7 +106,7 @@ func init() {
createAppCmd.Flags().Uint64Var(&localSchemaUints, "local-ints", 0, "Maximum number of integer values that may be stored in local (per-account) key/value stores for this app. Immutable.")
createAppCmd.Flags().Uint64Var(&localSchemaByteSlices, "local-byteslices", 0, "Maximum number of byte slices that may be stored in local (per-account) key/value stores for this app. Immutable.")
createAppCmd.Flags().StringVar(&appCreator, "creator", "", "Account to create the application")
createAppCmd.Flags().StringVar(&createOnCompletion, "on-completion", "NoOp", "OnCompletion action for application transaction")
createAppCmd.Flags().StringVar(&onCompletion, "on-completion", "NoOp", "OnCompletion action for application transaction")
createAppCmd.Flags().Uint32Var(&extraPages, "extra-pages", 0, "Additional program space for supporting larger TEAL assembly program. A maximum of 3 extra pages is allowed. A page is 1024 bytes.")

callAppCmd.Flags().StringVarP(&account, "from", "f", "", "Account to call app from")
Expand All @@ -120,6 +120,7 @@ func init() {

methodAppCmd.Flags().StringVar(&method, "method", "", "Method to be called")
methodAppCmd.Flags().StringArrayVar(&methodArgs, "arg", nil, "Args to pass in for calling a method")
methodAppCmd.Flags().StringVar(&onCompletion, "on-completion", "NoOp", "OnCompletion action for application transaction")

// Can't use PersistentFlags on the root because for some reason marking
// a root command as required with MarkPersistentFlagRequired isn't
Expand Down Expand Up @@ -176,12 +177,10 @@ func init() {

infoAppCmd.MarkFlagRequired("app-id")

methodAppCmd.MarkFlagRequired("method") // nolint:errcheck // follow previous required flag format
methodAppCmd.MarkFlagRequired("app-id") // nolint:errcheck
methodAppCmd.MarkFlagRequired("from") // nolint:errcheck
methodAppCmd.Flags().MarkHidden("app-arg") // nolint:errcheck
methodAppCmd.Flags().MarkHidden("app-input") // nolint:errcheck
methodAppCmd.Flags().MarkHidden("i") // nolint:errcheck
methodAppCmd.MarkFlagRequired("method") // nolint:errcheck // follow previous required flag format
methodAppCmd.MarkFlagRequired("app-id") // nolint:errcheck
methodAppCmd.MarkFlagRequired("from") // nolint:errcheck
methodAppCmd.Flags().MarkHidden("app-arg") // nolint:errcheck
}

type appCallArg struct {
Expand Down Expand Up @@ -434,15 +433,15 @@ var createAppCmd = &cobra.Command{

// Parse transaction parameters
approvalProg, clearProg := mustParseProgArgs()
onCompletion := mustParseOnCompletion(createOnCompletion)
onCompletionEnum := mustParseOnCompletion(onCompletion)
appArgs, appAccounts, foreignApps, foreignAssets := getAppInputs()

switch onCompletion {
switch onCompletionEnum {
case transactions.CloseOutOC, transactions.ClearStateOC:
reportWarnf("'--on-completion %s' may be ill-formed for 'goal app create'", createOnCompletion)
reportWarnf("'--on-completion %s' may be ill-formed for 'goal app create'", onCompletion)
}

tx, err := client.MakeUnsignedAppCreateTx(onCompletion, approvalProg, clearProg, globalSchema, localSchema, appArgs, appAccounts, foreignApps, foreignAssets, extraPages)
tx, err := client.MakeUnsignedAppCreateTx(onCompletionEnum, approvalProg, clearProg, globalSchema, localSchema, appArgs, appAccounts, foreignApps, foreignAssets, extraPages)
if err != nil {
reportErrorf("Cannot create application txn: %v", err)
}
Expand Down Expand Up @@ -1048,6 +1047,43 @@ var infoAppCmd = &cobra.Command{
},
}

// populateMethodCallTxnArgs parses and loads transactions from the files indicated by the values
// slice. An error will occur if the transaction does not matched the expected type, it has a nonzero
// group ID, or if it is signed by a normal signature or Msig signature (but not Lsig signature)
func populateMethodCallTxnArgs(types []string, values []string) ([]transactions.SignedTxn, error) {
loadedTxns := make([]transactions.SignedTxn, len(values))

for i, txFilename := range values {
data, err := readFile(txFilename)
if err != nil {
return nil, fmt.Errorf(fileReadError, txFilename, err)
}

var txn transactions.SignedTxn
err = protocol.Decode(data, &txn)
if err != nil {
return nil, fmt.Errorf(txDecodeError, txFilename, err)
}

if !txn.Sig.Blank() || !txn.Msig.Blank() {
return nil, fmt.Errorf("Transaction from %s has already been signed", txFilename)
}

if !txn.Txn.Group.IsZero() {
return nil, fmt.Errorf("Transaction from %s already has a group ID: %s", txFilename, txn.Txn.Group)
}

expectedType := types[i]
if expectedType != "txn" && txn.Txn.Type != protocol.TxType(expectedType) {
return nil, fmt.Errorf("Transaction from %s does not match method argument type. Expected %s, got %s", txFilename, expectedType, txn.Txn.Type)
}

loadedTxns[i] = txn
}

return loadedTxns, nil
}

var methodAppCmd = &cobra.Command{
Use: "method",
Short: "Invoke a method",
Expand All @@ -1062,14 +1098,14 @@ var methodAppCmd = &cobra.Command{
reportErrorf("in goal app method: --arg and --app-arg are mutually exclusive, do not use --app-arg")
}

onCompletion := mustParseOnCompletion(createOnCompletion)
onCompletionEnum := mustParseOnCompletion(onCompletion)

if appIdx == 0 {
reportErrorf("app id == 0, goal app create not supported in goal app method")
}

var approvalProg, clearProg []byte
if onCompletion == transactions.UpdateApplicationOC {
if onCompletionEnum == transactions.UpdateApplicationOC {
approvalProg, clearProg = mustParseProgArgs()
}

Expand All @@ -1080,56 +1116,146 @@ var methodAppCmd = &cobra.Command{
applicationArgs = append(applicationArgs, hash[0:4])

// parse down the ABI type from method signature
argTupleTypeStr, retTypeStr, err := abi.ParseMethodSignature(method)
_, argTypes, retTypeStr, err := abi.ParseMethodSignature(method)
if err != nil {
reportErrorf("cannot parse method signature: %v", err)
}
err = abi.ParseArgJSONtoByteSlice(argTupleTypeStr, methodArgs, &applicationArgs)

var retType *abi.Type
if retTypeStr != "void" {
theRetType, err := abi.TypeOf(retTypeStr)
if err != nil {
reportErrorf("cannot cast %s to abi type: %v", retTypeStr, err)
}
retType = &theRetType
}

if len(methodArgs) != len(argTypes) {
reportErrorf("incorrect number of arguments, method expected %d but got %d", len(argTypes), len(methodArgs))
}

var txnArgTypes []string
var txnArgValues []string
var basicArgTypes []string
var basicArgValues []string
for i, argType := range argTypes {
argValue := methodArgs[i]
if abi.IsTransactionType(argType) {
txnArgTypes = append(txnArgTypes, argType)
txnArgValues = append(txnArgValues, argValue)
} else {
basicArgTypes = append(basicArgTypes, argType)
basicArgValues = append(basicArgValues, argValue)
}
}

err = abi.ParseArgJSONtoByteSlice(basicArgTypes, basicArgValues, &applicationArgs)
if err != nil {
reportErrorf("cannot parse arguments to ABI encoding: %v", err)
}

tx, err := client.MakeUnsignedApplicationCallTx(
txnArgs, err := populateMethodCallTxnArgs(txnArgTypes, txnArgValues)
if err != nil {
reportErrorf("error populating transaction arguments: %v", err)
}

appCallTxn, err := client.MakeUnsignedApplicationCallTx(
appIdx, applicationArgs, appAccounts, foreignApps, foreignAssets,
onCompletion, approvalProg, clearProg, basics.StateSchema{}, basics.StateSchema{}, 0)
onCompletionEnum, approvalProg, clearProg, basics.StateSchema{}, basics.StateSchema{}, 0)

if err != nil {
reportErrorf("Cannot create application txn: %v", err)
}

// Fill in note and lease
tx.Note = parseNoteField(cmd)
tx.Lease = parseLease(cmd)
appCallTxn.Note = parseNoteField(cmd)
appCallTxn.Lease = parseLease(cmd)

// Fill in rounds, fee, etc.
fv, lv, err := client.ComputeValidityRounds(firstValid, lastValid, numValidRounds)
if err != nil {
reportErrorf("Cannot determine last valid round: %s", err)
}

tx, err = client.FillUnsignedTxTemplate(account, fv, lv, fee, tx)
appCallTxn, err = client.FillUnsignedTxTemplate(account, fv, lv, fee, appCallTxn)
if err != nil {
reportErrorf("Cannot construct transaction: %s", err)
}
explicitFee := cmd.Flags().Changed("fee")
if explicitFee {
tx.Fee = basics.MicroAlgos{Raw: fee}
appCallTxn.Fee = basics.MicroAlgos{Raw: fee}
}

// Broadcast
wh, pw := ensureWalletHandleMaybePassword(dataDir, walletName, true)
signedTxn, err := client.SignTransactionWithWallet(wh, pw, tx)
if err != nil {
reportErrorf(errorSigningTX, err)
// Compile group
var txnGroup []transactions.Transaction
for i := range txnArgs {
txnGroup = append(txnGroup, txnArgs[i].Txn)
}
txnGroup = append(txnGroup, appCallTxn)
if len(txnGroup) > 1 {
// Only if transaction arguments are present, assign group ID
groupID, err := client.GroupID(txnGroup)
if err != nil {
reportErrorf("Cannot assign transaction group ID: %s", err)
}
for i := range txnGroup {
txnGroup[i].Group = groupID
}
}

txid, err := client.BroadcastTransaction(signedTxn)
// Sign transactions
var signedTxnGroup []transactions.SignedTxn
shouldSign := sign || outFilename == ""
for i, unsignedTxn := range txnGroup {
txnFromArgs := transactions.SignedTxn{}
if i < len(txnArgs) {
txnFromArgs = txnArgs[i]
}

if !txnFromArgs.Lsig.Blank() {
signedTxnGroup = append(signedTxnGroup, transactions.SignedTxn{
Lsig: txnFromArgs.Lsig,
AuthAddr: txnFromArgs.AuthAddr,
Txn: unsignedTxn,
})
continue
}

signedTxn, err := createSignedTransaction(client, shouldSign, dataDir, walletName, unsignedTxn, txnFromArgs.AuthAddr)
if err != nil {
reportErrorf(errorSigningTX, err)
}

signedTxnGroup = append(signedTxnGroup, signedTxn)
}

// Output to file
if outFilename != "" {
if dumpForDryrun {
err = writeDryrunReqToFile(client, signedTxnGroup, outFilename)
} else {
err = writeSignedTxnsToFile(signedTxnGroup, outFilename)
}
if err != nil {
reportErrorf(err.Error())
}
return
}

// Broadcast
err = client.BroadcastTransactionGroup(signedTxnGroup)
if err != nil {
reportErrorf(errorBroadcastingTX, err)
}

// Report tx details to user
reportInfof("Issued transaction from account %s, txid %s (fee %d)", tx.Sender, txid, tx.Fee.Raw)
reportInfof("Issued %d transaction(s):", len(signedTxnGroup))
// remember the final txid in this variable
var txid string
for _, stxn := range signedTxnGroup {
txid = stxn.Txn.ID().String()
reportInfof("\tIssued transaction from account %s, txid %s (fee %d)", stxn.Txn.Sender, txid, stxn.Txn.Fee.Raw)
}

if !noWaitAfterSend {
_, err := waitForCommit(client, txid, lv)
Expand All @@ -1142,7 +1268,8 @@ var methodAppCmd = &cobra.Command{
reportErrorf(err.Error())
}

if retTypeStr == "void" {
if retType == nil {
fmt.Printf("method %s succeeded\n", method)
return
}

Expand All @@ -1167,10 +1294,6 @@ var methodAppCmd = &cobra.Command{
reportErrorf("cannot find return log for abi type %s", retTypeStr)
}

retType, err := abi.TypeOf(retTypeStr)
if err != nil {
reportErrorf("cannot cast %s to abi type: %v", retTypeStr, err)
}
decoded, err := retType.Decode(abiEncodedRet)
if err != nil {
reportErrorf("cannot decode return value %v: %v", abiEncodedRet, err)
Expand All @@ -1180,7 +1303,7 @@ var methodAppCmd = &cobra.Command{
if err != nil {
reportErrorf("cannot marshal returned bytes %v to JSON: %v", decoded, err)
}
fmt.Printf("method %s output: %s", method, string(decodedJSON))
fmt.Printf("method %s succeeded with output: %s\n", method, string(decodedJSON))
}
},
}
Loading

0 comments on commit 6c39870

Please sign in to comment.