diff options
author | obscuren <geffobscura@gmail.com> | 2015-03-10 18:25:32 +0800 |
---|---|---|
committer | obscuren <geffobscura@gmail.com> | 2015-03-10 18:25:32 +0800 |
commit | c0a8e3cd349ea9a9d1ea7e97254a6c9bf5e53e90 (patch) | |
tree | 867a55771deb1a6768c150ce91654eb72fb54c7e | |
parent | 0db4a0e898d09ffa7b6b1289e9a334edc0001cfa (diff) | |
parent | c9b6d268b45ec4cc0b1cc982ba544ed2f0a5ddd6 (diff) | |
download | dexon-c0a8e3cd349ea9a9d1ea7e97254a6c9bf5e53e90.tar dexon-c0a8e3cd349ea9a9d1ea7e97254a6c9bf5e53e90.tar.gz dexon-c0a8e3cd349ea9a9d1ea7e97254a6c9bf5e53e90.tar.bz2 dexon-c0a8e3cd349ea9a9d1ea7e97254a6c9bf5e53e90.tar.lz dexon-c0a8e3cd349ea9a9d1ea7e97254a6c9bf5e53e90.tar.xz dexon-c0a8e3cd349ea9a9d1ea7e97254a6c9bf5e53e90.tar.zst dexon-c0a8e3cd349ea9a9d1ea7e97254a6c9bf5e53e90.zip |
Merge branch 'poc-9' into develop
-rw-r--r-- | cmd/ethereum/main.go | 43 | ||||
-rw-r--r-- | cmd/utils/cmd.go | 41 | ||||
-rw-r--r-- | ethutil/natspec/natspec.go | 58 | ||||
-rw-r--r-- | ethutil/natspec/natspec_js.go (renamed from ethutil/natspec/natspec.js) | 91 | ||||
-rw-r--r-- | ethutil/natspec/natspec_test.go | 104 |
5 files changed, 199 insertions, 138 deletions
diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index 8b361f7ae..12e205f37 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -87,6 +87,11 @@ runtime will execute the file and exit. Name: "import", Usage: `import a blockchain file`, }, + { + Action: exportchain, + Name: "export", + Usage: `export blockchain into file`, + }, } app.Author = "" app.Email = "" @@ -171,25 +176,39 @@ func importchain(ctx *cli.Context) { if len(ctx.Args()) != 1 { utils.Fatalf("This command requires an argument.") } - chain, _, _ := utils.GetChain(ctx) + chainmgr, _, _ := utils.GetChain(ctx) start := time.Now() - err := utils.ImportChain(chain, ctx.Args().First()) + err := utils.ImportChain(chainmgr, ctx.Args().First()) if err != nil { utils.Fatalf("Import error: %v\n", err) } - fmt.Printf("Import done in", time.Since(start)) + fmt.Printf("Import done in %v", time.Since(start)) + return +} + +func exportchain(ctx *cli.Context) { + if len(ctx.Args()) != 1 { + utils.Fatalf("This command requires an argument.") + } + chainmgr, _, _ := utils.GetChain(ctx) + start := time.Now() + err := utils.ExportChain(chainmgr, ctx.Args().First()) + if err != nil { + utils.Fatalf("Export error: %v\n", err) + } + fmt.Printf("Export done in %v", time.Since(start)) return } func dump(ctx *cli.Context) { - chain, _, stateDb := utils.GetChain(ctx) + chainmgr, _, stateDb := utils.GetChain(ctx) for _, arg := range ctx.Args() { var block *types.Block if hashish(arg) { - block = chain.GetBlock(ethutil.Hex2Bytes(arg)) + block = chainmgr.GetBlock(ethutil.Hex2Bytes(arg)) } else { num, _ := strconv.Atoi(arg) - block = chain.GetBlockByNumber(uint64(num)) + block = chainmgr.GetBlockByNumber(uint64(num)) } if block == nil { fmt.Println("{}") @@ -209,11 +228,13 @@ func hashish(x string) bool { } func version(c *cli.Context) { - fmt.Printf(`%v %v -PV=%d -GOOS=%s -GO=%s + fmt.Printf(`%v +Version: %v +Protocol Version: %d +Network Id: %d +GO: %s +OS: %s GOPATH=%s GOROOT=%s -`, ClientIdentifier, Version, eth.ProtocolVersion, runtime.GOOS, runtime.Version(), os.Getenv("GOPATH"), runtime.GOROOT()) +`, ClientIdentifier, Version, eth.ProtocolVersion, eth.NetworkId, runtime.Version(), runtime.GOOS, os.Getenv("GOPATH"), runtime.GOROOT()) } diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index a77c6ad4d..4188802ac 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -35,7 +35,6 @@ import ( "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/rlp" rpchttp "github.com/ethereum/go-ethereum/rpc/http" - "github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/xeth" ) @@ -188,27 +187,8 @@ func FormatTransactionData(data string) []byte { return d } -// Replay block -func BlockDo(ethereum *eth.Ethereum, hash []byte) error { - block := ethereum.ChainManager().GetBlock(hash) - if block == nil { - return fmt.Errorf("unknown block %x", hash) - } - - parent := ethereum.ChainManager().GetBlock(block.ParentHash()) - - statedb := state.New(parent.Root(), ethereum.StateDb()) - _, err := ethereum.BlockProcessor().TransitionState(statedb, parent, block, true) - if err != nil { - return err - } - - return nil - -} - -func ImportChain(chain *core.ChainManager, fn string) error { - fmt.Printf("importing chain '%s'\n", fn) +func ImportChain(chainmgr *core.ChainManager, fn string) error { + fmt.Printf("importing blockchain '%s'\n", fn) fh, err := os.OpenFile(fn, os.O_RDONLY, os.ModePerm) if err != nil { return err @@ -220,11 +200,24 @@ func ImportChain(chain *core.ChainManager, fn string) error { return err } - chain.Reset() - if err := chain.InsertChain(blocks); err != nil { + chainmgr.Reset() + if err := chainmgr.InsertChain(blocks); err != nil { return err } fmt.Printf("imported %d blocks\n", len(blocks)) return nil } + +func ExportChain(chainmgr *core.ChainManager, fn string) error { + fmt.Printf("exporting blockchain '%s'\n", fn) + + data := chainmgr.Export() + + if err := ethutil.WriteFile(fn, data); err != nil { + return err + } + fmt.Printf("exported blockchain\n") + + return nil +} diff --git a/ethutil/natspec/natspec.go b/ethutil/natspec/natspec.go index 00e6f8720..793bf59ae 100644 --- a/ethutil/natspec/natspec.go +++ b/ethutil/natspec/natspec.go @@ -1,24 +1,21 @@ package natspec import ( + "fmt" "github.com/obscuren/otto" - "io/ioutil" ) type NatSpec struct { jsvm *otto.Otto } -func NewNATSpec(transaction string) (self *NatSpec, err error) { +// TODO: should initialise with abi and userdoc jsons +func New() (self *NatSpec, err error) { self = new(NatSpec) self.jsvm = otto.New() - code, err := ioutil.ReadFile("natspec.js") - if err != nil { - return - } - _, err = self.jsvm.Run(string(code)) + _, err = self.jsvm.Run(natspecJS) if err != nil { return } @@ -27,39 +24,40 @@ func NewNATSpec(transaction string) (self *NatSpec, err error) { return } - self.jsvm.Run("var transaction = " + transaction + ";") - - return -} - -func (self *NatSpec) SetDescription(desc string) (err error) { - - _, err = self.jsvm.Run("var expression = \"" + desc + "\";") return - } -func (self *NatSpec) SetABI(abi string) (err error) { - - _, err = self.jsvm.Run("var abi = " + abi + ";") - return - -} - -func (self *NatSpec) SetMethod(method string) (err error) { +func (self *NatSpec) Notice(transaction, abi, method, expression string) (string, error) { + var err error + if _, err = self.jsvm.Run("var transaction = " + transaction + ";"); err != nil { + return "", fmt.Errorf("natspec.js error setting transaction: %v", err) + } - _, err = self.jsvm.Run("var method = '" + method + "';") - return + if _, err = self.jsvm.Run("var abi = " + abi + ";"); err != nil { + return "", fmt.Errorf("natspec.js error setting abi: %v", err) + } -} + if _, err = self.jsvm.Run("var method = '" + method + "';"); err != nil { + return "", fmt.Errorf("natspec.js error setting method: %v", err) + } -func (self *NatSpec) Parse() string { + if _, err = self.jsvm.Run("var expression = \"" + expression + "\";"); err != nil { + return "", fmt.Errorf("natspec.js error setting expression: %v", err) + } self.jsvm.Run("var call = {method: method,abi: abi,transaction: transaction};") value, err := self.jsvm.Run("natspec.evaluateExpression(expression, call);") if err != nil { - return err.Error() + return "", fmt.Errorf("natspec.js error evaluating expression: %v", err) + } + evalError := "Natspec evaluation failed, wrong input params" + if value.String() == evalError { + return "", fmt.Errorf("natspec.js error evaluating expression: wrong input params in expression '%s'", expression) } - return value.String() + if len(value.String()) == 0 { + return "", fmt.Errorf("natspec.js error evaluating expression") + } + + return value.String(), nil } diff --git a/ethutil/natspec/natspec.js b/ethutil/natspec/natspec_js.go index 419ccd5c9..7acaaee4f 100644 --- a/ethutil/natspec/natspec.js +++ b/ethutil/natspec/natspec_js.go @@ -1,4 +1,6 @@ -require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ +package natspec + +const natspecJS = `require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ },{}],2:[function(require,module,exports){ // shim for using process in browser @@ -291,26 +293,26 @@ if (process.env.NODE_ENV !== 'build') { var BigNumber = require('bignumber.js'); // jshint ignore:line } -var ETH_UNITS = [ - 'wei', - 'Kwei', - 'Mwei', - 'Gwei', - 'szabo', - 'finney', - 'ether', - 'grand', - 'Mether', - 'Gether', - 'Tether', - 'Pether', - 'Eether', - 'Zether', - 'Yether', - 'Nether', - 'Dether', - 'Vether', - 'Uether' +var ETH_UNITS = [ + 'wei', + 'Kwei', + 'Mwei', + 'Gwei', + 'szabo', + 'finney', + 'ether', + 'grand', + 'Mether', + 'Gether', + 'Tether', + 'Pether', + 'Eether', + 'Zether', + 'Yether', + 'Nether', + 'Dether', + 'Vether', + 'Uether' ]; module.exports = { @@ -375,7 +377,7 @@ var formatInputInt = function (value) { BigNumber.config(c.ETH_BIGNUMBER_ROUNDING_MODE); value = value.round(); - if (value.lessThan(0)) + if (value.lessThan(0)) value = new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16).plus(value).plus(1); value = value.toString(16); } @@ -404,7 +406,7 @@ var formatInputBool = function (value) { /// Values are multiplied by 2^m and encoded as integers /// @returns byte representation of real var formatInputReal = function (value) { - return formatInputInt(new BigNumber(value).times(new BigNumber(2).pow(128))); + return formatInputInt(new BigNumber(value).times(new BigNumber(2).pow(128))); }; @@ -436,12 +438,12 @@ var formatOutputUInt = function (value) { /// @returns input bytes formatted to real var formatOutputReal = function (value) { - return formatOutputInt(value).dividedBy(new BigNumber(2).pow(128)); + return formatOutputInt(value).dividedBy(new BigNumber(2).pow(128)); }; /// @returns input bytes formatted to ureal var formatOutputUReal = function (value) { - return formatOutputUInt(value).dividedBy(new BigNumber(2).pow(128)); + return formatOutputUInt(value).dividedBy(new BigNumber(2).pow(128)); }; /// @returns right-aligned input bytes formatted to hex @@ -524,14 +526,14 @@ var namedType = function (name) { }; /// Setups input formatters for solidity types -/// @returns an array of input formatters +/// @returns an array of input formatters var inputTypes = function () { - + return [ { type: prefixedType('uint'), format: f.formatInputInt }, { type: prefixedType('int'), format: f.formatInputInt }, { type: prefixedType('hash'), format: f.formatInputInt }, - { type: prefixedType('string'), format: f.formatInputString }, + { type: prefixedType('string'), format: f.formatInputString }, { type: prefixedType('real'), format: f.formatInputReal }, { type: prefixedType('ureal'), format: f.formatInputReal }, { type: namedType('address'), format: f.formatInputInt }, @@ -620,7 +622,7 @@ var toAscii = function(hex) { return str; }; - + var toHex = function(str) { var hex = ""; for(var i = 0; i < str.length; i++) { @@ -642,7 +644,7 @@ var fromAscii = function(str, pad) { /// @returns display name for function/event eg. multiply(uint256) -> multiply var extractDisplayName = function (name) { - var length = name.indexOf('('); + var length = name.indexOf('('); return length !== -1 ? name.substr(0, length) : name; }; @@ -657,8 +659,8 @@ var extractTypeName = function (name) { /// @returns abi array with filtered objects of type 'function' var filterFunctions = function (json) { return json.filter(function (current) { - return current.type === 'function'; - }); + return current.type === 'function'; + }); }; /// Filters all events form input abi @@ -3404,7 +3406,7 @@ module.exports = { * @date 2015 */ -var abi = require('./node_modules/ethereum.js/lib/abi.js'); +var abi = require('./node_modules/ethereum.js/lib/abi.js'); /** * This object should be used to evaluate natspec expression @@ -3418,7 +3420,7 @@ var natspec = (function () { context[key] = obj[key]; }); } - + /// generate codes, which will be evaluated var generateCode = function (obj) { return Object.keys(obj).reduce(function (acc, key) { @@ -3440,20 +3442,20 @@ var natspec = (function () { /// @returns hashmap with all contract's method input variables var getMethodInputParams = function (method, transaction) { // do it with output formatter (cause we have to decode) - var params = abi.formatOutput(method.inputs, '0x' + transaction.params[0].data.slice(10)); + var params = abi.formatOutput(method.inputs, '0x' + transaction.params[0].data.slice(10)); return method.inputs.reduce(function (acc, current, index) { acc[current.name] = params[index]; return acc; }, {}); }; - + /// Should be called to evaluate expression var mapExpressionsToEvaluate = function (expression, cb) { var evaluatedExpression = ""; - // match everything in `` quotes - var pattern = /\`(?:\\.|[^`\\])*\`/gim + // match everything in backtick + var pattern = /\` + "`" + `(?:\\.|[^` + "`" + `\\])*\` + "`" + `/gim var match; var lastIndex = 0; while ((match = pattern.exec(expression)) !== null) { @@ -3464,9 +3466,9 @@ var natspec = (function () { evaluatedExpression += evaluatedPart; lastIndex = pattern.lastIndex; } - + evaluatedExpression += expression.slice(lastIndex); - + return evaluatedExpression; }; @@ -3478,11 +3480,11 @@ var natspec = (function () { var evaluateExpression = function (expression, call) { //var self = this; var context = {}; - + if (!!call) { try { var method = getMethodWithName(call.abi, call.method); - var params = getMethodInputParams(method, call.transaction); + var params = getMethodInputParams(method, call.transaction); copyToContext(params, context); } catch (err) { @@ -3498,7 +3500,7 @@ var natspec = (function () { return fn(context).toString(); } catch (err) { - return 'undefined'; + return 'undefined'; } }); @@ -3511,7 +3513,8 @@ var natspec = (function () { })(); -module.exports = natspec; +module.exports = natspec; },{"./node_modules/ethereum.js/lib/abi.js":3}]},{},[]); +` diff --git a/ethutil/natspec/natspec_test.go b/ethutil/natspec/natspec_test.go index 48a9cb25c..498f8d78e 100644 --- a/ethutil/natspec/natspec_test.go +++ b/ethutil/natspec/natspec_test.go @@ -6,41 +6,48 @@ import ( func TestNotice(t *testing.T) { - ns, err := NewNATSpec(` + tx := ` { - "jsonrpc": "2.0", - "method": "eth_call", - "params": [{ - "to": "0x8521742d3f456bd237e312d6e30724960f72517a", - "data": "0xc6888fa1000000000000000000000000000000000000000000000000000000000000007a" - }], - "id": 6 - } - `) + "jsonrpc": "2.0", + "method": "eth_call", + "params": [{ + "to": "0x8521742d3f456bd237e312d6e30724960f72517a", + "data": "0xc6888fa1000000000000000000000000000000000000000000000000000000000000007a" + }], + "id": 6 + } + ` + abi := ` + [{ + "name": "multiply", + "constant": false, + "type": "function", + "inputs": [{ + "name": "a", + "type": "uint256" + }], + "outputs": [{ + "name": "d", + "type": "uint256" + }] + }] + ` + + desc := "Will multiply `a` by 7 and return `a * 7`." + + method := "multiply" + + ns, err := New() if err != nil { t.Errorf("NewNATSpec error %v", err) } - ns.SetABI(` - [{ - "name": "multiply", - "constant": false, - "type": "function", - "inputs": [{ - "name": "a", - "type": "uint256" - }], - "outputs": [{ - "name": "d", - "type": "uint256" - }] - }] - `) - ns.SetDescription("Will multiply `a` by 7 and return `a * 7`.") - ns.SetMethod("multiply") - - notice := ns.Parse() + notice, err := ns.Notice(tx, abi, method, desc) + + if err != nil { + t.Errorf("expected no error got %v", err) + } expected := "Will multiply 122 by 7 and return 854." if notice != expected { @@ -48,4 +55,43 @@ func TestNotice(t *testing.T) { } else { t.Logf("returned notice \"%v\"", notice) } + + notice, err = ns.Notice(tx, abi, method, "Will multiply 122 by \"7\" and return 854.") + + expected = "natspec.js error setting expression: (anonymous): Line 1:41 Unexpected number" + + if err == nil { + t.Errorf("expected error, got nothing (notice: '%v')", err, notice) + } else { + if err.Error() != expected { + t.Errorf("expected error '%s' got '%v' (notice: '%v')", expected, err, notice) + } + } + + // https://github.com/ethereum/natspec.js/issues/1 + // badDesc := "Will multiply `e` by 7 and return `a * 7`." + // notice, err = ns.Notice(tx, abi, method, badDesc) + + // expected = "natspec.js error evaluating expression: wrong input param in expression ''" + + // if err == nil { + // t.Errorf("expected error, got nothing (notice: '%v')", notice) + // } else { + // if err.Error() != expected { + // t.Errorf("expected error '%s' got '%v' (notice: '%v')", expected, err, notice) + // } + // } + + notice, err = ns.Notice(tx, abi, "missing_method", desc) + + expected = "natspec.js error evaluating expression: wrong input params in expression 'Will multiply `a` by 7 and return `a * 7`.'" + + if err == nil { + t.Errorf("expected error, got nothing (notice: '%v')", notice) + } else { + if err.Error() != expected { + t.Errorf("expected error '%s' got '%v' (notice: '%v')", expected, err, notice) + } + } + } |