Skip to content

Commit 6c39870

Browse files
authored
Merge branch 'master' into jack/upgrade-golang-version-to-1.16.7
2 parents 32b0b38 + 850f7c7 commit 6c39870

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1564
-711
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,6 @@ commands:
322322
export PACKAGE_NAMES=$(echo $PACKAGES | tr -d '\n')
323323
export PARTITION_TOTAL=${CIRCLE_NODE_TOTAL}
324324
export PARTITION_ID=${CIRCLE_NODE_INDEX}
325-
export PARALLEL_FLAG="-p 1"
326325
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
327326
- store_artifacts:
328327
path: << parameters.result_path >>
@@ -432,6 +431,7 @@ commands:
432431
export TEST_RESULTS=<< parameters.result_path >>/<< parameters.result_subdir >>/${CIRCLE_NODE_INDEX}
433432
export PARTITION_TOTAL=${CIRCLE_NODE_TOTAL}
434433
export PARTITION_ID=${CIRCLE_NODE_INDEX}
434+
export PARALLEL_FLAG="-p 1"
435435
test/scripts/run_integration_tests.sh
436436
- store_artifacts:
437437
path: << parameters.result_path >>

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
[![Build Status](https://travis-ci.com/algorand/go-algorand.svg?branch=master)](https://travis-ci.com/algorand/go-algorand)
1+
| 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) |
2+
| --- | --- | --- |
23

34
go-algorand
45
====================

cmd/goal/application.go

Lines changed: 158 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ var (
5353

5454
extraPages uint32
5555

56-
createOnCompletion string
56+
onCompletion string
5757

5858
localSchemaUints uint64
5959
localSchemaByteSlices uint64
@@ -106,7 +106,7 @@ func init() {
106106
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.")
107107
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.")
108108
createAppCmd.Flags().StringVar(&appCreator, "creator", "", "Account to create the application")
109-
createAppCmd.Flags().StringVar(&createOnCompletion, "on-completion", "NoOp", "OnCompletion action for application transaction")
109+
createAppCmd.Flags().StringVar(&onCompletion, "on-completion", "NoOp", "OnCompletion action for application transaction")
110110
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.")
111111

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

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

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

177178
infoAppCmd.MarkFlagRequired("app-id")
178179

179-
methodAppCmd.MarkFlagRequired("method") // nolint:errcheck // follow previous required flag format
180-
methodAppCmd.MarkFlagRequired("app-id") // nolint:errcheck
181-
methodAppCmd.MarkFlagRequired("from") // nolint:errcheck
182-
methodAppCmd.Flags().MarkHidden("app-arg") // nolint:errcheck
183-
methodAppCmd.Flags().MarkHidden("app-input") // nolint:errcheck
184-
methodAppCmd.Flags().MarkHidden("i") // nolint:errcheck
180+
methodAppCmd.MarkFlagRequired("method") // nolint:errcheck // follow previous required flag format
181+
methodAppCmd.MarkFlagRequired("app-id") // nolint:errcheck
182+
methodAppCmd.MarkFlagRequired("from") // nolint:errcheck
183+
methodAppCmd.Flags().MarkHidden("app-arg") // nolint:errcheck
185184
}
186185

187186
type appCallArg struct {
@@ -434,15 +433,15 @@ var createAppCmd = &cobra.Command{
434433

435434
// Parse transaction parameters
436435
approvalProg, clearProg := mustParseProgArgs()
437-
onCompletion := mustParseOnCompletion(createOnCompletion)
436+
onCompletionEnum := mustParseOnCompletion(onCompletion)
438437
appArgs, appAccounts, foreignApps, foreignAssets := getAppInputs()
439438

440-
switch onCompletion {
439+
switch onCompletionEnum {
441440
case transactions.CloseOutOC, transactions.ClearStateOC:
442-
reportWarnf("'--on-completion %s' may be ill-formed for 'goal app create'", createOnCompletion)
441+
reportWarnf("'--on-completion %s' may be ill-formed for 'goal app create'", onCompletion)
443442
}
444443

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

1050+
// populateMethodCallTxnArgs parses and loads transactions from the files indicated by the values
1051+
// slice. An error will occur if the transaction does not matched the expected type, it has a nonzero
1052+
// group ID, or if it is signed by a normal signature or Msig signature (but not Lsig signature)
1053+
func populateMethodCallTxnArgs(types []string, values []string) ([]transactions.SignedTxn, error) {
1054+
loadedTxns := make([]transactions.SignedTxn, len(values))
1055+
1056+
for i, txFilename := range values {
1057+
data, err := readFile(txFilename)
1058+
if err != nil {
1059+
return nil, fmt.Errorf(fileReadError, txFilename, err)
1060+
}
1061+
1062+
var txn transactions.SignedTxn
1063+
err = protocol.Decode(data, &txn)
1064+
if err != nil {
1065+
return nil, fmt.Errorf(txDecodeError, txFilename, err)
1066+
}
1067+
1068+
if !txn.Sig.Blank() || !txn.Msig.Blank() {
1069+
return nil, fmt.Errorf("Transaction from %s has already been signed", txFilename)
1070+
}
1071+
1072+
if !txn.Txn.Group.IsZero() {
1073+
return nil, fmt.Errorf("Transaction from %s already has a group ID: %s", txFilename, txn.Txn.Group)
1074+
}
1075+
1076+
expectedType := types[i]
1077+
if expectedType != "txn" && txn.Txn.Type != protocol.TxType(expectedType) {
1078+
return nil, fmt.Errorf("Transaction from %s does not match method argument type. Expected %s, got %s", txFilename, expectedType, txn.Txn.Type)
1079+
}
1080+
1081+
loadedTxns[i] = txn
1082+
}
1083+
1084+
return loadedTxns, nil
1085+
}
1086+
10511087
var methodAppCmd = &cobra.Command{
10521088
Use: "method",
10531089
Short: "Invoke a method",
@@ -1062,14 +1098,14 @@ var methodAppCmd = &cobra.Command{
10621098
reportErrorf("in goal app method: --arg and --app-arg are mutually exclusive, do not use --app-arg")
10631099
}
10641100

1065-
onCompletion := mustParseOnCompletion(createOnCompletion)
1101+
onCompletionEnum := mustParseOnCompletion(onCompletion)
10661102

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

10711107
var approvalProg, clearProg []byte
1072-
if onCompletion == transactions.UpdateApplicationOC {
1108+
if onCompletionEnum == transactions.UpdateApplicationOC {
10731109
approvalProg, clearProg = mustParseProgArgs()
10741110
}
10751111

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

10821118
// parse down the ABI type from method signature
1083-
argTupleTypeStr, retTypeStr, err := abi.ParseMethodSignature(method)
1119+
_, argTypes, retTypeStr, err := abi.ParseMethodSignature(method)
10841120
if err != nil {
10851121
reportErrorf("cannot parse method signature: %v", err)
10861122
}
1087-
err = abi.ParseArgJSONtoByteSlice(argTupleTypeStr, methodArgs, &applicationArgs)
1123+
1124+
var retType *abi.Type
1125+
if retTypeStr != "void" {
1126+
theRetType, err := abi.TypeOf(retTypeStr)
1127+
if err != nil {
1128+
reportErrorf("cannot cast %s to abi type: %v", retTypeStr, err)
1129+
}
1130+
retType = &theRetType
1131+
}
1132+
1133+
if len(methodArgs) != len(argTypes) {
1134+
reportErrorf("incorrect number of arguments, method expected %d but got %d", len(argTypes), len(methodArgs))
1135+
}
1136+
1137+
var txnArgTypes []string
1138+
var txnArgValues []string
1139+
var basicArgTypes []string
1140+
var basicArgValues []string
1141+
for i, argType := range argTypes {
1142+
argValue := methodArgs[i]
1143+
if abi.IsTransactionType(argType) {
1144+
txnArgTypes = append(txnArgTypes, argType)
1145+
txnArgValues = append(txnArgValues, argValue)
1146+
} else {
1147+
basicArgTypes = append(basicArgTypes, argType)
1148+
basicArgValues = append(basicArgValues, argValue)
1149+
}
1150+
}
1151+
1152+
err = abi.ParseArgJSONtoByteSlice(basicArgTypes, basicArgValues, &applicationArgs)
10881153
if err != nil {
10891154
reportErrorf("cannot parse arguments to ABI encoding: %v", err)
10901155
}
10911156

1092-
tx, err := client.MakeUnsignedApplicationCallTx(
1157+
txnArgs, err := populateMethodCallTxnArgs(txnArgTypes, txnArgValues)
1158+
if err != nil {
1159+
reportErrorf("error populating transaction arguments: %v", err)
1160+
}
1161+
1162+
appCallTxn, err := client.MakeUnsignedApplicationCallTx(
10931163
appIdx, applicationArgs, appAccounts, foreignApps, foreignAssets,
1094-
onCompletion, approvalProg, clearProg, basics.StateSchema{}, basics.StateSchema{}, 0)
1164+
onCompletionEnum, approvalProg, clearProg, basics.StateSchema{}, basics.StateSchema{}, 0)
10951165

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

11001170
// Fill in note and lease
1101-
tx.Note = parseNoteField(cmd)
1102-
tx.Lease = parseLease(cmd)
1171+
appCallTxn.Note = parseNoteField(cmd)
1172+
appCallTxn.Lease = parseLease(cmd)
11031173

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

1110-
tx, err = client.FillUnsignedTxTemplate(account, fv, lv, fee, tx)
1180+
appCallTxn, err = client.FillUnsignedTxTemplate(account, fv, lv, fee, appCallTxn)
11111181
if err != nil {
11121182
reportErrorf("Cannot construct transaction: %s", err)
11131183
}
11141184
explicitFee := cmd.Flags().Changed("fee")
11151185
if explicitFee {
1116-
tx.Fee = basics.MicroAlgos{Raw: fee}
1186+
appCallTxn.Fee = basics.MicroAlgos{Raw: fee}
11171187
}
11181188

1119-
// Broadcast
1120-
wh, pw := ensureWalletHandleMaybePassword(dataDir, walletName, true)
1121-
signedTxn, err := client.SignTransactionWithWallet(wh, pw, tx)
1122-
if err != nil {
1123-
reportErrorf(errorSigningTX, err)
1189+
// Compile group
1190+
var txnGroup []transactions.Transaction
1191+
for i := range txnArgs {
1192+
txnGroup = append(txnGroup, txnArgs[i].Txn)
1193+
}
1194+
txnGroup = append(txnGroup, appCallTxn)
1195+
if len(txnGroup) > 1 {
1196+
// Only if transaction arguments are present, assign group ID
1197+
groupID, err := client.GroupID(txnGroup)
1198+
if err != nil {
1199+
reportErrorf("Cannot assign transaction group ID: %s", err)
1200+
}
1201+
for i := range txnGroup {
1202+
txnGroup[i].Group = groupID
1203+
}
11241204
}
11251205

1126-
txid, err := client.BroadcastTransaction(signedTxn)
1206+
// Sign transactions
1207+
var signedTxnGroup []transactions.SignedTxn
1208+
shouldSign := sign || outFilename == ""
1209+
for i, unsignedTxn := range txnGroup {
1210+
txnFromArgs := transactions.SignedTxn{}
1211+
if i < len(txnArgs) {
1212+
txnFromArgs = txnArgs[i]
1213+
}
1214+
1215+
if !txnFromArgs.Lsig.Blank() {
1216+
signedTxnGroup = append(signedTxnGroup, transactions.SignedTxn{
1217+
Lsig: txnFromArgs.Lsig,
1218+
AuthAddr: txnFromArgs.AuthAddr,
1219+
Txn: unsignedTxn,
1220+
})
1221+
continue
1222+
}
1223+
1224+
signedTxn, err := createSignedTransaction(client, shouldSign, dataDir, walletName, unsignedTxn, txnFromArgs.AuthAddr)
1225+
if err != nil {
1226+
reportErrorf(errorSigningTX, err)
1227+
}
1228+
1229+
signedTxnGroup = append(signedTxnGroup, signedTxn)
1230+
}
1231+
1232+
// Output to file
1233+
if outFilename != "" {
1234+
if dumpForDryrun {
1235+
err = writeDryrunReqToFile(client, signedTxnGroup, outFilename)
1236+
} else {
1237+
err = writeSignedTxnsToFile(signedTxnGroup, outFilename)
1238+
}
1239+
if err != nil {
1240+
reportErrorf(err.Error())
1241+
}
1242+
return
1243+
}
1244+
1245+
// Broadcast
1246+
err = client.BroadcastTransactionGroup(signedTxnGroup)
11271247
if err != nil {
11281248
reportErrorf(errorBroadcastingTX, err)
11291249
}
11301250

11311251
// Report tx details to user
1132-
reportInfof("Issued transaction from account %s, txid %s (fee %d)", tx.Sender, txid, tx.Fee.Raw)
1252+
reportInfof("Issued %d transaction(s):", len(signedTxnGroup))
1253+
// remember the final txid in this variable
1254+
var txid string
1255+
for _, stxn := range signedTxnGroup {
1256+
txid = stxn.Txn.ID().String()
1257+
reportInfof("\tIssued transaction from account %s, txid %s (fee %d)", stxn.Txn.Sender, txid, stxn.Txn.Fee.Raw)
1258+
}
11331259

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

1145-
if retTypeStr == "void" {
1271+
if retType == nil {
1272+
fmt.Printf("method %s succeeded\n", method)
11461273
return
11471274
}
11481275

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

1170-
retType, err := abi.TypeOf(retTypeStr)
1171-
if err != nil {
1172-
reportErrorf("cannot cast %s to abi type: %v", retTypeStr, err)
1173-
}
11741297
decoded, err := retType.Decode(abiEncodedRet)
11751298
if err != nil {
11761299
reportErrorf("cannot decode return value %v: %v", abiEncodedRet, err)
@@ -1180,7 +1303,7 @@ var methodAppCmd = &cobra.Command{
11801303
if err != nil {
11811304
reportErrorf("cannot marshal returned bytes %v to JSON: %v", decoded, err)
11821305
}
1183-
fmt.Printf("method %s output: %s", method, string(decodedJSON))
1306+
fmt.Printf("method %s succeeded with output: %s\n", method, string(decodedJSON))
11841307
}
11851308
},
11861309
}

0 commit comments

Comments
 (0)