Merge remote-tracking branch 'upstream/poc8' into kademlia

This commit is contained in:
zelig 2015-01-05 16:10:56 +00:00
commit 6dd253f564
342 changed files with 17150 additions and 5180 deletions

View file

@ -1,6 +1,6 @@
language: go
go:
- 1.3
- tip
before_install:
- sudo add-apt-repository ppa:ubuntu-sdk-team/ppa -y
- sudo apt-get update -qq
@ -8,10 +8,10 @@ before_install:
install:
- go get code.google.com/p/go.tools/cmd/goimports
- go get github.com/golang/lint/golint
# - go get code.google.com/p/go.tools/cmd/vet
- go get code.google.com/p/go.tools/cmd/cover
# - go get golang.org/x/tools/cmd/vet
- if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi
- go get github.com/mattn/goveralls
- ./install_deps.sh
- ETH_DEPS=$(go list -f '{{.Imports}} {{.TestImports}} {{.XTestImports}}' github.com/ethereum/go-ethereum/... | sed -e 's/\[//g' | sed -e 's/\]//g' | sed -e 's/C //g'); if [ "$ETH_DEPS" ]; then go get $ETH_DEPS; fi
before_script:
- gofmt -l -w .
- goimports -l -w .
@ -19,7 +19,7 @@ before_script:
# - go vet ./...
# - go test -race ./...
script:
- ./gocoverage.sh && goveralls -coverprofile=profile.cov -service=travis-ci -repotoken $COVERALLS_TOKEN
- ./gocoverage.sh
env:
- secure: "U2U1AmkU4NJBgKR/uUAebQY87cNL0+1JHjnLOmmXwxYYyj5ralWb1aSuSH3qSXiT93qLBmtaUkuv9fberHVqrbAeVlztVdUsKAq7JMQH+M99iFkC9UiRMqHmtjWJ0ok4COD1sRYixxi21wb/JrMe3M1iL4QJVS61iltjHhVdM64="

View file

@ -25,14 +25,14 @@ RUN apt-get install -y qtbase5-private-dev qtdeclarative5-private-dev libqt5open
## Fetch and install serpent-go
RUN go get -v -d github.com/ethereum/serpent-go
WORKDIR $GOPATH/src/github.com/ethereum/serpent-go
RUN git checkout master
# RUN git checkout master
RUN git submodule update --init
RUN go install -v
# Fetch and install go-ethereum
RUN go get -v -d github.com/ethereum/go-ethereum/...
WORKDIR $GOPATH/src/github.com/ethereum/go-ethereum
RUN git checkout poc8
# RUN git checkout develop
RUN ETH_DEPS=$(go list -f '{{.Imports}} {{.TestImports}} {{.XTestImports}}' github.com/ethereum/go-ethereum/... | sed -e 's/\[//g' | sed -e 's/\]//g' | sed -e 's/C //g'); if [ "$ETH_DEPS" ]; then go get $ETH_DEPS; fi
RUN go install -v ./cmd/ethereum

View file

