Skip to content

Commit

Permalink
feat(cmd): Add support for outputting unsigned transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
kostko committed May 12, 2023
1 parent df1f4d1 commit d42912f
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 37 deletions.
20 changes: 10 additions & 10 deletions cmd/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ var (
sigTx, err := common.SignConsensusTransaction(ctx, npa, acc, conn, tx)
cobra.CheckErr(err)

common.BroadcastTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
common.BroadcastOrExportTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
},
}

Expand Down Expand Up @@ -325,8 +325,8 @@ var (
sigTx, meta, err := common.SignParaTimeTransaction(ctx, npa, acc, conn, tx, &txDetails)
cobra.CheckErr(err)

if txCfg.Offline {
common.PrintSignedTransaction(sigTx)
if txCfg.Export {
common.ExportTransaction(sigTx)
return
}

Expand Down Expand Up @@ -433,8 +433,8 @@ var (
sigTx, meta, err := common.SignParaTimeTransaction(ctx, npa, acc, conn, tx, nil)
cobra.CheckErr(err)

if txCfg.Offline {
common.PrintSignedTransaction(sigTx)
if txCfg.Export {
common.ExportTransaction(sigTx)
return
}

Expand Down Expand Up @@ -543,7 +543,7 @@ var (
cobra.CheckErr(err)
}

common.BroadcastTransaction(ctx, npa.ParaTime, conn, sigTx, meta, nil)
common.BroadcastOrExportTransaction(ctx, npa.ParaTime, conn, sigTx, meta, nil)
},
}

Expand Down Expand Up @@ -588,7 +588,7 @@ var (
sigTx, err := common.SignConsensusTransaction(ctx, npa, acc, conn, tx)
cobra.CheckErr(err)

common.BroadcastTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
common.BroadcastOrExportTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
},
}

Expand Down Expand Up @@ -641,7 +641,7 @@ var (
cobra.CheckErr("delegations within paratimes are not supported; use --no-paratime")
}

common.BroadcastTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
common.BroadcastOrExportTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
},
}

Expand Down Expand Up @@ -695,7 +695,7 @@ var (
cobra.CheckErr("delegations within paratimes are not supported; use --no-paratime")
}

common.BroadcastTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
common.BroadcastOrExportTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
},
}

Expand Down Expand Up @@ -794,7 +794,7 @@ var (
sigTx, err := common.SignConsensusTransaction(ctx, npa, acc, conn, tx)
cobra.CheckErr(err)

common.BroadcastTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
common.BroadcastOrExportTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
},
}

Expand Down
104 changes: 85 additions & 19 deletions cmd/common/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,23 @@ import (
)

var (
txOffline bool
txNonce uint64
txGasLimit uint64
txGasPrice string
txEncrypted bool
txYes bool
txOffline bool
txNonce uint64
txGasLimit uint64
txGasPrice string
txEncrypted bool
txYes bool
txUnsigned bool
txFormat string
txOutputFile string
)

const (
invalidNonce = math.MaxUint64
invalidGasLimit = math.MaxUint64

formatJSON = "json"
formatCBOR = "cbor"
)

// TransactionFlags contains the common transaction flags.
Expand All @@ -50,15 +56,24 @@ var TransactionFlags *flag.FlagSet
type TransactionConfig struct {
// Offline is a flag indicating that no online queries are allowed.
Offline bool

// Export is a flag indicating that the transaction should be exported instead of broadcast.
Export bool
}

// GetTransactionConfig returns the transaction-related configuration from flags.
func GetTransactionConfig() *TransactionConfig {
return &TransactionConfig{
Offline: txOffline,
Export: shouldExportTransaction(),
}
}

// shouldExportTransaction returns true if the transaction should be exported instead of broadcast.
func shouldExportTransaction() bool {
return txOffline || txUnsigned || txOutputFile != ""
}

