-
-
-
-
-
-
-
-
- contract
-
-
-
-
-
-
-
-
-
-
-
diff --git a/cmd/ethtest/example/index.html b/cmd/ethtest/example/index.html
deleted file mode 100644
index d0bf094ef2..0000000000
--- a/cmd/ethtest/example/index.html
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
-
-
-
-
- coinbase balance
-
-
-
-
-
-
-
-
diff --git a/cmd/ethtest/example/node-app.js b/cmd/ethtest/example/node-app.js
deleted file mode 100644
index f63fa9115f..0000000000
--- a/cmd/ethtest/example/node-app.js
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env node
-
-require('es6-promise').polyfill();
-
-var web3 = require("../index.js");
-
-web3.setProvider(new web3.providers.HttpRpcProvider('http://localhost:8080'));
-
-web3.eth.coinbase.then(function(result){
- console.log(result);
- return web3.eth.balanceAt(result);
-}).then(function(balance){
- console.log(web3.toDecimal(balance));
-}).catch(function(err){
- console.log(err);
-});
\ No newline at end of file
diff --git a/cmd/ethtest/gulpfile.js b/cmd/ethtest/gulpfile.js
deleted file mode 100644
index 9e0717d8b1..0000000000
--- a/cmd/ethtest/gulpfile.js
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/usr/bin/env node
-
-'use strict';
-
-var path = require('path');
-
-var del = require('del');
-var gulp = require('gulp');
-var browserify = require('browserify');
-var jshint = require('gulp-jshint');
-var uglify = require('gulp-uglify');
-var rename = require('gulp-rename');
-var envify = require('envify/custom');
-var unreach = require('unreachable-branch-transform');
-var source = require('vinyl-source-stream');
-var exorcist = require('exorcist');
-var bower = require('bower');
-
-var DEST = './dist/';
-
-var build = function(src, dst) {
- return browserify({
- debug: true,
- insert_global_vars: false,
- detectGlobals: false,
- bundleExternal: false
- })
- .require('./' + src + '.js', {expose: 'web3'})
- .add('./' + src + '.js')
- .transform('envify', {
- NODE_ENV: 'build'
- })
- .transform('unreachable-branch-transform')
- .transform('uglifyify', {
- mangle: false,
- compress: {
- dead_code: false,
- conditionals: true,
- unused: false,
- hoist_funs: true,
- hoist_vars: true,
- negate_iife: false
- },
- beautify: true,
- warnings: true
- })
- .bundle()
- .pipe(exorcist(path.join( DEST, dst + '.js.map')))
- .pipe(source(dst + '.js'))
- .pipe(gulp.dest( DEST ));
-};
-
-var buildDev = function(src, dst) {
- return browserify({
- debug: true,
- insert_global_vars: false,
- detectGlobals: false,
- bundleExternal: false
- })
- .require('./' + src + '.js', {expose: 'web3'})
- .add('./' + src + '.js')
- .transform('envify', {
- NODE_ENV: 'build'
- })
- .transform('unreachable-branch-transform')
- .bundle()
- .pipe(exorcist(path.join( DEST, dst + '.js.map')))
- .pipe(source(dst + '.js'))
- .pipe(gulp.dest( DEST ));
-};
-
-var uglifyFile = function(file) {
- return gulp.src( DEST + file + '.js')
- .pipe(uglify())
- .pipe(rename(file + '.min.js'))
- .pipe(gulp.dest( DEST ));
-};
-
-gulp.task('bower', function(cb){
- bower.commands.install().on('end', function (installed){
- console.log(installed);
- cb();
- });
-});
-
-gulp.task('lint', function(){
- return gulp.src(['./*.js', './lib/*.js'])
- .pipe(jshint())
- .pipe(jshint.reporter('default'));
-});
-
-gulp.task('clean', ['lint'], function(cb) {
- del([ DEST ], cb);
-});
-
-gulp.task('build', ['clean'], function () {
- return build('index', 'ethereum');
-});
-
-gulp.task('buildQt', ['clean'], function () {
- return build('index_qt', 'ethereum');
-});
-
-gulp.task('buildDev', ['clean'], function () {
- return buildDev('index', 'ethereum');
-});
-
-gulp.task('uglify', ['build'], function(){
- return uglifyFile('ethereum');
-});
-
-gulp.task('uglifyQt', ['buildQt'], function () {
- return uglifyFile('ethereum');
-});
-
-gulp.task('watch', function() {
- gulp.watch(['./lib/*.js'], ['lint', 'prepare', 'build']);
-});
-
-gulp.task('default', ['bower', 'lint', 'build', 'uglify']);
-gulp.task('qt', ['bower', 'lint', 'buildQt', 'uglifyQt']);
-gulp.task('dev', ['bower', 'lint', 'buildDev']);
-
diff --git a/cmd/ethtest/index.js b/cmd/ethtest/index.js
deleted file mode 100644
index c2de7e735e..0000000000
--- a/cmd/ethtest/index.js
+++ /dev/null
@@ -1,8 +0,0 @@
-var web3 = require('./lib/main');
-web3.providers.WebSocketProvider = require('./lib/websocket');
-web3.providers.HttpRpcProvider = require('./lib/httprpc');
-web3.providers.QtProvider = require('./lib/qt');
-web3.providers.AutoProvider = require('./lib/autoprovider');
-web3.contract = require('./lib/contract');
-
-module.exports = web3;
diff --git a/cmd/ethtest/index_qt.js b/cmd/ethtest/index_qt.js
deleted file mode 100644
index d5e47597e4..0000000000
--- a/cmd/ethtest/index_qt.js
+++ /dev/null
@@ -1,5 +0,0 @@
-var web3 = require('./lib/main');
-web3.providers.QtProvider = require('./lib/qt');
-web3.contract = require('./lib/contract');
-
-module.exports = web3;
diff --git a/cmd/ethtest/lib/abi.js b/cmd/ethtest/lib/abi.js
deleted file mode 100644
index 2cff503d38..0000000000
--- a/cmd/ethtest/lib/abi.js
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- This file is part of ethereum.js.
-
- ethereum.js 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.
-
- ethereum.js 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 ethereum.js. If not, see .
-*/
-/** @file abi.js
- * @authors:
- * Marek Kotewicz
- * Gav Wood
- * @date 2014
- */
-
-// TODO: make these be actually accurate instead of falling back onto JS's doubles.
-var hexToDec = function (hex) {
- return parseInt(hex, 16).toString();
-};
-
-var decToHex = function (dec) {
- return parseInt(dec).toString(16);
-};
-
-var findIndex = function (array, callback) {
- var end = false;
- var i = 0;
- for (; i < array.length && !end; i++) {
- end = callback(array[i]);
- }
- return end ? i - 1 : -1;
-};
-
-var findMethodIndex = function (json, methodName) {
- return findIndex(json, function (method) {
- return method.name === methodName;
- });
-};
-
-var padLeft = function (string, chars) {
- return Array(chars - string.length + 1).join("0") + string;
-};
-
-var setupInputTypes = function () {
- var prefixedType = function (prefix) {
- return function (type, value) {
- var expected = prefix;
- if (type.indexOf(expected) !== 0) {
- return false;
- }
-
- var padding = parseInt(type.slice(expected.length)) / 8;
- if (typeof value === "number")
- value = value.toString(16);
- else if (value.indexOf('0x') === 0)
- value = value.substr(2);
- else
- value = (+value).toString(16);
- return padLeft(value, padding * 2);
- };
- };
-
- var namedType = function (name, padding, formatter) {
- return function (type, value) {
- if (type !== name) {
- return false;
- }
-
- return padLeft(formatter ? formatter(value) : value, padding * 2);
- };
- };
-
- var formatBool = function (value) {
- return value ? '0x1' : '0x0';
- };
-
- return [
- prefixedType('uint'),
- prefixedType('int'),
- prefixedType('hash'),
- namedType('address', 20),
- namedType('bool', 1, formatBool),
- ];
-};
-
-var inputTypes = setupInputTypes();
-
-var toAbiInput = function (json, methodName, params) {
- var bytes = "";
- var index = findMethodIndex(json, methodName);
-
- if (index === -1) {
- return;
- }
-
- bytes = "0x" + padLeft(index.toString(16), 2);
- var method = json[index];
-
- for (var i = 0; i < method.inputs.length; i++) {
- var found = false;
- for (var j = 0; j < inputTypes.length && !found; j++) {
- found = inputTypes[j](method.inputs[i].type, params[i]);
- }
- if (!found) {
- console.error('unsupported json type: ' + method.inputs[i].type);
- }
- bytes += found;
- }
- return bytes;
-};
-
-var setupOutputTypes = function () {
- var prefixedType = function (prefix) {
- return function (type) {
- var expected = prefix;
- if (type.indexOf(expected) !== 0) {
- return -1;
- }
-
- var padding = parseInt(type.slice(expected.length)) / 8;
- return padding * 2;
- };
- };
-
- var namedType = function (name, padding) {
- return function (type) {
- return name === type ? padding * 2 : -1;
- };
- };
-
- var formatInt = function (value) {
- return value.length <= 8 ? +parseInt(value, 16) : hexToDec(value);
- };
-
- var formatHash = function (value) {
- return "0x" + value;
- };
-
- var formatBool = function (value) {
- return value === '1' ? true : false;
- };
-
- return [
- { padding: prefixedType('uint'), format: formatInt },
- { padding: prefixedType('int'), format: formatInt },
- { padding: prefixedType('hash'), format: formatHash },
- { padding: namedType('address', 20) },
- { padding: namedType('bool', 1), format: formatBool }
- ];
-};
-
-var outputTypes = setupOutputTypes();
-
-var fromAbiOutput = function (json, methodName, output) {
- var index = findMethodIndex(json, methodName);
-
- if (index === -1) {
- return;
- }
-
- output = output.slice(2);
-
- var result = [];
- var method = json[index];
- for (var i = 0; i < method.outputs.length; i++) {
- var padding = -1;
- for (var j = 0; j < outputTypes.length && padding === -1; j++) {
- padding = outputTypes[j].padding(method.outputs[i].type);
- }
-
- if (padding === -1) {
- // not found output parsing
- continue;
- }
- var res = output.slice(0, padding);
- var formatter = outputTypes[j - 1].format;
- result.push(formatter ? formatter(res) : ("0x" + res));
- output = output.slice(padding);
- }
-
- return result;
-};
-
-var inputParser = function (json) {
- var parser = {};
- json.forEach(function (method) {
- parser[method.name] = function () {
- var params = Array.prototype.slice.call(arguments);
- return toAbiInput(json, method.name, params);
- };
- });
-
- return parser;
-};
-
-var outputParser = function (json) {
- var parser = {};
- json.forEach(function (method) {
- parser[method.name] = function (output) {
- return fromAbiOutput(json, method.name, output);
- };
- });
-
- return parser;
-};
-
-module.exports = {
- inputParser: inputParser,
- outputParser: outputParser
-};
diff --git a/cmd/ethtest/lib/autoprovider.js b/cmd/ethtest/lib/autoprovider.js
deleted file mode 100644
index bfbc3ab6e1..0000000000
--- a/cmd/ethtest/lib/autoprovider.js
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- This file is part of ethereum.js.
-
- ethereum.js 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.
-
- ethereum.js 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 ethereum.js. If not, see .
-*/
-/** @file autoprovider.js
- * @authors:
- * Marek Kotewicz
- * Marian Oancea
- * @date 2014
- */
-
-/*
- * @brief if qt object is available, uses QtProvider,
- * if not tries to connect over websockets
- * if it fails, it uses HttpRpcProvider
- */
-
-// TODO: work out which of the following two lines it is supposed to be...
-//if (process.env.NODE_ENV !== 'build') {
-if ("build" !== 'build') {/*
- var WebSocket = require('ws'); // jshint ignore:line
- var web3 = require('./main.js'); // jshint ignore:line
-*/}
-
-var AutoProvider = function (userOptions) {
- if (web3.haveProvider()) {
- return;
- }
-
- // before we determine what provider we are, we have to cache request
- this.sendQueue = [];
- this.onmessageQueue = [];
-
- if (navigator.qt) {
- this.provider = new web3.providers.QtProvider();
- return;
- }
-
- userOptions = userOptions || {};
- var options = {
- httprpc: userOptions.httprpc || 'http://localhost:8080',
- websockets: userOptions.websockets || 'ws://localhost:40404/eth'
- };
-
- var self = this;
- var closeWithSuccess = function (success) {
- ws.close();
- if (success) {
- self.provider = new web3.providers.WebSocketProvider(options.websockets);
- } else {
- self.provider = new web3.providers.HttpRpcProvider(options.httprpc);
- self.poll = self.provider.poll.bind(self.provider);
- }
- self.sendQueue.forEach(function (payload) {
- self.provider(payload);
- });
- self.onmessageQueue.forEach(function (handler) {
- self.provider.onmessage = handler;
- });
- };
-
- var ws = new WebSocket(options.websockets);
-
- ws.onopen = function() {
- closeWithSuccess(true);
- };
-
- ws.onerror = function() {
- closeWithSuccess(false);
- };
-};
-
-AutoProvider.prototype.send = function (payload) {
- if (this.provider) {
- this.provider.send(payload);
- return;
- }
- this.sendQueue.push(payload);
-};
-
-Object.defineProperty(AutoProvider.prototype, 'onmessage', {
- set: function (handler) {
- if (this.provider) {
- this.provider.onmessage = handler;
- return;
- }
- this.onmessageQueue.push(handler);
- }
-});
-
-module.exports = AutoProvider;
diff --git a/cmd/ethtest/lib/contract.js b/cmd/ethtest/lib/contract.js
deleted file mode 100644
index 17b077484b..0000000000
--- a/cmd/ethtest/lib/contract.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- This file is part of ethereum.js.
-
- ethereum.js 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.
-
- ethereum.js 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 ethereum.js. If not, see .
-*/
-/** @file contract.js
- * @authors:
- * Marek Kotewicz
- * @date 2014
- */
-
-// TODO: work out which of the following two lines it is supposed to be...
-//if (process.env.NODE_ENV !== 'build') {
-if ("build" !== 'build') {/*
- var web3 = require('./web3'); // jshint ignore:line
-*/}
-var abi = require('./abi');
-
-var contract = function (address, desc) {
- var inputParser = abi.inputParser(desc);
- var outputParser = abi.outputParser(desc);
-
- var contract = {};
-
- desc.forEach(function (method) {
- contract[method.name] = function () {
- var params = Array.prototype.slice.call(arguments);
- var parsed = inputParser[method.name].apply(null, params);
-
- var onSuccess = function (result) {
- return outputParser[method.name](result);
- };
-
- return {
- call: function (extra) {
- extra = extra || {};
- extra.to = address;
- extra.data = parsed;
- return web3.eth.call(extra).then(onSuccess);
- },
- transact: function (extra) {
- extra = extra || {};
- extra.to = address;
- extra.data = parsed;
- return web3.eth.transact(extra).then(onSuccess);
- }
- };
- };
- });
-
- return contract;
-};
-
-module.exports = contract;
diff --git a/cmd/ethtest/lib/httprpc.js b/cmd/ethtest/lib/httprpc.js
deleted file mode 100644
index ee6b5c3070..0000000000
--- a/cmd/ethtest/lib/httprpc.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- This file is part of ethereum.js.
-
- ethereum.js 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.
-
- ethereum.js 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 ethereum.js. If not, see .
-*/
-/** @file httprpc.js
- * @authors:
- * Marek Kotewicz
- * Marian Oancea
- * @date 2014
- */
-
-// TODO: work out which of the following two lines it is supposed to be...
-//if (process.env.NODE_ENV !== 'build') {
-if ("build" !== "build") {/*
- var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line
-*/}
-
-var HttpRpcProvider = function (host) {
- this.handlers = [];
- this.host = host;
-};
-
-function formatJsonRpcObject(object) {
- return {
- jsonrpc: '2.0',
- method: object.call,
- params: object.args,
- id: object._id
- };
-}
-
-function formatJsonRpcMessage(message) {
- var object = JSON.parse(message);
-
- return {
- _id: object.id,
- data: object.result,
- error: object.error
- };
-}
-
-HttpRpcProvider.prototype.sendRequest = function (payload, cb) {
- var data = formatJsonRpcObject(payload);
-
- var request = new XMLHttpRequest();
- request.open("POST", this.host, true);
- request.send(JSON.stringify(data));
- request.onreadystatechange = function () {
- if (request.readyState === 4 && cb) {
- cb(request);
- }
- };
-};
-
-HttpRpcProvider.prototype.send = function (payload) {
- var self = this;
- this.sendRequest(payload, function (request) {
- self.handlers.forEach(function (handler) {
- handler.call(self, formatJsonRpcMessage(request.responseText));
- });
- });
-};
-
-HttpRpcProvider.prototype.poll = function (payload, id) {
- var self = this;
- this.sendRequest(payload, function (request) {
- var parsed = JSON.parse(request.responseText);
- if (parsed.error || (parsed.result instanceof Array ? parsed.result.length === 0 : !parsed.result)) {
- return;
- }
- self.handlers.forEach(function (handler) {
- handler.call(self, {_event: payload.call, _id: id, data: parsed.result});
- });
- });
-};
-
-Object.defineProperty(HttpRpcProvider.prototype, "onmessage", {
- set: function (handler) {
- this.handlers.push(handler);
- }
-});
-
-module.exports = HttpRpcProvider;
diff --git a/cmd/ethtest/lib/main.js b/cmd/ethtest/lib/main.js
deleted file mode 100644
index 59c60cfa81..0000000000
--- a/cmd/ethtest/lib/main.js
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- This file is part of ethereum.js.
-
- ethereum.js 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.
-
- ethereum.js 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 ethereum.js. If not, see .
-*/
-/** @file main.js
- * @authors:
- * Jeffrey Wilcke
- * Marek Kotewicz
- * Marian Oancea
- * Gav Wood
- * @date 2014
- */
-
-function flattenPromise (obj) {
- if (obj instanceof Promise) {
- return Promise.resolve(obj);
- }
-
- if (obj instanceof Array) {
- return new Promise(function (resolve) {
- var promises = obj.map(function (o) {
- return flattenPromise(o);
- });
-
- return Promise.all(promises).then(function (res) {
- for (var i = 0; i < obj.length; i++) {
- obj[i] = res[i];
- }
- resolve(obj);
- });
- });
- }
-
- if (obj instanceof Object) {
- return new Promise(function (resolve) {
- var keys = Object.keys(obj);
- var promises = keys.map(function (key) {
- return flattenPromise(obj[key]);
- });
-
- return Promise.all(promises).then(function (res) {
- for (var i = 0; i < keys.length; i++) {
- obj[keys[i]] = res[i];
- }
- resolve(obj);
- });
- });
- }
-
- return Promise.resolve(obj);
-}
-
-var web3Methods = function () {
- return [
- { name: 'sha3', call: 'web3_sha3' }
- ];
-};
-
-var ethMethods = function () {
- var blockCall = function (args) {
- return typeof args[0] === "string" ? "eth_blockByHash" : "eth_blockByNumber";
- };
-
- var transactionCall = function (args) {
- return typeof args[0] === "string" ? 'eth_transactionByHash' : 'eth_transactionByNumber';
- };
-
- var uncleCall = function (args) {
- return typeof args[0] === "string" ? 'eth_uncleByHash' : 'eth_uncleByNumber';
- };
-
- var methods = [
- { name: 'balanceAt', call: 'eth_balanceAt' },
- { name: 'stateAt', call: 'eth_stateAt' },
- { name: 'storageAt', call: 'eth_storageAt' },
- { name: 'countAt', call: 'eth_countAt'},
- { name: 'codeAt', call: 'eth_codeAt' },
- { name: 'transact', call: 'eth_transact' },
- { name: 'call', call: 'eth_call' },
- { name: 'block', call: blockCall },
- { name: 'transaction', call: transactionCall },
- { name: 'uncle', call: uncleCall },
- { name: 'compilers', call: 'eth_compilers' },
- { name: 'lll', call: 'eth_lll' },
- { name: 'solidity', call: 'eth_solidity' },
- { name: 'serpent', call: 'eth_serpent' },
- { name: 'logs', call: 'eth_logs' }
- ];
- return methods;
-};
-
-var ethProperties = function () {
- return [
- { name: 'coinbase', getter: 'eth_coinbase', setter: 'eth_setCoinbase' },
- { name: 'listening', getter: 'eth_listening', setter: 'eth_setListening' },
- { name: 'mining', getter: 'eth_mining', setter: 'eth_setMining' },
- { name: 'gasPrice', getter: 'eth_gasPrice' },
- { name: 'account', getter: 'eth_account' },
- { name: 'accounts', getter: 'eth_accounts' },
- { name: 'peerCount', getter: 'eth_peerCount' },
- { name: 'defaultBlock', getter: 'eth_defaultBlock', setter: 'eth_setDefaultBlock' },
- { name: 'number', getter: 'eth_number'}
- ];
-};
-
-var dbMethods = function () {
- return [
- { name: 'put', call: 'db_put' },
- { name: 'get', call: 'db_get' },
- { name: 'putString', call: 'db_putString' },
- { name: 'getString', call: 'db_getString' }
- ];
-};
-
-var shhMethods = function () {
- return [
- { name: 'post', call: 'shh_post' },
- { name: 'newIdentity', call: 'shh_newIdentity' },
- { name: 'haveIdentity', call: 'shh_haveIdentity' },
- { name: 'newGroup', call: 'shh_newGroup' },
- { name: 'addToGroup', call: 'shh_addToGroup' }
- ];
-};
-
-var ethWatchMethods = function () {
- var newFilter = function (args) {
- return typeof args[0] === 'string' ? 'eth_newFilterString' : 'eth_newFilter';
- };
-
- return [
- { name: 'newFilter', call: newFilter },
- { name: 'uninstallFilter', call: 'eth_uninstallFilter' },
- { name: 'getMessages', call: 'eth_filterLogs' }
- ];
-};
-
-var shhWatchMethods = function () {
- return [
- { name: 'newFilter', call: 'shh_newFilter' },
- { name: 'uninstallFilter', call: 'shh_uninstallFilter' },
- { name: 'getMessage', call: 'shh_getMessages' }
- ];
-};
-
-var setupMethods = function (obj, methods) {
- methods.forEach(function (method) {
- obj[method.name] = function () {
- return flattenPromise(Array.prototype.slice.call(arguments)).then(function (args) {
- var call = typeof method.call === "function" ? method.call(args) : method.call;
- return {call: call, args: args};
- }).then(function (request) {
- return new Promise(function (resolve, reject) {
- web3.provider.send(request, function (err, result) {
- if (!err) {
- resolve(result);
- return;
- }
- reject(err);
- });
- });
- }).catch(function(err) {
- console.error(err);
- });
- };
- });
-};
-
-var setupProperties = function (obj, properties) {
- properties.forEach(function (property) {
- var proto = {};
- proto.get = function () {
- return new Promise(function(resolve, reject) {
- web3.provider.send({call: property.getter}, function(err, result) {
- if (!err) {
- resolve(result);
- return;
- }
- reject(err);
- });
- });
- };
- if (property.setter) {
- proto.set = function (val) {
- return flattenPromise([val]).then(function (args) {
- return new Promise(function (resolve) {
- web3.provider.send({call: property.setter, args: args}, function (err, result) {
- if (!err) {
- resolve(result);
- return;
- }
- reject(err);
- });
- });
- }).catch(function (err) {
- console.error(err);
- });
- };
- }
- Object.defineProperty(obj, property.name, proto);
- });
-};
-
-// TODO: import from a dependency, don't duplicate.
-var hexToDec = function (hex) {
- return parseInt(hex, 16).toString();
-};
-
-var decToHex = function (dec) {
- return parseInt(dec).toString(16);
-};
-
-
-var web3 = {
- _callbacks: {},
- _events: {},
- providers: {},
-
- toAscii: function(hex) {
- // Find termination
- var str = "";
- var i = 0, l = hex.length;
- if (hex.substring(0, 2) === '0x')
- i = 2;
- for(; i < l; i+=2) {
- var code = hex.charCodeAt(i);
- if(code === 0) {
- break;
- }
-
- str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
- }
-
- return str;
- },
-
- fromAscii: function(str, pad) {
- pad = pad === undefined ? 32 : pad;
- var hex = this.toHex(str);
- while(hex.length < pad*2)
- hex += "00";
- return "0x" + hex;
- },
-
- toDecimal: function (val) {
- return hexToDec(val.substring(2));
- },
-
- fromDecimal: function (val) {
- return "0x" + decToHex(val);
- },
-
- toEth: function(str) {
- var val = typeof str === "string" ? str.indexOf('0x') == 0 ? parseInt(str.substr(2), 16) : parseInt(str) : str;
- var unit = 0;
- var units = [ 'wei', 'Kwei', 'Mwei', 'Gwei', 'szabo', 'finney', 'ether', 'grand', 'Mether', 'Gether', 'Tether', 'Pether', 'Eether', 'Zether', 'Yether', 'Nether', 'Dether', 'Vether', 'Uether' ];
- while (val > 3000 && unit < units.length - 1)
- {
- val /= 1000;
- unit++;
- }
- var s = val.toString().length < val.toFixed(2).length ? val.toString() : val.toFixed(2);
- while (true) {
- var o = s;
- s = s.replace(/(\d)(\d\d\d[\.\,])/, function($0, $1, $2) { return $1 + ',' + $2; });
- if (o == s)
- break;
- }
- return s + ' ' + units[unit];
- },
-
- eth: {
- prototype: Object(), // jshint ignore:line
- watch: function (params) {
- return new Filter(params, ethWatch);
- }
- },
-
- db: {
- prototype: Object() // jshint ignore:line
- },
-
- shh: {
- prototype: Object(), // jshint ignore:line
- watch: function (params) {
- return new Filter(params, shhWatch);
- }
- },
-
- on: function(event, id, cb) {
- if(web3._events[event] === undefined) {
- web3._events[event] = {};
- }
-
- web3._events[event][id] = cb;
- return this;
- },
-
- off: function(event, id) {
- if(web3._events[event] !== undefined) {
- delete web3._events[event][id];
- }
-
- return this;
- },
-
- trigger: function(event, id, data) {
- var callbacks = web3._events[event];
- if (!callbacks || !callbacks[id]) {
- return;
- }
- var cb = callbacks[id];
- cb(data);
- }
-};
-
-setupMethods(web3, web3Methods());
-setupMethods(web3.eth, ethMethods());
-setupProperties(web3.eth, ethProperties());
-setupMethods(web3.db, dbMethods());
-setupMethods(web3.shh, shhMethods());
-
-var ethWatch = {
- changed: 'eth_changed'
-};
-setupMethods(ethWatch, ethWatchMethods());
-var shhWatch = {
- changed: 'shh_changed'
-};
-setupMethods(shhWatch, shhWatchMethods());
-
-var ProviderManager = function() {
- this.queued = [];
- this.polls = [];
- this.ready = false;
- this.provider = undefined;
- this.id = 1;
-
- var self = this;
- var poll = function () {
- if (self.provider && self.provider.poll) {
- self.polls.forEach(function (data) {
- data.data._id = self.id;
- self.id++;
- self.provider.poll(data.data, data.id);
- });
- }
- setTimeout(poll, 12000);
- };
- poll();
-};
-
-ProviderManager.prototype.send = function(data, cb) {
- data._id = this.id;
- if (cb) {
- web3._callbacks[data._id] = cb;
- }
-
- data.args = data.args || [];
- this.id++;
-
- if(this.provider !== undefined) {
- this.provider.send(data);
- } else {
- console.warn("provider is not set");
- this.queued.push(data);
- }
-};
-
-ProviderManager.prototype.set = function(provider) {
- if(this.provider !== undefined && this.provider.unload !== undefined) {
- this.provider.unload();
- }
-
- this.provider = provider;
- this.ready = true;
-};
-
-ProviderManager.prototype.sendQueued = function() {
- for(var i = 0; this.queued.length; i++) {
- // Resend
- this.send(this.queued[i]);
- }
-};
-
-ProviderManager.prototype.installed = function() {
- return this.provider !== undefined;
-};
-
-ProviderManager.prototype.startPolling = function (data, pollId) {
- if (!this.provider || !this.provider.poll) {
- return;
- }
- this.polls.push({data: data, id: pollId});
-};
-
-ProviderManager.prototype.stopPolling = function (pollId) {
- for (var i = this.polls.length; i--;) {
- var poll = this.polls[i];
- if (poll.id === pollId) {
- this.polls.splice(i, 1);
- }
- }
-};
-
-web3.provider = new ProviderManager();
-
-web3.setProvider = function(provider) {
- provider.onmessage = messageHandler;
- web3.provider.set(provider);
- web3.provider.sendQueued();
-};
-
-web3.haveProvider = function() {
- return !!web3.provider.provider;
-};
-
-var Filter = function(options, impl) {
- this.impl = impl;
- this.callbacks = [];
-
- var self = this;
- this.promise = impl.newFilter(options);
- this.promise.then(function (id) {
- self.id = id;
- web3.on(impl.changed, id, self.trigger.bind(self));
- web3.provider.startPolling({call: impl.changed, args: [id]}, id);
- });
-};
-
-Filter.prototype.arrived = function(callback) {
- this.changed(callback);
-};
-
-Filter.prototype.changed = function(callback) {
- var self = this;
- this.promise.then(function(id) {
- self.callbacks.push(callback);
- });
-};
-
-Filter.prototype.trigger = function(messages) {
- for(var i = 0; i < this.callbacks.length; i++) {
- this.callbacks[i].call(this, messages);
- }
-};
-
-Filter.prototype.uninstall = function() {
- var self = this;
- this.promise.then(function (id) {
- self.impl.uninstallFilter(id);
- web3.provider.stopPolling(id);
- web3.off(impl.changed, id);
- });
-};
-
-Filter.prototype.messages = function() {
- var self = this;
- return this.promise.then(function (id) {
- return self.impl.getMessages(id);
- });
-};
-
-Filter.prototype.logs = function () {
- return this.messages();
-};
-
-function messageHandler(data) {
- if(data._event !== undefined) {
- web3.trigger(data._event, data._id, data.data);
- return;
- }
-
- if(data._id) {
- var cb = web3._callbacks[data._id];
- if (cb) {
- cb.call(this, data.error, data.data);
- delete web3._callbacks[data._id];
- }
- }
-}
-
-module.exports = web3;
diff --git a/cmd/ethtest/lib/qt.js b/cmd/ethtest/lib/qt.js
deleted file mode 100644
index f022395476..0000000000
--- a/cmd/ethtest/lib/qt.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- This file is part of ethereum.js.
-
- ethereum.js 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.
-
- ethereum.js 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 ethereum.js. If not, see .
-*/
-/** @file qt.js
- * @authors:
- * Jeffrey Wilcke
- * Marek Kotewicz
- * @date 2014
- */
-
-var QtProvider = function() {
- this.handlers = [];
-
- var self = this;
- navigator.qt.onmessage = function (message) {
- self.handlers.forEach(function (handler) {
- handler.call(self, JSON.parse(message.data));
- });
- };
-};
-
-QtProvider.prototype.send = function(payload) {
- navigator.qt.postMessage(JSON.stringify(payload));
-};
-
-Object.defineProperty(QtProvider.prototype, "onmessage", {
- set: function(handler) {
- this.handlers.push(handler);
- }
-});
-
-module.exports = QtProvider;
diff --git a/cmd/ethtest/lib/websocket.js b/cmd/ethtest/lib/websocket.js
deleted file mode 100644
index 24a0725313..0000000000
--- a/cmd/ethtest/lib/websocket.js
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- This file is part of ethereum.js.
-
- ethereum.js 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.
-
- ethereum.js 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 ethereum.js. If not, see .
-*/
-/** @file websocket.js
- * @authors:
- * Jeffrey Wilcke
- * Marek Kotewicz
- * Marian Oancea
- * @date 2014
- */
-
-// TODO: work out which of the following two lines it is supposed to be...
-//if (process.env.NODE_ENV !== 'build') {
-if ("build" !== "build") {/*
- var WebSocket = require('ws'); // jshint ignore:line
-*/}
-
-var WebSocketProvider = function(host) {
- // onmessage handlers
- this.handlers = [];
- // queue will be filled with messages if send is invoked before the ws is ready
- this.queued = [];
- this.ready = false;
-
- this.ws = new WebSocket(host);
-
- var self = this;
- this.ws.onmessage = function(event) {
- for(var i = 0; i < self.handlers.length; i++) {
- self.handlers[i].call(self, JSON.parse(event.data), event);
- }
- };
-
- this.ws.onopen = function() {
- self.ready = true;
-
- for(var i = 0; i < self.queued.length; i++) {
- // Resend
- self.send(self.queued[i]);
- }
- };
-};
-
-WebSocketProvider.prototype.send = function(payload) {
- if(this.ready) {
- var data = JSON.stringify(payload);
-
- this.ws.send(data);
- } else {
- this.queued.push(payload);
- }
-};
-
-WebSocketProvider.prototype.onMessage = function(handler) {
- this.handlers.push(handler);
-};
-
-WebSocketProvider.prototype.unload = function() {
- this.ws.close();
-};
-Object.defineProperty(WebSocketProvider.prototype, "onmessage", {
- set: function(provider) { this.onMessage(provider); }
-});
-
-module.exports = WebSocketProvider;
diff --git a/cmd/ethtest/package.json b/cmd/ethtest/package.json
deleted file mode 100644
index 24141ea2e4..0000000000
--- a/cmd/ethtest/package.json
+++ /dev/null
@@ -1,67 +0,0 @@
-{
- "name": "ethereum.js",
- "namespace": "ethereum",
- "version": "0.0.5",
- "description": "Ethereum Compatible JavaScript API",
- "main": "./index.js",
- "directories": {
- "lib": "./lib"
- },
- "dependencies": {
- "es6-promise": "*",
- "ws": "*",
- "xmlhttprequest": "*"
- },
- "devDependencies": {
- "bower": ">=1.3.0",
- "browserify": ">=6.0",
- "del": ">=0.1.1",
- "envify": "^3.0.0",
- "exorcist": "^0.1.6",
- "gulp": ">=3.4.0",
- "gulp-jshint": ">=1.5.0",
- "gulp-rename": ">=1.2.0",
- "gulp-uglify": ">=1.0.0",
- "jshint": ">=2.5.0",
- "uglifyify": "^2.6.0",
- "unreachable-branch-transform": "^0.1.0",
- "vinyl-source-stream": "^1.0.0"
- },
- "scripts": {
- "build": "gulp",
- "watch": "gulp watch",
- "lint": "gulp lint"
- },
- "repository": {
- "type": "git",
- "url": "https://github.com/ethereum/ethereum.js.git"
- },
- "homepage": "https://github.com/ethereum/ethereum.js",
- "bugs": {
- "url": "https://github.com/ethereum/ethereum.js/issues"
- },
- "keywords": [
- "ethereum",
- "javascript",
- "API"
- ],
- "author": "ethdev.com",
- "authors": [
- {
- "name": "Jeffery Wilcke",
- "email": "jeff@ethdev.com",
- "url": "https://github.com/obscuren"
- },
- {
- "name": "Marek Kotewicz",
- "email": "marek@ethdev.com",
- "url": "https://github.com/debris"
- },
- {
- "name": "Marian Oancea",
- "email": "marian@ethdev.com",
- "url": "https://github.com/cubedro"
- }
- ],
- "license": "LGPL-3.0"
-}
diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml
index 06a7bc2a8e..5df4c8aad2 100644
--- a/cmd/mist/assets/qml/main.qml
+++ b/cmd/mist/assets/qml/main.qml
@@ -866,12 +866,14 @@ ApplicationWindow {
model: ListModel { id: pastPeers }
Component.onCompleted: {
+ /*
var ips = eth.pastPeers()
for(var i = 0; i < ips.length; i++) {
pastPeers.append({text: ips.get(i)})
}
pastPeers.insert(0, {text: "poc-7.ethdev.com:30303"})
+ */
}
}
diff --git a/cmd/mist/assets/qml/views/wallet.qml b/cmd/mist/assets/qml/views/wallet.qml
index 9727ef35c8..b81273a173 100644
--- a/cmd/mist/assets/qml/views/wallet.qml
+++ b/cmd/mist/assets/qml/views/wallet.qml
@@ -20,7 +20,7 @@ Rectangle {
}
function setBalance() {
- balance.text = "Balance: " + eth.numberToHuman(eth.balanceAt(eth.key().address))
+ //balance.text = "Balance: " + eth.numberToHuman(eth.balanceAt(eth.key().address))
if(menuItem)
menuItem.secondaryTitle = eth.numberToHuman(eth.balanceAt(eth.key().address))
}
diff --git a/cmd/mist/bindings.go b/cmd/mist/bindings.go
index 6d2342c876..66d8d14916 100644
--- a/cmd/mist/bindings.go
+++ b/cmd/mist/bindings.go
@@ -72,7 +72,7 @@ func (gui *Gui) GetCustomIdentifier() string {
// functions that allow Gui to implement interface guilogger.LogSystem
func (gui *Gui) SetLogLevel(level logger.LogLevel) {
gui.logLevel = level
- gui.stdLog.SetLogLevel(level)
+ gui.eth.Logger().SetLogLevel(level)
gui.config.Save("loglevel", level)
}
diff --git a/cmd/mist/debugger.go b/cmd/mist/debugger.go
index 0e97a6652c..618e31f4ed 100644
--- a/cmd/mist/debugger.go
+++ b/cmd/mist/debugger.go
@@ -151,7 +151,7 @@ func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, data
block := self.lib.eth.ChainManager().CurrentBlock()
- env := utils.NewEnv(statedb, block, account.Address(), value)
+ env := utils.NewEnv(self.lib.eth.ChainManager(), statedb, block, account.Address(), value)
self.Logf("callsize %d", len(script))
go func() {
diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go
index 98ca70b162..8e533d9772 100644
--- a/cmd/mist/gui.go
+++ b/cmd/mist/gui.go
@@ -72,8 +72,7 @@ type Gui struct {
plugins map[string]plugin
- miner *miner.Miner
- stdLog logger.LogSystem
+ miner *miner.Miner
}
// Create GUI, but doesn't start it
@@ -113,7 +112,7 @@ func (gui *Gui) Start(assetPath string) {
// Expose the eth library and the ui library to QML
context.SetVar("gui", gui)
context.SetVar("eth", gui.uiLib)
- context.SetVar("shh", gui.whisper)
+ //context.SetVar("shh", gui.whisper)
// Load the main QML interface
data, _ := ethutil.Config.Db.Get([]byte("KeyRing"))
diff --git a/cmd/mist/main.go b/cmd/mist/main.go
index 6f578ff48f..ce5e8449a0 100644
--- a/cmd/mist/main.go
+++ b/cmd/mist/main.go
@@ -26,15 +26,17 @@ import (
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/logger"
+ "github.com/ethereum/go-ethereum/p2p"
"gopkg.in/qml.v1"
)
const (
ClientIdentifier = "Mist"
- Version = "0.7.11"
+ Version = "0.8.0"
)
var ethereum *eth.Ethereum
+var mainlogger = logger.NewLogger("MAIN")
func run() error {
// precedence: code-internal flag default < config file < environment variables < command line
@@ -43,27 +45,24 @@ func run() error {
tstart := time.Now()
config := utils.InitConfig(VmType, ConfigFile, Datadir, "ETH")
- utils.InitDataDir(Datadir)
-
- stdLog := utils.InitLogging(Datadir, LogFile, LogLevel, DebugFile)
-
- db := utils.NewDatabase()
- err := utils.DBSanityCheck(db)
+ ethereum, err := eth.New(ð.Config{
+ Name: ClientIdentifier,
+ Version: Version,
+ KeyStore: KeyStore,
+ DataDir: Datadir,
+ LogFile: LogFile,
+ LogLevel: LogLevel,
+ Identifier: Identifier,
+ MaxPeers: MaxPeer,
+ Port: OutboundPort,
+ NATType: PMPGateway,
+ PMPGateway: PMPGateway,
+ KeyRing: KeyRing,
+ })
if err != nil {
- ErrorWindow(err)
-
- os.Exit(1)
- }
- keyManager := utils.NewKeyManager(KeyStore, Datadir, db)
-
- // create, import, export keys
- utils.KeyTasks(keyManager, KeyRing, GenAddr, SecretFile, ExportDir, NonInteractive)
- clientIdentity := utils.NewClientIdentity(ClientIdentifier, Version, Identifier, string(keyManager.PublicKey()))
- ethereum := utils.NewEthereum(db, clientIdentity, keyManager, utils.NatType(NatType, PMPGateway), OutboundPort, MaxPeer)
-
- if ShowGenesis {
- utils.ShowGenesis(ethereum)
+ mainlogger.Fatalln(err)
}
+ utils.KeyTasks(ethereum.KeyManager(), KeyRing, GenAddr, SecretFile, ExportDir, NonInteractive)
if StartRpc {
utils.StartRpc(ethereum, RpcPort)
@@ -73,8 +72,7 @@ func run() error {
utils.StartWebSockets(ethereum)
}
- gui := NewWindow(ethereum, config, clientIdentity, KeyRing, LogLevel)
- gui.stdLog = stdLog
+ gui := NewWindow(ethereum, config, ethereum.ClientIdentity().(*p2p.SimpleClientIdentity), KeyRing, LogLevel)
utils.RegisterInterrupt(func(os.Signal) {
gui.Stop()
diff --git a/cmd/peerserver/main.go b/cmd/peerserver/main.go
index 0fa7a9b440..18d183f0bd 100644
--- a/cmd/peerserver/main.go
+++ b/cmd/peerserver/main.go
@@ -18,7 +18,7 @@ func main() {
marshaled := elliptic.Marshal(crypto.S256(), key.PublicKey.X, key.PublicKey.Y)
srv := p2p.Server{
- MaxPeers: 10,
+ MaxPeers: 100,
Identity: p2p.NewSimpleClientIdentity("Ethereum(G)", "0.1", "Peer Server Two", string(marshaled)),
ListenAddr: ":30301",
NAT: p2p.UPNP(),
@@ -29,12 +29,12 @@ func main() {
}
// add seed peers
- seed, err := net.ResolveTCPAddr("tcp", "poc-7.ethdev.com:30300")
+ seed, err := net.ResolveTCPAddr("tcp", "poc-8.ethdev.com:30303")
if err != nil {
fmt.Println("couldn't resolve:", err)
- os.Exit(1)
+ } else {
+ srv.SuggestPeer(seed.IP, seed.Port, nil)
}
- srv.SuggestPeer(seed.IP, seed.Port, nil)
select {}
}
diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go
index 466c513835..6b1cf37265 100644
--- a/cmd/utils/cmd.go
+++ b/cmd/utils/cmd.go
@@ -2,9 +2,6 @@ package utils
import (
"fmt"
- "io"
- "log"
- "net"
"os"
"os/signal"
"path"
@@ -16,11 +13,9 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/miner"
- "github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/xeth"
@@ -52,15 +47,8 @@ func RunInterruptCallbacks(sig os.Signal) {
}
}
-func AbsolutePath(Datadir string, filename string) string {
- if path.IsAbs(filename) {
- return filename
- }
- return path.Join(Datadir, filename)
-}
-
func openLogFile(Datadir string, filename string) *os.File {
- path := AbsolutePath(Datadir, filename)
+ path := ethutil.AbsolutePath(Datadir, filename)
file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
panic(fmt.Sprintf("error opening log file '%s': %v", filename, err))
@@ -76,23 +64,13 @@ func confirm(message string) bool {
if r == "n" || r == "y" {
break
} else {
- fmt.Printf("Yes or no?", r)
+ fmt.Printf("Yes or no? (%s)", r)
}
}
return r == "y"
}
-func DBSanityCheck(db ethutil.Database) error {
- d, _ := db.Get([]byte("ProtocolVersion"))
- protov := ethutil.NewValue(d).Uint()
- if protov != eth.ProtocolVersion && protov != 0 {
- return fmt.Errorf("Database version mismatch. Protocol(%d / %d). `rm -rf %s`", protov, eth.ProtocolVersion, ethutil.Config.ExecPath+"/database")
- }
-
- return nil
-}
-
-func InitDataDir(Datadir string) {
+func initDataDir(Datadir string) {
_, err := os.Stat(Datadir)
if err != nil {
if os.IsNotExist(err) {
@@ -102,26 +80,8 @@ func InitDataDir(Datadir string) {
}
}
-func InitLogging(Datadir string, LogFile string, LogLevel int, DebugFile string) logger.LogSystem {
- var writer io.Writer
- if LogFile == "" {
- writer = os.Stdout
- } else {
- writer = openLogFile(Datadir, LogFile)
- }
-
- sys := logger.NewStdLogSystem(writer, log.LstdFlags, logger.LogLevel(LogLevel))
- logger.AddLogSystem(sys)
- if DebugFile != "" {
- writer = openLogFile(Datadir, DebugFile)
- logger.AddLogSystem(logger.NewStdLogSystem(writer, log.LstdFlags, logger.DebugLevel))
- }
-
- return sys
-}
-
func InitConfig(vmType int, ConfigFile string, Datadir string, EnvPrefix string) *ethutil.ConfigManager {
- InitDataDir(Datadir)
+ initDataDir(Datadir)
cfg := ethutil.ReadConfig(ConfigFile, Datadir, EnvPrefix)
cfg.VmType = vmType
@@ -138,43 +98,6 @@ func exit(err error) {
os.Exit(status)
}
-func NewDatabase() ethutil.Database {
- db, err := ethdb.NewLDBDatabase("database")
- if err != nil {
- exit(err)
- }
- return db
-}
-
-func NewClientIdentity(clientIdentifier, version, customIdentifier string, pubkey string) *p2p.SimpleClientIdentity {
- return p2p.NewSimpleClientIdentity(clientIdentifier, version, customIdentifier, pubkey)
-}
-
-func NatType(natType string, gateway string) (nat p2p.NAT) {
- switch natType {
- case "UPNP":
- nat = p2p.UPNP()
- case "PMP":
- ip := net.ParseIP(gateway)
- if ip == nil {
- clilogger.Fatalf("cannot resolve PMP gateway IP %s", gateway)
- }
- nat = p2p.PMP(ip)
- case "":
- default:
- clilogger.Fatalf("unrecognised NAT type '%s'", natType)
- }
- return
-}
-
-func NewEthereum(db ethutil.Database, clientIdentity p2p.ClientIdentity, keyManager *crypto.KeyManager, nat p2p.NAT, OutboundPort string, MaxPeer int) *eth.Ethereum {
- ethereum, err := eth.New(db, clientIdentity, keyManager, nat, OutboundPort, MaxPeer)
- if err != nil {
- clilogger.Fatalln("eth start err:", err)
- }
- return ethereum
-}
-
func StartEthereum(ethereum *eth.Ethereum, UseSeed bool) {
clilogger.Infof("Starting %s", ethereum.ClientIdentity())
ethereum.Start(UseSeed)
@@ -184,24 +107,6 @@ func StartEthereum(ethereum *eth.Ethereum, UseSeed bool) {
})
}
-func ShowGenesis(ethereum *eth.Ethereum) {
- clilogger.Infoln(ethereum.ChainManager().Genesis())
- exit(nil)
-}
-
-func NewKeyManager(KeyStore string, Datadir string, db ethutil.Database) *crypto.KeyManager {
- var keyManager *crypto.KeyManager
- switch {
- case KeyStore == "db":
- keyManager = crypto.NewDBKeyManager(db)
- case KeyStore == "file":
- keyManager = crypto.NewFileKeyManager(Datadir)
- default:
- exit(fmt.Errorf("unknown keystore type: %s", KeyStore))
- }
- return keyManager
-}
-
func DefaultAssetPath() string {
var assetPath string
// If the current working directory is the go-ethereum dir
diff --git a/cmd/utils/vm_env.go b/cmd/utils/vm_env.go
index 19091bdc5d..acc2ffad95 100644
--- a/cmd/utils/vm_env.go
+++ b/cmd/utils/vm_env.go
@@ -10,6 +10,7 @@ import (
)
type VMEnv struct {
+ chain *core.ChainManager
state *state.StateDB
block *types.Block
@@ -20,8 +21,9 @@ type VMEnv struct {
Gas *big.Int
}
-func NewEnv(state *state.StateDB, block *types.Block, transactor []byte, value *big.Int) *VMEnv {
+func NewEnv(chain *core.ChainManager, state *state.StateDB, block *types.Block, transactor []byte, value *big.Int) *VMEnv {
return &VMEnv{
+ chain: chain,
state: state,
block: block,
transactor: transactor,
@@ -35,12 +37,18 @@ func (self *VMEnv) PrevHash() []byte { return self.block.ParentHash() }
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase() }
func (self *VMEnv) Time() int64 { return self.block.Time() }
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty() }
-func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit() }
func (self *VMEnv) Value() *big.Int { return self.value }
func (self *VMEnv) State() *state.StateDB { return self.state }
func (self *VMEnv) Depth() int { return self.depth }
func (self *VMEnv) SetDepth(i int) { self.depth = i }
+func (self *VMEnv) GetHash(n uint64) []byte {
+ if block := self.chain.GetBlockByNumber(n); block != nil {
+ return block.Hash()
+ }
+
+ return nil
+}
func (self *VMEnv) AddLog(log state.Log) {
self.state.AddLog(log)
}
diff --git a/core/block_manager.go b/core/block_manager.go
index 8a5455306c..76385ea1fd 100644
--- a/core/block_manager.go
+++ b/core/block_manager.go
@@ -6,7 +6,6 @@ import (
"fmt"
"math/big"
"sync"
- "time"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
@@ -22,18 +21,6 @@ import (
var statelogger = logger.NewLogger("BLOCK")
-type Peer interface {
- Inbound() bool
- LastSend() time.Time
- LastPong() int64
- Host() []byte
- Port() uint16
- Version() string
- PingTime() string
- Connected() *int32
- Caps() *ethutil.Value
-}
-
type EthManager interface {
BlockManager() *BlockManager
ChainManager() *ChainManager
@@ -113,7 +100,7 @@ done:
txGas := new(big.Int).Set(tx.Gas())
cb := state.GetStateObject(coinbase.Address())
- st := NewStateTransition(cb, tx, state, block)
+ st := NewStateTransition(NewEnv(state, self.bc, tx, block), tx, cb)
_, err = st.TransitionState()
if err != nil {
switch {
@@ -232,6 +219,8 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
// Sync the current block's state to the database and cancelling out the deferred Undo
state.Sync()
+ state.Manifest().SetHash(block.Hash())
+
messages := state.Manifest().Messages
state.Manifest().Reset()
@@ -339,10 +328,10 @@ func (sm *BlockManager) AccumelateRewards(statedb *state.StateDB, block, parent
account.AddAmount(reward)
statedb.Manifest().AddMessage(&state.Message{
- To: block.Header().Coinbase,
- Input: nil,
- Origin: nil,
- Block: block.Hash(), Timestamp: int64(block.Header().Time), Coinbase: block.Header().Coinbase, Number: block.Header().Number,
+ To: block.Header().Coinbase,
+ Input: nil,
+ Origin: nil,
+ Timestamp: int64(block.Header().Time), Coinbase: block.Header().Coinbase, Number: block.Header().Number,
Value: new(big.Int).Add(reward, block.Reward),
})
diff --git a/core/chain_manager.go b/core/chain_manager.go
index ece98d7830..82b17cd931 100644
--- a/core/chain_manager.go
+++ b/core/chain_manager.go
@@ -271,15 +271,15 @@ func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block {
self.mu.RLock()
defer self.mu.RUnlock()
- block := self.currentBlock
- for ; block != nil; block = self.GetBlock(block.Header().ParentHash) {
- if block.Header().Number.Uint64() == num {
- break
- }
- }
+ var block *types.Block
- if block != nil && block.Header().Number.Uint64() == 0 && num != 0 {
- return nil
+ if num <= self.currentBlock.Number().Uint64() {
+ block = self.currentBlock
+ for ; block != nil; block = self.GetBlock(block.Header().ParentHash) {
+ if block.Header().Number.Uint64() == num {
+ break
+ }
+ }
}
return block
diff --git a/core/state_transition.go b/core/state_transition.go
index 91cfd5fe3b..b22c5bf217 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -4,7 +4,6 @@ import (
"fmt"
"math/big"
- "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state"
@@ -28,18 +27,17 @@ import (
* 6) Derive new state root
*/
type StateTransition struct {
- coinbase, receiver []byte
- msg Message
- gas, gasPrice *big.Int
- initialGas *big.Int
- value *big.Int
- data []byte
- state *state.StateDB
- block *types.Block
+ coinbase []byte
+ msg Message
+ gas, gasPrice *big.Int
+ initialGas *big.Int
+ value *big.Int
+ data []byte
+ state *state.StateDB
cb, rec, sen *state.StateObject
- Env vm.Environment
+ env vm.Environment
}
type Message interface {
@@ -69,16 +67,19 @@ func MessageGasValue(msg Message) *big.Int {
return new(big.Int).Mul(msg.Gas(), msg.GasPrice())
}
-func NewStateTransition(coinbase *state.StateObject, msg Message, state *state.StateDB, block *types.Block) *StateTransition {
- return &StateTransition{coinbase.Address(), msg.To(), msg, new(big.Int), new(big.Int).Set(msg.GasPrice()), new(big.Int), msg.Value(), msg.Data(), state, block, coinbase, nil, nil, nil}
-}
-
-func (self *StateTransition) VmEnv() vm.Environment {
- if self.Env == nil {
- self.Env = NewEnv(self.state, self.msg, self.block)
+func NewStateTransition(env vm.Environment, msg Message, coinbase *state.StateObject) *StateTransition {
+ return &StateTransition{
+ coinbase: coinbase.Address(),
+ env: env,
+ msg: msg,
+ gas: new(big.Int),
+ gasPrice: new(big.Int).Set(msg.GasPrice()),
+ initialGas: new(big.Int),
+ value: msg.Value(),
+ data: msg.Data(),
+ state: env.State(),
+ cb: coinbase,
}
-
- return self.Env
}
func (self *StateTransition) Coinbase() *state.StateObject {
@@ -183,7 +184,7 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) {
return
}
- vmenv := self.VmEnv()
+ vmenv := self.env
var ref vm.ContextRef
if MessageCreatesContract(msg) {
contract := MakeContract(msg, self.state)
diff --git a/core/vm_env.go b/core/vm_env.go
index 4e0315ff3b..624a633334 100644
--- a/core/vm_env.go
+++ b/core/vm_env.go
@@ -13,10 +13,12 @@ type VMEnv struct {
block *types.Block
msg Message
depth int
+ chain *ChainManager
}
-func NewEnv(state *state.StateDB, msg Message, block *types.Block) *VMEnv {
+func NewEnv(state *state.StateDB, chain *ChainManager, msg Message, block *types.Block) *VMEnv {
return &VMEnv{
+ chain: chain,
state: state,
block: block,
msg: msg,
@@ -25,16 +27,21 @@ func NewEnv(state *state.StateDB, msg Message, block *types.Block) *VMEnv {
func (self *VMEnv) Origin() []byte { return self.msg.From() }
func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number() }
-func (self *VMEnv) PrevHash() []byte { return self.block.ParentHash() }
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase() }
func (self *VMEnv) Time() int64 { return self.block.Time() }
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty() }
-func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit() }
func (self *VMEnv) Value() *big.Int { return self.msg.Value() }
func (self *VMEnv) State() *state.StateDB { return self.state }
func (self *VMEnv) Depth() int { return self.depth }
func (self *VMEnv) SetDepth(i int) { self.depth = i }
+func (self *VMEnv) GetHash(n uint64) []byte {
+ if block := self.chain.GetBlockByNumber(n); block != nil {
+ return block.Hash()
+ }
+
+ return nil
+}
func (self *VMEnv) AddLog(log state.Log) {
self.state.AddLog(log)
}
diff --git a/eth/backend.go b/eth/backend.go
index 36c1ac30f3..bf6c912826 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -1,11 +1,13 @@
package eth
import (
+ "fmt"
"net"
"sync"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/event"
ethlogger "github.com/ethereum/go-ethereum/logger"
@@ -19,6 +21,24 @@ const (
seedNodeAddress = "poc-7.ethdev.com:30300"
)
+type Config struct {
+ Name string
+ Version string
+ Identifier string
+ KeyStore string
+ DataDir string
+ LogFile string
+ LogLevel int
+ KeyRing string
+
+ MaxPeers int
+ Port string
+ NATType string
+ PMPGateway string
+
+ KeyManager *crypto.KeyManager
+}
+
var logger = ethlogger.NewLogger("SERV")
type Ethereum struct {
@@ -38,7 +58,7 @@ type Ethereum struct {
blockPool *BlockPool
whisper *whisper.Whisper
- server *p2p.Server
+ net *p2p.Server
eventMux *event.TypeMux
txSub event.Subscription
blockSub event.Subscription
@@ -47,6 +67,7 @@ type Ethereum struct {
keyManager *crypto.KeyManager
clientIdentity p2p.ClientIdentity
+ logger ethlogger.LogSystem
synclock sync.Mutex
syncGroup sync.WaitGroup
@@ -54,7 +75,36 @@ type Ethereum struct {
Mining bool
}
-func New(db ethutil.Database, identity p2p.ClientIdentity, keyManager *crypto.KeyManager, nat p2p.NAT, port string, maxPeers int) (*Ethereum, error) {
+func New(config *Config) (*Ethereum, error) {
+ // Boostrap database
+ logger := ethlogger.New(config.DataDir, config.LogFile, config.LogLevel)
+ db, err := ethdb.NewLDBDatabase("database")
+ if err != nil {
+ return nil, err
+ }
+
+ // Perform database sanity checks
+ d, _ := db.Get([]byte("ProtocolVersion"))
+ protov := ethutil.NewValue(d).Uint()
+ if protov != ProtocolVersion && protov != 0 {
+ return nil, fmt.Errorf("Database version mismatch. Protocol(%d / %d). `rm -rf %s`", protov, ProtocolVersion, ethutil.Config.ExecPath+"/database")
+ }
+
+ // Create new keymanager
+ var keyManager *crypto.KeyManager
+ switch config.KeyStore {
+ case "db":
+ keyManager = crypto.NewDBKeyManager(db)
+ case "file":
+ keyManager = crypto.NewFileKeyManager(config.DataDir)
+ default:
+ return nil, fmt.Errorf("unknown keystore type: %s", config.KeyStore)
+ }
+ // Initialise the keyring
+ keyManager.Init(config.KeyRing, 0, false)
+
+ // Create a new client id for this instance. This will help identifying the node on the network
+ clientId := p2p.NewSimpleClientIdentity(config.Name, config.Version, config.Identifier, keyManager.PublicKey())
saveProtocolVersion(db)
ethutil.Config.Db = db
@@ -64,9 +114,10 @@ func New(db ethutil.Database, identity p2p.ClientIdentity, keyManager *crypto.Ke
quit: make(chan bool),
db: db,
keyManager: keyManager,
- clientIdentity: identity,
+ clientIdentity: clientId,
blacklist: p2p.NewBlacklist(),
eventMux: &event.TypeMux{},
+ logger: logger,
}
eth.chainManager = core.NewChainManager(eth.EventMux())
@@ -85,17 +136,20 @@ func New(db ethutil.Database, identity p2p.ClientIdentity, keyManager *crypto.Ke
ethProto := EthProtocol(eth.txPool, eth.chainManager, eth.blockPool)
protocols := []p2p.Protocol{ethProto, eth.whisper.Protocol()}
- server := &p2p.Server{
- Identity: identity,
- MaxPeers: maxPeers,
+ nat, err := p2p.ParseNAT(config.NATType, config.PMPGateway)
+ if err != nil {
+ return nil, err
+ }
+
+ eth.net = &p2p.Server{
+ Identity: clientId,
+ MaxPeers: config.MaxPeers,
Protocols: protocols,
- ListenAddr: ":" + port,
+ ListenAddr: ":" + config.Port,
Blacklist: eth.blacklist,
NAT: nat,
}
- eth.server = server
-
return eth, nil
}
@@ -103,6 +157,10 @@ func (s *Ethereum) KeyManager() *crypto.KeyManager {
return s.keyManager
}
+func (s *Ethereum) Logger() ethlogger.LogSystem {
+ return s.logger
+}
+
func (s *Ethereum) ClientIdentity() p2p.ClientIdentity {
return s.clientIdentity
}
@@ -144,20 +202,20 @@ func (s *Ethereum) IsListening() bool {
}
func (s *Ethereum) PeerCount() int {
- return s.server.PeerCount()
+ return s.net.PeerCount()
}
func (s *Ethereum) Peers() []*p2p.Peer {
- return s.server.Peers()
+ return s.net.Peers()
}
func (s *Ethereum) MaxPeers() int {
- return s.server.MaxPeers
+ return s.net.MaxPeers
}
// Start the ethereum
func (s *Ethereum) Start(seed bool) error {
- err := s.server.Start()
+ err := s.net.Start()
if err != nil {
return err
}
@@ -191,7 +249,7 @@ func (self *Ethereum) SuggestPeer(addr string) error {
return err
}
- self.server.SuggestPeer(netaddr.IP, netaddr.Port, nil)
+ self.net.SuggestPeer(netaddr.IP, netaddr.Port, nil)
return nil
}
@@ -227,7 +285,7 @@ func (self *Ethereum) txBroadcastLoop() {
// automatically stops if unsubscribe
for obj := range self.txSub.Chan() {
event := obj.(core.TxPreEvent)
- self.server.Broadcast("eth", TxMsg, []interface{}{event.Tx.RlpData()})
+ self.net.Broadcast("eth", TxMsg, []interface{}{event.Tx.RlpData()})
}
}
@@ -236,7 +294,7 @@ func (self *Ethereum) blockBroadcastLoop() {
for obj := range self.txSub.Chan() {
switch ev := obj.(type) {
case core.NewMinedBlockEvent:
- self.server.Broadcast("eth", NewBlockMsg, ev.Block.RlpData())
+ self.net.Broadcast("eth", NewBlockMsg, ev.Block.RlpData())
}
}
}
diff --git a/ethutil/path.go b/ethutil/path.go
index cfbc389508..f64e3849e0 100644
--- a/ethutil/path.go
+++ b/ethutil/path.go
@@ -4,6 +4,7 @@ import (
"io/ioutil"
"os"
"os/user"
+ "path"
"strings"
)
@@ -58,3 +59,10 @@ func WriteFile(filePath string, content []byte) error {
return nil
}
+
+func AbsolutePath(Datadir string, filename string) string {
+ if path.IsAbs(filename) {
+ return filename
+ }
+ return path.Join(Datadir, filename)
+}
diff --git a/logger/log.go b/logger/log.go
new file mode 100644
index 0000000000..53065f870b
--- /dev/null
+++ b/logger/log.go
@@ -0,0 +1,33 @@
+package logger
+
+import (
+ "fmt"
+ "io"
+ "log"
+ "os"
+
+ "github.com/ethereum/go-ethereum/ethutil"
+)
+
+func openLogFile(datadir string, filename string) *os.File {
+ path := ethutil.AbsolutePath(datadir, filename)
+ file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
+ if err != nil {
+ panic(fmt.Sprintf("error opening log file '%s': %v", filename, err))
+ }
+ return file
+}
+
+func New(datadir string, logFile string, logLevel int) LogSystem {
+ var writer io.Writer
+ if logFile == "" {
+ writer = os.Stdout
+ } else {
+ writer = openLogFile(datadir, logFile)
+ }
+
+ sys := NewStdLogSystem(writer, log.LstdFlags, LogLevel(logLevel))
+ AddLogSystem(sys)
+
+ return sys
+}
diff --git a/p2p/client_identity.go b/p2p/client_identity.go
index bc865b63b0..f15fd01bfc 100644
--- a/p2p/client_identity.go
+++ b/p2p/client_identity.go
@@ -17,10 +17,10 @@ type SimpleClientIdentity struct {
customIdentifier string
os string
implementation string
- pubkey string
+ pubkey []byte
}
-func NewSimpleClientIdentity(clientIdentifier string, version string, customIdentifier string, pubkey string) *SimpleClientIdentity {
+func NewSimpleClientIdentity(clientIdentifier string, version string, customIdentifier string, pubkey []byte) *SimpleClientIdentity {
clientIdentity := &SimpleClientIdentity{
clientIdentifier: clientIdentifier,
version: version,
diff --git a/p2p/nat.go b/p2p/nat.go
new file mode 100644
index 0000000000..9b771c3e8c
--- /dev/null
+++ b/p2p/nat.go
@@ -0,0 +1,23 @@
+package p2p
+
+import (
+ "fmt"
+ "net"
+)
+
+func ParseNAT(natType string, gateway string) (nat NAT, err error) {
+ switch natType {
+ case "UPNP":
+ nat = UPNP()
+ case "PMP":
+ ip := net.ParseIP(gateway)
+ if ip == nil {
+ return nil, fmt.Errorf("cannot resolve PMP gateway IP %s", gateway)
+ }
+ nat = PMP(ip)
+ case "":
+ default:
+ return nil, fmt.Errorf("unrecognised NAT type '%s'", natType)
+ }
+ return
+}
diff --git a/core/dagger.go b/pow/dagger/dagger.go
similarity index 99%
rename from core/dagger.go
rename to pow/dagger/dagger.go
index 3039d89959..9ac0004433 100644
--- a/core/dagger.go
+++ b/pow/dagger/dagger.go
@@ -1,4 +1,4 @@
-package core
+package dagger
import (
"hash"
diff --git a/core/dagger_test.go b/pow/dagger/dagger_test.go
similarity index 96%
rename from core/dagger_test.go
rename to pow/dagger/dagger_test.go
index e80064e6bf..f3a71d1eb4 100644
--- a/core/dagger_test.go
+++ b/pow/dagger/dagger_test.go
@@ -1,4 +1,4 @@
-package core
+package dagger
import (
"math/big"
diff --git a/state/manifest.go b/state/manifest.go
index 21cd04a1a9..994019a086 100644
--- a/state/manifest.go
+++ b/state/manifest.go
@@ -30,6 +30,12 @@ func (self *Manifest) AddMessage(msg *Message) *Message {
return msg
}
+func (self *Manifest) SetHash(hash []byte) {
+ for _, message := range self.Messages {
+ message.Block = hash
+ }
+}
+
type Messages []*Message
type Message struct {
To, From []byte
diff --git a/tests/helper/vm.go b/tests/helper/vm.go
index aa17313b77..123003faa3 100644
--- a/tests/helper/vm.go
+++ b/tests/helper/vm.go
@@ -55,9 +55,11 @@ func (self *Env) PrevHash() []byte { return self.parent }
func (self *Env) Coinbase() []byte { return self.coinbase }
func (self *Env) Time() int64 { return self.time }
func (self *Env) Difficulty() *big.Int { return self.difficulty }
-func (self *Env) BlockHash() []byte { return nil }
func (self *Env) State() *state.StateDB { return self.state }
func (self *Env) GasLimit() *big.Int { return self.gasLimit }
+func (self *Env) GetHash(n uint64) []byte {
+ return nil
+}
func (self *Env) AddLog(log state.Log) {
self.logs = append(self.logs, log)
}
@@ -126,10 +128,9 @@ func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.
message := NewMessage(keyPair.Address(), to, data, value, gas, price)
Log.DebugDetailf("message{ to: %x, from %x, value: %v, gas: %v, price: %v }\n", message.to[:4], message.from[:4], message.value, message.gas, message.price)
- st := core.NewStateTransition(coinbase, message, statedb, nil)
vmenv := NewEnvFromMap(statedb, env, tx)
+ st := core.NewStateTransition(vmenv, message, coinbase)
vmenv.origin = keyPair.Address()
- st.Env = vmenv
ret, err := st.TransitionState()
statedb.Update(vmenv.Gas)
diff --git a/vm/context.go b/vm/context.go
index ccbadabdaa..d14df1aa77 100644
--- a/vm/context.go
+++ b/vm/context.go
@@ -5,7 +5,6 @@ import (
"math/big"
"github.com/ethereum/go-ethereum/ethutil"
- "github.com/ethereum/go-ethereum/state"
)
type ContextRef interface {
@@ -15,10 +14,9 @@ type ContextRef interface {
}
type Context struct {
- caller ContextRef
- object ContextRef
- Code []byte
- message *state.Message
+ caller ContextRef
+ object ContextRef
+ Code []byte
Gas, UsedGas, Price *big.Int
@@ -26,8 +24,8 @@ type Context struct {
}
// Create a new context for the given data items
-func NewContext(msg *state.Message, caller ContextRef, object ContextRef, code []byte, gas, price *big.Int) *Context {
- c := &Context{message: msg, caller: caller, object: object, Code: code, Args: nil}
+func NewContext(caller ContextRef, object ContextRef, code []byte, gas, price *big.Int) *Context {
+ c := &Context{caller: caller, object: object, Code: code, Args: nil}
// Gas should be a pointer so it can safely be reduced through the run
// This pointer will be off the state transition
@@ -40,13 +38,13 @@ func NewContext(msg *state.Message, caller ContextRef, object ContextRef, code [
return c
}
-func (c *Context) GetOp(x uint64) OpCode {
- return OpCode(c.GetByte(x))
+func (c *Context) GetOp(n uint64) OpCode {
+ return OpCode(c.GetByte(n))
}
-func (c *Context) GetByte(x uint64) byte {
- if x < uint64(len(c.Code)) {
- return c.Code[x]
+func (c *Context) GetByte(n uint64) byte {
+ if n < uint64(len(c.Code)) {
+ return c.Code[n]
}
return 0
diff --git a/vm/environment.go b/vm/environment.go
index 01bbd56cea..8ec13ee412 100644
--- a/vm/environment.go
+++ b/vm/environment.go
@@ -14,11 +14,10 @@ type Environment interface {
Origin() []byte
BlockNumber() *big.Int
- PrevHash() []byte
+ GetHash(n uint64) []byte
Coinbase() []byte
Time() int64
Difficulty() *big.Int
- BlockHash() []byte
GasLimit() *big.Int
Transfer(from, to Account, amount *big.Int) error
AddLog(state.Log)
@@ -31,11 +30,6 @@ type Environment interface {
Create(me ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, ContextRef)
}
-type Object interface {
- GetStorage(key *big.Int) *ethutil.Value
- SetStorage(key *big.Int, value *ethutil.Value)
-}
-
type Account interface {
SubBalance(amount *big.Int)
AddBalance(amount *big.Int)
diff --git a/vm/types.go b/vm/types.go
index ec9c7e74e6..1ea80a212d 100644
--- a/vm/types.go
+++ b/vm/types.go
@@ -59,7 +59,7 @@ const (
const (
// 0x40 range - block operations
- PREVHASH OpCode = 0x40 + iota
+ BLOCKHASH OpCode = 0x40 + iota
COINBASE
TIMESTAMP
NUMBER
@@ -216,7 +216,7 @@ var opCodeToString = map[OpCode]string{
GASPRICE: "TXGASPRICE",
// 0x40 range - block operations
- PREVHASH: "PREVHASH",
+ BLOCKHASH: "BLOCKHASH",
COINBASE: "COINBASE",
TIMESTAMP: "TIMESTAMP",
NUMBER: "NUMBER",
diff --git a/vm/vm_debug.go b/vm/vm_debug.go
index 6ad385fd0c..92e4154e4f 100644
--- a/vm/vm_debug.go
+++ b/vm/vm_debug.go
@@ -42,12 +42,12 @@ func (self *DebugVm) Run(me, caller ContextRef, code []byte, value, gas, price *
msg := self.env.State().Manifest().AddMessage(&state.Message{
To: me.Address(), From: caller.Address(),
- Input: callData,
- Origin: self.env.Origin(),
- Block: self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
+ Input: callData,
+ Origin: self.env.Origin(),
+ Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
Value: value,
})
- context := NewContext(msg, caller, me, code, gas, price)
+ context := NewContext(caller, me, code, gas, price)
if self.Recoverable {
// Recover from any require exception
@@ -83,7 +83,7 @@ func (self *DebugVm) Run(me, caller ContextRef, code []byte, value, gas, price *
jump = func(from uint64, to *big.Int) {
p := to.Uint64()
- nop := OpCode(context.GetOp(p))
+ nop := context.GetOp(p)
if !destinations.Has(p) {
panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p))
}
@@ -516,12 +516,15 @@ func (self *DebugVm) Run(me, caller ContextRef, code []byte, value, gas, price *
self.Printf(" => %v", context.Price)
// 0x40 range
- case PREVHASH:
- prevHash := self.env.PrevHash()
+ case BLOCKHASH:
+ num := stack.Pop()
+ if num.Cmp(new(big.Int).Sub(self.env.BlockNumber(), ethutil.Big256)) < 0 {
+ stack.Push(ethutil.Big0)
+ } else {
+ stack.Push(ethutil.BigD(self.env.GetHash(num.Uint64())))
+ }
- stack.Push(ethutil.BigD(prevHash))
-
- self.Printf(" => 0x%x", prevHash)
+ self.Printf(" => 0x%x", stack.Peek().Bytes())
case COINBASE:
coinbase := self.env.Coinbase()
@@ -614,7 +617,7 @@ func (self *DebugVm) Run(me, caller ContextRef, code []byte, value, gas, price *
val, loc := stack.Popn()
statedb.SetState(context.Address(), loc.Bytes(), val)
- context.message.AddStorageChange(loc.Bytes())
+ msg.AddStorageChange(loc.Bytes())
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
case JUMP:
diff --git a/xeth/pipe.go b/xeth/pipe.go
index cae6ee1dec..05cefd8ad2 100644
--- a/xeth/pipe.go
+++ b/xeth/pipe.go
@@ -87,7 +87,7 @@ func (self *XEth) ExecuteObject(object *Object, data []byte, value, gas, price *
self.Vm.State = self.World().State().Copy()
- vmenv := NewEnv(self.Vm.State, block, value.BigInt(), initiator.Address())
+ vmenv := NewEnv(self.chainManager, self.Vm.State, block, value.BigInt(), initiator.Address())
return vmenv.Call(initiator, object.Address(), data, gas.BigInt(), price.BigInt(), value.BigInt())
}
diff --git a/xeth/vm_env.go b/xeth/vm_env.go
index d2a21afd5d..1470b9eaa5 100644
--- a/xeth/vm_env.go
+++ b/xeth/vm_env.go
@@ -10,6 +10,7 @@ import (
)
type VMEnv struct {
+ chain *core.ChainManager
state *state.StateDB
block *types.Block
value *big.Int
@@ -18,7 +19,7 @@ type VMEnv struct {
depth int
}
-func NewEnv(state *state.StateDB, block *types.Block, value *big.Int, sender []byte) *VMEnv {
+func NewEnv(chain *core.ChainManager, state *state.StateDB, block *types.Block, value *big.Int, sender []byte) *VMEnv {
return &VMEnv{
state: state,
block: block,
@@ -33,12 +34,18 @@ func (self *VMEnv) PrevHash() []byte { return self.block.ParentHash() }
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase() }
func (self *VMEnv) Time() int64 { return self.block.Time() }
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty() }
-func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit() }
func (self *VMEnv) Value() *big.Int { return self.value }
func (self *VMEnv) State() *state.StateDB { return self.state }
func (self *VMEnv) Depth() int { return self.depth }
func (self *VMEnv) SetDepth(i int) { self.depth = i }
+func (self *VMEnv) GetHash(n uint64) []byte {
+ if block := self.chain.GetBlockByNumber(n); block != nil {
+ return block.Hash()
+ }
+
+ return nil
+}
func (self *VMEnv) AddLog(log state.Log) {
self.state.AddLog(log)
}