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
100 changes: 29 additions & 71 deletions cmd/goal/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/data/transactions"
"github.com/algorand/go-algorand/data/transactions/logic"
"github.com/algorand/go-algorand/libgoal"
"github.com/algorand/go-algorand/protocol"
)

Expand Down Expand Up @@ -434,19 +433,13 @@ var createAppCmd = &cobra.Command{
}
} else {
if dumpForDryrun {
// Write dryrun data to file
proto, _ := getProto(protoVersion)
data, err := libgoal.MakeDryrunStateBytes(client, tx, []transactions.SignedTxn{}, string(proto), dumpForDryrunFormat.String())
if err != nil {
reportErrorf(err.Error())
}
writeFile(outFilename, data, 0600)
err = writeDryrunReqToFile(client, tx, outFilename)
} else {
// Write transaction to file
err = writeTxnToFile(client, sign, dataDir, walletName, tx, outFilename)
if err != nil {
reportErrorf(err.Error())
}
}
if err != nil {
reportErrorf(err.Error())
}
}
},
Expand Down Expand Up @@ -513,18 +506,12 @@ var updateAppCmd = &cobra.Command{
}
} else {
if dumpForDryrun {
// Write dryrun data to file
proto, _ := getProto(protoVersion)
data, err := libgoal.MakeDryrunStateBytes(client, tx, []transactions.SignedTxn{}, string(proto), dumpForDryrunFormat.String())
if err != nil {
reportErrorf(err.Error())
}
writeFile(outFilename, data, 0600)
err = writeDryrunReqToFile(client, tx, outFilename)
} else {
err = writeTxnToFile(client, sign, dataDir, walletName, tx, outFilename)
if err != nil {
reportErrorf(err.Error())
}
}
if err != nil {
reportErrorf(err.Error())
}
}
},
Expand Down Expand Up @@ -590,18 +577,12 @@ var optInAppCmd = &cobra.Command{
}
} else {
if dumpForDryrun {
// Write dryrun data to file
proto, _ := getProto(protoVersion)
data, err := libgoal.MakeDryrunStateBytes(client, tx, []transactions.SignedTxn{}, string(proto), dumpForDryrunFormat.String())
if err != nil {
reportErrorf(err.Error())
}
writeFile(outFilename, data, 0600)
err = writeDryrunReqToFile(client, tx, outFilename)
} else {
err = writeTxnToFile(client, sign, dataDir, walletName, tx, outFilename)
if err != nil {
reportErrorf(err.Error())
}
}
if err != nil {
reportErrorf(err.Error())
}
}
},
Expand Down Expand Up @@ -667,18 +648,12 @@ var closeOutAppCmd = &cobra.Command{
}
} else {
if dumpForDryrun {
// Write dryrun data to file
proto, _ := getProto(protoVersion)
data, err := libgoal.MakeDryrunStateBytes(client, tx, []transactions.SignedTxn{}, string(proto), dumpForDryrunFormat.String())
if err != nil {
reportErrorf(err.Error())
}
writeFile(outFilename, data, 0600)
err = writeDryrunReqToFile(client, tx, outFilename)
} else {
err = writeTxnToFile(client, sign, dataDir, walletName, tx, outFilename)
if err != nil {
reportErrorf(err.Error())
}
}
if err != nil {
reportErrorf(err.Error())
}
}
},
Expand Down Expand Up @@ -744,18 +719,12 @@ var clearAppCmd = &cobra.Command{
}
} else {
if dumpForDryrun {
// Write dryrun data to file
proto, _ := getProto(protoVersion)
data, err := libgoal.MakeDryrunStateBytes(client, tx, []transactions.SignedTxn{}, string(proto), dumpForDryrunFormat.String())
if err != nil {
reportErrorf(err.Error())
}
writeFile(outFilename, data, 0600)
err = writeDryrunReqToFile(client, tx, outFilename)
} else {
err = writeTxnToFile(client, sign, dataDir, walletName, tx, outFilename)
if err != nil {
reportErrorf(err.Error())
}
}
if err != nil {
reportErrorf(err.Error())
}
}
},
Expand Down Expand Up @@ -821,18 +790,12 @@ var callAppCmd = &cobra.Command{
}
} else {
if dumpForDryrun {
// Write dryrun data to file
proto, _ := getProto(protoVersion)
data, err := libgoal.MakeDryrunStateBytes(client, tx, []transactions.SignedTxn{}, string(proto), dumpForDryrunFormat.String())
if err != nil {
reportErrorf(err.Error())
}
writeFile(outFilename, data, 0600)
err = writeDryrunReqToFile(client, tx, outFilename)
} else {
err = writeTxnToFile(client, sign, dataDir, walletName, tx, outFilename)
if err != nil {
reportErrorf(err.Error())
}
}
if err != nil {
reportErrorf(err.Error())
}
}
},
Expand Down Expand Up @@ -898,18 +861,13 @@ var deleteAppCmd = &cobra.Command{
}
} else {
if dumpForDryrun {
// Write dryrun data to file
proto, _ := getProto(protoVersion)
data, err := libgoal.MakeDryrunStateBytes(client, tx, []transactions.SignedTxn{}, string(proto), dumpForDryrunFormat.String())
if err != nil {
reportErrorf(err.Error())
}
writeFile(outFilename, data, 0600)
err = writeDryrunReqToFile(client, tx, outFilename)
} else {
err = writeTxnToFile(client, sign, dataDir, walletName, tx, outFilename)
if err != nil {
reportErrorf(err.Error())
}

}
if err != nil {
reportErrorf(err.Error())
}
}
},
Expand Down
34 changes: 23 additions & 11 deletions cmd/goal/clerk.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ func init() {
dryrunCmd.Flags().StringVarP(&protoVersion, "proto", "P", "", "consensus protocol version id string")
dryrunCmd.Flags().BoolVar(&dumpForDryrun, "dryrun-dump", false, "Dump in dryrun format acceptable by dryrun REST api instead of running")
dryrunCmd.Flags().Var(&dumpForDryrunFormat, "dryrun-dump-format", "Dryrun dump format: "+dumpForDryrunFormat.AllowedString())
dryrunCmd.Flags().StringSliceVar(&dumpForDryrunAccts, "dryrun-accounts", nil, "additional accounts to include into dryrun request obj")
dryrunCmd.Flags().StringVarP(&outFilename, "outfile", "o", "", "Filename for writing dryrun state object")
dryrunCmd.MarkFlagRequired("txfile")

Expand Down Expand Up @@ -484,18 +485,12 @@ var sendCmd = &cobra.Command{
}
} else {
if dumpForDryrun {
// Write dryrun data to file
proto, _ := getProto(protoVersion)
data, err := libgoal.MakeDryrunStateBytes(client, stx, []transactions.SignedTxn{}, string(proto), dumpForDryrunFormat.String())
if err != nil {
reportErrorf(err.Error())
}
writeFile(outFilename, data, 0600)
err = writeDryrunReqToFile(client, stx, outFilename)
} else {
err = writeFile(outFilename, protocol.Encode(&stx), 0600)
if err != nil {
reportErrorf(err.Error())
}
}
if err != nil {
reportErrorf(err.Error())
}
}
},
Expand Down Expand Up @@ -1069,7 +1064,11 @@ var dryrunCmd = &cobra.Command{
// Write dryrun data to file
dataDir := ensureSingleDataDir()
client := ensureFullClient(dataDir)
data, err := libgoal.MakeDryrunStateBytes(client, nil, txgroup, string(proto), dumpForDryrunFormat.String())
accts, err := unmarshalSlice(dumpForDryrunAccts)
if err != nil {
reportErrorf(err.Error())
}
data, err := libgoal.MakeDryrunStateBytes(client, nil, txgroup, accts, string(proto), dumpForDryrunFormat.String())
if err != nil {
reportErrorf(err.Error())
}
Expand Down Expand Up @@ -1182,3 +1181,16 @@ var dryrunRemoteCmd = &cobra.Command{
}
},
}

