diff --git a/cmd/signer/README.md b/cmd/signer/README.md
index 25db2c9ee4..66490aaf74 100644
--- a/cmd/signer/README.md
+++ b/cmd/signer/README.md
@@ -506,29 +506,137 @@ Invoked when there's a transaction for approval.
#### Sample call
+Here's a method invocation:
+```bash
+
+curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_signTransaction","params":[{"from":"0x694267f14675d7e1b9494fd8d72fefe1755710fa","gas":"0x333","gasPrice":"0x1","nonce":"0x0","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0", "value":"0x0", "data":"0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"},"safeSend(address)"],"id":67}' http://localhost:8550/
+```
+
```json
{
- "jsonrpc": "2.0",
- "method": "ApproveTx",
- "params": [{
- "transaction": {
- "to": "0xae967917c465db8578ca9024c205720b1a3651A9",
- "gas": "0x333",
- "gasPrice": "0x123",
- "value": "0x10",
- "data": "0xd7a5865800000000000000000000000000000000000000000000000000000000000000ff",
- "nonce": "0x0"
- },
- "fromaccount": "0xAe967917c465db8578ca9024c205720b1a3651A9",
- "call_info": "Warning! Could not validate ABI-data against calldata\nSupplied ABI spec does not contain method signature in data: 0xd7a58658",
- "meta": {
- "remote": "127.0.0.1:34572",
- "local": "localhost:8550",
- "scheme": "HTTP/1.1"
- }
- }],
- "id": 1
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "ApproveTx",
+ "params": [
+ {
+ "transaction": {
+ "from": "0x0x694267f14675d7e1b9494fd8d72fefe1755710fa",
+ "to": "0x0x07a565b7ed7d7a678680a4c162885bedbb695fe0",
+ "gas": "0x333",
+ "gasPrice": "0x1",
+ "value": "0x0",
+ "nonce": "0x0",
+ "data": "0x4401a6e40000000000000000000000000000000000000000000000000000000000000012",
+ "input": null
+ },
+ "call_info": {
+ "Messages": [
+ {
+ "type": "WARNING",
+ "message": "Invalid checksum on to-address"
+ },
+ {
+ "type": "Info",
+ "message": "safeSend(address: 0x0000000000000000000000000000000000000012)"
+ }
+ ]
+ },
+ "meta": {
+ "remote": "127.0.0.1:48486",
+ "local": "localhost:8550",
+ "scheme": "HTTP/1.1"
+ }
+ }
+ ]
+}
+
+```
+
+The same method invocation, but with invalid data:
+```bash
+
+curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_signTransaction","params":[{"from":"0x694267f14675d7e1b9494fd8d72fefe1755710fa","gas":"0x333","gasPrice":"0x1","nonce":"0x0","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0", "value":"0x0", "data":"0x4401a6e40000000000000002000000000000000000000000000000000000000000000012"},"safeSend(address)"],"id":67}' http://localhost:8550/
+```
+
+```json
+
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "ApproveTx",
+ "params": [
+ {
+ "transaction": {
+ "from": "0x0x694267f14675d7e1b9494fd8d72fefe1755710fa",
+ "to": "0x0x07a565b7ed7d7a678680a4c162885bedbb695fe0",
+ "gas": "0x333",
+ "gasPrice": "0x1",
+ "value": "0x0",
+ "nonce": "0x0",
+ "data": "0x4401a6e40000000000000002000000000000000000000000000000000000000000000012",
+ "input": null
+ },
+ "call_info": {
+ "Messages": [
+ {
+ "type": "WARNING",
+ "message": "Invalid checksum on to-address"
+ },
+ {
+ "type": "WARNING",
+ "message": "Transaction data did not match ABI-interface: WARNING: Supplied data is stuffed with extra data. \nWant 0000000000000002000000000000000000000000000000000000000000000012\nHave 0000000000000000000000000000000000000000000000000000000000000012\nfor method safeSend(address)"
+ }
+ ]
+ },
+ "meta": {
+ "remote": "127.0.0.1:48492",
+ "local": "localhost:8550",
+ "scheme": "HTTP/1.1"
+ }
+ }
+ ]
+}
+
+
+```
+
+One which has missing `to`, but with no `data`:
+
+
+```json
+
+{
+ "jsonrpc": "2.0",
+ "id": 3,
+ "method": "ApproveTx",
+ "params": [
+ {
+ "transaction": {
+ "from": "",
+ "to": null,
+ "gas": "0x0",
+ "gasPrice": "0x0",
+ "value": "0x0",
+ "nonce": "0x0",
+ "data": null,
+ "input": null
+ },
+ "call_info": {
+ "Messages": [
+ {
+ "type": "CRITICAL",
+ "message": "Tx will create contract with empty code!"
+ }
+ ]
+ },
+ "meta": {
+ "remote": "signer binary",
+ "local": "main",
+ "scheme": "in-proc"
+ }
+ }
+ ]
}
```
diff --git a/cmd/signer/core/abihelper.go b/cmd/signer/core/abihelper.go
index 625d5cbdf9..61dea02ebd 100644
--- a/cmd/signer/core/abihelper.go
+++ b/cmd/signer/core/abihelper.go
@@ -161,6 +161,11 @@ type AbiDb struct {
db map[string]string
}
+// NewEmptyAbiDB exists for test purposes
+func NewEmptyAbiDB() (*AbiDb, error) {
+ return &AbiDb{make(map[string]string)}, nil
+}
+
// NewAbiDBFromFile loads signature database from file, and
// errors if the file is not valid json. Does no other validation of contents
func NewAbiDBFromFile(path string) (*AbiDb, error) {
diff --git a/cmd/signer/core/api.go b/cmd/signer/core/api.go
index 8e9f4c2d3b..6b96bae094 100644
--- a/cmd/signer/core/api.go
+++ b/cmd/signer/core/api.go
@@ -23,9 +23,6 @@ import (
"fmt"
"io/ioutil"
"math/big"
-
- "bytes"
-
"reflect"
"github.com/ethereum/go-ethereum/accounts"
@@ -84,10 +81,10 @@ type SignerUI interface {
// SignerAPI defines the actual implementation of ExternalAPI
type SignerAPI struct {
- chainID *big.Int
- am *accounts.Manager
- UI SignerUI
- abidb AbiDb
+ chainID *big.Int
+ am *accounts.Manager
+ UI SignerUI
+ validator *Validator
}
// Metadata about a request
@@ -126,9 +123,9 @@ func (m Metadata) String() string {
type (
// SignTxRequest contains info about a Transaction to sign
SignTxRequest struct {
- Transaction SendTxArgs `json:"transaction"`
- Callinfo string `json:"call_info"`
- Meta Metadata `json:"meta"`
+ Transaction SendTxArgs `json:"transaction"`
+ Callinfo *ValidationMessages `json:"call_info"`
+ Meta Metadata `json:"meta"`
}
// SignTxResponse result from SignTxRequest
SignTxResponse struct {
@@ -229,7 +226,7 @@ func NewSignerAPI(chainID int64, ksLocation string, noUSB bool, ui SignerUI, abi
log.Debug("Trezor support enabled")
}
}
- return &SignerAPI{big.NewInt(chainID), accounts.NewManager(backends...), ui, *abidb}
+ return &SignerAPI{big.NewInt(chainID), accounts.NewManager(backends...), ui, NewValidator(abidb)}
}
// List returns the set of wallet this signer manages. Each wallet can contain
@@ -318,66 +315,21 @@ func logDiff(original *SignTxRequest, new *SignTxResponse) bool {
return modified
}
-// determineCallInfo turns ABI-data + methodselector (if given) into a string suitable
-// to present to the user.
-func (api *SignerAPI) determineCallInfo(data []byte, methodSelector *string) string {
-
- if len(data) < 4 {
- return ""
- }
- var (
- selector string
- err error
- )
- // Try to make sense of the data
- if methodSelector == nil {
- selector, err = api.abidb.LookupMethodSelector(data[:4])
- if err != nil {
- return errorWrapper{"Warning! Could not locate ABI", err}.String()
- }
- } else {
- selector = *methodSelector
- }
- if selector != "" {
- abiData, err := MethodSelectorToAbi(selector)
- if err != nil {
- return errorWrapper{"Warning! Could not validate ABI-data against calldata", err}.String()
- } else {
- var info *decodedCallData
- info, err = parseCallData(data, string(abiData))
- if err != nil {
- return errorWrapper{"Warning! Could not validate ABI-data against calldata", err}.String()
- } else {
- return info.String()
- }
- }
- }
- return ""
-}
-
// SignTransaction signs the given Transaction and returns it both as json and rlp-encoded form
func (api *SignerAPI) SignTransaction(ctx context.Context, args SendTxArgs, methodSelector *string) (*ethapi.SignTransactionResult, error) {
var (
err error
result SignTxResponse
- data []byte
)
- // Prevent accidental erroneous usage of both 'input' and 'data'
- if args.Data != nil && args.Input != nil && !bytes.Equal(*args.Data, *args.Input) {
- return nil, errors.New(`Ambiguous request: moth "data" and "input" are set and are not identical`)
+ msgs, err:= api.validator.ValidateTransaction(&args, methodSelector)
+ if err != nil {
+ return nil, err
}
- if args.Data != nil {
- data = *args.Data
- } else if args.Input != nil {
- data = *args.Input
- *args.Data = data
- *args.Input = nil
- }
req := SignTxRequest{
Transaction: args,
Meta: MetadataFromContext(ctx),
- Callinfo: api.determineCallInfo(data, methodSelector),
+ Callinfo: msgs,
}
// Process approval
result, err = api.UI.ApproveTx(&req)
diff --git a/cmd/signer/core/cliui.go b/cmd/signer/core/cliui.go
index de4ab466ca..11e85a1bcb 100644
--- a/cmd/signer/core/cliui.go
+++ b/cmd/signer/core/cliui.go
@@ -92,7 +92,7 @@ func (ui *CommandlineUI) confirm() bool {
}
func showMetadata(metadata Metadata) {
- fmt.Printf("Request info:\n\t%v -> %v -> %v\n", metadata.Remote, metadata.Scheme, metadata.Local)
+ fmt.Printf("Request context:\n\t%v -> %v -> %v\n", metadata.Remote, metadata.Scheme, metadata.Local)
}
// ApproveTx prompt the user for confirmation to request to sign Transaction
@@ -117,9 +117,12 @@ func (ui *CommandlineUI) ApproveTx(request *SignTxRequest) (SignTxResponse, erro
fmt.Printf("data: %v\n", common.Bytes2Hex(d))
}
}
- if request.Callinfo != "" {
- fmt.Printf("\nNote: This Transaction contains data. Review abi-decoding info below:")
- fmt.Printf("\nCall info:\n\t%v\n", request.Callinfo)
+ if request.Callinfo != nil {
+ fmt.Printf("\nTransaction validation:\n")
+ for _,m := range request.Callinfo.Messages{
+ fmt.Printf(" * %s : %s", m.Typ, m.Message)
+ }
+ fmt.Println()
}
fmt.Printf("\n")
diff --git a/cmd/signer/core/stdioui.go b/cmd/signer/core/stdioui.go
index a42ff845a5..26818d7f66 100644
--- a/cmd/signer/core/stdioui.go
+++ b/cmd/signer/core/stdioui.go
@@ -44,8 +44,13 @@ func NewStdIOUI() *StdIOUI {
}
// dispatch sends a request over the stdio
-func (ui *StdIOUI) dispatch(serviceMethod string, args interface{}, reply interface{}) error {
- err := ui.client.Call(&reply, serviceMethod, args)
+func (ui *StdIOUI) dispatch(serviceMethod string, args interface{}, reply interface{}) error{
+ var err error
+ if reply != nil{
+ err = ui.client.Call(nil, serviceMethod, args)
+ }else{
+ err = ui.client.Call(&reply, serviceMethod, args)
+ }
if err != nil {
log.Info("Error", "exc", err.Error())
}
diff --git a/cmd/signer/core/types.go b/cmd/signer/core/types.go
index 03c3a58ff3..63dd9f3a61 100644
--- a/cmd/signer/core/types.go
+++ b/cmd/signer/core/types.go
@@ -50,6 +50,14 @@ func (a Account) String() string {
}
return err.Error()
}
+type ValidationInfo struct {
+ Typ string `json:"type"`
+ Message string `json:"message"`
+}
+type ValidationMessages struct {
+ Messages []ValidationInfo
+}
+
/*
// TransactionArg represents a Transaction for the signer.
type TransactionArg struct {
diff --git a/cmd/signer/core/validation.go b/cmd/signer/core/validation.go
new file mode 100644
index 0000000000..64974e664b
--- /dev/null
+++ b/cmd/signer/core/validation.go
@@ -0,0 +1,152 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package core
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "github.com/ethereum/go-ethereum/common"
+ "math/big"
+)
+
+// The validation package contains validation checks for transactions
+// - ABI-data validation
+// - Transaction semantics validation
+// The package provides warnings for typical pitfalls
+
+func (vs *ValidationMessages) crit(msg string) {
+ vs.Messages = append(vs.Messages, ValidationInfo{"CRITICAL", msg})
+}
+func (vs *ValidationMessages) warn(msg string) {
+ vs.Messages = append(vs.Messages, ValidationInfo{"WARNING", msg})
+}
+func (vs *ValidationMessages) info(msg string) {
+ vs.Messages = append(vs.Messages, ValidationInfo{"Info", msg})
+}
+
+type Validator struct {
+ db *AbiDb
+}
+
+func NewValidator(db *AbiDb) *Validator {
+ return &Validator{db}
+}
+
+// validateCallData checks if the ABI-data + methodselector (if given) can be parsed and seems to match
+func (v *Validator) validateCallData(msgs *ValidationMessages, data []byte, methodSelector *string) {
+ if len(data) == 0 {
+ return
+ }
+ if len(data) < 4 {
+ msgs.warn("Tx contains data which is not valid ABI")
+ return
+ }
+ var (
+ selector string
+ err error
+ )
+ // Try to make sense of the data
+ if methodSelector != nil {
+ selector = *methodSelector
+ }
+
+ if selector == "" {
+ selector, err = v.db.LookupMethodSelector(data[:4])
+ if err != nil {
+ msgs.warn(fmt.Sprintf("Tx contains data, but the ABI signature could not be found: %v", err))
+ return
+ }
+ }
+ if selector == "" {
+ // No more to do that this stage
+ return
+ }
+ abiData, err := MethodSelectorToAbi(selector)
+ if err != nil {
+ msgs.warn(fmt.Sprintf("Transaction data did not match ABI-interface: %v", err))
+ return
+ }
+
+ info, err := parseCallData(data, string(abiData))
+ if err != nil {
+ msgs.warn(fmt.Sprintf("Transaction data did not match ABI-interface: %v", err))
+ } else {
+ msgs.info(info.String())
+ }
+ return
+}
+
+// validateSemantics checks if the transactions 'makes sense', and generate warnings for a couple of typical scenarios
+func (v *Validator) validate(msgs *ValidationMessages, txargs *SendTxArgs, methodSelector *string) error {
+ // Prevent accidental erroneous usage of both 'input' and 'data'
+ if txargs.Data != nil && txargs.Input != nil && !bytes.Equal(*txargs.Data, *txargs.Input) {
+ // This is a showstopper
+ return errors.New(`Ambiguous request: moth "data" and "input" are set and are not identical`)
+ }
+ var (
+ data []byte
+ )
+ // Place data on 'data', and nil 'input'
+ if txargs.Input != nil {
+ txargs.Data = txargs.Input
+ txargs.Input = nil
+ }
+ if txargs.Data != nil {
+ data = *txargs.Data
+ }
+
+ if txargs.To == nil {
+ //Contract creation should contain sufficient data to deploy a contract
+ // A typical error is omitting sender due to some quirk in the javascript call
+ // e.g. https://github.com/ethereum/go-ethereum/issues/16106
+ if len(data) == 0 {
+ if txargs.Value.ToInt().Cmp(big.NewInt(0)) > 0 {
+ // Sending ether into black hole
+ return errors.New(`Tx will create contract with value but empty code!`)
+ }
+ // No value submitted at least
+ msgs.crit("Tx will create contract with empty code!")
+ } else if len(data) < 40 { //Arbitrary limit
+ msgs.warn(fmt.Sprintf("Tx will will create contract, but payload is suspiciously small (%d b)", len(data)))
+ }
+ // methodSelector should be nil for contract creation
+ if methodSelector != nil {
+ msgs.warn("Tx will create contract, but method selector supplied; indicating intent to call a method.")
+ }
+
+ } else {
+ if !txargs.To.ValidChecksum() {
+ msgs.warn("Invalid checksum on to-address")
+ }
+ // Normal transaction
+ if bytes.Equal(txargs.To.Address().Bytes(), common.Address{}.Bytes()) {
+ // Sending to 0
+ msgs.crit("Tx destination is the zero address!")
+ }
+ // Validate calldata
+ v.validateCallData(msgs, data, methodSelector);
+ }
+ return nil
+}
+
+// ValidateTransaction does a number of checks on the supplied transaction, and returns either a list of warnings,
+// or an error, indicating that the transaction should be immediately rejected
+func (v *Validator) ValidateTransaction(txArgs *SendTxArgs, methodSelector *string) (*ValidationMessages, error) {
+ msgs := &ValidationMessages{}
+ return msgs, v.validate(msgs, txArgs, methodSelector)
+}
diff --git a/cmd/signer/core/validation_test.go b/cmd/signer/core/validation_test.go
new file mode 100644
index 0000000000..9b599d36c7
--- /dev/null
+++ b/cmd/signer/core/validation_test.go
@@ -0,0 +1,140 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package core
+
+import (
+ "fmt"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/hexutil"
+ "math/big"
+ "testing"
+)
+
+func hexAddr(a string) common.Address { return common.BytesToAddress(common.FromHex(a)) }
+func mixAddr(a string) (*common.MixedcaseAddress, error) {
+ return common.NewMixedcaseAddressFromString(a)
+}
+func toHexBig(h string) hexutil.Big {
+ b := big.NewInt(0).SetBytes(common.FromHex(h))
+ return hexutil.Big(*b)
+}
+func toHexUint(h string) hexutil.Uint64 {
+ b := big.NewInt(0).SetBytes(common.FromHex(h))
+ return hexutil.Uint64(b.Uint64())
+}
+func dummyTxArgs(t txtestcase) *SendTxArgs {
+ to, _ := mixAddr(t.to)
+ from, _ := mixAddr(t.from)
+ n := toHexUint(t.n)
+ gas := toHexBig(t.g)
+ gasPrice := toHexBig(t.gp)
+ value := toHexBig(t.value)
+ var(
+ data, input *hexutil.Bytes
+ )
+ if t.d != ""{
+ a := hexutil.Bytes(common.FromHex(t.d))
+ data = &a
+ }
+ if t.i != ""{
+ a := hexutil.Bytes(common.FromHex(t.i))
+ input = &a
+
+ }
+ return &SendTxArgs{
+ From: *from,
+ To: to,
+ Value: value,
+ Nonce: n,
+ GasPrice: gas,
+ Gas: gasPrice,
+ Data: data,
+ Input: input,
+ }
+}
+
+type txtestcase struct {
+ from, to, n, g, gp, value, d, i string
+ expectErr bool
+ numMessages int
+}
+
+func TestValidator(t *testing.T) {
+ var (
+ // use empty db, there are other tests for the abi-specific stuff
+ db, _ = NewEmptyAbiDB()
+ v = NewValidator(db)
+ )
+ testcases := []txtestcase{
+ // Invalid to checksum
+ {from: "000000000000000000000000000000000000dead", to: "000000000000000000000000000000000000dead",
+ n: "0x01", g: "0x20", gp: "0x40", value: "0x01", numMessages: 1},
+ // valid 0x000000000000000000000000000000000000dEaD
+ {from: "000000000000000000000000000000000000dead", to: "0x000000000000000000000000000000000000dEaD",
+ n: "0x01", g: "0x20", gp: "0x40", value: "0x01", numMessages: 0},
+ // conflicting input and data
+ {from: "000000000000000000000000000000000000dead", to: "0x000000000000000000000000000000000000dEaD",
+ n: "0x01", g: "0x20", gp: "0x40", value: "0x01", d: "0x01", i: "0x02", expectErr: true, },
+ // Data can't be parsed
+ {from: "000000000000000000000000000000000000dead", to: "0x000000000000000000000000000000000000dEaD",
+ n: "0x01", g: "0x20", gp: "0x40", value: "0x01", d: "0x0102", numMessages:1 },
+ // Data (on Input) can't be parsed
+ {from: "000000000000000000000000000000000000dead", to: "0x000000000000000000000000000000000000dEaD",
+ n: "0x01", g: "0x20", gp: "0x40", value: "0x01", i: "0x0102", numMessages:1 },
+ // Send to 0
+ {from: "000000000000000000000000000000000000dead", to: "0x0000000000000000000000000000000000000000",
+ n: "0x01", g: "0x20", gp: "0x40", value: "0x01", numMessages: 1},
+ // Create empty contract (no value)
+ {from: "000000000000000000000000000000000000dead", to: "",
+ n: "0x01", g: "0x20", gp: "0x40", value: "0x00", numMessages: 1},
+ // Create empty contract (with value)
+ {from: "000000000000000000000000000000000000dead", to: "",
+ n: "0x01", g: "0x20", gp: "0x40", value: "0x01", expectErr: true},
+ // Small payload for create
+ {from: "000000000000000000000000000000000000dead", to: "",
+ n: "0x01", g: "0x20", gp: "0x40", value: "0x01",d:"0x01", numMessages: 1},
+
+
+ }
+ for i, test := range testcases {
+ msgs, err := v.ValidateTransaction(dummyTxArgs(test), nil)
+ if err == nil && test.expectErr {
+ t.Errorf("Test %d, expected error", i)
+ for _, msg := range msgs.Messages {
+ fmt.Printf("* %s: %s\n", msg.Typ, msg.Message)
+ }
+ }
+ if err != nil && !test.expectErr {
+ t.Errorf("Test %d, unexpected error: %v", i, err)
+ }
+ if err == nil {
+ got := len(msgs.Messages)
+ if got != test.numMessages {
+ for _, msg := range msgs.Messages {
+ fmt.Printf("* %s: %s\n", msg.Typ, msg.Message)
+ }
+ t.Errorf("Test %d, expected %d messages, got %d", i,test.numMessages, got)
+ }else{
+ //Debug printout, remove later
+ for _, msg := range msgs.Messages {
+ fmt.Printf("* [%d] %s: %s\n", i, msg.Typ, msg.Message)
+ }
+ fmt.Println()
+ }
+ }
+ }
+}
diff --git a/cmd/signer/rules/rules_test.go b/cmd/signer/rules/rules_test.go
index a789923644..80024e9801 100644
--- a/cmd/signer/rules/rules_test.go
+++ b/cmd/signer/rules/rules_test.go
@@ -9,8 +9,8 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/internal/ethapi"
"math/big"
- "testing"
"strings"
+ "testing"
)
const JS = `
@@ -167,7 +167,7 @@ func TestSignTxRequest(t *testing.T) {
Transaction: core.SendTxArgs{
From: *from,
To: to},
- Callinfo: "",
+ Callinfo: nil,
Meta: core.Metadata{"remoteip", "localip", "inproc"},
})
if err != nil {
@@ -251,7 +251,7 @@ func TestForwarding(t *testing.T) {
exp_calls := 8
if len(ui.calls) != exp_calls {
- t.Errorf("Expected %d forwarded calls, got %d: %s", exp_calls, len(ui.calls), strings.Join(ui.calls,","))
+ t.Errorf("Expected %d forwarded calls, got %d: %s", exp_calls, len(ui.calls), strings.Join(ui.calls, ","))
}
@@ -425,8 +425,12 @@ func dummyTx(value hexutil.Big) *core.SignTxRequest {
GasPrice: gas,
Gas: gasPrice,
},
- Callinfo: "Warning, all your base are bellong to us",
- Meta: core.Metadata{"remoteip", "localip", "inproc"},
+ Callinfo: &core.ValidationMessages{
+ []core.ValidationInfo{
+ {"Warning", "All your base are bellong to us"},
+ },
+ },
+ Meta: core.Metadata{"remoteip", "localip", "inproc"},
}
}
func dummyTxWithV(value uint64) *core.SignTxRequest {
@@ -484,7 +488,7 @@ func TestLimitWindow(t *testing.T) {
}
// dontCallMe is used as a next-handler that does not want to be called - it invokes test failure
-type dontCallMe struct{
+type dontCallMe struct {
t *testing.T
}
@@ -530,7 +534,6 @@ func (d *dontCallMe) OnApprovedTx(tx ethapi.SignTransactionResult) {
d.t.Fatalf("Did not expect next-handler to be called")
}
-
//TestContextIsCleared tests that the rule-engine does not retain variables over several requests.
// if it does, that would be bad since developers may rely on that to store data,
// instead of using the disk-based data storage
@@ -561,7 +564,7 @@ func TestContextIsCleared(t *testing.T) {
tx := dummyTxWithV(0)
r1, err := r.ApproveTx(tx)
r2, err := r.ApproveTx(tx)
- if r1.Approved != r2.Approved{
+ if r1.Approved != r2.Approved {
t.Errorf("Expected execution context to be cleared between executions")
}
}