// isRuntimeTx returns true, if given object is a signed or unsigned runtime transaction.
func isRuntimeTx(tx interface{}) bool {
_, isRuntimeTx := tx.(*types.Transaction)
Expand All @@ -75,7 +90,7 @@ func SignConsensusTransaction(
wallet wallet.Account,
conn connection.Connection,
tx *consensusTx.Transaction,
) (*consensusTx.SignedTransaction, error) {
) (interface{}, error) {
// Require consensus signer.
signer := wallet.ConsensusSigner()
if signer == nil {
Expand Down Expand Up @@ -135,6 +150,11 @@ func SignConsensusTransaction(
}
tx.Fee.Amount = *gasPrice

if txUnsigned {
// Return an unsigned transaction.
return tx, nil
}

PrintTransactionBeforeSigning(npa, tx)

// Sign the transaction.
Expand All @@ -159,7 +179,7 @@ func SignParaTimeTransaction(
conn connection.Connection,
tx *types.Transaction,
txDetails *signature.TxDetails,
) (*types.UnverifiedTransaction, interface{}, error) {
) (interface{}, interface{}, error) {
if npa.ParaTime == nil {
return nil, nil, fmt.Errorf("no paratime configured for paratime transaction signing")
}
Expand Down Expand Up @@ -253,6 +273,11 @@ func SignParaTimeTransaction(
tx.Call = *encCall
}

if txUnsigned {
// Return an unsigned transaction.
return tx, meta, nil
}

PrintTransactionBeforeSigning(npa, tx)

// Sign the transaction.
Expand Down Expand Up @@ -342,30 +367,68 @@ func PrintTransactionBeforeSigning(npa *NPASelection, tx interface{}) {
fmt.Println("(In case you are using a hardware-based signer you may need to confirm on device.)")
}

// PrintSignedTransaction prints a signed transaction.
func PrintSignedTransaction(sigTx interface{}) {
// TODO: Add some options for controlling output.
formatted, err := json.MarshalIndent(sigTx, "", " ")
cobra.CheckErr(err)
fmt.Println(string(formatted))
// ExportTransaction exports a (signed) transaction based on configuration.
func ExportTransaction(sigTx interface{}) {
// Determine output destination.
var err error
outputFile := os.Stdout
if txOutputFile != "" {
outputFile, err = os.Create(txOutputFile)
if err != nil {
cobra.CheckErr(fmt.Errorf("failed to open output file: %w", err))
}
defer outputFile.Close()
}

// Determine output format.
var data []byte
switch txFormat {
case formatJSON:
data, err = json.MarshalIndent(sigTx, "", " ")
cobra.CheckErr(err)
case formatCBOR:
data = cbor.Marshal(sigTx)
default:
cobra.CheckErr(fmt.Errorf("unknown transaction format: %s", txFormat))
}

_, err = outputFile.Write(data)
if err != nil {
cobra.CheckErr(fmt.Errorf("failed to write output: %w", err))
}
}

// BroadcastTransaction broadcasts a transaction.
// BroadcastOrExportTransaction broadcasts or exports a transaction based on configuration.
//
// When in offline mode, it outputs the transaction instead.
func BroadcastTransaction(
// When in offline or unsigned mode, it exports the transaction. Otherwise it broadcasts the
// transaction.
func BroadcastOrExportTransaction(
ctx context.Context,
pt *config.ParaTime,
conn connection.Connection,
tx interface{},
meta interface{},
result interface{},
) {
if txOffline {
PrintSignedTransaction(tx)
if shouldExportTransaction() {
ExportTransaction(tx)
return
}

BroadcastTransaction(ctx, pt, conn, tx, meta, result)
}

// BroadcastTransaction broadcasts a transaction.
//
// When in offline mode, it outputs the transaction instead.
func BroadcastTransaction(
ctx context.Context,
pt *config.ParaTime,
conn connection.Connection,
tx interface{},
meta interface{},
result interface{},
) {
switch sigTx := tx.(type) {
case *consensusTx.SignedTransaction:
// Consensus transaction.
Expand Down Expand Up @@ -480,4 +543,7 @@ func init() {
TransactionFlags.StringVar(&txGasPrice, "gas-price", "", "override gas price to use")
TransactionFlags.BoolVar(&txEncrypted, "encrypted", false, "encrypt transaction call data (requires online mode)")
TransactionFlags.BoolVarP(&txYes, "yes", "y", false, "answer yes to all questions")
TransactionFlags.BoolVar(&txUnsigned, "unsigned", false, "do not sign transaction")
TransactionFlags.StringVar(&txFormat, "format", "json", "transaction output format (for offline/unsigned modes) [json, cbor]")
TransactionFlags.StringVarP(&txOutputFile, "output-file", "o", "", "output transaction into specified file instead of broadcasting")
}
8 changes: 4 additions & 4 deletions cmd/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ otherwise as Base64.`,
cobra.CheckErr(err)

var result contracts.UploadResult
common.BroadcastTransaction(ctx, npa.ParaTime, conn, sigTx, meta, &result)
common.BroadcastOrExportTransaction(ctx, npa.ParaTime, conn, sigTx, meta, &result)

if txCfg.Offline {
return
Expand Down Expand Up @@ -337,7 +337,7 @@ otherwise as Base64.`,
cobra.CheckErr(err)

var result contracts.InstantiateResult
common.BroadcastTransaction(ctx, npa.ParaTime, conn, sigTx, meta, &result)
common.BroadcastOrExportTransaction(ctx, npa.ParaTime, conn, sigTx, meta, &result)

if txCfg.Offline {
return
Expand Down Expand Up @@ -394,7 +394,7 @@ otherwise as Base64.`,
cobra.CheckErr(err)

var result contracts.CallResult
common.BroadcastTransaction(ctx, npa.ParaTime, conn, sigTx, meta, &result)
common.BroadcastOrExportTransaction(ctx, npa.ParaTime, conn, sigTx, meta, &result)

if txCfg.Offline {
return
Expand Down Expand Up @@ -456,7 +456,7 @@ otherwise as Base64.`,
sigTx, meta, err := common.SignParaTimeTransaction(ctx, npa, acc, conn, tx, nil)
cobra.CheckErr(err)

common.BroadcastTransaction(ctx, npa.ParaTime, conn, sigTx, meta, nil)
common.BroadcastOrExportTransaction(ctx, npa.ParaTime, conn, sigTx, meta, nil)
},
}
)
Expand Down
8 changes: 4 additions & 4 deletions cmd/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ var (
sigTx, err := common.SignConsensusTransaction(ctx, npa, acc, conn, tx)
cobra.CheckErr(err)

common.BroadcastTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
common.BroadcastOrExportTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
},
}

Expand Down Expand Up @@ -116,7 +116,7 @@ var (
sigTx, err := common.SignConsensusTransaction(ctx, npa, acc, conn, tx)
cobra.CheckErr(err)

common.BroadcastTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
common.BroadcastOrExportTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
},
}

Expand Down Expand Up @@ -157,7 +157,7 @@ var (
sigTx, err := common.SignConsensusTransaction(ctx, npa, acc, conn, tx)
cobra.CheckErr(err)

common.BroadcastTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
common.BroadcastOrExportTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
},
}

Expand Down Expand Up @@ -201,7 +201,7 @@ var (
sigTx, err := common.SignConsensusTransaction(ctx, npa, acc, conn, tx)
cobra.CheckErr(err)

common.BroadcastTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
common.BroadcastOrExportTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
},
}

Expand Down

0 comments on commit d42912f

Please sign in to comment.