// unmarshalSlice converts string addresses to basics.Address
func unmarshalSlice(accts []string) ([]basics.Address, error) {
result := make([]basics.Address, 0, len(accts))
for _, acct := range accts {
addr, err := basics.UnmarshalChecksumAddress(acct)
if err != nil {
return nil, err
}
result = append(result, addr)
}
return result, nil
}
18 changes: 17 additions & 1 deletion cmd/goal/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/daemon/algod/api/spec/common"
"github.com/algorand/go-algorand/data/bookkeeping"
"github.com/algorand/go-algorand/data/transactions"
"github.com/algorand/go-algorand/libgoal"
"github.com/algorand/go-algorand/logging"
"github.com/algorand/go-algorand/protocol"
Expand Down Expand Up @@ -563,7 +564,22 @@ func writeFile(filename string, data []byte, perm os.FileMode) error {
return ioutil.WriteFile(filename, data, perm)
}

// readFile is a wrapper of ioutil.ReadFile which consniders the
// writeDryrunReqToFile creates dryrun request object and writes to a file
func writeDryrunReqToFile(client libgoal.Client, txnOrStxn interface{}, outFilename string) (err error) {
proto, _ := getProto(protoVersion)
accts, err := unmarshalSlice(dumpForDryrunAccts)
if err != nil {
reportErrorf(err.Error())
}
data, err := libgoal.MakeDryrunStateBytes(client, txnOrStxn, []transactions.SignedTxn{}, accts, string(proto), dumpForDryrunFormat.String())
if err != nil {
reportErrorf(err.Error())
}
err = writeFile(outFilename, data, 0600)
return
}