@ -9,10 +9,11 @@ Ethereum
[![Build
Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20master%20branch)](http://build.ethdev.com:8010/builders/Linux%20Go%20master%20branch/builds/-1) master [![Build
Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20develop%20branch)](http://build.ethdev.com:8010/builders/Linux%20Go%20develop%20branch/builds/-1) develop
[![Coverage Status](https://coveralls.io/repos/ethereum/go-ethereum/badge.png?branch=tests)](https://coveralls.io/r/ethereum/go-ethereum?branch=tests) tests
Ethereum Go Client © 2014 Jeffrey Wilcke.
Current state: Proof of Concept 0.7
Current state: Proof of Concept 0.8
Ethereum is currently in its testing phase.

Binary file not shown.

Binary file not shown.

BIN
_data/invalid1 Executable file

Binary file not shown.

BIN
_data/valid1 Executable file

Binary file not shown.

BIN
_data/valid2 Executable file

Binary file not shown.

BIN
_data/valid3 Executable file

Binary file not shown.

BIN
_data/valid4 Executable file

Binary file not shown.

View file

@ -58,6 +58,7 @@ var (
DumpHash string
DumpNumber int
VmType int
ImportChain string
)
// flags specific to cli client
@ -87,7 +88,7 @@ func Init() {
flag.StringVar(&OutboundPort, "port", "30303", "listening port")
flag.StringVar(&NatType, "nat", "", "NAT support (UPNP|PMP) (none)")
flag.StringVar(&PMPGateway, "pmp", "", "Gateway IP for PMP")
flag.IntVar(&MaxPeer, "maxpeer", 10, "maximum desired peers")
flag.IntVar(&MaxPeer, "maxpeer", 30, "maximum desired peers")
flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on")
flag.BoolVar(&StartRpc, "rpc", false, "start rpc server")
flag.BoolVar(&StartWebSockets, "ws", false, "start websocket server")
@ -104,6 +105,7 @@ func Init() {
flag.BoolVar(&DiffTool, "difftool", false, "creates output for diff'ing. Sets LogLevel=0")
flag.StringVar(&DiffType, "diff", "all", "sets the level of diff output [vm, all]. Has no effect if difftool=false")
flag.BoolVar(&ShowGenesis, "genesis", false, "Dump the genesis block")
flag.StringVar(&ImportChain, "chain", "", "Imports fiven chain")
flag.BoolVar(&Dump, "dump", false, "output the ethereum state in JSON format. Sub args [number, hash]")
flag.StringVar(&DumpHash, "hash", "", "specify arg in hex")

View file

@ -21,16 +21,18 @@ import (
"fmt"
"os"
"runtime"
"time"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger"
)
const (
ClientIdentifier = "Ethereum(G)"
Version = "0.7.9"
Version = "0.8.0"
)
var clilogger = logger.NewLogger("CLI")
@ -38,40 +40,35 @@ var clilogger = logger.NewLogger("CLI")
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
defer func() {
logger.Flush()
}()
utils.HandleInterrupt()
// precedence: code-internal flag default < config file < environment variables < command line
Init() // parsing command line
// If the difftool option is selected ignore all other log output
if DiffTool || Dump {
LogLevel = 0
}
utils.InitConfig(VmType, ConfigFile, Datadir, "ETH")
ethutil.Config.Diff = DiffTool
ethutil.Config.DiffType = DiffType
utils.InitDataDir(Datadir)
utils.InitLogging(Datadir, LogFile, LogLevel, DebugFile)
db := utils.NewDatabase()
err := utils.DBSanityCheck(db)
ethereum, err := eth.New(&eth.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 {
fmt.Println(err)
os.Exit(1)
clilogger.Fatalln(err)
}
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)
utils.KeyTasks(ethereum.KeyManager(), KeyRing, GenAddr, SecretFile, ExportDir, NonInteractive)
if Dump {
var block *types.Block
@ -93,25 +90,28 @@ func main() {
os.Exit(1)
}
// block.GetRoot() does not exist
//fmt.Printf("RLP: %x\nstate: %x\nhash: %x\n", ethutil.Rlp(block), block.GetRoot(), block.Hash())
// Leave the Println. This needs clean output for piping
fmt.Printf("%s\n", block.State().Dump())
fmt.Println(block)
os.Exit(0)
}
if ShowGenesis {
utils.ShowGenesis(ethereum)
return
}
if StartMining {
utils.StartMining(ethereum)
}
if len(ImportChain) > 0 {
start := time.Now()
err := utils.ImportChain(ethereum, ImportChain)
if err != nil {
clilogger.Infoln(err)
}
clilogger.Infoln("import done in", time.Since(start))
return
}
// better reworked as cases
if StartJsConsole {
InitJsConsole(ethereum)
@ -131,5 +131,4 @@ func main() {
// this blocks the thread
ethereum.WaitForShutdown()
logger.Flush()
}

View file

@ -86,11 +86,6 @@ func (self *JSRepl) Stop() {
}
func (self *JSRepl) parseInput(code string) {
defer func() {
if r := recover(); r != nil {
fmt.Println("[native] error", r)
}
}()
value, err := self.re.Run(code)
if err != nil {

5
cmd/ethtest/.bowerrc Normal file
View file

@ -0,0 +1,5 @@
{
"directory": "example/js/",
"cwd": "./",
"analytics": false
}

12
cmd/ethtest/.editorconfig Normal file
View file

@ -0,0 +1,12 @@
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

18
cmd/ethtest/.gitignore vendored Normal file
View file

@ -0,0 +1,18 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
# git config --global core.excludesfile ~/.gitignore_global
*.swp
/tmp
*/**/*un~
*un~
.DS_Store
*/**/.DS_Store
ethereum/ethereum
ethereal/ethereal
example/js
node_modules
bower_components
npm-debug.log

50
cmd/ethtest/.jshintrc Normal file
View file

@ -0,0 +1,50 @@
{
"predef": [
"console",
"require",
"equal",
"test",
"testBoth",
"testWithDefault",
"raises",
"deepEqual",
"start",
"stop",
"ok",
"strictEqual",
"module",
"expect",
"reject",
"impl"
],
"esnext": true,
"proto": true,
"node" : true,
"browser" : true,
"browserify" : true,
"boss" : true,
"curly": false,
"debug": true,
"devel": true,
"eqeqeq": true,
"evil": true,
"forin": false,
"immed": false,
"laxbreak": false,
"newcap": true,
"noarg": true,
"noempty": false,
"nonew": false,
"nomen": false,
"onevar": false,
"plusplus": false,
"regexp": false,
"undef": true,
"sub": true,
"strict": false,
"white": false,
"shadow": true,
"eqnull": true
}

9
cmd/ethtest/.npmignore Normal file
View file

@ -0,0 +1,9 @@
example/js
node_modules
test
.gitignore
.editorconfig
.travis.yml
.npmignore
component.json
testling.html

11
cmd/ethtest/.travis.yml Normal file
View file

@ -0,0 +1,11 @@
language: node_js
node_js:
- "0.11"
- "0.10"
before_script:
- npm install
- npm install jshint
script:
- "jshint *.js lib"
after_script:
- npm run-script gulp

View file

@ -95,10 +95,15 @@ func RunVmTest(js string) (failed int) {
failed = 1
}
gexp := ethutil.Big(test.Gas)
if gexp.Cmp(gas) != 0 {
log.Printf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas)
if len(test.Gas) == 0 && err == nil {
log.Printf("0 gas indicates error but no error given by VM")
failed = 1
} else {
gexp := ethutil.Big(test.Gas)
if gexp.Cmp(gas) != 0 {
log.Printf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas)
failed = 1
}
}
for addr, account := range test.Post {

View file

@ -37,8 +37,8 @@ import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/ptrie"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/trie"
"github.com/ethereum/go-ethereum/vm"
)
@ -65,7 +65,7 @@ func main() {
ethutil.ReadConfig("/tmp/evmtest", "/tmp/evm", "")
db, _ := ethdb.NewMemDatabase()
statedb := state.New(trie.New(db, ""))
statedb := state.New(ptrie.New(nil, db))
sender := statedb.NewStateObject([]byte("sender"))
receiver := statedb.NewStateObject([]byte("receiver"))
//receiver.SetCode([]byte(*code))
@ -141,24 +141,22 @@ func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error {
}
func (self *VMEnv) vm(addr, data []byte, gas, price, value *big.Int) *core.Execution {
evm := vm.New(self, vm.DebugVmTy)
return core.NewExecution(evm, addr, data, gas, price, value)
return core.NewExecution(self, addr, data, gas, price, value)
}
func (self *VMEnv) Call(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
func (self *VMEnv) Call(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
exe := self.vm(addr, data, gas, price, value)
ret, err := exe.Call(addr, caller)
self.Gas = exe.Gas
return ret, err
}
func (self *VMEnv) CallCode(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
func (self *VMEnv) CallCode(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
exe := self.vm(caller.Address(), data, gas, price, value)
return exe.Call(addr, caller)
}
func (self *VMEnv) Create(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ClosureRef) {
func (self *VMEnv) Create(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
exe := self.vm(addr, data, gas, price, value)
return exe.Create(caller)
}

View file

@ -66,7 +66,11 @@ Rectangle {
onMessages: {
// Bit of a cheat to get proper JSON
var m = JSON.parse(JSON.parse(JSON.stringify(messages)))
webview.postEvent("messages", [m, id]);
webview.postEvent("messages", id, m);
}
function onShhMessage(message, id) {
webview.postEvent("shhChanged", id, message)
}
Item {
@ -327,6 +331,33 @@ Rectangle {
require(1);
eth.uninstallFilter(data.args[0])
break;
case "shhNewFilter":
require(1);
var id = shh.watch(data.args[0], window);
postData(data._id, id);
break;
case "newIdentity":
postData(data._id, shh.newIdentity())
break
case "post":
require(1);
var params = data.args[0];
var fields = ["payload", "to", "from"];
for(var i = 0; i < fields.length; i++) {
params[fields[i]] = params[fields[i]] || "";
}
if(typeof params.payload !== "object") { params.payload = [params.payload]; } //params.payload = params.payload.join(""); }
params.topics = params.topics || [];
params.priority = params.priority || 1000;
params.ttl = params.ttl || 100;
console.log(JSON.stringify(params))
shh.post(params.payload, params.to, params.from, params.topics, params.priority, params.ttl);
break;
}
} catch(e) {
console.log(data.call + ": " + e)
@ -348,8 +379,8 @@ Rectangle {
function postData(seed, data) {
webview.experimental.postMessage(JSON.stringify({data: data, _id: seed}))
}
function postEvent(event, data) {
webview.experimental.postMessage(JSON.stringify({data: data, _event: event}))
function postEvent(event, id, data) {
webview.experimental.postMessage(JSON.stringify({data: data, _id: id, _event: event}))
}
function onWatchedCb(data, id) {

View file

@ -45,7 +45,7 @@ ApplicationWindow {
// Takes care of loading all default plugins
Component.onCompleted: {
var wallet = addPlugin("./views/wallet.qml", {noAdd: true, close: false, section: "ethereum", active: true});
var browser = addPlugin("./webapp.qml", {noAdd: true, close: false, section: "ethereum", active: true});
var browser = addPlugin("./browser.qml", {noAdd: true, close: false, section: "ethereum", active: true});
root.browser = browser;
addPlugin("./views/miner.qml", {noAdd: true, close: false, section: "ethereum", active: true});
@ -787,8 +787,8 @@ ApplicationWindow {
title: "About"
minimumWidth: 350
maximumWidth: 350
maximumHeight: 200
minimumHeight: 200
maximumHeight: 280
minimumHeight: 280
Image {
id: aboutIcon
@ -798,7 +798,7 @@ ApplicationWindow {
smooth: true
source: "../facet.png"
x: 10
y: 10
y: 30
}
Text {
@ -807,7 +807,7 @@ ApplicationWindow {
anchors.top: parent.top
anchors.topMargin: 30
font.pointSize: 12
text: "<h2>Mist (0.6.5)</h2><h4>Amalthea</h4><br><h3>Development</h3>Jeffrey Wilcke<br>Viktor Trón<br><h3>Building</h3>Maran Hidskes"
text: "<h2>Mist (0.7.10)</h2><br><h3>Development</h3>Jeffrey Wilcke<br>Viktor Trón<br>Felix Lange<br>Taylor Gerring<br>Daniel Nagy<br><h3>UX</h3>Alex van de Sande<br>"
}
}
@ -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"})
*/
}
}

View file

@ -20,7 +20,7 @@ Rectangle {
}
function setBalance() {
balance.text = "<b>Balance</b>: " + eth.numberToHuman(eth.balanceAt(eth.key().address))
//balance.text = "<b>Balance</b>: " + eth.numberToHuman(eth.balanceAt(eth.key().address))
if(menuItem)
menuItem.secondaryTitle = eth.numberToHuman(eth.balanceAt(eth.key().address))
}

View file

@ -9,7 +9,7 @@ import Ethereum 1.0
Rectangle {
id: root
property var title: "Whisper"
property var title: "Whisper Traffic"
property var iconSource: "../facet.png"
property var menuItem
@ -21,10 +21,22 @@ Rectangle {
identity = shh.newIdentity()
console.log("New identity:", identity)
var t = shh.watch({topics: ["chat"]})
var t = shh.watch({}, root)
}
function onShhMessage(message, i) {
whisperModel.insert(0, {from: message.from, payload: eth.toAscii(message.payload)})
}
RowLayout {
id: input
anchors {
left: parent.left
leftMargin: 20
top: parent.top
topMargin: 20
}
TextField {
id: to
placeholderText: "To"
@ -40,8 +52,25 @@ Rectangle {
Button {
text: "Send"
onClicked: {
shh.post(eth.toHex(data.text), "", identity, topics.text.split(","), 500, 50)
shh.post([eth.toHex(data.text)], "", identity, topics.text.split(","), 500, 50)
}
}
}
TableView {
id: txTableView
anchors {
top: input.bottom
topMargin: 10
bottom: parent.bottom
left: parent.left
right: parent.right
}
TableViewColumn{ id: fromRole; role: "from" ; title: "From"; width: 300 }
TableViewColumn{ role: "payload" ; title: "Payload" ; width: parent.width - fromRole.width - 2 }
model: ListModel {
id: whisperModel
}
}
}

View file

@ -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)
}

View file

@ -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() {
@ -309,9 +309,11 @@ func (d *Debugger) halting(pc int, op vm.OpCode, mem *vm.Memory, stack *vm.Stack
d.win.Root().Call("setStack", val.String())
}
stateObject.EachStorage(func(key string, node *ethutil.Value) {
d.win.Root().Call("setStorage", storeVal{fmt.Sprintf("% x", key), fmt.Sprintf("% x", node.Str())})
})
it := stateObject.Trie().Iterator()
for it.Next() {
d.win.Root().Call("setStorage", storeVal{fmt.Sprintf("% x", it.Key), fmt.Sprintf("% x", it.Value)})
}
stackFrameAt := new(big.Int).SetBytes(mem.Get(0, 32))
psize := mem.Len() - int(new(big.Int).SetBytes(mem.Get(0, 32)).Uint64())

View file

@ -106,7 +106,7 @@ func Init() {
flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file (db)")
flag.StringVar(&OutboundPort, "port", "30303", "listening port")
flag.BoolVar(&UseUPnP, "upnp", true, "enable UPnP support")
flag.IntVar(&MaxPeer, "maxpeer", 10, "maximum desired peers")
flag.IntVar(&MaxPeer, "maxpeer", 30, "maximum desired peers")
flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on")
flag.BoolVar(&StartRpc, "rpc", false, "start rpc server")
flag.BoolVar(&StartWebSockets, "ws", false, "start websocket server")

View file

@ -43,38 +43,6 @@ import (
"gopkg.in/qml.v1"
)
/*
func LoadExtension(path string) (uintptr, error) {
lib, err := ffi.NewLibrary(path)
if err != nil {
return 0, err
}
so, err := lib.Fct("sharedObject", ffi.Pointer, nil)
if err != nil {
return 0, err
}
ptr := so()
err = lib.Close()
if err != nil {
return 0, err
}
return ptr.Interface().(uintptr), nil
}
*/
/*
vec, errr := LoadExtension("/Users/jeffrey/Desktop/build-libqmltest-Desktop_Qt_5_2_1_clang_64bit-Debug/liblibqmltest_debug.dylib")
fmt.Printf("Fetched vec with addr: %#x\n", vec)
if errr != nil {
fmt.Println(errr)
} else {
context.SetVar("vec", (unsafe.Pointer)(vec))
}
*/
var guilogger = logger.NewLogger("GUI")
type Gui struct {
@ -104,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
@ -145,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"))
@ -253,7 +220,7 @@ func (gui *Gui) setInitialChain(ancientBlocks bool) {
sBlk := gui.eth.ChainManager().LastBlockHash()
blk := gui.eth.ChainManager().GetBlock(sBlk)
for ; blk != nil; blk = gui.eth.ChainManager().GetBlock(sBlk) {
sBlk = blk.PrevHash
sBlk = blk.ParentHash()
gui.processBlock(blk, true)
}
@ -263,35 +230,33 @@ func (gui *Gui) loadAddressBook() {
view := gui.getObjectByName("infoView")
nameReg := gui.pipe.World().Config().Get("NameReg")
if nameReg != nil {
nameReg.EachStorage(func(name string, value *ethutil.Value) {
if name[0] != 0 {
value.Decode()
view.Call("addAddress", struct{ Name, Address string }{name, ethutil.Bytes2Hex(value.Bytes())})
it := nameReg.Trie().Iterator()
for it.Next() {
if it.Key[0] != 0 {
view.Call("addAddress", struct{ Name, Address string }{string(it.Key), ethutil.Bytes2Hex(it.Value)})
}
})
}
}
}
func (self *Gui) loadMergedMiningOptions() {
view := self.getObjectByName("mergedMiningModel")
nameReg := self.pipe.World().Config().Get("MergeMining")
if nameReg != nil {
mergeMining := self.pipe.World().Config().Get("MergeMining")
if mergeMining != nil {
i := 0
nameReg.EachStorage(func(name string, value *ethutil.Value) {
if name[0] != 0 {
value.Decode()
it := mergeMining.Trie().Iterator()
for it.Next() {
view.Call("addMergedMiningOption", struct {
Checked bool
Name, Address string
Id, ItemId int
}{false, string(it.Key), ethutil.Bytes2Hex(it.Value), 0, i})
view.Call("addMergedMiningOption", struct {
Checked bool
Name, Address string
Id, ItemId int
}{false, name, ethutil.Bytes2Hex(value.Bytes()), 0, i})
i++
i++
}
})
}
}
}
@ -354,7 +319,7 @@ func (gui *Gui) readPreviousTransactions() {
}
func (gui *Gui) processBlock(block *types.Block, initial bool) {
name := strings.Trim(gui.pipe.World().Config().Get("NameReg").Storage(block.Coinbase).Str(), "\x00")
name := strings.Trim(gui.pipe.World().Config().Get("NameReg").Storage(block.Coinbase()).Str(), "\x00")
b := xeth.NewJSBlock(block)
b.Name = name
@ -432,7 +397,7 @@ func (gui *Gui) update() {
switch ev := ev.(type) {
case core.NewBlockEvent:
gui.processBlock(ev.Block, false)
if bytes.Compare(ev.Block.Coinbase, gui.address()) == 0 {
if bytes.Compare(ev.Block.Coinbase(), gui.address()) == 0 {
gui.setWalletValue(gui.eth.ChainManager().State().GetBalance(gui.address()), nil)
}
@ -470,7 +435,7 @@ func (gui *Gui) update() {
case <-peerUpdateTicker.C:
gui.setPeerInfo()
case <-generalUpdateTicker.C:
statusText := "#" + gui.eth.ChainManager().CurrentBlock().Number.String()
statusText := "#" + gui.eth.ChainManager().CurrentBlock().Number().String()
lastBlockLabel.Set("text", statusText)
miningLabel.Set("text", "Mining @ "+strconv.FormatInt(gui.uiLib.miner.GetPow().GetHashrate(), 10)+"Khash")
@ -535,3 +500,35 @@ func (gui *Gui) privateKey() string {
func (gui *Gui) address() []byte {
return gui.eth.KeyManager().Address()
}
/*
func LoadExtension(path string) (uintptr, error) {
lib, err := ffi.NewLibrary(path)
if err != nil {
return 0, err
}
so, err := lib.Fct("sharedObject", ffi.Pointer, nil)
if err != nil {
return 0, err
}
ptr := so()
err = lib.Close()
if err != nil {
return 0, err
}
return ptr.Interface().(uintptr), nil
}
*/
/*
vec, errr := LoadExtension("/Users/jeffrey/Desktop/build-libqmltest-Desktop_Qt_5_2_1_clang_64bit-Debug/liblibqmltest_debug.dylib")
fmt.Printf("Fetched vec with addr: %#x\n", vec)
if errr != nil {
fmt.Println(errr)
} else {
context.SetVar("vec", (unsafe.Pointer)(vec))
}
*/

View file

@ -139,7 +139,7 @@ func (app *HtmlApplication) Window() *qml.Window {
}
func (app *HtmlApplication) NewBlock(block *types.Block) {
b := &xeth.JSBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Bytes2Hex(block.Hash())}
b := &xeth.JSBlock{Number: int(block.NumberU64()), Hash: ethutil.Bytes2Hex(block.Hash())}
app.webView.Call("onNewBlockCb", b)
}

View file

@ -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.9"
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(&eth.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()

View file

@ -66,7 +66,7 @@ func (app *QmlApplication) NewWatcher(quitChan chan bool) {
// Events
func (app *QmlApplication) NewBlock(block *types.Block) {
pblock := &xeth.JSBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Bytes2Hex(block.Hash())}
pblock := &xeth.JSBlock{Number: int(block.NumberU64()), Hash: ethutil.Bytes2Hex(block.Hash())}
app.win.Call("onNewBlockCb", pblock)
}

View file

@ -225,6 +225,83 @@ func (self *UiLib) StartDebugger() {
dbWindow.Show()
}
func (self *UiLib) Transact(params map[string]interface{}) (string, error) {
object := mapToTxParams(params)
return self.JSXEth.Transact(
object["from"],
object["to"],
object["value"],
object["gas"],
object["gasPrice"],
object["data"],
)
}
func (self *UiLib) Compile(code string) (string, error) {
bcode, err := ethutil.Compile(code, false)
if err != nil {
return err.Error(), err
}
return ethutil.Bytes2Hex(bcode), err
}
func (self *UiLib) Call(params map[string]interface{}) (string, error) {
object := mapToTxParams(params)
return self.JSXEth.Execute(
object["to"],
object["value"],
object["gas"],
object["gasPrice"],
object["data"],
)
}
func (self *UiLib) AddLocalTransaction(to, data, gas, gasPrice, value string) int {
return self.miner.AddLocalTx(&miner.LocalTx{
To: ethutil.Hex2Bytes(to),
Data: ethutil.Hex2Bytes(data),
Gas: gas,
GasPrice: gasPrice,
Value: value,
}) - 1
}
func (self *UiLib) RemoveLocalTransaction(id int) {
self.miner.RemoveLocalTx(id)
}
func (self *UiLib) SetGasPrice(price string) {
self.miner.MinAcceptedGasPrice = ethutil.Big(price)
}
func (self *UiLib) ToggleMining() bool {
if !self.miner.Mining() {
self.miner.Start()
return true
} else {
self.miner.Stop()
return false
}
}
func (self *UiLib) ToHex(data string) string {
return "0x" + ethutil.Bytes2Hex([]byte(data))
}
func (self *UiLib) ToAscii(data string) string {
start := 0
if len(data) > 1 && data[0:2] == "0x" {
start = 2
}
return string(ethutil.Hex2Bytes(data[start:]))
}
/// Ethereum filter methods
func (self *UiLib) NewFilter(object map[string]interface{}) (id int) {
filter := qt.NewFilterFromMap(object, self.eth)
filter.MessageCallback = func(messages state.Messages) {
@ -312,80 +389,3 @@ func mapToTxParams(object map[string]interface{}) map[string]string {
return conv
}
func (self *UiLib) Transact(params map[string]interface{}) (string, error) {
object := mapToTxParams(params)
return self.JSXEth.Transact(
object["from"],
object["to"],
object["value"],
object["gas"],
object["gasPrice"],
object["data"],
)
}
func (self *UiLib) Compile(code string) (string, error) {
bcode, err := ethutil.Compile(code, false)
if err != nil {
return err.Error(), err
}
return ethutil.Bytes2Hex(bcode), err
}
func (self *UiLib) Call(params map[string]interface{}) (string, error) {
object := mapToTxParams(params)
return self.JSXEth.Execute(
object["to"],
object["value"],
object["gas"],
object["gasPrice"],
object["data"],
)
}
func (self *UiLib) AddLocalTransaction(to, data, gas, gasPrice, value string) int {
return self.miner.AddLocalTx(&miner.LocalTx{
To: ethutil.Hex2Bytes(to),
Data: ethutil.Hex2Bytes(data),
Gas: gas,
GasPrice: gasPrice,
Value: value,
}) - 1
}
func (self *UiLib) RemoveLocalTransaction(id int) {
self.miner.RemoveLocalTx(id)
}
func (self *UiLib) SetGasPrice(price string) {
self.miner.MinAcceptedGasPrice = ethutil.Big(price)
}
func (self *UiLib) ToggleMining() bool {
if !self.miner.Mining() {
self.miner.Start()
return true
} else {
self.miner.Stop()
return false
}
}
func (self *UiLib) ToHex(data string) string {
return "0x" + ethutil.Bytes2Hex([]byte(data))
}
/*
// XXX Refactor me & MOVE
func (self *Ethereum) InstallFilter(filter *core.Filter) (id int) {
return self.filterManager.InstallFilter(filter)
}
func (self *Ethereum) UninstallFilter(id int) { self.filterManager.UninstallFilter(id) }
func (self *Ethereum) GetFilter(id int) *core.Filter { return self.filterManager.GetFilter(id) }
*/

View file

@ -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 {}
}

View file

@ -2,9 +2,6 @@ package utils
import (
"fmt"
"io"
"log"
"net"
"os"
"os/signal"
"path"
@ -13,13 +10,13 @@ import (
"runtime"
"bitbucket.org/kardianos/osext"
"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"
)
@ -50,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))
@ -74,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) {
@ -100,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
@ -136,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)
@ -182,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
@ -325,9 +232,9 @@ func BlockDo(ethereum *eth.Ethereum, hash []byte) error {
return fmt.Errorf("unknown block %x", hash)
}
parent := ethereum.ChainManager().GetBlock(block.PrevHash)
parent := ethereum.ChainManager().GetBlock(block.ParentHash())
_, err := ethereum.BlockManager().TransitionState(parent.State(), parent, block)
_, err := ethereum.BlockProcessor().TransitionState(parent.State(), parent, block)
if err != nil {
return err
}
@ -335,3 +242,25 @@ func BlockDo(ethereum *eth.Ethereum, hash []byte) error {
return nil
}
func ImportChain(ethereum *eth.Ethereum, fn string) error {
clilogger.Infof("importing chain '%s'\n", fn)
fh, err := os.OpenFile(fn, os.O_RDONLY, os.ModePerm)
if err != nil {
return err
}
defer fh.Close()
var chain types.Blocks
if err := rlp.Decode(fh, &chain); err != nil {
return err
}
ethereum.ChainManager().Reset()
if err := ethereum.ChainManager().InsertChain(chain); err != nil {
return err
}
clilogger.Infof("imported %d blocks\n", len(chain))
return nil
}

View file

@ -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,
@ -30,17 +32,23 @@ func NewEnv(state *state.StateDB, block *types.Block, transactor []byte, value *
}
func (self *VMEnv) Origin() []byte { return self.transactor }
func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number }
func (self *VMEnv) PrevHash() []byte { return self.block.PrevHash }
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) 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) 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) GasLimit() *big.Int { return self.block.GasLimit }
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)
}
@ -52,19 +60,19 @@ func (self *VMEnv) vm(addr, data []byte, gas, price, value *big.Int) *core.Execu
return core.NewExecution(self, addr, data, gas, price, value)
}
func (self *VMEnv) Call(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
func (self *VMEnv) Call(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
exe := self.vm(addr, data, gas, price, value)
ret, err := exe.Call(addr, caller)
self.Gas = exe.Gas
return ret, err
}
func (self *VMEnv) CallCode(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
func (self *VMEnv) CallCode(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
exe := self.vm(caller.Address(), data, gas, price, value)
return exe.Call(addr, caller)
}
func (self *VMEnv) Create(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ClosureRef) {
func (self *VMEnv) Create(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
exe := self.vm(addr, data, gas, price, value)
return exe.Create(caller)
}

View file

@ -3,10 +3,13 @@ package utils
import (
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/websocket"
"github.com/ethereum/go-ethereum/xeth"
)
var wslogger = logger.NewLogger("WS")
func args(v ...interface{}) []interface{} {
return v
}
@ -106,6 +109,8 @@ func (self *WebSocketServer) Serv() {
}
func StartWebSockets(eth *eth.Ethereum) {
wslogger.Infoln("Starting WebSockets")
sock := NewWebSocketServer(eth)
go sock.Serv()
}

View file

@ -6,7 +6,6 @@ import (
"fmt"
"math/big"
"sync"
"time"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
@ -17,24 +16,13 @@ import (
"github.com/ethereum/go-ethereum/pow"
"github.com/ethereum/go-ethereum/pow/ezp"
"github.com/ethereum/go-ethereum/state"
"gopkg.in/fatih/set.v0"
)
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
BlockProcessor() *BlockProcessor
ChainManager() *ChainManager
TxPool() *TxPool
PeerCount() int
@ -47,7 +35,7 @@ type EthManager interface {
EventMux() *event.TypeMux
}
type BlockManager struct {
type BlockProcessor struct {
// Mutex for locking the block processor. Blocks can only be handled one at a time
mutex sync.Mutex
// Canonical block chain
@ -69,8 +57,8 @@ type BlockManager struct {
eventMux *event.TypeMux
}
func NewBlockManager(txpool *TxPool, chainManager *ChainManager, eventMux *event.TypeMux) *BlockManager {
sm := &BlockManager{
func NewBlockProcessor(txpool *TxPool, chainManager *ChainManager, eventMux *event.TypeMux) *BlockProcessor {
sm := &BlockProcessor{
mem: make(map[string]*big.Int),
Pow: ezp.New(),
bc: chainManager,
@ -81,11 +69,11 @@ func NewBlockManager(txpool *TxPool, chainManager *ChainManager, eventMux *event
return sm
}
func (sm *BlockManager) TransitionState(statedb *state.StateDB, parent, block *types.Block) (receipts types.Receipts, err error) {
coinbase := statedb.GetOrNewStateObject(block.Coinbase)
coinbase.SetGasPool(block.CalcGasLimit(parent))
func (sm *BlockProcessor) TransitionState(statedb *state.StateDB, parent, block *types.Block) (receipts types.Receipts, err error) {
coinbase := statedb.GetOrNewStateObject(block.Header().Coinbase)
coinbase.SetGasPool(CalcGasLimit(parent, block))
// Process the transactions on to current block
// Process the transactions on to parent state
receipts, _, _, _, err = sm.ApplyTransactions(coinbase, statedb, block, block.Transactions(), false)
if err != nil {
return nil, err
@ -94,7 +82,7 @@ func (sm *BlockManager) TransitionState(statedb *state.StateDB, parent, block *t
return receipts, nil
}
func (self *BlockManager) ApplyTransactions(coinbase *state.StateObject, state *state.StateDB, block *types.Block, txs types.Transactions, transientProcess bool) (types.Receipts, types.Transactions, types.Transactions, types.Transactions, error) {
func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, state *state.StateDB, block *types.Block, txs types.Transactions, transientProcess bool) (types.Receipts, types.Transactions, types.Transactions, types.Transactions, error) {
var (
receipts types.Receipts
handled, unhandled types.Transactions
@ -112,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 {
@ -127,7 +115,6 @@ done:
statelogger.Infoln(err)
erroneous = append(erroneous, tx)
err = nil
continue
}
}
@ -141,6 +128,7 @@ done:
receipt := types.NewReceipt(state.Root(), cumulative)
receipt.SetLogs(state.Logs())
receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
chainlogger.Debugln(receipt)
// Notify all subscribers
if !transientProcess {
@ -156,38 +144,33 @@ done:
}
block.Reward = cumulativeSum
block.GasUsed = totalUsedGas
block.Header().GasUsed = totalUsedGas
return receipts, handled, unhandled, erroneous, err
}
func (sm *BlockManager) Process(block *types.Block) (td *big.Int, msgs state.Messages, err error) {
func (sm *BlockProcessor) Process(block *types.Block) (td *big.Int, msgs state.Messages, err error) {
// Processing a blocks may never happen simultaneously
sm.mutex.Lock()
defer sm.mutex.Unlock()
if sm.bc.HasBlock(block.Hash()) {
return nil, nil, &KnownBlockError{block.Number, block.Hash()}
header := block.Header()
if sm.bc.HasBlock(header.Hash()) {
return nil, nil, &KnownBlockError{header.Number, header.Hash()}
}
if !sm.bc.HasBlock(block.PrevHash) {
return nil, nil, ParentError(block.PrevHash)
if !sm.bc.HasBlock(header.ParentHash) {
return nil, nil, ParentError(header.ParentHash)
}
parent := sm.bc.GetBlock(block.PrevHash)
parent := sm.bc.GetBlock(header.ParentHash)
return sm.ProcessWithParent(block, parent)
}
func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.Int, messages state.Messages, err error) {
func (sm *BlockProcessor) ProcessWithParent(block, parent *types.Block) (td *big.Int, messages state.Messages, err error) {
sm.lastAttemptedBlock = block
state := parent.State().Copy()
// Defer the Undo on the Trie. If the block processing happened
// we don't want to undo but since undo only happens on dirty
// nodes this won't happen because Commit would have been called
// before that.
defer state.Reset()
state := state.New(parent.Trie().Copy())
// Block validation
if err = sm.ValidateBlock(block, parent); err != nil {
@ -199,21 +182,24 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
return
}
header := block.Header()
rbloom := types.CreateBloom(receipts)
if bytes.Compare(rbloom, block.LogsBloom) != 0 {
if bytes.Compare(rbloom, header.Bloom) != 0 {
err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom)
return
}
txSha := types.DeriveSha(block.Transactions())
if bytes.Compare(txSha, block.TxSha) != 0 {
err = fmt.Errorf("validating transaction root. received=%x got=%x", block.TxSha, txSha)
if bytes.Compare(txSha, header.TxHash) != 0 {
err = fmt.Errorf("validating transaction root. received=%x got=%x", header.TxHash, txSha)
return
}
receiptSha := types.DeriveSha(receipts)
if bytes.Compare(receiptSha, block.ReceiptSha) != 0 {
err = fmt.Errorf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha)
if bytes.Compare(receiptSha, header.ReceiptHash) != 0 {
fmt.Println("receipts", receipts)
err = fmt.Errorf("validating receipt root. received=%x got=%x", header.ReceiptHash, receiptSha)
return
}
@ -223,8 +209,8 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
state.Update(ethutil.Big0)
if !block.State().Cmp(state) {
err = fmt.Errorf("invalid merkle root. received=%x got=%x", block.Root(), state.Root())
if !bytes.Equal(header.Root, state.Root()) {
err = fmt.Errorf("invalid merkle root. received=%x got=%x", header.Root, state.Root())
return
}
@ -233,10 +219,12 @@ 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()
chainlogger.Infof("Processed block #%d (%x...)\n", block.Number, block.Hash()[0:4])
chainlogger.Infof("processed block #%d (%x...)\n", header.Number, block.Hash()[0:4])
sm.txpool.RemoveSet(block.Transactions())
@ -246,16 +234,16 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
}
}
func (sm *BlockManager) CalculateTD(block *types.Block) (*big.Int, bool) {
func (sm *BlockProcessor) CalculateTD(block *types.Block) (*big.Int, bool) {
uncleDiff := new(big.Int)
for _, uncle := range block.Uncles {
for _, uncle := range block.Uncles() {
uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty)
}
// TD(genesis_block) = 0 and TD(B) = TD(B.parent) + sum(u.difficulty for u in B.uncles) + B.difficulty
td := new(big.Int)
td = td.Add(sm.bc.Td(), uncleDiff)
td = td.Add(td, block.Difficulty)
td = td.Add(td, block.Header().Difficulty)
// The new TD will only be accepted if the new difficulty is
// is greater than the previous.
@ -269,15 +257,15 @@ func (sm *BlockManager) CalculateTD(block *types.Block) (*big.Int, bool) {
// Validates the current block. Returns an error if the block was invalid,
// an uncle or anything that isn't on the current block chain.
// Validation validates easy over difficult (dagger takes longer time = difficult)
func (sm *BlockManager) ValidateBlock(block, parent *types.Block) error {
func (sm *BlockProcessor) ValidateBlock(block, parent *types.Block) error {
expd := CalcDifficulty(block, parent)
if expd.Cmp(block.Difficulty) < 0 {
return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd)
if expd.Cmp(block.Header().Difficulty) < 0 {
return fmt.Errorf("Difficulty check failed for block %v, %v", block.Header().Difficulty, expd)
}
diff := block.Time - parent.Time
diff := block.Header().Time - parent.Header().Time
if diff < 0 {
return ValidationError("Block timestamp less then prev block %v (%v - %v)", diff, block.Time, sm.bc.CurrentBlock().Time)
return ValidationError("Block timestamp less then prev block %v (%v - %v)", diff, block.Header().Time, sm.bc.CurrentBlock().Header().Time)
}
/* XXX
@ -289,33 +277,37 @@ func (sm *BlockManager) ValidateBlock(block, parent *types.Block) error {
// Verify the nonce of the block. Return an error if it's not valid
if !sm.Pow.Verify(block /*block.HashNoNonce(), block.Difficulty, block.Nonce*/) {
return ValidationError("Block's nonce is invalid (= %v)", ethutil.Bytes2Hex(block.Nonce))
return ValidationError("Block's nonce is invalid (= %v)", ethutil.Bytes2Hex(block.Header().Nonce))
}
return nil
}
func (sm *BlockManager) AccumelateRewards(statedb *state.StateDB, block, parent *types.Block) error {
func (sm *BlockProcessor) AccumelateRewards(statedb *state.StateDB, block, parent *types.Block) error {
reward := new(big.Int).Set(BlockReward)
knownUncles := ethutil.Set(parent.Uncles)
nonces := ethutil.NewSet(block.Nonce)
for _, uncle := range block.Uncles {
knownUncles := set.New()
for _, uncle := range parent.Uncles() {
knownUncles.Add(string(uncle.Hash()))
}
nonces := ethutil.NewSet(block.Header().Nonce)
for _, uncle := range block.Uncles() {
if nonces.Include(uncle.Nonce) {
// Error not unique
return UncleError("Uncle not unique")
}
uncleParent := sm.bc.GetBlock(uncle.PrevHash)
uncleParent := sm.bc.GetBlock(uncle.ParentHash)
if uncleParent == nil {
return UncleError(fmt.Sprintf("Uncle's parent unknown (%x)", uncle.PrevHash[0:4]))
return UncleError(fmt.Sprintf("Uncle's parent unknown (%x)", uncle.ParentHash[0:4]))
}
if uncleParent.Number.Cmp(new(big.Int).Sub(parent.Number, big.NewInt(6))) < 0 {
if uncleParent.Header().Number.Cmp(new(big.Int).Sub(parent.Header().Number, big.NewInt(6))) < 0 {
return UncleError("Uncle too old")
}
if knownUncles.Include(uncle.Hash()) {
if knownUncles.Has(string(uncle.Hash())) {
return UncleError("Uncle in chain")
}
@ -331,31 +323,31 @@ func (sm *BlockManager) AccumelateRewards(statedb *state.StateDB, block, parent
}
// Get the account associated with the coinbase
account := statedb.GetAccount(block.Coinbase)
account := statedb.GetAccount(block.Header().Coinbase)
// Reward amount of ether to the coinbase address
account.AddAmount(reward)
statedb.Manifest().AddMessage(&state.Message{
To: block.Coinbase,
Input: nil,
Origin: nil,
Block: block.Hash(), Timestamp: block.Time, Coinbase: block.Coinbase, Number: block.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),
})
return nil
}
func (sm *BlockManager) GetMessages(block *types.Block) (messages []*state.Message, err error) {
if !sm.bc.HasBlock(block.PrevHash) {
return nil, ParentError(block.PrevHash)
func (sm *BlockProcessor) GetMessages(block *types.Block) (messages []*state.Message, err error) {
if !sm.bc.HasBlock(block.Header().ParentHash) {
return nil, ParentError(block.Header().ParentHash)
}
sm.lastAttemptedBlock = block
var (
parent = sm.bc.GetBlock(block.PrevHash)
state = parent.State().Copy()
parent = sm.bc.GetBlock(block.Header().ParentHash)
state = state.New(parent.Trie().Copy())
)
defer state.Reset()

View file

@ -1,6 +1,7 @@
package core
import (
"bytes"
"fmt"
"math/big"
"sync"
@ -9,42 +10,49 @@ import (
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/state"
)
var chainlogger = logger.NewLogger("CHAIN")
func AddTestNetFunds(block *types.Block) {
for _, addr := range []string{
"51ba59315b3a95761d0863b05ccc7a7f54703d99",
"e4157b34ea9615cfbde6b4fda419828124b70c78",
"b9c015918bdaba24b4ff057a92a3873d6eb201be",
"6c386a4b26f73c802f34673f7248bb118f97424a",
"cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
"2ef47100e0787b915105fd5e3f4ff6752079d5cb",
"e6716f9544a56c530d868e4bfbacb172315bdead",
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4",
} {
codedAddr := ethutil.Hex2Bytes(addr)
account := block.State().GetAccount(codedAddr)
account.SetBalance(ethutil.Big("1606938044258990275541962092341162602522202993782792835301376")) //ethutil.BigPow(2, 200)
block.State().UpdateStateObject(account)
}
type StateQuery interface {
GetAccount(addr []byte) *state.StateObject
}
func CalcDifficulty(block, parent *types.Block) *big.Int {
diff := new(big.Int)
adjust := new(big.Int).Rsh(parent.Difficulty, 10)
if block.Time >= parent.Time+5 {
diff.Sub(parent.Difficulty, adjust)
bh, ph := block.Header(), parent.Header()
adjust := new(big.Int).Rsh(ph.Difficulty, 10)
if bh.Time >= ph.Time+5 {
diff.Sub(ph.Difficulty, adjust)
} else {
diff.Add(parent.Difficulty, adjust)
diff.Add(ph.Difficulty, adjust)
}
return diff
}
func CalcGasLimit(parent, block *types.Block) *big.Int {
if block.Number().Cmp(big.NewInt(0)) == 0 {
return ethutil.BigPow(10, 6)
}
// ((1024-1) * parent.gasLimit + (gasUsed * 6 / 5)) / 1024
previous := new(big.Int).Mul(big.NewInt(1024-1), parent.GasLimit())
current := new(big.Rat).Mul(new(big.Rat).SetInt(parent.GasUsed()), big.NewRat(6, 5))
curInt := new(big.Int).Div(current.Num(), current.Denom())
result := new(big.Int).Add(previous, curInt)
result.Div(result, big.NewInt(1024))
min := big.NewInt(125000)
return ethutil.BigMax(min, result)
}
type ChainManager struct {
//eth EthManager
processor types.BlockProcessor
@ -90,7 +98,7 @@ func (self *ChainManager) CurrentBlock() *types.Block {
func NewChainManager(mux *event.TypeMux) *ChainManager {
bc := &ChainManager{}
bc.genesisBlock = types.NewBlockFromBytes(ethutil.Encode(Genesis))
bc.genesisBlock = GenesisBlock()
bc.eventMux = mux
bc.setLastBlock()
@ -112,7 +120,7 @@ func (self *ChainManager) SetProcessor(proc types.BlockProcessor) {
}
func (self *ChainManager) State() *state.StateDB {
return self.CurrentBlock().State()
return state.New(self.CurrentBlock().Trie())
}
func (self *ChainManager) TransState() *state.StateDB {
@ -122,13 +130,11 @@ func (self *ChainManager) TransState() *state.StateDB {
func (bc *ChainManager) setLastBlock() {
data, _ := ethutil.Config.Db.Get([]byte("LastBlock"))
if len(data) != 0 {
// Prep genesis
AddTestNetFunds(bc.genesisBlock)
block := types.NewBlockFromBytes(data)
bc.currentBlock = block
var block types.Block
rlp.Decode(bytes.NewReader(data), &block)
bc.currentBlock = &block
bc.lastBlockHash = block.Hash()
bc.lastBlockNumber = block.Number.Uint64()
bc.lastBlockNumber = block.Header().Number.Uint64()
// Set the last know difficulty (might be 0x0 as initial value, Genesis)
bc.td = ethutil.BigD(ethutil.Config.Db.LastKnownTD())
@ -144,27 +150,28 @@ func (bc *ChainManager) NewBlock(coinbase []byte) *types.Block {
bc.mu.RLock()
defer bc.mu.RUnlock()
var root interface{}
hash := ZeroHash256
var root []byte
parentHash := ZeroHash256
if bc.CurrentBlock != nil {
root = bc.currentBlock.Root()
hash = bc.lastBlockHash
root = bc.currentBlock.Header().Root
parentHash = bc.lastBlockHash
}
block := types.CreateBlock(
root,
hash,
block := types.NewBlock(
parentHash,
coinbase,
root,
ethutil.BigPow(2, 32),
nil,
"")
parent := bc.currentBlock
if parent != nil {
block.Difficulty = CalcDifficulty(block, parent)
block.Number = new(big.Int).Add(bc.currentBlock.Number, ethutil.Big1)
block.GasLimit = block.CalcGasLimit(bc.currentBlock)
header := block.Header()
header.Difficulty = CalcDifficulty(block, parent)
header.Number = new(big.Int).Add(parent.Header().Number, ethutil.Big1)
header.GasLimit = CalcGasLimit(parent, block)
}
@ -175,36 +182,34 @@ func (bc *ChainManager) Reset() {
bc.mu.Lock()
defer bc.mu.Unlock()
AddTestNetFunds(bc.genesisBlock)
for block := bc.currentBlock; block != nil; block = bc.GetBlock(block.Header().ParentHash) {
ethutil.Config.Db.Delete(block.Hash())
}
bc.genesisBlock.Trie().Sync()
// Prepare the genesis block
bc.write(bc.genesisBlock)
bc.insert(bc.genesisBlock)
bc.currentBlock = bc.genesisBlock
bc.setTotalDifficulty(ethutil.Big("0"))
// Set the last know difficulty (might be 0x0 as initial value, Genesis)
bc.td = ethutil.BigD(ethutil.Config.Db.LastKnownTD())
}
func (self *ChainManager) Export() []byte {
self.mu.RLock()
defer self.mu.RUnlock()
chainlogger.Infof("exporting %v blocks...\n", self.currentBlock.Number)
chainlogger.Infof("exporting %v blocks...\n", self.currentBlock.Header().Number)
blocks := make([]*types.Block, int(self.currentBlock.Number.Int64())+1)
for block := self.currentBlock; block != nil; block = self.GetBlock(block.PrevHash) {
blocks[block.Number.Int64()] = block
blocks := make([]*types.Block, int(self.currentBlock.NumberU64())+1)
for block := self.currentBlock; block != nil; block = self.GetBlock(block.Header().ParentHash) {
blocks[block.NumberU64()] = block
}
return ethutil.Encode(blocks)
}
func (bc *ChainManager) insert(block *types.Block) {
encodedBlock := block.RlpEncode()
encodedBlock := ethutil.Encode(block)
ethutil.Config.Db.Put([]byte("LastBlock"), encodedBlock)
bc.currentBlock = block
bc.lastBlockHash = block.Hash()
@ -213,7 +218,7 @@ func (bc *ChainManager) insert(block *types.Block) {
func (bc *ChainManager) write(block *types.Block) {
bc.writeBlockInfo(block)
encodedBlock := block.RlpEncode()
encodedBlock := ethutil.Encode(block)
ethutil.Config.Db.Put(block.Hash(), encodedBlock)
}
@ -238,11 +243,11 @@ func (self *ChainManager) GetBlockHashesFromHash(hash []byte, max uint64) (chain
for i := uint64(0); i < max; i++ {
chain = append(chain, block.Hash())
if block.Number.Cmp(ethutil.Big0) <= 0 {
if block.Header().Number.Cmp(ethutil.Big0) <= 0 {
break
}
block = self.GetBlock(block.PrevHash)
block = self.GetBlock(block.Header().ParentHash)
}
return
@ -253,23 +258,28 @@ func (self *ChainManager) GetBlock(hash []byte) *types.Block {
if len(data) == 0 {
return nil
}
var block types.Block
if err := rlp.Decode(bytes.NewReader(data), &block); err != nil {
fmt.Println(err)
return nil
}
return types.NewBlockFromBytes(data)
return &block
}
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.PrevHash) {
if block.Number.Uint64() == num {
break
}
}
var block *types.Block
if block != nil && block.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
@ -281,40 +291,28 @@ func (bc *ChainManager) setTotalDifficulty(td *big.Int) {
}
func (self *ChainManager) CalcTotalDiff(block *types.Block) (*big.Int, error) {
parent := self.GetBlock(block.PrevHash)
parent := self.GetBlock(block.Header().ParentHash)
if parent == nil {
return nil, fmt.Errorf("Unable to calculate total diff without known parent %x", block.PrevHash)
return nil, fmt.Errorf("Unable to calculate total diff without known parent %x", block.Header().ParentHash)
}
parentTd := parent.BlockInfo().TD
parentTd := parent.Td
uncleDiff := new(big.Int)
for _, uncle := range block.Uncles {
for _, uncle := range block.Uncles() {
uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty)
}
td := new(big.Int)
td = td.Add(parentTd, uncleDiff)
td = td.Add(td, block.Difficulty)
td = td.Add(td, block.Header().Difficulty)
return td, nil
}
func (bc *ChainManager) BlockInfo(block *types.Block) types.BlockInfo {
bi := types.BlockInfo{}
data, _ := ethutil.Config.Db.Get(append(block.Hash(), []byte("Info")...))
bi.RlpDecode(data)
return bi
}
// Unexported method for writing extra non-essential block info to the db
func (bc *ChainManager) writeBlockInfo(block *types.Block) {
bc.lastBlockNumber++
bi := types.BlockInfo{Number: bc.lastBlockNumber, Hash: block.Hash(), Parent: block.PrevHash, TD: bc.td}
// For now we use the block hash with the words "info" appended as key
ethutil.Config.Db.Put(append(block.Hash(), []byte("Info")...), bi.RlpEncode())
}
func (bc *ChainManager) Stop() {
@ -331,24 +329,26 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
continue
}
chainlogger.Infof("block #%v process failed (%x)\n", block.Number, block.Hash()[:4])
h := block.Header()
chainlogger.Infof("block #%v process failed (%x)\n", h.Number, h.Hash()[:4])
chainlogger.Infoln(block)
chainlogger.Infoln(err)
return err
}
block.Td = td
self.mu.Lock()
{
self.write(block)
cblock := self.currentBlock
if td.Cmp(self.td) > 0 {
if block.Number.Cmp(new(big.Int).Add(self.currentBlock.Number, ethutil.Big1)) < 0 {
chainlogger.Infof("Split detected. New head #%v (%x), was #%v (%x)\n", block.Number, block.Hash()[:4], self.currentBlock.Number, self.currentBlock.Hash()[:4])
if block.Header().Number.Cmp(new(big.Int).Add(cblock.Header().Number, ethutil.Big1)) < 0 {
chainlogger.Infof("Split detected. New head #%v (%x), was #%v (%x)\n", block.Header().Number, block.Hash()[:4], cblock.Header().Number, cblock.Hash()[:4])
}
self.setTotalDifficulty(td)
self.insert(block)
self.transState = self.currentBlock.State().Copy()
self.transState = state.New(cblock.Trie().Copy())
}
}
@ -360,3 +360,8 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
return nil
}
// Satisfy state query interface
func (self *ChainManager) GetAccount(addr []byte) *state.StateObject {
return self.State().GetAccount(addr)
}

View file

@ -2,27 +2,26 @@ package core
import (
"fmt"
"os"
"path"
"reflect"
"runtime"
"strconv"
"testing"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/event"
//logpkg "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/rlp"
)
//var Logger logpkg.LogSystem
//var Log = logpkg.NewLogger("TEST")
func init() {
runtime.GOMAXPROCS(runtime.NumCPU())
//Logger = logpkg.NewStdLogSystem(os.Stdout, log.LstdFlags, logpkg.InfoLevel)
//logpkg.AddLogSystem(Logger)
ethutil.ReadConfig("/tmp/ethtest", "/tmp/ethtest", "ETH")
}
func reset() {
db, err := ethdb.NewMemDatabase()
if err != nil {
panic("Could not create mem-db, failing")
@ -30,20 +29,19 @@ func init() {
ethutil.Config.Db = db
}
func loadChain(fn string, t *testing.T) types.Blocks {
c1, err := ethutil.ReadAllFile(path.Join("..", "_data", fn))
func loadChain(fn string, t *testing.T) (types.Blocks, error) {
fh, err := os.OpenFile(path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "_data", fn), os.O_RDONLY, os.ModePerm)
if err != nil {
fmt.Println(err)
t.FailNow()
return nil, err
}
value := ethutil.NewValueFromBytes([]byte(c1))
blocks := make(types.Blocks, value.Len())
it := value.NewIterator()
for it.Next() {
blocks[it.Idx()] = types.NewBlockFromRlpValue(it.Value())
defer fh.Close()
var chain types.Blocks
if err := rlp.Decode(fh, &chain); err != nil {
return nil, err
}
return blocks
return chain, nil
}
func insertChain(done chan bool, chainMan *ChainManager, chain types.Blocks, t *testing.T) {
@ -56,11 +54,23 @@ func insertChain(done chan bool, chainMan *ChainManager, chain types.Blocks, t *
}
func TestChainInsertions(t *testing.T) {
chain1 := loadChain("chain1", t)
chain2 := loadChain("chain2", t)
reset()
chain1, err := loadChain("valid1", t)
if err != nil {
fmt.Println(err)
t.FailNow()
}
chain2, err := loadChain("valid2", t)
if err != nil {
fmt.Println(err)
t.FailNow()
}
var eventMux event.TypeMux
chainMan := NewChainManager(&eventMux)
txPool := NewTxPool(chainMan, nil, &eventMux)
txPool := NewTxPool(&eventMux)
blockMan := NewBlockManager(txPool, chainMan, &eventMux)
chainMan.SetProcessor(blockMan)
@ -73,5 +83,56 @@ func TestChainInsertions(t *testing.T) {
for i := 0; i < max; i++ {
<-done
}
fmt.Println(chainMan.CurrentBlock())
if reflect.DeepEqual(chain2[len(chain2)-1], chainMan.CurrentBlock()) {
t.Error("chain2 is canonical and shouldn't be")
}
if !reflect.DeepEqual(chain1[len(chain1)-1], chainMan.CurrentBlock()) {
t.Error("chain1 isn't canonical and should be")
}
}
func TestChainMultipleInsertions(t *testing.T) {
reset()
const max = 4
chains := make([]types.Blocks, max)
var longest int
for i := 0; i < max; i++ {
var err error
name := "valid" + strconv.Itoa(i+1)
chains[i], err = loadChain(name, t)
if len(chains[i]) >= len(chains[longest]) {
longest = i
}
fmt.Println("loaded", name, "with a length of", len(chains[i]))
if err != nil {
fmt.Println(err)
t.FailNow()
}
}
var eventMux event.TypeMux
chainMan := NewChainManager(&eventMux)
txPool := NewTxPool(&eventMux)
blockMan := NewBlockManager(txPool, chainMan, &eventMux)
chainMan.SetProcessor(blockMan)
done := make(chan bool, max)
for i, chain := range chains {
// XXX the go routine would otherwise reference the same (chain[3]) variable and fail
i := i
chain := chain
go func() {
insertChain(done, chainMan, chain, t)
fmt.Println(i, "done")
}()
}
for i := 0; i < max; i++ {
<-done
}
if !reflect.DeepEqual(chains[longest][len(chains[longest])-1], chainMan.CurrentBlock()) {
t.Error("Invalid canonical chain")
}
}

View file

@ -3,41 +3,39 @@ package core
import (
"fmt"
"math/big"
"time"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/vm"
)
type Execution struct {
vm vm.VirtualMachine
env vm.Environment
address, input []byte
Gas, price, value *big.Int
object *state.StateObject
SkipTransfer bool
}
func NewExecution(env vm.Environment, address, input []byte, gas, gasPrice, value *big.Int) *Execution {
evm := vm.New(env, vm.DebugVmTy)
return &Execution{vm: evm, address: address, input: input, Gas: gas, price: gasPrice, value: value}
return &Execution{env: env, address: address, input: input, Gas: gas, price: gasPrice, value: value}
}
func (self *Execution) Addr() []byte {
return self.address
}
func (self *Execution) Call(codeAddr []byte, caller vm.ClosureRef) ([]byte, error) {
func (self *Execution) Call(codeAddr []byte, caller vm.ContextRef) ([]byte, error) {
// Retrieve the executing code
code := self.vm.Env().State().GetCode(codeAddr)
code := self.env.State().GetCode(codeAddr)
return self.exec(code, codeAddr, caller)
}
func (self *Execution) exec(code, contextAddr []byte, caller vm.ClosureRef) (ret []byte, err error) {
env := self.vm.Env()
chainlogger.Debugf("pre state %x\n", env.State().Root())
func (self *Execution) exec(code, contextAddr []byte, caller vm.ContextRef) (ret []byte, err error) {
env := self.env
evm := vm.New(env, vm.DebugVmTy)
if self.vm.Env().Depth() == vm.MaxCallDepth {
if env.Depth() == vm.MaxCallDepth {
// Consume all gas (by not returning it) and return a depth error
return nil, vm.DepthError{}
}
@ -55,22 +53,19 @@ func (self *Execution) exec(code, contextAddr []byte, caller vm.ClosureRef) (ret
}
snapshot := env.State().Copy()
defer func() {
if /*vm.IsDepthErr(err) ||*/ vm.IsOOGErr(err) {
env.State().Set(snapshot)
}
chainlogger.Debugf("post state %x\n", env.State().Root())
}()
self.object = to
ret, err = self.vm.Run(to, caller, code, self.value, self.Gas, self.price, self.input)
start := time.Now()
ret, err = evm.Run(to, caller, code, self.value, self.Gas, self.price, self.input)
if err != nil {
env.State().Set(snapshot)
}
chainlogger.Debugf("vm took %v\n", time.Since(start))
return
}
func (self *Execution) Create(caller vm.ClosureRef) (ret []byte, err error, account *state.StateObject) {
func (self *Execution) Create(caller vm.ContextRef) (ret []byte, err error, account *state.StateObject) {
ret, err = self.exec(self.input, nil, caller)
account = self.vm.Env().State().GetStateObject(self.address)
account = self.env.State().GetStateObject(self.address)
return
}

View file

@ -76,13 +76,14 @@ func (self *Filter) SetSkip(skip int) {
// Run filters messages with the current parameters set
func (self *Filter) Find() []*state.Message {
earliestBlock := self.eth.ChainManager().CurrentBlock()
var earliestBlockNo uint64 = uint64(self.earliest)
if self.earliest == -1 {
earliestBlockNo = self.eth.ChainManager().CurrentBlock().Number.Uint64()
earliestBlockNo = earliestBlock.NumberU64()
}
var latestBlockNo uint64 = uint64(self.latest)
if self.latest == -1 {
latestBlockNo = self.eth.ChainManager().CurrentBlock().Number.Uint64()
latestBlockNo = earliestBlock.NumberU64()
}
var (
@ -93,7 +94,7 @@ func (self *Filter) Find() []*state.Message {
for i := 0; !quit && block != nil; i++ {
// Quit on latest
switch {
case block.Number.Uint64() == earliestBlockNo, block.Number.Uint64() == 0:
case block.NumberU64() == earliestBlockNo, block.NumberU64() == 0:
quit = true
case self.max <= len(messages):
break
@ -103,7 +104,7 @@ func (self *Filter) Find() []*state.Message {
// current parameters
if self.bloomFilter(block) {
// Get the messages of the block
msgs, err := self.eth.BlockManager().GetMessages(block)
msgs, err := self.eth.BlockProcessor().GetMessages(block)
if err != nil {
chainlogger.Warnln("err: filter get messages ", err)
@ -113,7 +114,7 @@ func (self *Filter) Find() []*state.Message {
messages = append(messages, self.FilterMessages(msgs)...)
}
block = self.eth.ChainManager().GetBlock(block.PrevHash)
block = self.eth.ChainManager().GetBlock(block.ParentHash())
}
skip := int(math.Min(float64(len(messages)), float64(self.skip)))
@ -176,7 +177,7 @@ func (self *Filter) bloomFilter(block *types.Block) bool {
var fromIncluded, toIncluded bool
if len(self.from) > 0 {
for _, from := range self.from {
if types.BloomLookup(block.LogsBloom, from) || bytes.Equal(block.Coinbase, from) {
if types.BloomLookup(block.Bloom(), from) || bytes.Equal(block.Coinbase(), from) {
fromIncluded = true
break
}
@ -187,7 +188,7 @@ func (self *Filter) bloomFilter(block *types.Block) bool {
if len(self.to) > 0 {
for _, to := range self.to {
if types.BloomLookup(block.LogsBloom, ethutil.U256(new(big.Int).Add(ethutil.Big1, ethutil.BigD(to))).Bytes()) || bytes.Equal(block.Coinbase, to) {
if types.BloomLookup(block.Bloom(), ethutil.U256(new(big.Int).Add(ethutil.Big1, ethutil.BigD(to))).Bytes()) || bytes.Equal(block.Coinbase(), to) {
toIncluded = true
break
}

View file

@ -3,8 +3,10 @@ package core
import (
"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"
)
/*
@ -17,36 +19,35 @@ var ZeroHash512 = make([]byte, 64)
var EmptyShaList = crypto.Sha3(ethutil.Encode([]interface{}{}))
var EmptyListRoot = crypto.Sha3(ethutil.Encode(""))
var GenesisHeader = []interface{}{
// Previous hash (none)
ZeroHash256,
// Empty uncles
EmptyShaList,
// Coinbase
ZeroHash160,
// Root state
EmptyShaList,
// tx root
EmptyListRoot,
// receipt root
EmptyListRoot,
// bloom
ZeroHash512,
// Difficulty
//ethutil.BigPow(2, 22),
big.NewInt(131072),
// Number
ethutil.Big0,
// Block upper gas bound
big.NewInt(1000000),
// Block gas used
ethutil.Big0,
// Time
ethutil.Big0,
// Extra
nil,
// Nonce
crypto.Sha3(big.NewInt(42).Bytes()),
}
func GenesisBlock() *types.Block {
genesis := types.NewBlock(ZeroHash256, ZeroHash160, nil, big.NewInt(131072), crypto.Sha3(big.NewInt(42).Bytes()), "")
genesis.Header().Number = ethutil.Big0
genesis.Header().GasLimit = big.NewInt(1000000)
genesis.Header().GasUsed = ethutil.Big0
genesis.Header().Time = 0
var Genesis = []interface{}{GenesisHeader, []interface{}{}, []interface{}{}}
genesis.SetUncles([]*types.Header{})
genesis.SetTransactions(types.Transactions{})
genesis.SetReceipts(types.Receipts{})
statedb := state.New(genesis.Trie())
for _, addr := range []string{
"51ba59315b3a95761d0863b05ccc7a7f54703d99",
"e4157b34ea9615cfbde6b4fda419828124b70c78",
"b9c015918bdaba24b4ff057a92a3873d6eb201be",
"6c386a4b26f73c802f34673f7248bb118f97424a",
"cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
"2ef47100e0787b915105fd5e3f4ff6752079d5cb",
"e6716f9544a56c530d868e4bfbacb172315bdead",
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4",
} {
codedAddr := ethutil.Hex2Bytes(addr)
account := statedb.GetAccount(codedAddr)
account.SetBalance(ethutil.Big("1606938044258990275541962092341162602522202993782792835301376")) //ethutil.BigPow(2, 200)
statedb.UpdateStateObject(account)
}
statedb.Sync()
genesis.Header().Root = statedb.Root()
return genesis
}

View file

@ -9,7 +9,7 @@ import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/wire"
"github.com/ethereum/go-ethereum/p2p"
)
// Implement our EthTest Manager
@ -54,11 +54,11 @@ func (tm *TestManager) TxPool() *TxPool {
func (tm *TestManager) EventMux() *event.TypeMux {
return tm.eventMux
}
func (tm *TestManager) Broadcast(msgType wire.MsgType, data []interface{}) {
func (tm *TestManager) Broadcast(msgType p2p.Msg, data []interface{}) {
fmt.Println("Broadcast not implemented")
}
func (tm *TestManager) ClientIdentity() wire.ClientIdentity {
func (tm *TestManager) ClientIdentity() p2p.ClientIdentity {
return nil
}
func (tm *TestManager) KeyManager() *crypto.KeyManager {

View file

@ -1 +0,0 @@
package core

View file

@ -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 {
@ -112,7 +113,7 @@ func (self *StateTransition) BuyGas() error {
sender := self.From()
if sender.Balance().Cmp(MessageGasValue(self.msg)) < 0 {
return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", MessageGasValue(self.msg), sender.Balance())
return fmt.Errorf("insufficient ETH for gas (%x). Req %v, has %v", sender.Address()[:4], MessageGasValue(self.msg), sender.Balance())
}
coinbase := self.Coinbase()
@ -183,18 +184,25 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) {
return
}
vmenv := self.VmEnv()
var ref vm.ClosureRef
vmenv := self.env
var ref vm.ContextRef
if MessageCreatesContract(msg) {
self.rec = MakeContract(msg, self.state)
ret, err, ref = vmenv.Create(sender, self.rec.Address(), self.msg.Data(), self.gas, self.gasPrice, self.value)
ref.SetCode(ret)
contract := MakeContract(msg, self.state)
ret, err, ref = vmenv.Create(sender, contract.Address(), self.msg.Data(), self.gas, self.gasPrice, self.value)
if err == nil {
dataGas := big.NewInt(int64(len(ret)))
dataGas.Mul(dataGas, vm.GasCreateByte)
if err = self.UseGas(dataGas); err == nil {
//self.state.SetCode(ref.Address(), ret)
ref.SetCode(ret)
}
}
} else {
ret, err = vmenv.Call(self.From(), self.To().Address(), self.msg.Data(), self.gas, self.gasPrice, self.value)
}
if err != nil {
statelogger.Debugln(err)
self.UseGas(self.gas)
}
return
@ -211,20 +219,19 @@ func MakeContract(msg Message, state *state.StateDB) *state.StateObject {
}
func (self *StateTransition) RefundGas() {
coinbaseSub := new(big.Int).Set(self.gas)
uhalf := new(big.Int).Div(self.GasUsed(), ethutil.Big2)
for addr, ref := range self.state.Refunds() {
refund := ethutil.BigMin(uhalf, ref)
coinbaseSub.Add(self.gas, refund)
self.state.AddBalance([]byte(addr), refund.Mul(refund, self.msg.GasPrice()))
}
coinbase, sender := self.Coinbase(), self.From()
coinbase.RefundGas(coinbaseSub, self.msg.GasPrice())
// Return remaining gas
remaining := new(big.Int).Mul(self.gas, self.msg.GasPrice())
sender.AddAmount(remaining)
uhalf := new(big.Int).Div(self.GasUsed(), ethutil.Big2)
for addr, ref := range self.state.Refunds() {
refund := ethutil.BigMin(uhalf, ref)
self.gas.Add(self.gas, refund)
self.state.AddBalance([]byte(addr), refund.Mul(refund, self.msg.GasPrice()))
}
coinbase.RefundGas(self.gas, self.msg.GasPrice())
}
func (self *StateTransition) GasUsed() *big.Int {

View file

@ -1,16 +1,13 @@
package core
import (
"bytes"
"container/list"
"fmt"
"math/big"
"sync"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/state"
"gopkg.in/fatih/set.v0"
)
var txplogger = logger.NewLogger("TXP")
@ -26,101 +23,66 @@ const (
minGasPrice = 1000000
)
var MinGasPrice = big.NewInt(10000000000000)
func EachTx(pool *list.List, it func(*types.Transaction, *list.Element) bool) {
for e := pool.Front(); e != nil; e = e.Next() {
if it(e.Value.(*types.Transaction), e) {
break
}
}
}
func FindTx(pool *list.List, finder func(*types.Transaction, *list.Element) bool) *types.Transaction {
for e := pool.Front(); e != nil; e = e.Next() {
if tx, ok := e.Value.(*types.Transaction); ok {
if finder(tx, e) {
return tx
}
}
}
return nil
}
type TxProcessor interface {
ProcessTransaction(tx *types.Transaction)
}
// The tx pool a thread safe transaction pool handler. In order to
// guarantee a non blocking pool we use a queue channel which can be
// independently read without needing access to the actual pool. If the
// pool is being drained or synced for whatever reason the transactions
// will simple queue up and handled when the mutex is freed.
// independently read without needing access to the actual pool.
type TxPool struct {
// The mutex for accessing the Tx pool.
mutex sync.Mutex
// Queueing channel for reading and writing incoming
// transactions to
queueChan chan *types.Transaction
// Quiting channel
quit chan bool
// The actual pool
pool *list.List
//pool *list.List
pool *set.Set
SecondaryProcessor TxProcessor
subscribers []chan TxMsg
chainManager *ChainManager
eventMux *event.TypeMux
eventMux *event.TypeMux
}
func NewTxPool(chainManager *ChainManager, eventMux *event.TypeMux) *TxPool {
func NewTxPool(eventMux *event.TypeMux) *TxPool {
return &TxPool{
pool: list.New(),
queueChan: make(chan *types.Transaction, txPoolQueueSize),
quit: make(chan bool),
chainManager: chainManager,
eventMux: eventMux,
pool: set.New(),
queueChan: make(chan *types.Transaction, txPoolQueueSize),
quit: make(chan bool),
eventMux: eventMux,
}
}
// Blocking function. Don't use directly. Use QueueTransaction instead
func (pool *TxPool) addTransaction(tx *types.Transaction) {
pool.mutex.Lock()
defer pool.mutex.Unlock()
pool.pool.PushBack(tx)
pool.pool.Add(tx)
// Broadcast the transaction to the rest of the peers
pool.eventMux.Post(TxPreEvent{tx})
}
func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error {
// Get the last block so we can retrieve the sender and receiver from
// the merkle trie
block := pool.chainManager.CurrentBlock
// Something has gone horribly wrong if this happens
if block == nil {
return fmt.Errorf("No last block on the block chain")
}
if len(tx.To()) != 0 && len(tx.To()) != 20 {
return fmt.Errorf("Invalid recipient. len = %d", len(tx.To()))
}
v, _, _ := tx.Curve()
if v > 28 || v < 27 {
return fmt.Errorf("tx.v != (28 || 27)")
return fmt.Errorf("tx.v != (28 || 27) => %v", v)
}
/* XXX this kind of validation needs to happen elsewhere in the gui when sending txs.
Other clients should do their own validation. Value transfer could throw error
but doesn't necessarily invalidate the tx. Gas can still be payed for and miner
can still be rewarded for their inclusion and processing.
// Get the sender
senderAddr := tx.From()
if senderAddr == nil {
return fmt.Errorf("invalid sender")
}
sender := pool.chainManager.State().GetAccount(senderAddr)
sender := pool.stateQuery.GetAccount(senderAddr)
totAmount := new(big.Int).Set(tx.Value())
// Make sure there's enough in the sender's account. Having insufficient
@ -128,20 +90,14 @@ func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error {
if sender.Balance().Cmp(totAmount) < 0 {
return fmt.Errorf("Insufficient amount in sender's (%x) account", tx.From())
}
// Increment the nonce making each tx valid only once to prevent replay
// attacks
*/
return nil
}
func (self *TxPool) Add(tx *types.Transaction) error {
hash := tx.Hash()
foundTx := FindTx(self.pool, func(tx *types.Transaction, e *list.Element) bool {
return bytes.Compare(tx.Hash(), hash) == 0
})
if foundTx != nil {
if self.pool.Has(tx) {
return fmt.Errorf("Known transaction (%x)", hash[0:4])
}
@ -152,7 +108,14 @@ func (self *TxPool) Add(tx *types.Transaction) error {
self.addTransaction(tx)
txplogger.Debugf("(t) %x => %x (%v) %x\n", tx.From()[:4], tx.To()[:4], tx.Value, tx.Hash())
var to string
if len(tx.To()) > 0 {
to = ethutil.Bytes2Hex(tx.To()[:4])
} else {
to = "[NEW_CONTRACT]"
}
txplogger.Debugf("(t) %x => %s (%v) %x\n", tx.From()[:4], to, tx.Value, tx.Hash())
// Notify the subscribers
go self.eventMux.Post(TxPreEvent{tx})
@ -161,7 +124,7 @@ func (self *TxPool) Add(tx *types.Transaction) error {
}
func (self *TxPool) Size() int {
return self.pool.Len()
return self.pool.Size()
}
func (self *TxPool) AddTransactions(txs []*types.Transaction) {
@ -175,63 +138,47 @@ func (self *TxPool) AddTransactions(txs []*types.Transaction) {
}
func (pool *TxPool) GetTransactions() []*types.Transaction {
pool.mutex.Lock()
defer pool.mutex.Unlock()
txList := make([]*types.Transaction, pool.pool.Len())
txList := make([]*types.Transaction, pool.Size())
i := 0
for e := pool.pool.Front(); e != nil; e = e.Next() {
tx := e.Value.(*types.Transaction)
txList[i] = tx
pool.pool.Each(func(v interface{}) bool {
txList[i] = v.(*types.Transaction)
i++
}
return true
})
return txList
}
func (pool *TxPool) RemoveInvalid(state *state.StateDB) {
pool.mutex.Lock()
defer pool.mutex.Unlock()
for e := pool.pool.Front(); e != nil; e = e.Next() {
tx := e.Value.(*types.Transaction)
sender := state.GetAccount(tx.From())
func (pool *TxPool) RemoveInvalid(query StateQuery) {
var removedTxs types.Transactions
pool.pool.Each(func(v interface{}) bool {
tx := v.(*types.Transaction)
sender := query.GetAccount(tx.From())
err := pool.ValidateTransaction(tx)
if err != nil || sender.Nonce >= tx.Nonce() {
pool.pool.Remove(e)
removedTxs = append(removedTxs, tx)
}
}
return true
})
pool.RemoveSet(removedTxs)
}
func (self *TxPool) RemoveSet(txs types.Transactions) {
self.mutex.Lock()
defer self.mutex.Unlock()
for _, tx := range txs {
EachTx(self.pool, func(t *types.Transaction, element *list.Element) bool {
if t == tx {
self.pool.Remove(element)
return true // To stop the loop
}
return false
})
self.pool.Remove(tx)
}
}
func (pool *TxPool) Flush() []*types.Transaction {
txList := pool.GetTransactions()
// Recreate a new list all together
// XXX Is this the fastest way?
pool.pool = list.New()
pool.pool.Clear()
return txList
}
func (pool *TxPool) Start() {
//go pool.queueHandler()
}
func (pool *TxPool) Stop() {

View file

@ -0,0 +1,81 @@
package core
import (
"crypto/ecdsa"
"testing"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/state"
)
// State query interface
type stateQuery struct{}
func (self stateQuery) GetAccount(addr []byte) *state.StateObject {
return state.NewStateObject(addr)
}
func transaction() *types.Transaction {
return types.NewTransactionMessage(make([]byte, 20), ethutil.Big0, ethutil.Big0, ethutil.Big0, nil)
}
func setup() (*TxPool, *ecdsa.PrivateKey) {
var m event.TypeMux
key, _ := crypto.GenerateKey()
return NewTxPool(&m), key
}
func TestTxAdding(t *testing.T) {
pool, key := setup()
tx1 := transaction()
tx1.SignECDSA(key)
err := pool.Add(tx1)
if err != nil {
t.Error(err)
}
err = pool.Add(tx1)
if err == nil {
t.Error("added tx twice")
}
}
func TestAddInvalidTx(t *testing.T) {
pool, _ := setup()
tx1 := transaction()
err := pool.Add(tx1)
if err == nil {
t.Error("expected error")
}
}
func TestRemoveSet(t *testing.T) {
pool, _ := setup()
tx1 := transaction()
pool.pool.Add(tx1)
pool.RemoveSet(types.Transactions{tx1})
if pool.Size() > 0 {
t.Error("expected pool size to be 0")
}
}
func TestRemoveInvalid(t *testing.T) {
pool, key := setup()
tx1 := transaction()
pool.pool.Add(tx1)
pool.RemoveInvalid(stateQuery{})
if pool.Size() > 0 {
t.Error("expected pool size to be 0")
}
tx1.SetNonce(1)
tx1.SignECDSA(key)
pool.pool.Add(tx1)
pool.RemoveInvalid(stateQuery{})
if pool.Size() != 1 {
t.Error("expected pool size to be 1, is", pool.Size())
}
}

View file

@ -9,41 +9,240 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/ptrie"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/trie"
)
type BlockInfo struct {
Number uint64
Hash []byte
Parent []byte
TD *big.Int
type Header struct {
// Hash to the previous block
ParentHash ethutil.Bytes
// Uncles of this block
UncleHash []byte
// The coin base address
Coinbase []byte
// Block Trie state
Root []byte
// Tx sha
TxHash []byte
// Receipt sha
ReceiptHash []byte
// Bloom
Bloom []byte
// Difficulty for the current block
Difficulty *big.Int
// The block number
Number *big.Int
// Gas limit
GasLimit *big.Int
// Gas used
GasUsed *big.Int
// Creation time
Time uint64
// Extra data
Extra string
// Block Nonce for verification
Nonce ethutil.Bytes
}
func (bi *BlockInfo) RlpDecode(data []byte) {
decoder := ethutil.NewValueFromBytes(data)
func (self *Header) rlpData(withNonce bool) []interface{} {
fields := []interface{}{self.ParentHash, self.UncleHash, self.Coinbase, self.Root, self.TxHash, self.ReceiptHash, self.Bloom, self.Difficulty, self.Number, self.GasLimit, self.GasUsed, self.Time, self.Extra}
if withNonce {
fields = append(fields, self.Nonce)
}
bi.Number = decoder.Get(0).Uint()
bi.Hash = decoder.Get(1).Bytes()
bi.Parent = decoder.Get(2).Bytes()
bi.TD = decoder.Get(3).BigInt()
return fields
}
func (bi *BlockInfo) RlpEncode() []byte {
return ethutil.Encode([]interface{}{bi.Number, bi.Hash, bi.Parent, bi.TD})
func (self *Header) RlpData() interface{} {
return self.rlpData(true)
}
func (self *Header) Hash() []byte {
return crypto.Sha3(ethutil.Encode(self.rlpData(true)))
}
func (self *Header) HashNoNonce() []byte {
return crypto.Sha3(ethutil.Encode(self.rlpData(false)))
}
type Block struct {
header *Header
uncles []*Header
transactions Transactions
Td *big.Int
receipts Receipts
Reward *big.Int
}
func NewBlock(parentHash []byte, coinbase []byte, root []byte, difficulty *big.Int, nonce []byte, extra string) *Block {
header := &Header{
Root: root,
ParentHash: parentHash,
Coinbase: coinbase,
Difficulty: difficulty,
Nonce: nonce,
Time: uint64(time.Now().Unix()),
Extra: extra,
GasUsed: new(big.Int),
GasLimit: new(big.Int),
}
block := &Block{header: header, Reward: new(big.Int)}
return block
}
func NewBlockWithHeader(header *Header) *Block {
return &Block{header: header}
}
func (self *Block) DecodeRLP(s *rlp.Stream) error {
if _, err := s.List(); err != nil {
return err
}
var header Header
if err := s.Decode(&header); err != nil {
return err
}
var transactions []*Transaction
if err := s.Decode(&transactions); err != nil {
return err
}
var uncleHeaders []*Header
if err := s.Decode(&uncleHeaders); err != nil {
return err
}
var tdBytes []byte
if err := s.Decode(&tdBytes); err != nil {
// If this block comes from the network that's fine. If loaded from disk it should be there
// Blocks don't store their Td when propagated over the network
} else {
self.Td = ethutil.BigD(tdBytes)
}
if err := s.ListEnd(); err != nil {
return err
}
self.header = &header
self.uncles = uncleHeaders
self.transactions = transactions
return nil
}
func (self *Block) Header() *Header {
return self.header
}
func (self *Block) Uncles() []*Header {
return self.uncles
}
func (self *Block) SetUncles(uncleHeaders []*Header) {
self.uncles = uncleHeaders
self.header.UncleHash = crypto.Sha3(ethutil.Encode(uncleHeaders))
}
func (self *Block) Transactions() Transactions {
return self.transactions
}
func (self *Block) Transaction(hash []byte) *Transaction {
for _, transaction := range self.transactions {
if bytes.Equal(hash, transaction.Hash()) {
return transaction
}
}
return nil
}
func (self *Block) SetTransactions(transactions Transactions) {
self.transactions = transactions
self.header.TxHash = DeriveSha(transactions)
}
func (self *Block) Receipts() Receipts {
return self.receipts
}
func (self *Block) SetReceipts(receipts Receipts) {
self.receipts = receipts
self.header.ReceiptHash = DeriveSha(receipts)
self.header.Bloom = CreateBloom(receipts)
}
func (self *Block) RlpData() interface{} {
return []interface{}{self.header, self.transactions, self.uncles}
}
func (self *Block) RlpDataForStorage() interface{} {
return []interface{}{self.header, self.transactions, self.uncles, self.Td /* TODO receipts */}
}
// Header accessors (add as you need them)
func (self *Block) Number() *big.Int { return self.header.Number }
func (self *Block) NumberU64() uint64 { return self.header.Number.Uint64() }
func (self *Block) ParentHash() []byte { return self.header.ParentHash }
func (self *Block) Bloom() []byte { return self.header.Bloom }
func (self *Block) Coinbase() []byte { return self.header.Coinbase }
func (self *Block) Time() int64 { return int64(self.header.Time) }
func (self *Block) GasLimit() *big.Int { return self.header.GasLimit }
func (self *Block) GasUsed() *big.Int { return self.header.GasUsed }
func (self *Block) Hash() []byte { return self.header.Hash() }
func (self *Block) Trie() *ptrie.Trie { return ptrie.New(self.header.Root, ethutil.Config.Db) }
func (self *Block) State() *state.StateDB { return state.New(self.Trie()) }
func (self *Block) Size() ethutil.StorageSize { return ethutil.StorageSize(len(ethutil.Encode(self))) }
func (self *Block) SetRoot(root []byte) { self.header.Root = root }
// Implement block.Pow
func (self *Block) Difficulty() *big.Int { return self.header.Difficulty }
func (self *Block) N() []byte { return self.header.Nonce }
func (self *Block) HashNoNonce() []byte {
return crypto.Sha3(ethutil.Encode(self.header.rlpData(false)))
}
func (self *Block) String() string {
return fmt.Sprintf(`BLOCK(%x): Size: %v TD: %v {
Header:
[
%v
]
Transactions:
%v
Uncles:
%v
}
`, self.header.Hash(), self.Size(), self.Td, self.header, self.transactions, self.uncles)
}
func (self *Header) String() string {
return fmt.Sprintf(`
ParentHash: %x
UncleHash: %x
Coinbase: %x
Root: %x
TxSha %x
ReceiptSha: %x
Bloom: %x
Difficulty: %v
Number: %v
GasLimit: %v
GasUsed: %v
Time: %v
Extra: %v
Nonce: %x
`, self.ParentHash, self.UncleHash, self.Coinbase, self.Root, self.TxHash, self.ReceiptHash, self.Bloom, self.Difficulty, self.Number, self.GasLimit, self.GasUsed, self.Time, self.Extra, self.Nonce)
}
type Blocks []*Block
func (self Blocks) AsSet() ethutil.UniqueSet {
set := make(ethutil.UniqueSet)
for _, block := range self {
set.Insert(block.Hash())
}
return set
}
type BlockBy func(b1, b2 *Block) bool
func (self BlockBy) Sort(blocks Blocks) {
@ -65,352 +264,4 @@ func (self blockSorter) Swap(i, j int) {
}
func (self blockSorter) Less(i, j int) bool { return self.by(self.blocks[i], self.blocks[j]) }
func Number(b1, b2 *Block) bool { return b1.Number.Cmp(b2.Number) < 0 }
type Block struct {
// Hash to the previous block
PrevHash ethutil.Bytes
// Uncles of this block
Uncles Blocks
UncleSha []byte
// The coin base address
Coinbase []byte
// Block Trie state
//state *ethutil.Trie
state *state.StateDB
// Difficulty for the current block
Difficulty *big.Int
// Creation time
Time int64
// The block number
Number *big.Int
// Gas limit
GasLimit *big.Int
// Gas used
GasUsed *big.Int
// Extra data
Extra string
// Block Nonce for verification
Nonce ethutil.Bytes
// List of transactions and/or contracts
transactions Transactions
receipts Receipts
TxSha, ReceiptSha []byte
LogsBloom []byte
Reward *big.Int
}
func NewBlockFromBytes(raw []byte) *Block {
block := &Block{}
block.RlpDecode(raw)
return block
}
// New block takes a raw encoded string
func NewBlockFromRlpValue(rlpValue *ethutil.Value) *Block {
block := &Block{}
block.RlpValueDecode(rlpValue)
return block
}
func CreateBlock(root interface{},
prevHash []byte,
base []byte,
Difficulty *big.Int,
Nonce []byte,
extra string) *Block {
block := &Block{
PrevHash: prevHash,
Coinbase: base,
Difficulty: Difficulty,
Nonce: Nonce,
Time: time.Now().Unix(),
Extra: extra,
UncleSha: nil,
GasUsed: new(big.Int),
GasLimit: new(big.Int),
}
block.SetUncles([]*Block{})
block.state = state.New(trie.New(ethutil.Config.Db, root))
return block
}
// Returns a hash of the block
func (block *Block) Hash() ethutil.Bytes {
return crypto.Sha3(ethutil.NewValue(block.header()).Encode())
//return crypto.Sha3(block.Value().Encode())
}
func (block *Block) HashNoNonce() []byte {
return crypto.Sha3(ethutil.Encode(block.miningHeader()))
}
func (block *Block) State() *state.StateDB {
return block.state
}
func (block *Block) Transactions() Transactions {
return block.transactions
}
func (block *Block) CalcGasLimit(parent *Block) *big.Int {
if block.Number.Cmp(big.NewInt(0)) == 0 {
return ethutil.BigPow(10, 6)
}
// ((1024-1) * parent.gasLimit + (gasUsed * 6 / 5)) / 1024
previous := new(big.Int).Mul(big.NewInt(1024-1), parent.GasLimit)
current := new(big.Rat).Mul(new(big.Rat).SetInt(parent.GasUsed), big.NewRat(6, 5))
curInt := new(big.Int).Div(current.Num(), current.Denom())
result := new(big.Int).Add(previous, curInt)
result.Div(result, big.NewInt(1024))
min := big.NewInt(125000)
return ethutil.BigMax(min, result)
}
func (block *Block) BlockInfo() BlockInfo {
bi := BlockInfo{}
data, _ := ethutil.Config.Db.Get(append(block.Hash(), []byte("Info")...))
bi.RlpDecode(data)
return bi
}
func (self *Block) GetTransaction(hash []byte) *Transaction {
for _, tx := range self.transactions {
if bytes.Compare(tx.Hash(), hash) == 0 {
return tx
}
}
return nil
}
// Sync the block's state and contract respectively
func (block *Block) Sync() {
block.state.Sync()
}
func (block *Block) Undo() {
// Sync the block state itself
block.state.Reset()
}
/////// Block Encoding
func (block *Block) rlpReceipts() interface{} {
// Marshal the transactions of this block
encR := make([]interface{}, len(block.receipts))
for i, r := range block.receipts {
// Cast it to a string (safe)
encR[i] = r.RlpData()
}
return encR
}
func (block *Block) rlpUncles() interface{} {
// Marshal the transactions of this block
uncles := make([]interface{}, len(block.Uncles))
for i, uncle := range block.Uncles {
// Cast it to a string (safe)
uncles[i] = uncle.header()
}
return uncles
}
func (block *Block) SetUncles(uncles []*Block) {
block.Uncles = uncles
block.UncleSha = crypto.Sha3(ethutil.Encode(block.rlpUncles()))
}
func (self *Block) SetReceipts(receipts Receipts) {
self.receipts = receipts
self.ReceiptSha = DeriveSha(receipts)
self.LogsBloom = CreateBloom(receipts)
}
func (self *Block) SetTransactions(txs Transactions) {
self.transactions = txs
self.TxSha = DeriveSha(txs)
}
func (block *Block) Value() *ethutil.Value {
return ethutil.NewValue([]interface{}{block.header(), block.transactions, block.rlpUncles()})
}
func (block *Block) RlpEncode() []byte {
// Encode a slice interface which contains the header and the list of
// transactions.
return block.Value().Encode()
}
func (block *Block) RlpDecode(data []byte) {
rlpValue := ethutil.NewValueFromBytes(data)
block.RlpValueDecode(rlpValue)
}
func (block *Block) RlpValueDecode(decoder *ethutil.Value) {
block.setHeader(decoder.Get(0))
// Tx list might be empty if this is an uncle. Uncles only have their
// header set.
if decoder.Get(1).IsNil() == false { // Yes explicitness
//receipts := decoder.Get(1)
//block.receipts = make([]*Receipt, receipts.Len())
txs := decoder.Get(1)
block.transactions = make(Transactions, txs.Len())
for i := 0; i < txs.Len(); i++ {
block.transactions[i] = NewTransactionFromValue(txs.Get(i))
//receipt := NewRecieptFromValue(receipts.Get(i))
//block.transactions[i] = receipt.Tx
//block.receipts[i] = receipt
}
}
if decoder.Get(2).IsNil() == false { // Yes explicitness
uncles := decoder.Get(2)
block.Uncles = make([]*Block, uncles.Len())
for i := 0; i < uncles.Len(); i++ {
block.Uncles[i] = NewUncleBlockFromValue(uncles.Get(i))
}
}
}
func (self *Block) setHeader(header *ethutil.Value) {
self.PrevHash = header.Get(0).Bytes()
self.UncleSha = header.Get(1).Bytes()
self.Coinbase = header.Get(2).Bytes()
self.state = state.New(trie.New(ethutil.Config.Db, header.Get(3).Val))
self.TxSha = header.Get(4).Bytes()
self.ReceiptSha = header.Get(5).Bytes()
self.LogsBloom = header.Get(6).Bytes()
self.Difficulty = header.Get(7).BigInt()
self.Number = header.Get(8).BigInt()
self.GasLimit = header.Get(9).BigInt()
self.GasUsed = header.Get(10).BigInt()
self.Time = int64(header.Get(11).BigInt().Uint64())
self.Extra = header.Get(12).Str()
self.Nonce = header.Get(13).Bytes()
}
func NewUncleBlockFromValue(header *ethutil.Value) *Block {
block := &Block{}
block.setHeader(header)
return block
}
func (block *Block) Trie() *trie.Trie {
return block.state.Trie
}
func (block *Block) Root() interface{} {
return block.state.Root()
}
func (block *Block) Diff() *big.Int {
return block.Difficulty
}
func (self *Block) Receipts() []*Receipt {
return self.receipts
}
func (block *Block) miningHeader() []interface{} {
return []interface{}{
// Sha of the previous block
block.PrevHash,
// Sha of uncles
block.UncleSha,
// Coinbase address
block.Coinbase,
// root state
block.Root(),
// tx root
block.TxSha,
// Sha of tx
block.ReceiptSha,
// Bloom
block.LogsBloom,
// Current block Difficulty
block.Difficulty,
// The block number
block.Number,
// Block upper gas bound
block.GasLimit,
// Block gas used
block.GasUsed,
// Time the block was found?
block.Time,
// Extra data
block.Extra,
}
}
func (block *Block) header() []interface{} {
return append(block.miningHeader(), block.Nonce)
}
func (block *Block) String() string {
return fmt.Sprintf(`
BLOCK(%x): Size: %v
PrevHash: %x
UncleSha: %x
Coinbase: %x
Root: %x
TxSha %x
ReceiptSha: %x
Bloom: %x
Difficulty: %v
Number: %v
MaxLimit: %v
GasUsed: %v
Time: %v
Extra: %v
Nonce: %x
NumTx: %v
`,
block.Hash(),
block.Size(),
block.PrevHash,
block.UncleSha,
block.Coinbase,
block.Root(),
block.TxSha,
block.ReceiptSha,
block.LogsBloom,
block.Difficulty,
block.Number,
block.GasLimit,
block.GasUsed,
block.Time,
block.Extra,
block.Nonce,
len(block.transactions),
)
}
func (self *Block) Size() ethutil.StorageSize {
return ethutil.StorageSize(len(self.RlpEncode()))
}
// Implement RlpEncodable
func (self *Block) RlpData() interface{} {
return []interface{}{self.header(), self.transactions, self.rlpUncles()}
}
// Implement pow.Block
func (self *Block) N() []byte { return self.Nonce }
func Number(b1, b2 *Block) bool { return b1.Header().Number.Cmp(b2.Header().Number) < 0 }

1
core/types/block_test.go Normal file
View file

@ -0,0 +1 @@
package types

View file

@ -2,7 +2,7 @@ package types
import (
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/trie"
"github.com/ethereum/go-ethereum/ptrie"
)
type DerivableList interface {
@ -11,10 +11,10 @@ type DerivableList interface {
}
func DeriveSha(list DerivableList) []byte {
trie := trie.New(ethutil.Config.Db, "")
trie := ptrie.New(nil, ethutil.Config.Db)
for i := 0; i < list.Len(); i++ {
trie.Update(string(ethutil.NewValue(i).Encode()), string(list.GetRlp(i)))
trie.Update(ethutil.Encode(i), list.GetRlp(i))
}
return trie.GetRoot()
return trie.Root()
}

View file

@ -1,11 +1,14 @@
package types
import (
"bytes"
"crypto/ecdsa"
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/rlp"
"github.com/obscuren/secp256k1-go"
)
@ -14,22 +17,22 @@ func IsContractAddr(addr []byte) bool {
}
type Transaction struct {
nonce uint64
recipient []byte
value *big.Int
gas *big.Int
gasPrice *big.Int
data []byte
v byte
r, s []byte
AccountNonce uint64
Price *big.Int
GasLimit *big.Int
Recipient []byte
Amount *big.Int
Payload []byte
V uint64
R, S []byte
}
func NewContractCreationTx(value, gas, gasPrice *big.Int, script []byte) *Transaction {
return &Transaction{recipient: nil, value: value, gas: gas, gasPrice: gasPrice, data: script}
func NewContractCreationTx(Amount, gasAmount, price *big.Int, data []byte) *Transaction {
return NewTransactionMessage(nil, Amount, gasAmount, price, data)
}
func NewTransactionMessage(to []byte, value, gas, gasPrice *big.Int, data []byte) *Transaction {
return &Transaction{recipient: to, value: value, gasPrice: gasPrice, gas: gas, data: data}
func NewTransactionMessage(to []byte, Amount, gasAmount, price *big.Int, data []byte) *Transaction {
return &Transaction{Recipient: to, Amount: Amount, Price: price, GasLimit: gasAmount, Payload: data}
}
func NewTransactionFromBytes(data []byte) *Transaction {
@ -39,7 +42,7 @@ func NewTransactionFromBytes(data []byte) *Transaction {
return tx
}
func NewTransactionFromValue(val *ethutil.Value) *Transaction {
func NewTransactionFromAmount(val *ethutil.Value) *Transaction {
tx := &Transaction{}
tx.RlpValueDecode(val)
@ -47,33 +50,33 @@ func NewTransactionFromValue(val *ethutil.Value) *Transaction {
}
func (tx *Transaction) Hash() []byte {
data := []interface{}{tx.Nonce, tx.gasPrice, tx.gas, tx.recipient, tx.Value, tx.Data}
data := []interface{}{tx.AccountNonce, tx.Price, tx.GasLimit, tx.Recipient, tx.Amount, tx.Payload}
return crypto.Sha3(ethutil.NewValue(data).Encode())
return crypto.Sha3(ethutil.Encode(data))
}
func (self *Transaction) Data() []byte {
return self.data
return self.Payload
}
func (self *Transaction) Gas() *big.Int {
return self.gas
return self.GasLimit
}
func (self *Transaction) GasPrice() *big.Int {
return self.gasPrice
return self.Price
}
func (self *Transaction) Value() *big.Int {
return self.value
return self.Amount
}
func (self *Transaction) Nonce() uint64 {
return self.nonce
return self.AccountNonce
}
func (self *Transaction) SetNonce(nonce uint64) {
self.nonce = nonce
func (self *Transaction) SetNonce(AccountNonce uint64) {
self.AccountNonce = AccountNonce
}
func (self *Transaction) From() []byte {
@ -81,13 +84,13 @@ func (self *Transaction) From() []byte {
}
func (self *Transaction) To() []byte {
return self.recipient
return self.Recipient
}
func (tx *Transaction) Curve() (v byte, r []byte, s []byte) {
v = tx.v
r = ethutil.LeftPadBytes(tx.r, 32)
s = ethutil.LeftPadBytes(tx.s, 32)
v = byte(tx.V)
r = ethutil.LeftPadBytes(tx.R, 32)
s = ethutil.LeftPadBytes(tx.S, 32)
return
}
@ -108,8 +111,8 @@ func (tx *Transaction) PublicKey() []byte {
sig := append(r, s...)
sig = append(sig, v-27)
pubkey := crypto.Ecrecover(append(hash, sig...))
//pubkey, _ := secp256k1.RecoverPubkey(hash, sig)
//pubkey := crypto.Ecrecover(append(hash, sig...))
pubkey, _ := secp256k1.RecoverPubkey(hash, sig)
return pubkey
}
@ -130,44 +133,41 @@ func (tx *Transaction) Sign(privk []byte) error {
sig := tx.Signature(privk)
tx.r = sig[:32]
tx.s = sig[32:64]
tx.v = sig[64] + 27
tx.R = sig[:32]
tx.S = sig[32:64]
tx.V = uint64(sig[64] + 27)
return nil
}
func (tx *Transaction) RlpData() interface{} {
data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.recipient, tx.Value, tx.Data}
// TODO Remove prefixing zero's
return append(data, tx.v, new(big.Int).SetBytes(tx.r).Bytes(), new(big.Int).SetBytes(tx.s).Bytes())
func (tx *Transaction) SignECDSA(key *ecdsa.PrivateKey) error {
return tx.Sign(crypto.FromECDSA(key))
}
func (tx *Transaction) RlpValue() *ethutil.Value {
return ethutil.NewValue(tx.RlpData())
func (tx *Transaction) RlpData() interface{} {
data := []interface{}{tx.AccountNonce, tx.Price, tx.GasLimit, tx.Recipient, tx.Amount, tx.Payload}
return append(data, tx.V, new(big.Int).SetBytes(tx.R).Bytes(), new(big.Int).SetBytes(tx.S).Bytes())
}
func (tx *Transaction) RlpEncode() []byte {
return tx.RlpValue().Encode()
return ethutil.Encode(tx)
}
func (tx *Transaction) RlpDecode(data []byte) {
tx.RlpValueDecode(ethutil.NewValueFromBytes(data))
rlp.Decode(bytes.NewReader(data), tx)
}
func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
tx.nonce = decoder.Get(0).Uint()
tx.gasPrice = decoder.Get(1).BigInt()
tx.gas = decoder.Get(2).BigInt()
tx.recipient = decoder.Get(3).Bytes()
tx.value = decoder.Get(4).BigInt()
tx.data = decoder.Get(5).Bytes()
tx.v = byte(decoder.Get(6).Uint())
tx.r = decoder.Get(7).Bytes()
tx.s = decoder.Get(8).Bytes()
tx.AccountNonce = decoder.Get(0).Uint()
tx.Price = decoder.Get(1).BigInt()
tx.GasLimit = decoder.Get(2).BigInt()
tx.Recipient = decoder.Get(3).Bytes()
tx.Amount = decoder.Get(4).BigInt()
tx.Payload = decoder.Get(5).Bytes()
tx.V = decoder.Get(6).Uint()
tx.R = decoder.Get(7).Bytes()
tx.S = decoder.Get(8).Bytes()
}
func (tx *Transaction) String() string {
@ -178,25 +178,28 @@ func (tx *Transaction) String() string {
To: %x
Nonce: %v
GasPrice: %v
Gas: %v
GasLimit %v
Value: %v
Data: 0x%x
V: 0x%x
R: 0x%x
S: 0x%x
`,
Hex: %x
`,
tx.Hash(),
len(tx.recipient) == 0,
len(tx.Recipient) == 0,
tx.From(),
tx.recipient,
tx.nonce,
tx.gasPrice,
tx.gas,
tx.Value,
tx.Data,
tx.v,
tx.r,
tx.s)
tx.To(),
tx.AccountNonce,
tx.Price,
tx.GasLimit,
tx.Amount,
tx.Payload,
tx.V,
tx.R,
tx.S,
ethutil.Encode(tx),
)
}
// Transaction slice type for basic sorting
@ -219,5 +222,5 @@ func (s Transactions) GetRlp(i int) []byte { return ethutil.Rlp(s[i]) }
type TxByNonce struct{ Transactions }
func (s TxByNonce) Less(i, j int) bool {
return s.Transactions[i].nonce < s.Transactions[j].nonce
return s.Transactions[i].AccountNonce < s.Transactions[j].AccountNonce
}

View file

@ -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,
@ -24,17 +26,22 @@ 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.PrevHash }
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) BlockNumber() *big.Int { return self.block.Number() }
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) 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) GasLimit() *big.Int { return self.block.GasLimit }
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)
}
@ -46,16 +53,16 @@ func (self *VMEnv) vm(addr, data []byte, gas, price, value *big.Int) *Execution
return NewExecution(self, addr, data, gas, price, value)
}
func (self *VMEnv) Call(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
func (self *VMEnv) Call(me vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
exe := self.vm(addr, data, gas, price, value)
return exe.Call(addr, me)
}
func (self *VMEnv) CallCode(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
func (self *VMEnv) CallCode(me vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
exe := self.vm(me.Address(), data, gas, price, value)
return exe.Call(addr, me)
}
func (self *VMEnv) Create(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ClosureRef) {
func (self *VMEnv) Create(me vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
exe := self.vm(addr, data, gas, price, value)
return exe.Create(me)
}

View file

@ -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 {
@ -32,13 +52,13 @@ type Ethereum struct {
//*** SERVICES ***
// State manager for processing new blocks and managing the over all states
blockManager *core.BlockManager
txPool *core.TxPool
chainManager *core.ChainManager
blockPool *BlockPool
whisper *whisper.Whisper
blockProcessor *core.BlockProcessor
txPool *core.TxPool
chainManager *core.ChainManager
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,15 +114,16 @@ 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())
eth.txPool = core.NewTxPool(eth.chainManager, eth.EventMux())
eth.blockManager = core.NewBlockManager(eth.txPool, eth.chainManager, eth.EventMux())
eth.chainManager.SetProcessor(eth.blockManager)
eth.txPool = core.NewTxPool(eth.EventMux())
eth.blockProcessor = core.NewBlockProcessor(eth.txPool, eth.chainManager, eth.EventMux())
eth.chainManager.SetProcessor(eth.blockProcessor)
eth.whisper = whisper.New()
hasBlock := eth.chainManager.HasBlock
@ -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
}
@ -111,8 +169,8 @@ func (s *Ethereum) ChainManager() *core.ChainManager {
return s.chainManager
}
func (s *Ethereum) BlockManager() *core.BlockManager {
return s.blockManager
func (s *Ethereum) BlockProcessor() *core.BlockProcessor {
return s.blockProcessor
}
func (s *Ethereum) TxPool() *core.TxPool {
@ -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,15 +285,17 @@ 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()})
}
}
func (self *Ethereum) blockBroadcastLoop() {
// automatically stops if unsubscribe
for obj := range self.txSub.Chan() {
event := obj.(core.NewMinedBlockEvent)
self.server.Broadcast("eth", NewBlockMsg, event.Block.Value().Val)
switch ev := obj.(type) {
case core.NewMinedBlockEvent:
self.net.Broadcast("eth", NewBlockMsg, ev.Block.RlpData())
}
}
}

View file

@ -13,7 +13,7 @@ import (
)
const (
ProtocolVersion = 49
ProtocolVersion = 51
NetworkId = 0
ProtocolLength = uint64(8)
ProtocolMaxMsgSize = 10 * 1024 * 1024
@ -172,7 +172,7 @@ func (self *ethProtocol) handle() error {
}
block := self.chainManager.GetBlock(hash)
if block != nil {
blocks = append(blocks, block.Value().Raw())
blocks = append(blocks, block.RlpData())
}
}
return self.rw.EncodeMsg(BlocksMsg, blocks...)

80
eth/wallet.go Normal file
View file

@ -0,0 +1,80 @@
package eth
/*
import (
"crypto/ecdsa"
"errors"
"math/big"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
)
type Account struct {
w *Wallet
}
func (self *Account) Transact(to *Account, value, gas, price *big.Int, data []byte) error {
return self.w.transact(self, to, value, gas, price, data)
}
func (self *Account) Address() []byte {
return nil
}
func (self *Account) PrivateKey() *ecdsa.PrivateKey {
return nil
}
type Wallet struct{}
func NewWallet() *Wallet {
return &Wallet{}
}
func (self *Wallet) GetAccount(i int) *Account {
}
func (self *Wallet) transact(from, to *Account, value, gas, price *big.Int, data []byte) error {
if from.PrivateKey() == nil {
return errors.New("accounts is not owned (no private key available)")
}
var createsContract bool
if to == nil {
createsContract = true
}
var msg *types.Transaction
if contractCreation {
msg = types.NewContractCreationTx(value, gas, price, data)
} else {
msg = types.NewTransactionMessage(to.Address(), value, gas, price, data)
}
state := self.chainManager.TransState()
nonce := state.GetNonce(key.Address())
msg.SetNonce(nonce)
msg.SignECDSA(from.PriateKey())
// Do some pre processing for our "pre" events and hooks
block := self.chainManager.NewBlock(from.Address())
coinbase := state.GetOrNewStateObject(from.Address())
coinbase.SetGasPool(block.GasLimit())
self.blockManager.ApplyTransactions(coinbase, state, block, types.Transactions{tx}, true)
err := self.obj.TxPool().Add(tx)
if err != nil {
return nil, err
}
state.SetNonce(key.Address(), nonce+1)
if contractCreation {
addr := core.AddressFromMessage(tx)
pipelogger.Infof("Contract addr %x\n", addr)
}
return tx, nil
}
*/

View file

@ -71,6 +71,10 @@ func (self *LDBDatabase) NewIterator() iterator.Iterator {
return self.db.NewIterator(nil, nil)
}
func (self *LDBDatabase) Write(batch *leveldb.Batch) error {
return self.db.Write(batch, nil)
}
func (self *LDBDatabase) Close() {
// Close the leveldb database
self.db.Close()

View file

@ -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)
}

View file

@ -13,7 +13,10 @@ for dir in $(find . -maxdepth 10 -not -path './.git*' -not -path '*/_*' -type d)
do
if ls $dir/*.go &> /dev/null; then
# echo $dir
go test -covermode=count -coverprofile=$dir/profile.tmp $dir
if [[ $dir != "./tests/vm" ]]
then
go test -covermode=count -coverprofile=$dir/profile.tmp $dir
fi
if [ -f $dir/profile.tmp ]
then
cat $dir/profile.tmp | tail -n +2 >> profile.cov
@ -26,4 +29,4 @@ go tool cover -func profile.cov
# To submit the test coverage result to coveralls.io,
# use goveralls (https://github.com/mattn/goveralls)
# goveralls -coverprofile=profile.cov -service=travis-ci
goveralls -coverprofile=profile.cov -service=travis-ci -repotoken $COVERALLS_TOKEN

View file

@ -1,8 +0,0 @@
#!/bin/bash
set -e
TEST_DEPS=$(go list -f '{{.Imports}} {{.TestImports}} {{.XTestImports}}' github.com/ethereum/go-ethereum/... | sed -e 's/\[//g' | sed -e 's/\]//g' | sed -e 's/C //g')
if [ "$TEST_DEPS" ]; then
go get -race $TEST_DEPS
fi

View file

@ -18,11 +18,11 @@ type JSStateObject struct {
func (self *JSStateObject) EachStorage(call otto.FunctionCall) otto.Value {
cb := call.Argument(0)
self.JSObject.EachStorage(func(key string, value *ethutil.Value) {
value.Decode()
cb.Call(self.eth.toVal(self), self.eth.toVal(key), self.eth.toVal(ethutil.Bytes2Hex(value.Bytes())))
})
it := self.JSObject.Trie().Iterator()
for it.Next() {
cb.Call(self.eth.toVal(self), self.eth.toVal(ethutil.Bytes2Hex(it.Key)), self.eth.toVal(ethutil.Bytes2Hex(it.Value)))
}
return otto.UndefinedValue()
}
@ -72,15 +72,21 @@ type JSEthereum struct {
ethereum *eth.Ethereum
}
func (self *JSEthereum) GetBlock(hash string) otto.Value {
return self.toVal(&JSBlock{self.JSXEth.BlockByHash(hash), self})
func (self *JSEthereum) Block(v interface{}) otto.Value {
if number, ok := v.(int64); ok {
return self.toVal(&JSBlock{self.JSXEth.BlockByNumber(int32(number)), self})
} else if hash, ok := v.(string); ok {
return self.toVal(&JSBlock{self.JSXEth.BlockByHash(hash), self})
}
return otto.UndefinedValue()
}
func (self *JSEthereum) GetPeers() otto.Value {
func (self *JSEthereum) Peers() otto.Value {
return self.toVal(self.JSXEth.Peers())
}
func (self *JSEthereum) GetKey() otto.Value {
func (self *JSEthereum) Key() otto.Value {
return self.toVal(self.JSXEth.Key())
}
@ -88,10 +94,6 @@ func (self *JSEthereum) GetStateObject(addr string) otto.Value {
return self.toVal(&JSStateObject{xeth.NewJSObject(self.JSXEth.World().SafeGet(ethutil.Hex2Bytes(addr))), self})
}
func (self *JSEthereum) Peers() otto.Value {
return self.toVal(self.JSXEth.Peers())
}
func (self *JSEthereum) Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr string) otto.Value {
r, err := self.JSXEth.Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr)
if err != nil {
@ -103,18 +105,6 @@ func (self *JSEthereum) Transact(key, recipient, valueStr, gasStr, gasPriceStr,
return self.toVal(r)
}
func (self *JSEthereum) Create(key, valueStr, gasStr, gasPriceStr, scriptStr string) otto.Value {
r, err := self.JSXEth.Transact(key, "", valueStr, gasStr, gasPriceStr, scriptStr)
if err != nil {
fmt.Println(err)
return otto.UndefinedValue()
}
return self.toVal(r)
}
func (self *JSEthereum) toVal(v interface{}) otto.Value {
result, err := self.vm.ToValue(v)

33
logger/log.go Normal file
View file

@ -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
}

View file

@ -56,7 +56,7 @@ type Miner struct {
eth *eth.Ethereum
events event.Subscription
uncles types.Blocks
uncles []*types.Header
localTxs map[int]*LocalTx
localTxId int
@ -174,9 +174,9 @@ func (self *Miner) reset() {
func (self *Miner) mine() {
var (
blockManager = self.eth.BlockManager()
chainMan = self.eth.ChainManager()
block = chainMan.NewBlock(self.Coinbase)
blockProcessor = self.eth.BlockProcessor()
chainMan = self.eth.ChainManager()
block = chainMan.NewBlock(self.Coinbase)
)
// Apply uncles
@ -184,15 +184,17 @@ func (self *Miner) mine() {
block.SetUncles(self.uncles)
}
parent := chainMan.GetBlock(block.PrevHash)
coinbase := block.State().GetOrNewStateObject(block.Coinbase)
coinbase.SetGasPool(block.CalcGasLimit(parent))
parent := chainMan.GetBlock(block.ParentHash())
coinbase := block.State().GetOrNewStateObject(block.Coinbase())
coinbase.SetGasPool(core.CalcGasLimit(parent, block))
transactions := self.finiliseTxs()
state := block.State()
// Accumulate all valid transactions and apply them to the new state
// Error may be ignored. It's not important during mining
receipts, txs, _, erroneous, err := blockManager.ApplyTransactions(coinbase, block.State(), block, transactions, true)
receipts, txs, _, erroneous, err := blockProcessor.ApplyTransactions(coinbase, state, block, transactions, true)
if err != nil {
minerlogger.Debugln(err)
}
@ -202,16 +204,17 @@ func (self *Miner) mine() {
block.SetReceipts(receipts)
// Accumulate the rewards included for this block
blockManager.AccumelateRewards(block.State(), block, parent)
blockProcessor.AccumelateRewards(state, block, parent)
block.State().Update(ethutil.Big0)
state.Update(ethutil.Big0)
block.SetRoot(state.Root())
minerlogger.Infof("Mining on block. Includes %v transactions", len(transactions))
// Find a valid nonce
nonce := self.pow.Search(block, self.powQuitCh)
if nonce != nil {
block.Nonce = nonce
block.Header().Nonce = nonce
err := chainMan.InsertChain(types.Blocks{block})
if err != nil {
minerlogger.Infoln(err)

View file

@ -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,

23
p2p/nat.go Normal file
View file

@ -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
}

View file

@ -3,7 +3,7 @@ package pow
import "math/big"
type Block interface {
Diff() *big.Int
Difficulty() *big.Int
HashNoNonce() []byte
N() []byte
}

View file

@ -1,4 +1,4 @@
package core
package dagger
import (
"hash"

View file

@ -1,4 +1,4 @@
package core
package dagger
import (
"math/big"

View file

@ -35,7 +35,7 @@ func (pow *EasyPow) Turbo(on bool) {
func (pow *EasyPow) Search(block pow.Block, stop <-chan struct{}) []byte {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
hash := block.HashNoNonce()
diff := block.Diff()
diff := block.Difficulty()
i := int64(0)
start := time.Now().UnixNano()
t := time.Now()
@ -89,5 +89,5 @@ func verify(hash []byte, diff *big.Int, nonce []byte) bool {
}
func Verify(block pow.Block) bool {
return verify(block.HashNoNonce(), block.Diff(), block.N())
return verify(block.HashNoNonce(), block.Difficulty(), block.N())
}

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,7 @@
package ptrie
import "fmt"
type FullNode struct {
trie *Trie
nodes [17]Node
@ -21,7 +23,9 @@ func (self *FullNode) Branches() []Node {
func (self *FullNode) Copy() Node {
nnode := NewFullNode(self.trie)
for i, node := range self.nodes {
nnode.nodes[i] = node
if node != nil {
nnode.nodes[i] = node
}
}
return nnode
@ -56,6 +60,10 @@ func (self *FullNode) RlpData() interface{} {
}
func (self *FullNode) set(k byte, value Node) {
if _, ok := value.(*ValueNode); ok && k != 16 {
fmt.Println(value, k)
}
self.nodes[int(k)] = value
}

View file

@ -14,7 +14,7 @@ type Iterator struct {
}
func NewIterator(trie *Trie) *Iterator {
return &Iterator{trie: trie, Key: []byte{0}}
return &Iterator{trie: trie, Key: make([]byte, 32)}
}
func (self *Iterator) Next() bool {

View file

@ -17,7 +17,7 @@ type Node interface {
func (self *ValueNode) String() string { return self.fstring("") }
func (self *FullNode) String() string { return self.fstring("") }
func (self *ShortNode) String() string { return self.fstring("") }
func (self *ValueNode) fstring(ind string) string { return fmt.Sprintf("%s ", self.data) }
func (self *ValueNode) fstring(ind string) string { return fmt.Sprintf("%x ", self.data) }
func (self *HashNode) fstring(ind string) string { return fmt.Sprintf("%x ", self.key) }
// Full node
@ -36,5 +36,5 @@ func (self *FullNode) fstring(ind string) string {
// Short node
func (self *ShortNode) fstring(ind string) string {
return fmt.Sprintf("[ %s: %v ] ", self.key, self.value.fstring(ind+" "))
return fmt.Sprintf("[ %x: %v ] ", self.key, self.value.fstring(ind+" "))
}

View file

@ -19,7 +19,7 @@ func ParanoiaCheck(t1 *Trie, backend Backend) (bool, *Trie) {
t2.Update(it.Key, it.Value)
}
return bytes.Compare(t2.Hash(), t1.Hash()) == 0, t2
return bytes.Equal(t2.Hash(), t1.Hash()), t2
}
type Trie struct {
@ -49,14 +49,17 @@ func (self *Trie) Iterator() *Iterator {
return NewIterator(self)
}
func (self *Trie) Copy() *Trie {
return New(self.roothash, self.cache.backend)
}
// Legacy support
func (self *Trie) Root() []byte { return self.Hash() }
func (self *Trie) Hash() []byte {
var hash []byte
if self.root != nil {
//hash = self.root.Hash().([]byte)
t := self.root.Hash()
if byts, ok := t.([]byte); ok {
if byts, ok := t.([]byte); ok && len(byts) > 0 {
hash = byts
} else {
hash = crypto.Sha3(ethutil.Encode(self.root.RlpData()))
@ -73,6 +76,9 @@ func (self *Trie) Hash() []byte {
return hash
}
func (self *Trie) Commit() {
self.mu.Lock()
defer self.mu.Unlock()
// Hash first
self.Hash()
@ -81,10 +87,15 @@ func (self *Trie) Commit() {
// Reset should only be called if the trie has been hashed
func (self *Trie) Reset() {
self.mu.Lock()
defer self.mu.Unlock()
self.cache.Reset()
revision := self.revisions.Remove(self.revisions.Back()).([]byte)
self.roothash = revision
if self.revisions.Len() > 0 {
revision := self.revisions.Remove(self.revisions.Back()).([]byte)
self.roothash = revision
}
value := ethutil.NewValueFromBytes(self.cache.Get(self.roothash))
self.root = self.mknode(value)
}
@ -173,7 +184,7 @@ func (self *Trie) insert(node Node, key []byte, value Node) Node {
return cpy
default:
panic("Invalid node")
panic(fmt.Sprintf("%T: invalid node: %v", node, node))
}
}
@ -204,7 +215,7 @@ func (self *Trie) get(node Node, key []byte) Node {
}
func (self *Trie) delete(node Node, key []byte) Node {
if len(key) == 0 {
if len(key) == 0 && node == nil {
return nil
}
@ -223,7 +234,9 @@ func (self *Trie) delete(node Node, key []byte) Node {
nkey := append(k, child.Key()...)
n = NewShortNode(self, nkey, child.Value())
case *FullNode:
n = NewShortNode(self, node.key, child)
sn := NewShortNode(self, node.Key(), child)
sn.key = node.key
n = sn
}
return n
@ -264,9 +277,10 @@ func (self *Trie) delete(node Node, key []byte) Node {
}
return nnode
case nil:
return nil
default:
panic("Invalid node")
panic(fmt.Sprintf("%T: invalid node: %v (%v)", node, node, key))
}
}
@ -274,8 +288,13 @@ func (self *Trie) delete(node Node, key []byte) Node {
func (self *Trie) mknode(value *ethutil.Value) Node {
l := value.Len()
switch l {
case 0:
return nil
case 2:
return NewShortNode(self, trie.CompactDecode(string(value.Get(0).Bytes())), self.mknode(value.Get(1)))
// A value node may consists of 2 bytes.
if value.Get(0).Len() != 0 {
return NewShortNode(self, trie.CompactDecode(string(value.Get(0).Bytes())), self.mknode(value.Get(1)))
}
case 17:
fnode := NewFullNode(self)
for i := 0; i < l; i++ {
@ -284,9 +303,9 @@ func (self *Trie) mknode(value *ethutil.Value) Node {
return fnode
case 32:
return &HashNode{value.Bytes()}
default:
return &ValueNode{self, value.Bytes()}
}
return &ValueNode{self, value.Bytes()}
}
func (self *Trie) trans(node Node) Node {
@ -310,3 +329,7 @@ func (self *Trie) store(node Node) interface{} {
return node.RlpData()
}
func (self *Trie) PrintRoot() {
fmt.Println(self.root)
}

View file

@ -141,7 +141,7 @@ func TestReplication(t *testing.T) {
trie2 := New(trie.roothash, trie.cache.backend)
if string(trie2.GetString("horse")) != "stallion" {
t.Error("expected to have harse => stallion")
t.Error("expected to have horse => stallion")
}
hash := trie2.Hash()

View file

@ -22,22 +22,23 @@ type World struct {
func (self *StateDB) Dump() []byte {
world := World{
Root: ethutil.Bytes2Hex(self.Trie.GetRoot()),
Root: ethutil.Bytes2Hex(self.trie.Root()),
Accounts: make(map[string]Account),
}
self.Trie.NewIterator().Each(func(key string, value *ethutil.Value) {
stateObject := NewStateObjectFromBytes([]byte(key), value.Bytes())
it := self.trie.Iterator()
for it.Next() {
stateObject := NewStateObjectFromBytes(it.Key, it.Value)
account := Account{Balance: stateObject.balance.String(), Nonce: stateObject.Nonce, Root: ethutil.Bytes2Hex(stateObject.Root()), CodeHash: ethutil.Bytes2Hex(stateObject.codeHash)}
account.Storage = make(map[string]string)
stateObject.EachStorage(func(key string, value *ethutil.Value) {
value.Decode()
account.Storage[ethutil.Bytes2Hex([]byte(key))] = ethutil.Bytes2Hex(value.Bytes())
})
world.Accounts[ethutil.Bytes2Hex([]byte(key))] = account
})
storageIt := stateObject.State.trie.Iterator()
for storageIt.Next() {
account.Storage[ethutil.Bytes2Hex(it.Key)] = ethutil.Bytes2Hex(it.Value)
}
world.Accounts[ethutil.Bytes2Hex(it.Key)] = account
}
json, err := json.MarshalIndent(world, "", " ")
if err != nil {
@ -50,7 +51,8 @@ func (self *StateDB) Dump() []byte {
// Debug stuff
func (self *StateObject) CreateOutputForDiff() {
fmt.Printf("%x %x %x %x\n", self.Address(), self.State.Root(), self.balance.Bytes(), self.Nonce)
self.EachStorage(func(addr string, value *ethutil.Value) {
fmt.Printf("%x %x\n", addr, value.Bytes())
})
it := self.State.trie.Iterator()
for it.Next() {
fmt.Printf("%x %x\n", it.Key, it.Value)
}
}

View file

@ -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

View file

@ -6,7 +6,7 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/trie"
"github.com/ethereum/go-ethereum/ptrie"
)
type Code []byte
@ -62,7 +62,7 @@ func NewStateObject(addr []byte) *StateObject {
address := ethutil.Address(addr)
object := &StateObject{address: address, balance: new(big.Int), gasPool: new(big.Int)}
object.State = New(trie.New(ethutil.Config.Db, ""))
object.State = New(ptrie.New(nil, ethutil.Config.Db)) //New(trie.New(ethutil.Config.Db, ""))
object.storage = make(Storage)
object.gasPool = new(big.Int)
@ -72,7 +72,7 @@ func NewStateObject(addr []byte) *StateObject {
func NewContract(address []byte, balance *big.Int, root []byte) *StateObject {
contract := NewStateObject(address)
contract.balance = balance
contract.State = New(trie.New(ethutil.Config.Db, string(root)))
contract.State = New(ptrie.New(nil, ethutil.Config.Db)) //New(trie.New(ethutil.Config.Db, string(root)))
return contract
}
@ -89,12 +89,12 @@ func (self *StateObject) MarkForDeletion() {
statelogger.DebugDetailf("%x: #%d %v (deletion)\n", self.Address(), self.Nonce, self.balance)
}
func (c *StateObject) GetAddr(addr []byte) *ethutil.Value {
return ethutil.NewValueFromBytes([]byte(c.State.Trie.Get(string(addr))))
func (c *StateObject) getAddr(addr []byte) *ethutil.Value {
return ethutil.NewValueFromBytes([]byte(c.State.trie.Get(addr)))
}
func (c *StateObject) SetAddr(addr []byte, value interface{}) {
c.State.Trie.Update(string(addr), string(ethutil.NewValue(value).Encode()))
func (c *StateObject) setAddr(addr []byte, value interface{}) {
c.State.trie.Update(addr, ethutil.Encode(value))
}
func (self *StateObject) GetStorage(key *big.Int) *ethutil.Value {
@ -113,7 +113,7 @@ func (self *StateObject) GetState(k []byte) *ethutil.Value {
value := self.storage[string(key)]
if value == nil {
value = self.GetAddr(key)
value = self.getAddr(key)
if !value.IsNil() {
self.storage[string(key)] = value
@ -128,6 +128,7 @@ func (self *StateObject) SetState(k []byte, value *ethutil.Value) {
self.storage[string(key)] = value.Copy()
}
/*
// Iterate over each storage address and yield callback
func (self *StateObject) EachStorage(cb trie.EachCallback) {
// First loop over the uncommit/cached values in storage
@ -145,23 +146,26 @@ func (self *StateObject) EachStorage(cb trie.EachCallback) {
}
})
}
*/
func (self *StateObject) Sync() {
for key, value := range self.storage {
if value.Len() == 0 {
self.State.Trie.Delete(string(key))
self.State.trie.Delete([]byte(key))
continue
}
self.SetAddr([]byte(key), value)
self.setAddr([]byte(key), value)
}
valid, t2 := trie.ParanoiaCheck(self.State.Trie)
if !valid {
statelogger.Infof("Warn: PARANOIA: Different state storage root during copy %x vs %x\n", self.State.Root(), t2.GetRoot())
/*
valid, t2 := ptrie.ParanoiaCheck(self.State.trie, ethutil.Config.Db)
if !valid {
statelogger.Infof("Warn: PARANOIA: Different state storage root during copy %x vs %x\n", self.State.Root(), t2.Root())
self.State.Trie = t2
}
self.State.trie = t2
}
*/
}
func (c *StateObject) GetInstr(pc *big.Int) *ethutil.Value {
@ -276,8 +280,12 @@ func (c *StateObject) Init() Code {
return c.InitCode
}
func (self *StateObject) Trie() *ptrie.Trie {
return self.State.trie
}
func (self *StateObject) Root() []byte {
return self.State.Trie.GetRoot()
return self.Trie().Root()
}
func (self *StateObject) SetCode(code []byte) {
@ -302,7 +310,7 @@ func (c *StateObject) RlpDecode(data []byte) {
c.Nonce = decoder.Get(0).Uint()
c.balance = decoder.Get(1).BigInt()
c.State = New(trie.New(ethutil.Config.Db, decoder.Get(2).Interface()))
c.State = New(ptrie.New(decoder.Get(2).Bytes(), ethutil.Config.Db)) //New(trie.New(ethutil.Config.Db, decoder.Get(2).Interface()))
c.storage = make(map[string]*ethutil.Value)
c.gasPool = new(big.Int)

View file

@ -5,7 +5,7 @@ import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/trie"
"github.com/ethereum/go-ethereum/ptrie"
)
type StateSuite struct {
@ -18,9 +18,8 @@ var _ = checker.Suite(&StateSuite{})
func (s *StateSuite) TestDump(c *checker.C) {
key := []byte{0x01}
value := "foo"
node := []interface{}{key, value}
s.state.Trie.Put(node)
value := []byte("foo")
s.state.trie.Update(key, value)
dump := s.state.Dump()
c.Assert(dump, checker.NotNil)
}
@ -29,7 +28,7 @@ func (s *StateSuite) SetUpTest(c *checker.C) {
db, _ := ethdb.NewMemDatabase()
ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "")
ethutil.Config.Db = db
s.state = New(trie.New(db, ""))
s.state = New(ptrie.New(nil, db))
}
func (s *StateSuite) TestSnapshot(c *checker.C) {

View file

@ -1,11 +1,12 @@
package state
import (
"bytes"
"math/big"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/trie"
"github.com/ethereum/go-ethereum/ptrie"
)
var statelogger = logger.NewLogger("STATE")
@ -16,8 +17,8 @@ var statelogger = logger.NewLogger("STATE")
// * Contracts
// * Accounts
type StateDB struct {
// The trie for this structure
Trie *trie.Trie
//Trie *trie.Trie
trie *ptrie.Trie
stateObjects map[string]*StateObject
@ -29,8 +30,8 @@ type StateDB struct {
}
// Create a new state from a given trie
func New(trie *trie.Trie) *StateDB {
return &StateDB{Trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string]*big.Int)}
func New(trie *ptrie.Trie) *StateDB {
return &StateDB{trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string]*big.Int)}
}
func (self *StateDB) EmptyLogs() {
@ -94,6 +95,13 @@ func (self *StateDB) GetCode(addr []byte) []byte {
return nil
}
func (self *StateDB) SetCode(addr, code []byte) {
stateObject := self.GetStateObject(addr)
if stateObject != nil {
stateObject.SetCode(code)
}
}
func (self *StateDB) GetState(a, b []byte) []byte {
stateObject := self.GetStateObject(a)
if stateObject != nil {
@ -133,12 +141,12 @@ func (self *StateDB) UpdateStateObject(stateObject *StateObject) {
ethutil.Config.Db.Put(stateObject.CodeHash(), stateObject.Code)
}
self.Trie.Update(string(addr), string(stateObject.RlpEncode()))
self.trie.Update(addr, stateObject.RlpEncode())
}
// Delete the given state object and delete it from the state trie
func (self *StateDB) DeleteStateObject(stateObject *StateObject) {
self.Trie.Delete(string(stateObject.Address()))
self.trie.Delete(stateObject.Address())
delete(self.stateObjects, string(stateObject.Address()))
}
@ -152,7 +160,7 @@ func (self *StateDB) GetStateObject(addr []byte) *StateObject {
return stateObject
}
data := self.Trie.Get(string(addr))
data := self.trie.Get(addr)
if len(data) == 0 {
return nil
}
@ -199,12 +207,12 @@ func (self *StateDB) GetAccount(addr []byte) *StateObject {
//
func (s *StateDB) Cmp(other *StateDB) bool {
return s.Trie.Cmp(other.Trie)
return bytes.Equal(s.trie.Root(), other.trie.Root())
}
func (self *StateDB) Copy() *StateDB {
if self.Trie != nil {
state := New(self.Trie.Copy())
if self.trie != nil {
state := New(self.trie.Copy())
for k, stateObject := range self.stateObjects {
state.stateObjects[k] = stateObject.Copy()
}
@ -228,19 +236,19 @@ func (self *StateDB) Set(state *StateDB) {
panic("Tried setting 'state' to nil through 'Set'")
}
self.Trie = state.Trie
self.trie = state.trie
self.stateObjects = state.stateObjects
self.refund = state.refund
self.logs = state.logs
}
func (s *StateDB) Root() []byte {
return s.Trie.GetRoot()
return s.trie.Root()
}
// Resets the trie and all siblings
func (s *StateDB) Reset() {
s.Trie.Undo()
s.trie.Reset()
// Reset all nested states
for _, stateObject := range s.stateObjects {
@ -265,7 +273,7 @@ func (s *StateDB) Sync() {
stateObject.State.Sync()
}
s.Trie.Sync()
s.trie.Commit()
s.Empty()
}
@ -297,11 +305,11 @@ func (self *StateDB) Update(gasUsed *big.Int) {
// FIXME trie delete is broken
if deleted {
valid, t2 := trie.ParanoiaCheck(self.Trie)
valid, t2 := ptrie.ParanoiaCheck(self.trie, ethutil.Config.Db)
if !valid {
statelogger.Infof("Warn: PARANOIA: Different state root during copy %x vs %x\n", self.Trie.GetRoot(), t2.GetRoot())
statelogger.Infof("Warn: PARANOIA: Different state root during copy %x vs %x\n", self.trie.Root(), t2.Root())
self.Trie = t2
self.trie = t2
}
}
}

View file

@ -1,4 +1,356 @@
{
"CallContractToCreateContractAndCallItOOG" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "100000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"logs" : [
],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "998",
"code" : "0x74600c60005566602060406000f060205260076039f36000526015600b6001f0600055600060006000600060016000546000f1",
"nonce" : "1",
"storage" : {
"0x" : "0xd2571607e241ecf590ed94b12d87c94babe36db6"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
"balance" : "1301",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "99998699",
"code" : "0x",
"nonce" : "1",
"storage" : {
}
},
"d2571607e241ecf590ed94b12d87c94babe36db6" : {
"balance" : "2",
"code" : "0x602060406000f0",
"nonce" : "0",
"storage" : {
"0x" : "0x0c"
}
}
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000",
"code" : "0x74600c60005566602060406000f060205260076039f36000526015600b6001f0600055600060006000600060016000546000f1",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" : {
"data" : "0x00",
"gasLimit" : "20000000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "0"
}
},
"CallContractToCreateContractNoCash" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "100000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"logs" : [
],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000",
"code" : "0x74600c60005566602060406000f060205260076039f36000526015600b6103e9f0600055",
"nonce" : "0",
"storage" : {
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
"balance" : "709",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "99999291",
"code" : "0x",
"nonce" : "1",
"storage" : {
}
}
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000",
"code" : "0x74600c60005566602060406000f060205260076039f36000526015600b6103e9f0600055",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" : {
"data" : "0x00",
"gasLimit" : "20000000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "0"
}
},
"CallContractToCreateContractOOG" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "100000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"logs" : [
],
"out" : "0x",
"post" : {
"0000000000000000000000000000000000000000" : {
"balance" : "0",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "0",
"code" : "0x74600c60005566602060406000f060205260076039f36000526015600b6001f0600055600060006000600060006000546000f1",
"nonce" : "0",
"storage" : {
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
"balance" : "756",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "99999244",
"code" : "0x",
"nonce" : "1",
"storage" : {
}
}
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "0",
"code" : "0x74600c60005566602060406000f060205260076039f36000526015600b6001f0600055600060006000600060006000546000f1",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" : {
"data" : "0x00",
"gasLimit" : "20000000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "0"
}
},
"CallContractToCreateContractWhichWouldCreateContractIfCalled" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "100000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"logs" : [
],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "998",
"code" : "0x74600c60005566602060406000f060205260076039f36000526015600b6001f0600055600060006000600060016000546101f4f1",
"nonce" : "1",
"storage" : {
"0x" : "0xd2571607e241ecf590ed94b12d87c94babe36db6"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
"balance" : "1407",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"62c01474f089b07dae603491675dc5b5748f7049" : {
"balance" : "0",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "99998593",
"code" : "0x",
"nonce" : "1",
"storage" : {
}
},
"d2571607e241ecf590ed94b12d87c94babe36db6" : {
"balance" : "2",
"code" : "0x602060406000f0",
"nonce" : "1",
"storage" : {
"0x" : "0x0c"
}
}
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000",
"code" : "0x74600c60005566602060406000f060205260076039f36000526015600b6001f0600055600060006000600060016000546101f4f1",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" : {
"data" : "0x00",
"gasLimit" : "20000000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "0"
}
},
"CallContractToCreateContractWhichWouldCreateContractInInitCode" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "100000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"logs" : [
],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1",
"code" : "0x6b600c600055602060406000f0600052600c60146000f0",
"nonce" : "1",
"storage" : {
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
"balance" : "1016",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"62c01474f089b07dae603491675dc5b5748f7049" : {
"balance" : "0",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "99998984",
"code" : "0x",
"nonce" : "1",
"storage" : {
}
},
"d2571607e241ecf590ed94b12d87c94babe36db6" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x" : "0x0c"
}
}
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1",
"code" : "0x6b600c600055602060406000f0600052600c60146000f0",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" : {
"data" : "0x00",
"gasLimit" : "20000000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "0"
}
},
"CallRecursiveContract" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
@ -244,251 +596,6 @@
"value" : "1"
}
},
"CallTheContractToCreateContractWithInitCode" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"logs" : [
],
"out" : "0x",
"post" : {
"04110d816c380812a427968ece99b1c963dfbce6" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0x04110d816c380812a427968ece99b1c963dfbce6"
}
},
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "10001",
"code" : "0x3060025560206000600039602060006000f0",
"nonce" : "1",
"storage" : {
"0x02" : "0x095e7baea6a6c7c4c2dfeb977efac326af552d87"
}
},
"0a517d755cebbf66312b30fff713666a9cb917e0" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0x0a517d755cebbf66312b30fff713666a9cb917e0"
}
},
"24dd378f51adc67a50e339e8031fe9bd4aafab36" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0x24dd378f51adc67a50e339e8031fe9bd4aafab36"
}
},
"293f982d000532a7861ab122bdc4bbfd26bf9030" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0x293f982d000532a7861ab122bdc4bbfd26bf9030"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
"balance" : "10000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"2cf5732f017b0cf1b1f13a1478e10239716bf6b5" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0x2cf5732f017b0cf1b1f13a1478e10239716bf6b5"
}
},
"31c640b92c21a1f1465c91070b4b3b4d6854195f" : {
"balance" : "0",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"37f998764813b136ddf5a754f34063fd03065e36" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0x37f998764813b136ddf5a754f34063fd03065e36"
}
},
"37fa399a749c121f8a15ce77e3d9f9bec8020d7a" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0x37fa399a749c121f8a15ce77e3d9f9bec8020d7a"
}
},
"4f36659fa632310b6ec438dea4085b522a2dd077" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0x4f36659fa632310b6ec438dea4085b522a2dd077"
}
},
"62c01474f089b07dae603491675dc5b5748f7049" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0x62c01474f089b07dae603491675dc5b5748f7049"
}
},
"729af7294be595a0efd7d891c9e51f89c07950c7" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0x729af7294be595a0efd7d891c9e51f89c07950c7"
}
},
"83e3e5a16d3b696a0314b30b2534804dd5e11197" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0x83e3e5a16d3b696a0314b30b2534804dd5e11197"
}
},
"8703df2417e0d7c59d063caa9583cb10a4d20532" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0x8703df2417e0d7c59d063caa9583cb10a4d20532"
}
},
"8dffcd74e5b5923512916c6a64b502689cfa65e1" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0x8dffcd74e5b5923512916c6a64b502689cfa65e1"
}
},
"95a4d7cccb5204733874fa87285a176fe1e9e240" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0x95a4d7cccb5204733874fa87285a176fe1e9e240"
}
},
"99b2fcba8120bedd048fe79f5262a6690ed38c39" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0x99b2fcba8120bedd048fe79f5262a6690ed38c39"
}
},
"a4202b8b8afd5354e3e40a219bdc17f6001bf2cf" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0xa4202b8b8afd5354e3e40a219bdc17f6001bf2cf"
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "89999",
"code" : "0x",
"nonce" : "1",
"storage" : {
}
},
"a9647f4a0a14042d91dc33c0328030a7157c93ae" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0xa9647f4a0a14042d91dc33c0328030a7157c93ae"
}
},
"aa6cffe5185732689c18f37a7f86170cb7304c2a" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0xaa6cffe5185732689c18f37a7f86170cb7304c2a"
}
},
"aae4a2e3c51c04606dcb3723456e58f3ed214f45" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0xaae4a2e3c51c04606dcb3723456e58f3ed214f45"
}
},
"c37a43e940dfb5baf581a0b82b351d48305fc885" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0xc37a43e940dfb5baf581a0b82b351d48305fc885"
}
},
"d2571607e241ecf590ed94b12d87c94babe36db6" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0xd2571607e241ecf590ed94b12d87c94babe36db6"
}
},
"f735071cbee190d76b704ce68384fc21e389fbe7" : {
"balance" : "0",
"code" : "0x",
"nonce" : "1",
"storage" : {
"0x02" : "0xf735071cbee190d76b704ce68384fc21e389fbe7"
}
}
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "10000",
"code" : "0x3060025560206000600039602060006000f0",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" : {
"data" : "0x00",
"gasLimit" : "10000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "1"
}
},
"CallTheContractToCreateEmptyContract" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
@ -651,6 +758,60 @@
"value" : "1"
}
},
"StackUnderFlowContractCreation" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"logs" : [
],
"out" : "0x",
"post" : {
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
"balance" : "1000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"6295ee1b4f6dd65047762f924ecd367c17eabf8f" : {
"balance" : "0",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "9000",
"code" : "0x",
"nonce" : "1",
"storage" : {
}
}
},
"pre" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" : {
"data" : "0x6000f1",
"gasLimit" : "1000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "",
"value" : "0"
}
},
"TransactionContractCreation" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",

View file

@ -552,14 +552,14 @@
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
"balance" : "261077",
"balance" : "261097",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "999999999999638923",
"balance" : "999999999999638903",
"code" : "0x",
"nonce" : "1",
"storage" : {
@ -584,7 +584,7 @@
},
"transaction" : {
"data" : "",
"gasLimit" : "365223",
"gasLimit" : "365243",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -610,19 +610,19 @@
"code" : "0x600160005401600055600060006000600060003060e05a03f1600155",
"nonce" : "0",
"storage" : {
"0x" : "0x03ff",
"0x" : "0x0400",
"0x01" : "0x01"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
"balance" : "261078",
"balance" : "260996",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "999999999999638922",
"balance" : "999999999999639004",
"code" : "0x",
"nonce" : "1",
"storage" : {
@ -647,7 +647,7 @@
},
"transaction" : {
"data" : "",
"gasLimit" : "365224",
"gasLimit" : "365244",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -4166,11 +4166,10 @@
"code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000527faaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa6020526000604060406000601773945304eb96065b2a98b57a48a06ae28d285a71b56103e8f1600055",
"nonce" : "0",
"storage" : {
"0x" : "0x01"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
"balance" : "1165",
"balance" : "1636",
"code" : "0x",
"nonce" : "0",
"storage" : {
@ -4181,11 +4180,10 @@
"code" : "0x60003554156009570060203560003555",
"nonce" : "0",
"storage" : {
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" : "0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa"
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "999999999999898835",
"balance" : "999999999999898364",
"code" : "0x",
"nonce" : "1",
"storage" : {
@ -4243,11 +4241,10 @@
"code" : "0x7feeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff006000527faaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa6020526000620f120660406000601773945304eb96065b2a98b57a48a06ae28d285a71b56101f4f1600055",
"nonce" : "0",
"storage" : {
"0x" : "0x01"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
"balance" : "1165",
"balance" : "1136",
"code" : "0x",
"nonce" : "0",
"storage" : {
@ -4258,11 +4255,10 @@
"code" : "0x60003554156009570060203560003555",
"nonce" : "0",
"storage" : {
"0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00" : "0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa"
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "999999999999898835",
"balance" : "999999999999898864",
"code" : "0x",
"nonce" : "1",
"storage" : {
@ -4320,11 +4316,10 @@
"code" : "0x7feeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff006000527faaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa602052600060406000620f1206601773945304eb96065b2a98b57a48a06ae28d285a71b56101f4f1600055",
"nonce" : "0",
"storage" : {
"0x" : "0x01"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
"balance" : "965",
"balance" : "1136",
"code" : "0x",
"nonce" : "0",
"storage" : {
@ -4338,7 +4333,7 @@
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "999999999999899035",
"balance" : "999999999999898864",
"code" : "0x",
"nonce" : "1",
"storage" : {
@ -4848,18 +4843,17 @@
"code" : "0x60003554156009570060203560003555",
"nonce" : "0",
"storage" : {
"0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa" : "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
"balance" : "1149",
"balance" : "1000000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "999999999999898851",
"balance" : "999999999998900000",
"code" : "0x",
"nonce" : "1",
"storage" : {
@ -4892,6 +4886,68 @@
"value" : "100000"
}
},
"callValue" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "10000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"logs" : [
],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000100000",
"code" : "0x34600055",
"nonce" : "0",
"storage" : {
"0x" : "0x0186a0"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
"balance" : "802",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "999999999999899198",
"code" : "0x",
"nonce" : "1",
"storage" : {
}
}
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"code" : "0x34600055",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000000000000000000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" : {
"data" : "",
"gasLimit" : "10000000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000"
}
},
"callcodeToNameRegistrator0" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
@ -4910,12 +4966,10 @@
"code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000527faaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa6020526000604060406000601773945304eb96065b2a98b57a48a06ae28d285a71b56103e8f2600055",
"nonce" : "0",
"storage" : {
"0x" : "0x01",
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" : "0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
"balance" : "1165",
"balance" : "1636",
"code" : "0x",
"nonce" : "0",
"storage" : {
@ -4929,7 +4983,7 @@
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "999999999999898835",
"balance" : "999999999999898364",
"code" : "0x",
"nonce" : "1",
"storage" : {
@ -5046,6 +5100,68 @@
"value" : "100000"
}
},
"callerAccountBalance" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "10000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"logs" : [
],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000100000",
"code" : "0x3331600055",
"nonce" : "0",
"storage" : {
"0x" : "0x0de0b6b3a6c9e2e0"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
"balance" : "822",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "999999999999899178",
"code" : "0x",
"nonce" : "1",
"storage" : {
}
}
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"code" : "0x3331600055",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000000000000000000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" : {
"data" : "",
"gasLimit" : "10000000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000"
}
},
"callstatelessToReturn1" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
@ -5367,6 +5483,68 @@
"value" : "100000"
}
},
"currentAccountBalance" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "10000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"logs" : [
],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000100000",
"code" : "0x3031600055",
"nonce" : "0",
"storage" : {
"0x" : "0x0de0b6b3a76586a0"
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
"balance" : "822",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "999999999999899178",
"code" : "0x",
"nonce" : "1",
"storage" : {
}
}
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"code" : "0x3031600055",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000000000000000000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" : {
"data" : "",
"gasLimit" : "10000000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000"
}
},
"return0" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",

View file

@ -1,4 +1,156 @@
{
"ContractStoreClearsOOG" : {
"env" : {
"currentCoinbase" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"currentDifficulty" : "45678256",
"currentGasLimit" : "10000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"logs" : [
],
"out" : "0x",
"post" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "6390",
"code" : "0x",
"nonce" : "1",
"storage" : {
}
},
"b94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "600",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"d2571607e241ecf590ed94b12d87c94babe36db6" : {
"balance" : "10",
"code" : "0x600060005560006001556000600255600060035560006004556000600555600060065560006007556000600855600c600955",
"nonce" : "0",
"storage" : {
"0x" : "0x0c",
"0x01" : "0x0c",
"0x02" : "0x0c",
"0x03" : "0x0c",
"0x04" : "0x0c",
"0x05" : "0x0c",
"0x06" : "0x0c",
"0x07" : "0x0c",
"0x08" : "0x0c",
"0x09" : "0x0c"
}
}
},
"pre" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "7000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"d2571607e241ecf590ed94b12d87c94babe36db6" : {
"balance" : "0",
"code" : "0x600060005560006001556000600255600060035560006004556000600555600060065560006007556000600855600c600955",
"nonce" : "0",
"storage" : {
"0x" : "0x0c",
"0x01" : "0x0c",
"0x02" : "0x0c",
"0x03" : "0x0c",
"0x04" : "0x0c",
"0x05" : "0x0c",
"0x06" : "0x0c",
"0x07" : "0x0c",
"0x08" : "0x0c",
"0x09" : "0x0c"
}
}
},
"transaction" : {
"data" : "",
"gasLimit" : "600",
"gasPrice" : "1",
"nonce" : "",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "d2571607e241ecf590ed94b12d87c94babe36db6",
"value" : "10"
}
},
"ContractStoreClearsSuccess" : {
"env" : {
"currentCoinbase" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"currentDifficulty" : "45678256",
"currentGasLimit" : "10000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"logs" : [
],
"out" : "0x",
"post" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "6730",
"code" : "0x",
"nonce" : "1",
"storage" : {
}
},
"b94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "260",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"d2571607e241ecf590ed94b12d87c94babe36db6" : {
"balance" : "10",
"code" : "0x6000600055600060015560006002556000600355600060045560006005556000600655600060075560006008556000600955",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "7000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"d2571607e241ecf590ed94b12d87c94babe36db6" : {
"balance" : "0",
"code" : "0x6000600055600060015560006002556000600355600060045560006005556000600655600060075560006008556000600955",
"nonce" : "0",
"storage" : {
"0x" : "0x0c",
"0x01" : "0x0c",
"0x02" : "0x0c",
"0x03" : "0x0c",
"0x04" : "0x0c",
"0x05" : "0x0c",
"0x06" : "0x0c",
"0x07" : "0x0c",
"0x08" : "0x0c",
"0x09" : "0x0c"
}
}
},
"transaction" : {
"data" : "",
"gasLimit" : "600",
"gasPrice" : "1",
"nonce" : "",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "d2571607e241ecf590ed94b12d87c94babe36db6",
"value" : "10"
}
},
"EmptyTransaction" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
@ -273,5 +425,59 @@
"to" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"value" : "502"
}
},
"TransactionTooManyRlpElements" : {
"env" : {
"currentCoinbase" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"currentDifficulty" : "45678256",
"currentGasLimit" : "10000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"logs" : [
],
"out" : "0x",
"post" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "93990",
"code" : "0x",
"nonce" : "1",
"storage" : {
}
},
"b94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "6000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"d2571607e241ecf590ed94b12d87c94babe36db6" : {
"balance" : "10",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" : {
"data" : "",
"gasLimit" : "1600",
"gasPrice" : "12",
"nonce" : "",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "d2571607e241ecf590ed94b12d87c94babe36db6",
"value" : "10"
}
}
}

View file

@ -12,6 +12,61 @@
],
"root": "0x5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84"
},
"branchingTests": {
"in":[
["0x04110d816c380812a427968ece99b1c963dfbce6", "something"],
["0x095e7baea6a6c7c4c2dfeb977efac326af552d87", "something"],
["0x0a517d755cebbf66312b30fff713666a9cb917e0", "something"],
["0x24dd378f51adc67a50e339e8031fe9bd4aafab36", "something"],
["0x293f982d000532a7861ab122bdc4bbfd26bf9030", "something"],
["0x2cf5732f017b0cf1b1f13a1478e10239716bf6b5", "something"],
["0x31c640b92c21a1f1465c91070b4b3b4d6854195f", "something"],
["0x37f998764813b136ddf5a754f34063fd03065e36", "something"],
["0x37fa399a749c121f8a15ce77e3d9f9bec8020d7a", "something"],
["0x4f36659fa632310b6ec438dea4085b522a2dd077", "something"],
["0x62c01474f089b07dae603491675dc5b5748f7049", "something"],
["0x729af7294be595a0efd7d891c9e51f89c07950c7", "something"],
["0x83e3e5a16d3b696a0314b30b2534804dd5e11197", "something"],
["0x8703df2417e0d7c59d063caa9583cb10a4d20532", "something"],
["0x8dffcd74e5b5923512916c6a64b502689cfa65e1", "something"],
["0x95a4d7cccb5204733874fa87285a176fe1e9e240", "something"],
["0x99b2fcba8120bedd048fe79f5262a6690ed38c39", "something"],
["0xa4202b8b8afd5354e3e40a219bdc17f6001bf2cf", "something"],
["0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "something"],
["0xa9647f4a0a14042d91dc33c0328030a7157c93ae", "something"],
["0xaa6cffe5185732689c18f37a7f86170cb7304c2a", "something"],
["0xaae4a2e3c51c04606dcb3723456e58f3ed214f45", "something"],
["0xc37a43e940dfb5baf581a0b82b351d48305fc885", "something"],
["0xd2571607e241ecf590ed94b12d87c94babe36db6", "something"],
["0xf735071cbee190d76b704ce68384fc21e389fbe7", "something"],
["0x04110d816c380812a427968ece99b1c963dfbce6", null],
["0x095e7baea6a6c7c4c2dfeb977efac326af552d87", null],
["0x0a517d755cebbf66312b30fff713666a9cb917e0", null],
["0x24dd378f51adc67a50e339e8031fe9bd4aafab36", null],
["0x293f982d000532a7861ab122bdc4bbfd26bf9030", null],
["0x2cf5732f017b0cf1b1f13a1478e10239716bf6b5", null],
["0x31c640b92c21a1f1465c91070b4b3b4d6854195f", null],
["0x37f998764813b136ddf5a754f34063fd03065e36", null],
["0x37fa399a749c121f8a15ce77e3d9f9bec8020d7a", null],
["0x4f36659fa632310b6ec438dea4085b522a2dd077", null],
["0x62c01474f089b07dae603491675dc5b5748f7049", null],
["0x729af7294be595a0efd7d891c9e51f89c07950c7", null],
["0x83e3e5a16d3b696a0314b30b2534804dd5e11197", null],
["0x8703df2417e0d7c59d063caa9583cb10a4d20532", null],
["0x8dffcd74e5b5923512916c6a64b502689cfa65e1", null],
["0x95a4d7cccb5204733874fa87285a176fe1e9e240", null],
["0x99b2fcba8120bedd048fe79f5262a6690ed38c39", null],
["0xa4202b8b8afd5354e3e40a219bdc17f6001bf2cf", null],
["0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", null],
["0xa9647f4a0a14042d91dc33c0328030a7157c93ae", null],
["0xaa6cffe5185732689c18f37a7f86170cb7304c2a", null],
["0xaae4a2e3c51c04606dcb3723456e58f3ed214f45", null],
["0xc37a43e940dfb5baf581a0b82b351d48305fc885", null],
["0xd2571607e241ecf590ed94b12d87c94babe36db6", null],
["0xf735071cbee190d76b704ce68384fc21e389fbe7", null]
],
"root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
},
"jeff": {
"in": [
["0x0000000000000000000000000000000000000000000000000000000000000045", "0x22b224a1420a802ab51d326e29fa98e34c4f24ea"],

View file

@ -0,0 +1,46 @@
{
"randomVMtest" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x63705a0b6b69a11044518876953776",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9998",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x63705a0b6b69a11044518876953776",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x63705a0b6b69a11044518876953776",
"nonce" : "0",
"storage" : {
}
}
}
}
}

View file

@ -0,0 +1,46 @@
{
"randomVMtest" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x5b6ca284a383618e389e20848652",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9998",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x5b6ca284a383618e389e20848652",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x5b6ca284a383618e389e20848652",
"nonce" : "0",
"storage" : {
}
}
}
}
}

View file

@ -0,0 +1,46 @@
{
"randomVMtest" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x6a5a558f440b6d7530533a356b7589",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9998",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x6a5a558f440b6d7530533a356b7589",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x6a5a558f440b6d7530533a356b7589",
"nonce" : "0",
"storage" : {
}
}
}
}
}

View file

@ -0,0 +1,46 @@
{
"randomVMtest" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x68931051429d9b75069160636bff",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9997",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x68931051429d9b75069160636bff",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x68931051429d9b75069160636bff",
"nonce" : "0",
"storage" : {
}
}
}
}
}

View file

@ -0,0 +1,46 @@
{
"randomVMtest" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x5a385968087df24038513535",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9996",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x5a385968087df24038513535",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x5a385968087df24038513535",
"nonce" : "0",
"storage" : {
}
}
}
}
}

View file

@ -0,0 +1,46 @@
{
"randomVMtest" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x3463823507",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9998",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x3463823507",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x3463823507",
"nonce" : "0",
"storage" : {
}
}
}
}
}

View file

@ -0,0 +1,46 @@
{
"randomVMtest" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x66a3535b8b8af38a658b3b",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9998",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x66a3535b8b8af38a658b3b",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x66a3535b8b8af38a658b3b",
"nonce" : "0",
"storage" : {
}
}
}
}
}

View file

@ -0,0 +1,46 @@
{
"randomVMtest" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x63794554ff426ef0a18a8a9c6e137a8c",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9997",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x63794554ff426ef0a18a8a9c6e137a8c",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x63794554ff426ef0a18a8a9c6e137a8c",
"nonce" : "0",
"storage" : {
}
}
}
}
}

View file

@ -0,0 +1,46 @@
{
"randomVMtest" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x66509a88803091046789893377",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9998",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x66509a88803091046789893377",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x66509a88803091046789893377",
"nonce" : "0",
"storage" : {
}
}
}
}
}

View file

@ -0,0 +1,46 @@
{
"randomVMtest" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x426a507bf0a09c7b6a381314",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9998",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x426a507bf0a09c7b6a381314",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x426a507bf0a09c7b6a381314",
"nonce" : "0",
"storage" : {
}
}
}
}
}

View file

@ -0,0 +1,46 @@
{
"randomVMtest" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x306383a29e826a05865054039f36",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9997",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x306383a29e826a05865054039f36",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x306383a29e826a05865054039f36",
"nonce" : "0",
"storage" : {
}
}
}
}
}

View file

@ -0,0 +1,46 @@
{
"randomVMtest" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x66691196a4a00209506d8290855570",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9997",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x66691196a4a00209506d8290855570",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x66691196a4a00209506d8290855570",
"nonce" : "0",
"storage" : {
}
}
}
}
}

View file

@ -0,0 +1,46 @@
{
"randomVMtest" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x645b7753a4806e848481311373338b66",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9998",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x645b7753a4806e848481311373338b66",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x645b7753a4806e848481311373338b66",
"nonce" : "0",
"storage" : {
}
}
}
}
}

View file

@ -0,0 +1,46 @@
{
"randomVMtest" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x386609796d5a7b53",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9998",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x386609796d5a7b53",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x386609796d5a7b53",
"nonce" : "0",
"storage" : {
}
}
}
}
}

View file

@ -0,0 +1,46 @@
{
"randomVMtest" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x67767162694473797350685804",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9997",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x67767162694473797350685804",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x67767162694473797350685804",
"nonce" : "0",
"storage" : {
}
}
}
}
}

View file

@ -0,0 +1,46 @@
{
"randomVMtest" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x33666b7c09ff376d",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9998",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x33666b7c09ff376d",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x33666b7c09ff376d",
"nonce" : "0",
"storage" : {
}
}
}
}
}

Some files were not shown because too many files have changed in this diff Show more