aboutsummaryrefslogtreecommitdiffstats
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/build/env.go116
-rw-r--r--internal/build/util.go23
-rw-r--r--internal/debug/flags.go9
-rw-r--r--internal/ethapi/api.go148
-rw-r--r--internal/ethapi/tracer_test.go22
-rw-r--r--internal/web3ext/web3ext.go30
6 files changed, 310 insertions, 38 deletions
diff --git a/internal/build/env.go b/internal/build/env.go
new file mode 100644
index 000000000..cd3355092
--- /dev/null
+++ b/internal/build/env.go
@@ -0,0 +1,116 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package build
+
+import (
+ "flag"
+ "fmt"
+ "os"
+)
+
+var (
+ // These flags override values in build env.
+ GitCommitFlag = flag.String("git-commit", "", `Overrides git commit hash embedded into executables`)
+ GitBranchFlag = flag.String("git-branch", "", `Overrides git branch being built`)
+ GitTagFlag = flag.String("git-tag", "", `Overrides git tag being built`)
+ BuildnumFlag = flag.String("buildnum", "", `Overrides CI build number`)
+ PullRequestFlag = flag.Bool("pull-request", false, `Overrides pull request status of the build`)
+)
+
+// Environment contains metadata provided by the build environment.
+type Environment struct {
+ Name string // name of the environment
+ Repo string // name of GitHub repo
+ Commit, Branch, Tag string // Git info
+ Buildnum string
+ IsPullRequest bool
+}
+
+func (env Environment) String() string {
+ return fmt.Sprintf("%s env (commit:%s branch:%s tag:%s buildnum:%s pr:%t)",
+ env.Name, env.Commit, env.Branch, env.Tag, env.Buildnum, env.IsPullRequest)
+}
+
+// Env returns metadata about the current CI environment, falling back to LocalEnv
+// if not running on CI.
+func Env() Environment {
+ switch {
+ case os.Getenv("CI") == "true" && os.Getenv("TRAVIS") == "true":
+ return Environment{
+ Name: "travis",
+ Repo: os.Getenv("TRAVIS_REPO_SLUG"),
+ Commit: os.Getenv("TRAVIS_COMMIT"),
+ Branch: os.Getenv("TRAVIS_BRANCH"),
+ Tag: os.Getenv("TRAVIS_TAG"),
+ Buildnum: os.Getenv("TRAVIS_BUILD_NUMBER"),
+ IsPullRequest: os.Getenv("TRAVIS_PULL_REQUEST") != "false",
+ }
+ case os.Getenv("CI") == "True" && os.Getenv("APPVEYOR") == "True":
+ return Environment{
+ Name: "appveyor",
+ Repo: os.Getenv("APPVEYOR_REPO_NAME"),
+ Commit: os.Getenv("APPVEYOR_REPO_COMMIT"),
+ Branch: os.Getenv("APPVEYOR_REPO_BRANCH"),
+ Tag: os.Getenv("APPVEYOR_REPO_TAG_NAME"),
+ Buildnum: os.Getenv("APPVEYOR_BUILD_NUMBER"),
+ IsPullRequest: os.Getenv("APPVEYOR_PULL_REQUEST_NUMBER") != "",
+ }
+ default:
+ return LocalEnv()
+ }
+}
+
+// LocalEnv returns build environment metadata gathered from git.
+func LocalEnv() Environment {
+ env := applyEnvFlags(Environment{Name: "local", Repo: "ethereum/go-ethereum"})
+ if _, err := os.Stat(".git"); err != nil {
+ return env
+ }
+ if env.Commit == "" {
+ env.Commit = RunGit("rev-parse", "HEAD")
+ }
+ if env.Branch == "" {
+ if b := RunGit("rev-parse", "--abbrev-ref", "HEAD"); b != "HEAD" {
+ env.Branch = b
+ }
+ }
+ // Note that we don't get the current git tag. It would slow down
+ // builds and isn't used by anything.
+ return env
+}
+
+func applyEnvFlags(env Environment) Environment {
+ if !flag.Parsed() {
+ panic("you need to call flag.Parse before Env or LocalEnv")
+ }
+ if *GitCommitFlag != "" {
+ env.Commit = *GitCommitFlag
+ }
+ if *GitBranchFlag != "" {
+ env.Branch = *GitBranchFlag
+ }
+ if *GitTagFlag != "" {
+ env.Tag = *GitTagFlag
+ }
+ if *BuildnumFlag != "" {
+ env.Buildnum = *BuildnumFlag
+ }
+ if *PullRequestFlag {
+ env.IsPullRequest = true
+ }
+ return env
+}
diff --git a/internal/build/util.go b/internal/build/util.go
index eead824b2..a821cd7f2 100644
--- a/internal/build/util.go
+++ b/internal/build/util.go
@@ -29,9 +29,7 @@ import (
"text/template"
)
-var (
- DryRunFlag = flag.Bool("n", false, "dry run, don't execute commands")
-)
+var DryRunFlag = flag.Bool("n", false, "dry run, don't execute commands")
// MustRun executes the given command and exits the host process for
// any error.
@@ -57,18 +55,18 @@ func GOPATH() string {
if len(path) == 0 {
log.Fatal("GOPATH is not set")
}
- // Ensure Godeps workspace is present in the path.
- godeps, _ := filepath.Abs(filepath.Join("Godeps", "_workspace"))
+ // Ensure that our internal vendor folder in on GOPATH
+ vendor, _ := filepath.Abs(filepath.Join("build", "_vendor"))
for _, dir := range path {
- if dir == godeps {
+ if dir == vendor {
return strings.Join(path, string(filepath.ListSeparator))
}
}
- newpath := append(path[:1], godeps)
- newpath = append(newpath, path[1:]...)
+ newpath := append(path[:1], append([]string{vendor}, path[1:]...)...)
return strings.Join(newpath, string(filepath.ListSeparator))
}
+// VERSION returns the content of the VERSION file.
func VERSION() string {
version, err := ioutil.ReadFile("VERSION")
if err != nil {
@@ -77,10 +75,8 @@ func VERSION() string {
return string(bytes.TrimSpace(version))
}
-func GitCommit() string {
- return RunGit("rev-parse", "HEAD")
-}
-
+// RunGit runs a git subcommand and returns its output.
+// The command must complete successfully.
func RunGit(args ...string) string {
cmd := exec.Command("git", args...)
var stdout, stderr bytes.Buffer
@@ -94,12 +90,13 @@ func RunGit(args ...string) string {
return strings.TrimSpace(stdout.String())
}
-// Render renders the given template file.
+// Render renders the given template file into outputFile.
func Render(templateFile, outputFile string, outputPerm os.FileMode, x interface{}) {
tpl := template.Must(template.ParseFiles(templateFile))
render(tpl, outputFile, outputPerm, x)
}
+// RenderString renders the given template string into outputFile.
func RenderString(templateContent, outputFile string, outputPerm os.FileMode, x interface{}) {
tpl := template.Must(template.New("").Parse(templateContent))
render(tpl, outputFile, outputPerm, x)
diff --git a/internal/debug/flags.go b/internal/debug/flags.go
index 9fc5fc4fe..ed17f87c4 100644
--- a/internal/debug/flags.go
+++ b/internal/debug/flags.go
@@ -52,6 +52,11 @@ var (
Usage: "pprof HTTP server listening port",
Value: 6060,
}
+ pprofAddrFlag = cli.StringFlag{
+ Name: "pprofaddr",
+ Usage: "pprof HTTP server listening interface",
+ Value: "127.0.0.1",
+ }
memprofilerateFlag = cli.IntFlag{
Name: "memprofilerate",
Usage: "Turn on memory profiling with the given rate",
@@ -74,7 +79,7 @@ var (
// Flags holds all command-line flags required for debugging.
var Flags = []cli.Flag{
verbosityFlag, vmoduleFlag, backtraceAtFlag,
- pprofFlag, pprofPortFlag,
+ pprofFlag, pprofAddrFlag, pprofPortFlag,
memprofilerateFlag, blockprofilerateFlag, cpuprofileFlag, traceFlag,
}
@@ -101,7 +106,7 @@ func Setup(ctx *cli.Context) error {
// pprof server
if ctx.GlobalBool(pprofFlag.Name) {
- address := fmt.Sprintf("127.0.0.1:%d", ctx.GlobalInt(pprofPortFlag.Name))
+ address := fmt.Sprintf("%s:%d", ctx.GlobalString(pprofAddrFlag.Name), ctx.GlobalInt(pprofPortFlag.Name))
go func() {
glog.V(logger.Info).Infof("starting pprof server at http://%s/debug/pprof", address)
glog.Errorln(http.ListenAndServe(address, nil))
diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go
index 9a97be25f..0e8e905aa 100644
--- a/internal/ethapi/api.go
+++ b/internal/ethapi/api.go
@@ -39,6 +39,7 @@ import (
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
"github.com/syndtr/goleveldb/leveldb"
+ "github.com/syndtr/goleveldb/leveldb/util"
"golang.org/x/net/context"
)
@@ -286,6 +287,66 @@ func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs
return submitTransaction(ctx, s.b, tx, signature)
}
+// signHash is a helper function that calculates a hash for the given message that can be
+// safely used to calculate a signature from. The hash is calulcated with:
+// keccak256("\x19Ethereum Signed Message:\n"${message length}${message}).
+func signHash(message string) []byte {
+ data := common.FromHex(message)
+ // Give context to the signed message. This prevents an adversery to sign a tx.
+ // It has no cryptographic purpose.
+ msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), data)
+ // Always hash, this prevents choosen plaintext attacks that can extract key information
+ return crypto.Keccak256([]byte(msg))
+}
+
+// Sign calculates an Ethereum ECDSA signature for:
+// keccack256("\x19Ethereum Signed Message:\n" + len(message) + message))
+//
+// The key used to calculate the signature is decrypted with the given password.
+//
+// https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_sign
+func (s *PrivateAccountAPI) Sign(ctx context.Context, message string, addr common.Address, passwd string) (string, error) {
+ hash := signHash(message)
+ signature, err := s.b.AccountManager().SignWithPassphrase(addr, passwd, hash)
+ if err != nil {
+ return "0x", err
+ }
+ return common.ToHex(signature), nil
+}
+
+// EcRecover returns the address for the account that was used to create the signature.
+// Note, this function is compatible with eth_sign and personal_sign. As such it recovers
+// the address of:
+// hash = keccak256("\x19Ethereum Signed Message:\n"${message length}${message})
+// addr = ecrecover(hash, signature)
+//
+// https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_ecRecover
+func (s *PrivateAccountAPI) EcRecover(ctx context.Context, message string, signature string) (common.Address, error) {
+ var (
+ hash = signHash(message)
+ sig = common.FromHex(signature)
+ )
+
+ if len(sig) != 65 {
+ return common.Address{}, fmt.Errorf("signature must be 65 bytes long")
+ }
+
+ // see crypto.Ecrecover description
+ if sig[64] == 27 || sig[64] == 28 {
+ sig[64] -= 27
+ }
+
+ rpk, err := crypto.Ecrecover(hash, sig)
+ if err != nil {
+ return common.Address{}, err
+ }
+
+ pubKey := crypto.ToECDSAPub(rpk)
+ recoveredAddr := crypto.PubkeyToAddress(*pubKey)
+
+ return recoveredAddr, nil
+}
+
// SignAndSendTransaction was renamed to SendTransaction. This method is deprecated
// and will be removed in the future. It primary goal is to give clients time to update.
func (s *PrivateAccountAPI) SignAndSendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) {
@@ -597,7 +658,7 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx
"gasUsed": rpc.NewHexNumber(head.GasUsed),
"timestamp": rpc.NewHexNumber(head.Time),
"transactionsRoot": head.TxHash,
- "receiptRoot": head.ReceiptHash,
+ "receiptsRoot": head.ReceiptHash,
}
if inclTx {
@@ -699,6 +760,16 @@ func newRPCTransactionFromBlockIndex(b *types.Block, txIndex int) (*RPCTransacti
return nil, nil
}
+// newRPCRawTransactionFromBlockIndex returns the bytes of a transaction given a block and a transaction index.
+func newRPCRawTransactionFromBlockIndex(b *types.Block, txIndex int) (rpc.HexBytes, error) {
+ if txIndex >= 0 && txIndex < len(b.Transactions()) {
+ tx := b.Transactions()[txIndex]
+ return rlp.EncodeToBytes(tx)
+ }
+
+ return nil, nil
+}
+
// newRPCTransaction returns a transaction that will serialize to the RPC representation.
func newRPCTransaction(b *types.Block, txHash common.Hash) (*RPCTransaction, error) {
for idx, tx := range b.Transactions() {
@@ -770,6 +841,22 @@ func (s *PublicTransactionPoolAPI) GetTransactionByBlockHashAndIndex(ctx context
return nil, nil
}
+// GetRawTransactionByBlockNumberAndIndex returns the bytes of the transaction for the given block number and index.
+func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index rpc.HexNumber) (rpc.HexBytes, error) {
+ if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil {
+ return newRPCRawTransactionFromBlockIndex(block, index.Int())
+ }
+ return nil, nil
+}
+
+// GetRawTransactionByBlockHashAndIndex returns the bytes of the transaction for the given block hash and index.
+func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index rpc.HexNumber) (rpc.HexBytes, error) {
+ if block, _ := s.b.GetBlock(ctx, blockHash); block != nil {
+ return newRPCRawTransactionFromBlockIndex(block, index.Int())
+ }
+ return nil, nil
+}
+
// GetTransactionCount returns the number of transactions the given address has sent for the given block number
func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (*rpc.HexNumber, error) {
state, _, err := s.b.StateAndHeaderByNumber(blockNr)
@@ -835,6 +922,21 @@ func (s *PublicTransactionPoolAPI) GetTransactionByHash(ctx context.Context, txH
return nil, nil
}
+// GetRawTransactionByHash returns the bytes of the transaction for the given hash.
+func (s *PublicTransactionPoolAPI) GetRawTransactionByHash(ctx context.Context, txHash common.Hash) (rpc.HexBytes, error) {
+ var tx *types.Transaction
+ var err error
+
+ if tx, _, err = getTransaction(s.b.ChainDb(), s.b, txHash); err != nil {
+ glog.V(logger.Debug).Infof("%v\n", err)
+ return nil, nil
+ } else if tx == nil {
+ return nil, nil
+ }
+
+ return rlp.EncodeToBytes(tx)
+}
+
// GetTransactionReceipt returns the transaction receipt for the given transaction hash.
func (s *PublicTransactionPoolAPI) GetTransactionReceipt(txHash common.Hash) (map[string]interface{}, error) {
receipt := core.GetReceipt(s.b.ChainDb(), txHash)
@@ -887,7 +989,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(txHash common.Hash) (ma
// sign is a helper function that signs a transaction with the private key of the given address.
func (s *PublicTransactionPoolAPI) sign(addr common.Address, tx *types.Transaction) (*types.Transaction, error) {
- signature, err := s.b.AccountManager().Sign(addr, tx.SigHash().Bytes())
+ signature, err := s.b.AccountManager().SignEthereum(addr, tx.SigHash().Bytes())
if err != nil {
return nil, err
}
@@ -969,7 +1071,7 @@ func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args Sen
tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data))
}
- signature, err := s.b.AccountManager().Sign(args.From, tx.SigHash().Bytes())
+ signature, err := s.b.AccountManager().SignEthereum(args.From, tx.SigHash().Bytes())
if err != nil {
return common.Hash{}, err
}
@@ -1003,11 +1105,16 @@ func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encod
return tx.Hash().Hex(), nil
}
-// Sign signs the given hash using the key that matches the address. The key must be
-// unlocked in order to sign the hash.
-func (s *PublicTransactionPoolAPI) Sign(addr common.Address, hash common.Hash) (string, error) {
- signature, error := s.b.AccountManager().Sign(addr, hash[:])
- return common.ToHex(signature), error
+// Sign calculates an ECDSA signature for:
+// keccack256("\x19Ethereum Signed Message:\n" + len(message) + message).
+//
+// The account associated with addr must be unlocked.
+//
+// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign
+func (s *PublicTransactionPoolAPI) Sign(addr common.Address, message string) (string, error) {
+ hash := signHash(message)
+ signature, err := s.b.AccountManager().SignEthereum(addr, hash)
+ return common.ToHex(signature), err
}
// SignTransactionArgs represents the arguments to sign a transaction.
@@ -1170,8 +1277,7 @@ func (s *PublicTransactionPoolAPI) PendingTransactions() []*RPCTransaction {
// Resend accepts an existing transaction and a new gas price and limit. It will remove the given transaction from the
// pool and reinsert it with the new gas price and limit.
-func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, tx *Tx, gasPrice, gasLimit *rpc.HexNumber) (common.Hash, error) {
-
+func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, tx Tx, gasPrice, gasLimit *rpc.HexNumber) (common.Hash, error) {
pending := s.b.GetPoolTransactions()
for _, p := range pending {
if pFrom, err := p.FromFrontier(); err == nil && pFrom == tx.From && p.SigHash() == tx.tx.SigHash() {
@@ -1184,9 +1290,9 @@ func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, tx *Tx, gasPrice,
var newTx *types.Transaction
if tx.tx.To() == nil {
- newTx = types.NewContractCreation(tx.tx.Nonce(), tx.tx.Value(), gasPrice.BigInt(), gasLimit.BigInt(), tx.tx.Data())
+ newTx = types.NewContractCreation(tx.tx.Nonce(), tx.tx.Value(), gasLimit.BigInt(), gasPrice.BigInt(), tx.tx.Data())
} else {
- newTx = types.NewTransaction(tx.tx.Nonce(), *tx.tx.To(), tx.tx.Value(), gasPrice.BigInt(), gasLimit.BigInt(), tx.tx.Data())
+ newTx = types.NewTransaction(tx.tx.Nonce(), *tx.tx.To(), tx.tx.Value(), gasLimit.BigInt(), gasPrice.BigInt(), tx.tx.Data())
}
signedTx, err := s.sign(tx.From, newTx)
@@ -1281,6 +1387,24 @@ func (api *PrivateDebugAPI) ChaindbProperty(property string) (string, error) {
return ldb.LDB().GetProperty(property)
}
+func (api *PrivateDebugAPI) ChaindbCompact() error {
+ ldb, ok := api.b.ChainDb().(interface {
+ LDB() *leveldb.DB
+ })
+ if !ok {
+ return fmt.Errorf("chaindbCompact does not work for memory databases")
+ }
+ for b := byte(0); b < 255; b++ {
+ glog.V(logger.Info).Infof("compacting chain DB range 0x%0.2X-0x%0.2X", b, b+1)
+ err := ldb.LDB().CompactRange(util.Range{Start: []byte{b}, Limit: []byte{b + 1}})
+ if err != nil {
+ glog.Errorf("compaction error: %v", err)
+ return err
+ }
+ }
+ return nil
+}
+
// SetHead rewinds the head of the blockchain to a previous block.
func (api *PrivateDebugAPI) SetHead(number rpc.HexNumber) {
api.b.SetHead(uint64(number.Int64()))
diff --git a/internal/ethapi/tracer_test.go b/internal/ethapi/tracer_test.go
index 301ff4840..577b426f1 100644
--- a/internal/ethapi/tracer_test.go
+++ b/internal/ethapi/tracer_test.go
@@ -26,11 +26,13 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/params"
)
type ruleSet struct{}
-func (self *ruleSet) IsHomestead(*big.Int) bool { return true }
+func (self *ruleSet) IsHomestead(*big.Int) bool { return true }
+func (*ruleSet) GasTable(*big.Int) params.GasTable { return params.GasTableHomesteadGasRepriceFork }
type Env struct {
gasLimit *big.Int
@@ -50,14 +52,14 @@ func (self *Env) Origin() common.Address { return common.Address{} }
func (self *Env) BlockNumber() *big.Int { return big.NewInt(0) }
//func (self *Env) PrevHash() []byte { return self.parent }
-func (self *Env) Coinbase() common.Address { return common.Address{} }
-func (self *Env) MakeSnapshot() vm.Database { return nil }
-func (self *Env) SetSnapshot(vm.Database) {}
-func (self *Env) Time() *big.Int { return big.NewInt(time.Now().Unix()) }
-func (self *Env) Difficulty() *big.Int { return big.NewInt(0) }
-func (self *Env) Db() vm.Database { return nil }
-func (self *Env) GasLimit() *big.Int { return self.gasLimit }
-func (self *Env) VmType() vm.Type { return vm.StdVmTy }
+func (self *Env) Coinbase() common.Address { return common.Address{} }
+func (self *Env) SnapshotDatabase() int { return 0 }
+func (self *Env) RevertToSnapshot(int) {}
+func (self *Env) Time() *big.Int { return big.NewInt(time.Now().Unix()) }
+func (self *Env) Difficulty() *big.Int { return big.NewInt(0) }
+func (self *Env) Db() vm.Database { return nil }
+func (self *Env) GasLimit() *big.Int { return self.gasLimit }
+func (self *Env) VmType() vm.Type { return vm.StdVmTy }
func (self *Env) GetHash(n uint64) common.Hash {
return common.BytesToHash(crypto.Keccak256([]byte(big.NewInt(int64(n)).String())))
}
@@ -93,7 +95,7 @@ func (account) SetNonce(uint64) {}
func (account) Balance() *big.Int { return nil }
func (account) Address() common.Address { return common.Address{} }
func (account) ReturnGas(*big.Int, *big.Int) {}
-func (account) SetCode([]byte) {}
+func (account) SetCode(common.Hash, []byte) {}
func (account) ForEachStorage(cb func(key, value common.Hash) bool) {}
func runTrace(tracer *JavascriptTracer) (interface{}, error) {
diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go
index 04b13e483..c8a0cac8c 100644
--- a/internal/web3ext/web3ext.go
+++ b/internal/web3ext/web3ext.go
@@ -338,6 +338,10 @@ web3._extend({
outputFormatter: console.log
}),
new web3._extend.Method({
+ name: 'chaindbCompact',
+ call: 'debug_chaindbCompact',
+ }),
+ new web3._extend.Method({
name: 'metrics',
call: 'debug_metrics',
params: 1
@@ -468,6 +472,19 @@ web3._extend({
call: 'eth_submitTransaction',
params: 1,
inputFormatter: [web3._extend.formatters.inputTransactionFormatter]
+ }),
+ new web3._extend.Method({
+ name: 'getRawTransaction',
+ call: 'eth_getRawTransactionByHash',
+ params: 1
+ }),
+ new web3._extend.Method({
+ name: 'getRawTransactionFromBlock',
+ call: function(args) {
+ return (web3._extend.utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getRawTransactionByBlockHashAndIndex' : 'eth_getRawTransactionByBlockNumberAndIndex';
+ },
+ params: 2,
+ inputFormatter: [web3._extend.formatters.inputBlockNumberFormatter, web3._extend.utils.toHex]
})
],
properties:
@@ -570,9 +587,20 @@ web3._extend({
call: 'personal_sendTransaction',
params: 2,
inputFormatter: [web3._extend.formatters.inputTransactionFormatter, null]
+ }),
+ new web3._extend.Method({
+ name: 'sign',
+ call: 'personal_sign',
+ params: 3,
+ inputFormatter: [null, web3._extend.formatters.inputAddressFormatter, null]
+ }),
+ new web3._extend.Method({
+ name: 'ecRecover',
+ call: 'personal_ecRecover',
+ params: 2
})
]
-});
+})
`
const RPC_JS = `