// readFile is a wrapper of ioutil.ReadFile which considers the
// special case of stdin filename
func readFile(filename string) ([]byte, error) {
if filename == stdinFileNameValue {
Expand Down
18 changes: 10 additions & 8 deletions cmd/goal/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,15 @@ var lastValid uint64
var numValidRounds uint64 // also used in account and asset

var (
fee uint64
outFilename string
sign bool
noteBase64 string
noteText string
lease string
noWaitAfterSend bool
dumpForDryrun bool
fee uint64
outFilename string
sign bool
noteBase64 string
noteText string
lease string
noWaitAfterSend bool
dumpForDryrun bool
dumpForDryrunAccts []string
)

var dumpForDryrunFormat cobraStringValue = *makeCobraStringValue("json", []string{"msgp"})
Expand All @@ -66,6 +67,7 @@ func addTxnFlags(cmd *cobra.Command) {
cmd.Flags().BoolVarP(&noWaitAfterSend, "no-wait", "N", false, "Don't wait for transaction to commit")
cmd.Flags().BoolVar(&dumpForDryrun, "dryrun-dump", false, "Dump in dryrun format acceptable by dryrun REST api")
cmd.Flags().Var(&dumpForDryrunFormat, "dryrun-dump-format", "Dryrun dump format: "+dumpForDryrunFormat.AllowedString())
cmd.Flags().StringSliceVar(&dumpForDryrunAccts, "dryrun-accounts", nil, "additional accounts to include into dryrun request obj")
}

type cobraStringValue struct {
Expand Down
22 changes: 13 additions & 9 deletions libgoal/libgoal.go
Original file line number Diff line number Diff line change
Expand Up @@ -970,18 +970,18 @@ func (c *Client) Catchup(catchpointLabel string) error {
const defaultAppIdx = 1380011588

// MakeDryrunStateBytes function creates DryrunRequest data structure in serialized form according to the format
func MakeDryrunStateBytes(client Client, txnOrStxn interface{}, other []transactions.SignedTxn, proto string, format string) (result []byte, err error) {
func MakeDryrunStateBytes(client Client, txnOrStxn interface{}, otherTxns []transactions.SignedTxn, otherAccts []basics.Address, proto string, format string) (result []byte, err error) {
switch format {
case "json":
var gdr generatedV2.DryrunRequest
gdr, err = MakeDryrunStateGenerated(client, txnOrStxn, other, proto)
gdr, err = MakeDryrunStateGenerated(client, txnOrStxn, otherTxns, otherAccts, proto)
if err == nil {
result = protocol.EncodeJSON(&gdr)
}
return
case "msgp":
var dr v2.DryrunRequest
dr, err = MakeDryrunState(client, txnOrStxn, other, proto)
dr, err = MakeDryrunState(client, txnOrStxn, otherTxns, otherAccts, proto)
if err == nil {
result = protocol.EncodeReflect(&dr)
}
Expand All @@ -992,16 +992,16 @@ func MakeDryrunStateBytes(client Client, txnOrStxn interface{}, other []transact
}

// MakeDryrunState function creates v2.DryrunRequest data structure
func MakeDryrunState(client Client, txnOrStxn interface{}, other []transactions.SignedTxn, proto string) (dr v2.DryrunRequest, err error) {
gdr, err := MakeDryrunStateGenerated(client, txnOrStxn, other, proto)
func MakeDryrunState(client Client, txnOrStxn interface{}, otherTxns []transactions.SignedTxn, otherAccts []basics.Address, proto string) (dr v2.DryrunRequest, err error) {
gdr, err := MakeDryrunStateGenerated(client, txnOrStxn, otherTxns, otherAccts, proto)
if err != nil {
return
}
return v2.DryrunRequestFromGenerated(&gdr)
}

// MakeDryrunStateGenerated function creates generatedV2.DryrunRequest data structure
func MakeDryrunStateGenerated(client Client, txnOrStxn interface{}, other []transactions.SignedTxn, proto string) (dr generatedV2.DryrunRequest, err error) {
func MakeDryrunStateGenerated(client Client, txnOrStxn interface{}, otherTxns []transactions.SignedTxn, otherAccts []basics.Address, proto string) (dr generatedV2.DryrunRequest, err error) {
var txns []transactions.SignedTxn
if txnOrStxn == nil {
// empty input do nothing
Expand All @@ -1014,7 +1014,7 @@ func MakeDryrunStateGenerated(client Client, txnOrStxn interface{}, other []tran
return
}

txns = append(txns, other...)
txns = append(txns, otherTxns...)
for i := range txns {
enc := protocol.EncodeJSON(&txns[i])
dr.Txns = append(dr.Txns, enc)
Expand All @@ -1023,6 +1023,9 @@ func MakeDryrunStateGenerated(client Client, txnOrStxn interface{}, other []tran
for _, txn := range txns {
tx := txn.Txn
if tx.Type == protocol.ApplicationCallTx {
accounts := append(tx.Accounts, tx.Sender)
accounts = append(accounts, otherAccts...)

apps := []basics.AppIndex{tx.ApplicationID}
apps = append(apps, tx.ForeignApps...)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not directly relevant to this change, but should this code also collect all foreign assets and look up the account balances of their creator to add to dr.Accounts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add this in a separate PR

for _, appIdx := range apps {
Expand All @@ -1049,18 +1052,19 @@ func MakeDryrunStateGenerated(client Client, txnOrStxn interface{}, other []tran
return
}
appParams = app.Params
accounts = append(accounts, appIdx.Address())
}
dr.Apps = append(dr.Apps, generatedV2.Application{
Id: uint64(appIdx),
Params: appParams,
})
}

accounts := append(tx.Accounts, tx.Sender)
for _, acc := range accounts {
var info generatedV2.Account
if info, err = client.AccountInformationV2(acc.String()); err != nil {
return
// ignore error - accounts might have app addresses that were not funded
continue
}
dr.Accounts = append(dr.Accounts, info)
}
Expand Down