aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/ethtest/main.go16
-rw-r--r--cmd/evm/main.go2
-rw-r--r--cmd/mist/assets/examples/coin.html7
-rw-r--r--cmd/utils/customflags.go133
-rw-r--r--cmd/utils/customflags_test.go28
-rw-r--r--cmd/utils/flags.go7
-rw-r--r--core/block_processor.go11
-rw-r--r--core/chain_makers.go13
-rw-r--r--core/chain_manager_test.go4
-rw-r--r--core/filter.go6
-rw-r--r--core/state/log.go88
-rw-r--r--core/state/managed_state.go4
-rw-r--r--core/state/managed_state_test.go9
-rw-r--r--core/state/statedb.go40
-rw-r--r--core/state_transition.go31
-rw-r--r--core/transaction_pool.go87
-rw-r--r--core/transaction_pool_test.go97
-rw-r--r--core/types/bloom9.go8
-rw-r--r--core/types/receipt.go19
-rw-r--r--core/vm/environment.go2
-rw-r--r--core/vm/vm.go3
-rw-r--r--core/vm_env.go2
-rw-r--r--eth/backend.go4
-rw-r--r--miner/worker.go4
-rw-r--r--rpc/args.go5
-rw-r--r--rpc/args_test.go15
-rw-r--r--rpc/responses.go16
-rw-r--r--rpc/responses_test.go4
-rw-r--r--tests/helper/vm.go2
-rw-r--r--tests/vm/gh_test.go32
-rw-r--r--xeth/types.go16
-rw-r--r--xeth/xeth.go20
32 files changed, 411 insertions, 324 deletions
diff --git a/cmd/ethtest/main.go b/cmd/ethtest/main.go
index 952ba1bd6..3c5b2cedf 100644
--- a/cmd/ethtest/main.go
+++ b/cmd/ethtest/main.go
@@ -176,23 +176,23 @@ func RunVmTest(r io.Reader) (failed int) {
failed = 1
} else {
for i, log := range test.Logs {
- if common.HexToAddress(log.AddressF) != logs[i].Address() {
- helper.Log.Infof("'%s' log address failed. Expected %v got %x", name, log.AddressF, logs[i].Address())
+ if common.HexToAddress(log.AddressF) != logs[i].Address {
+ helper.Log.Infof("'%s' log address failed. Expected %v got %x", name, log.AddressF, logs[i].Address)
failed = 1
}
- if !bytes.Equal(logs[i].Data(), helper.FromHex(log.DataF)) {
- helper.Log.Infof("'%s' log data failed. Expected %v got %x", name, log.DataF, logs[i].Data())
+ if !bytes.Equal(logs[i].Data, helper.FromHex(log.DataF)) {
+ helper.Log.Infof("'%s' log data failed. Expected %v got %x", name, log.DataF, logs[i].Data)
failed = 1
}
- if len(log.TopicsF) != len(logs[i].Topics()) {
- helper.Log.Infof("'%s' log topics length failed. Expected %d got %d", name, len(log.TopicsF), logs[i].Topics())
+ if len(log.TopicsF) != len(logs[i].Topics) {
+ helper.Log.Infof("'%s' log topics length failed. Expected %d got %d", name, len(log.TopicsF), logs[i].Topics)
failed = 1
} else {
for j, topic := range log.TopicsF {
- if common.HexToHash(topic) != logs[i].Topics()[j] {
- helper.Log.Infof("'%s' log topic[%d] failed. Expected %v got %x", name, j, topic, logs[i].Topics()[j])
+ if common.HexToHash(topic) != logs[i].Topics[j] {
+ helper.Log.Infof("'%s' log topic[%d] failed. Expected %v got %x", name, j, topic, logs[i].Topics[j])
failed = 1
}
}
diff --git a/cmd/evm/main.go b/cmd/evm/main.go
index 5eb753fa8..561f1a943 100644
--- a/cmd/evm/main.go
+++ b/cmd/evm/main.go
@@ -133,7 +133,7 @@ func (self *VMEnv) GetHash(n uint64) common.Hash {
}
return common.Hash{}
}
-func (self *VMEnv) AddLog(log state.Log) {
+func (self *VMEnv) AddLog(log *state.Log) {
self.state.AddLog(log)
}
func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error {
diff --git a/cmd/mist/assets/examples/coin.html b/cmd/mist/assets/examples/coin.html
index a734e144f..257a19977 100644
--- a/cmd/mist/assets/examples/coin.html
+++ b/cmd/mist/assets/examples/coin.html
@@ -72,16 +72,19 @@
// deploy if not exist
if(address === null) {
var code = "0x60056013565b61014f8061003a6000396000f35b620f42406000600033600160a060020a0316815260200190815260200160002081905550560060e060020a600035048063d0679d3414610020578063e3d670d71461003457005b61002e600435602435610049565b60006000f35b61003f600435610129565b8060005260206000f35b806000600033600160a060020a03168152602001908152602001600020541061007157610076565b610125565b806000600033600160a060020a03168152602001908152602001600020908154039081905550806000600084600160a060020a031681526020019081526020016000209081540190819055508033600160a060020a03167fb52dda022b6c1a1f40905a85f257f689aa5d69d850e49cf939d688fbe5af594660006000a38082600160a060020a03167fb52dda022b6c1a1f40905a85f257f689aa5d69d850e49cf939d688fbe5af594660006000a35b5050565b60006000600083600160a060020a0316815260200190815260200160002054905091905056";
- address = web3.eth.sendTransaction({from: eth.coinbase, data: code, gas: "1000000"});
+ address = web3.eth.sendTransaction({from: eth.accounts[0], data: code, gas: "1000000"});
localStorage.setItem("address", address);
}
document.querySelector("#contract_addr").innerHTML = address;
var Contract = web3.eth.contract(desc);
contract = new Contract(address);
- contract.Changed({from: eth.accounts[0]}).watch(function() {
+ var filter = contract.Changed({from: eth.accounts[0]})
+ filter.watch(function(logs) {
+ console.log(logs);
refresh();
});
+window.filter = filter;
function refresh() {
document.querySelector("#balance").innerHTML = contract.call({from:eth.coinbase}).balance(eth.coinbase);
diff --git a/cmd/utils/customflags.go b/cmd/utils/customflags.go
new file mode 100644
index 000000000..a623ae19c
--- /dev/null
+++ b/cmd/utils/customflags.go
@@ -0,0 +1,133 @@
+package utils
+
+import (
+ "flag"
+ "fmt"
+ "os"
+ "os/user"
+ "path/filepath"
+ "strings"
+
+ "github.com/codegangsta/cli"
+)
+
+// Custom type which is registered in the flags library which cli uses for
+// argument parsing. This allows us to expand Value to an absolute path when
+// the argument is parsed
+type DirectoryString struct {
+ Value string
+}
+
+func (self DirectoryString) String() string {
+ return self.Value
+}
+
+func (self DirectoryString) Set(value string) error {
+ self.Value = expandPath(value)
+ return nil
+}
+
+// Custom cli.Flag type which expand the received string to an absolute path.
+// e.g. ~/.ethereum -> /home/username/.ethereum
+type DirectoryFlag struct {
+ cli.GenericFlag
+ Name string
+ Value DirectoryString
+ Usage string
+ EnvVar string
+}
+
+func (self DirectoryFlag) String() string {
+ var fmtString string
+ fmtString = "%s %v\t%v"
+
+ if len(self.Value.Value) > 0 {
+ fmtString = "%s \"%v\"\t%v"
+ } else {
+ fmtString = "%s %v\t%v"
+ }
+
+ return withEnvHint(self.EnvVar, fmt.Sprintf(fmtString, prefixedNames(self.Name), self.Value.Value, self.Usage))
+}
+
+func eachName(longName string, fn func(string)) {
+ parts := strings.Split(longName, ",")
+ for _, name := range parts {
+ name = strings.Trim(name, " ")
+ fn(name)
+ }
+}
+
+// called by cli library, grabs variable from environment (if in env)
+// and adds variable to flag set for parsing.
+func (self DirectoryFlag) Apply(set *flag.FlagSet) {
+ if self.EnvVar != "" {
+ for _, envVar := range strings.Split(self.EnvVar, ",") {
+ envVar = strings.TrimSpace(envVar)
+ if envVal := os.Getenv(envVar); envVal != "" {
+ self.Value.Value = envVal
+ break
+ }
+ }
+ }
+
+ eachName(self.Name, func(name string) {
+ set.Var(self.Value, self.Name, "a: "+self.Usage)
+ })
+
+}
+
+func prefixFor(name string) (prefix string) {
+ if len(name) == 1 {
+ prefix = "-"
+ } else {
+ prefix = "--"
+ }
+
+ return
+}
+
+func prefixedNames(fullName string) (prefixed string) {
+ parts := strings.Split(fullName, ",")
+ for i, name := range parts {
+ name = strings.Trim(name, " ")
+ prefixed += prefixFor(name) + name
+ if i < len(parts)-1 {
+ prefixed += ", "
+ }
+ }
+ return
+}
+
+func withEnvHint(envVar, str string) string {
+ envText := ""
+ if envVar != "" {
+ envText = fmt.Sprintf(" [$%s]", strings.Join(strings.Split(envVar, ","), ", $"))
+ }
+ return str + envText
+}
+
+func (self DirectoryFlag) getName() string {
+ return self.Name
+}
+
+func (self *DirectoryFlag) Set(value string) {
+ self.Value.Value = value
+}
+
+// Expands a file path
+// 1. replace tilde with users home dir
+// 2. expands embedded environment variables
+// 3. cleans the path, e.g. /a/b/../c -> /a/c
+// Note, it has limitations, e.g. ~someuser/tmp will not be expanded
+func expandPath(p string) string {
+ if strings.HasPrefix(p, "~/") || strings.HasPrefix(p, "~\\") {
+ if user, err := user.Current(); err == nil {
+ if err == nil {
+ p = strings.Replace(p, "~", user.HomeDir, 1)
+ }
+ }
+ }
+
+ return filepath.Clean(os.ExpandEnv(p))
+}
diff --git a/cmd/utils/customflags_test.go b/cmd/utils/customflags_test.go
new file mode 100644
index 000000000..11deb38ef
--- /dev/null
+++ b/cmd/utils/customflags_test.go
@@ -0,0 +1,28 @@
+package utils
+
+import (
+ "os"
+ "os/user"
+ "testing"
+)
+
+func TestPathExpansion(t *testing.T) {
+
+ user, _ := user.Current()
+
+ tests := map[string]string{
+ "/home/someuser/tmp": "/home/someuser/tmp",
+ "~/tmp": user.HomeDir + "/tmp",
+ "$DDDXXX/a/b": "/tmp/a/b",
+ "/a/b/": "/a/b",
+ }
+
+ os.Setenv("DDDXXX", "/tmp")
+
+ for test, expected := range tests {
+ got := expandPath(test)
+ if got != expected {
+ t.Errorf("test %s, got %s, expected %s\n", test, got, expected)
+ }
+ }
+}
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 51844a68e..3ad06653e 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -68,10 +68,10 @@ func NewApp(version, usage string) *cli.App {
var (
// General settings
- DataDirFlag = cli.StringFlag{
+ DataDirFlag = DirectoryFlag{
Name: "datadir",
Usage: "Data directory to be used",
- Value: common.DefaultDataDir(),
+ Value: DirectoryString{common.DefaultDataDir()},
}
ProtocolVersionFlag = cli.IntFlag{
Name: "protocolversion",
@@ -231,7 +231,8 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
// Set verbosity on glog
glog.SetV(ctx.GlobalInt(LogLevelFlag.Name))
// Set the log type
- glog.SetToStderr(ctx.GlobalBool(LogToStdErrFlag.Name))
+ //glog.SetToStderr(ctx.GlobalBool(LogToStdErrFlag.Name))
+ glog.SetToStderr(true)
// Set the log dir
glog.SetLogDir(ctx.GlobalString(LogFileFlag.Name))
diff --git a/core/block_processor.go b/core/block_processor.go
index 39134c63e..7aded346a 100644
--- a/core/block_processor.go
+++ b/core/block_processor.go
@@ -73,7 +73,7 @@ func (sm *BlockProcessor) TransitionState(statedb *state.StateDB, parent, block
func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, statedb *state.StateDB, block *types.Block, tx *types.Transaction, usedGas *big.Int, transientProcess bool) (*types.Receipt, *big.Int, error) {
// If we are mining this block and validating we want to set the logs back to 0
- statedb.EmptyLogs()
+ //statedb.EmptyLogs()
cb := statedb.GetStateObject(coinbase.Address())
_, gas, err := ApplyMessage(NewEnv(statedb, self.bc, tx, block), tx, cb)
@@ -89,7 +89,9 @@ func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, stated
cumulative := new(big.Int).Set(usedGas.Add(usedGas, gas))
receipt := types.NewReceipt(statedb.Root().Bytes(), cumulative)
- receipt.SetLogs(statedb.Logs())
+
+ logs := statedb.GetLogs(tx.Hash())
+ receipt.SetLogs(logs)
receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
glog.V(logger.Debug).Infoln(receipt)
@@ -97,7 +99,6 @@ func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, stated
// Notify all subscribers
if !transientProcess {
go self.eventMux.Post(TxPostEvent{tx})
- logs := statedb.Logs()
go self.eventMux.Post(logs)
}
@@ -115,7 +116,9 @@ func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, state
cumulativeSum = new(big.Int)
)
- for _, tx := range txs {
+ for i, tx := range txs {
+ statedb.StartRecord(tx.Hash(), block.Hash(), i)
+
receipt, txGas, err := self.ApplyTransaction(coinbase, statedb, block, tx, totalUsedGas, transientProcess)
if err != nil && (IsNonceErr(err) || state.IsGasLimitErr(err) || IsInvalidTxErr(err)) {
return nil, err
diff --git a/core/chain_makers.go b/core/chain_makers.go
index bbf1b1439..810741820 100644
--- a/core/chain_makers.go
+++ b/core/chain_makers.go
@@ -45,8 +45,8 @@ func NewChainMan(block *types.Block, eventMux *event.TypeMux, db common.Database
return newChainManager(block, eventMux, db)
}
-func NewBlockProc(db common.Database, txpool *TxPool, cman *ChainManager, eventMux *event.TypeMux) *BlockProcessor {
- return newBlockProcessor(db, txpool, cman, eventMux)
+func NewBlockProc(db common.Database, cman *ChainManager, eventMux *event.TypeMux) *BlockProcessor {
+ return newBlockProcessor(db, cman, eventMux)
}
func NewCanonical(n int, db common.Database) (*BlockProcessor, error) {
@@ -120,8 +120,10 @@ func newChainManager(block *types.Block, eventMux *event.TypeMux, db common.Data
}
// block processor with fake pow
-func newBlockProcessor(db common.Database, txpool *TxPool, cman *ChainManager, eventMux *event.TypeMux) *BlockProcessor {
- bman := NewBlockProcessor(db, db, FakePow{}, txpool, newChainManager(nil, eventMux, db), eventMux)
+func newBlockProcessor(db common.Database, cman *ChainManager, eventMux *event.TypeMux) *BlockProcessor {
+ chainMan := newChainManager(nil, eventMux, db)
+ txpool := NewTxPool(eventMux, chainMan.State)
+ bman := NewBlockProcessor(db, db, FakePow{}, txpool, chainMan, eventMux)
return bman
}
@@ -129,9 +131,8 @@ func newBlockProcessor(db common.Database, txpool *TxPool, cman *ChainManager, e
// on result of makeChain
func newCanonical(n int, db common.Database) (*BlockProcessor, error) {
eventMux := &event.TypeMux{}
- txpool := NewTxPool(eventMux)
- bman := newBlockProcessor(db, txpool, newChainManager(nil, eventMux, db), eventMux)
+ bman := newBlockProcessor(db, newChainManager(nil, eventMux, db), eventMux)
bman.bc.SetProcessor(bman)
parent := bman.bc.CurrentBlock()
if n == 0 {
diff --git a/core/chain_manager_test.go b/core/chain_manager_test.go
index bf172f3bf..19afe0d5c 100644
--- a/core/chain_manager_test.go
+++ b/core/chain_manager_test.go
@@ -255,7 +255,7 @@ func TestChainInsertions(t *testing.T) {
var eventMux event.TypeMux
chainMan := NewChainManager(db, db, &eventMux)
- txPool := NewTxPool(&eventMux)
+ txPool := NewTxPool(&eventMux, chainMan.State)
blockMan := NewBlockProcessor(db, db, nil, txPool, chainMan, &eventMux)
chainMan.SetProcessor(blockMan)
@@ -301,7 +301,7 @@ func TestChainMultipleInsertions(t *testing.T) {
}
var eventMux event.TypeMux
chainMan := NewChainManager(db, db, &eventMux)
- txPool := NewTxPool(&eventMux)
+ txPool := NewTxPool(&eventMux, chainMan.State)
blockMan := NewBlockProcessor(db, db, nil, txPool, chainMan, &eventMux)
chainMan.SetProcessor(blockMan)
done := make(chan bool, max)
diff --git a/core/filter.go b/core/filter.go
index 1dca5501d..dd15db27d 100644
--- a/core/filter.go
+++ b/core/filter.go
@@ -124,17 +124,17 @@ func (self *Filter) FilterLogs(logs state.Logs) state.Logs {
// Filter the logs for interesting stuff
Logs:
for _, log := range logs {
- if len(self.address) > 0 && !includes(self.address, log.Address()) {
+ if len(self.address) > 0 && !includes(self.address, log.Address) {
continue
}
logTopics := make([]common.Hash, len(self.topics))
- copy(logTopics, log.Topics())
+ copy(logTopics, log.Topics)
for i, topics := range self.topics {
for _, topic := range topics {
var match bool
- if log.Topics()[i] == topic {
+ if log.Topics[i] == topic {
match = true
}
if !match {
diff --git a/core/state/log.go b/core/state/log.go
index f8aa4c08c..a7aa784e2 100644
--- a/core/state/log.go
+++ b/core/state/log.go
@@ -8,87 +8,31 @@ import (
"github.com/ethereum/go-ethereum/rlp"
)
-type Log interface {
- Address() common.Address
- Topics() []common.Hash
- Data() []byte
+type Log struct {
+ Address common.Address
+ Topics []common.Hash
+ Data []byte
+ Number uint64
- Number() uint64
+ TxHash common.Hash
+ TxIndex uint
+ BlockHash common.Hash
+ Index uint
}
-type StateLog struct {
- address common.Address
- topics []common.Hash
- data []byte
- number uint64
+func NewLog(address common.Address, topics []common.Hash, data []byte, number uint64) *Log {
+ return &Log{Address: address, Topics: topics, Data: data, Number: number}
}
-func NewLog(address common.Address, topics []common.Hash, data []byte, number uint64) *StateLog {
- return &StateLog{address, topics, data, number}
+func (self *Log) EncodeRLP(w io.Writer) error {
+ return rlp.Encode(w, []interface{}{self.Address, self.Topics, self.Data})
}
-func (self *StateLog) Address() common.Address {
- return self.address
+func (self *Log) String() string {
+ return fmt.Sprintf(`log: %x %x %x`, self.Address, self.Topics, self.Data)
}
-func (self *StateLog) Topics() []common.Hash {
- return self.topics
-}
-
-func (self *StateLog) Data() []byte {
- return self.data
-}
-
-func (self *StateLog) Number() uint64 {
- return self.number
-}
-
-/*
-func NewLogFromValue(decoder *common.Value) *StateLog {
- var extlog struct {
-
- }
-
- log := &StateLog{
- address: decoder.Get(0).Bytes(),
- data: decoder.Get(2).Bytes(),
- }
-
- it := decoder.Get(1).NewIterator()
- for it.Next() {
- log.topics = append(log.topics, it.Value().Bytes())
- }
-
- return log
-}
-*/
-
-func (self *StateLog) EncodeRLP(w io.Writer) error {
- return rlp.Encode(w, []interface{}{self.address, self.topics, self.data})
-}
-
-/*
-func (self *StateLog) RlpData() interface{} {
- return []interface{}{self.address, common.ByteSliceToInterface(self.topics), self.data}
-}
-*/
-
-func (self *StateLog) String() string {
- return fmt.Sprintf(`log: %x %x %x`, self.address, self.topics, self.data)
-}
-
-type Logs []Log
-
-/*
-func (self Logs) RlpData() interface{} {
- data := make([]interface{}, len(self))
- for i, log := range self {
- data[i] = log.RlpData()
- }
-
- return data
-}
-*/
+type Logs []*Log
func (self Logs) String() (ret string) {
for _, log := range self {
diff --git a/core/state/managed_state.go b/core/state/managed_state.go
index ddf337af3..9d2fc48e7 100644
--- a/core/state/managed_state.go
+++ b/core/state/managed_state.go
@@ -62,7 +62,7 @@ func (ms *ManagedState) NewNonce(addr common.Address) uint64 {
}
}
account.nonces = append(account.nonces, true)
- return uint64(len(account.nonces)) + account.nstart
+ return uint64(len(account.nonces)-1) + account.nstart
}
// GetNonce returns the canonical nonce for the managed or unmanged account
@@ -109,5 +109,5 @@ func (ms *ManagedState) getAccount(addr common.Address) *account {
}
func newAccount(so *StateObject) *account {
- return &account{so, so.nonce - 1, nil}
+ return &account{so, so.nonce, nil}
}
diff --git a/core/state/managed_state_test.go b/core/state/managed_state_test.go
index 766231d21..c7ef2b323 100644
--- a/core/state/managed_state_test.go
+++ b/core/state/managed_state_test.go
@@ -4,12 +4,15 @@ import (
"testing"
"github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/ethdb"
)
var addr = common.BytesToAddress([]byte("test"))
func create() (*ManagedState, *account) {
- ms := ManageState(&StateDB{stateObjects: make(map[string]*StateObject)})
+ db, _ := ethdb.NewMemDatabase()
+ statedb := New(common.Hash{}, db)
+ ms := ManageState(statedb)
so := &StateObject{address: addr, nonce: 100}
ms.StateDB.stateObjects[addr.Str()] = so
ms.accounts[addr.Str()] = newAccount(so)
@@ -95,13 +98,13 @@ func TestSetNonce(t *testing.T) {
ms.SetNonce(addr, 10)
if ms.GetNonce(addr) != 10 {
- t.Errorf("Expected nonce of 10, got", ms.GetNonce(addr))
+ t.Error("Expected nonce of 10, got", ms.GetNonce(addr))
}
addr[0] = 1
ms.StateDB.SetNonce(addr, 1)
if ms.GetNonce(addr) != 1 {
- t.Errorf("Expected nonce of 1, got", ms.GetNonce(addr))
+ t.Error("Expected nonce of 1, got", ms.GetNonce(addr))
}
}
diff --git a/core/state/statedb.go b/core/state/statedb.go
index 065cbd607..b3050515b 100644
--- a/core/state/statedb.go
+++ b/core/state/statedb.go
@@ -23,29 +23,44 @@ type StateDB struct {
refund map[string]*big.Int
- logs Logs
+ thash, bhash common.Hash
+ txIndex int
+ logs map[common.Hash]Logs
}
// Create a new state from a given trie
func New(root common.Hash, db common.Database) *StateDB {
trie := trie.NewSecure(root[:], db)
- return &StateDB{db: db, trie: trie, stateObjects: make(map[string]*StateObject), refund: make(map[string]*big.Int)}
+ return &StateDB{db: db, trie: trie, stateObjects: make(map[string]*StateObject), refund: make(map[string]*big.Int), logs: make(map[common.Hash]Logs)}
}
func (self *StateDB) PrintRoot() {
self.trie.Trie.PrintRoot()
}
-func (self *StateDB) EmptyLogs() {
- self.logs = nil
+func (self *StateDB) StartRecord(thash, bhash common.Hash, ti int) {
+ self.thash = thash
+ self.bhash = bhash
+ self.txIndex = ti
}
-func (self *StateDB) AddLog(log Log) {
- self.logs = append(self.logs, log)
+func (self *StateDB) AddLog(log *Log) {
+ log.TxHash = self.thash
+ log.BlockHash = self.bhash
+ log.TxIndex = uint(self.txIndex)
+ self.logs[self.thash] = append(self.logs[self.thash], log)
+}
+
+func (self *StateDB) GetLogs(hash common.Hash) Logs {
+ return self.logs[hash]
}
func (self *StateDB) Logs() Logs {
- return self.logs
+ var logs Logs
+ for _, lgs := range self.logs {
+ logs = append(logs, lgs...)
+ }
+ return logs
}
func (self *StateDB) Refund(address common.Address, gas *big.Int) {
@@ -60,6 +75,10 @@ func (self *StateDB) Refund(address common.Address, gas *big.Int) {
* GETTERS
*/
+func (self *StateDB) HasAccount(addr common.Address) bool {
+ return self.GetStateObject(addr) != nil
+}
+
// Retrieve the balance from the given address or 0 if object not found
func (self *StateDB) GetBalance(addr common.Address) *big.Int {
stateObject := self.GetStateObject(addr)
@@ -253,9 +272,10 @@ func (self *StateDB) Copy() *StateDB {
state.refund[addr] = new(big.Int).Set(refund)
}
- logs := make(Logs, len(self.logs))
- copy(logs, self.logs)
- state.logs = logs
+ for hash, logs := range self.logs {
+ state.logs[hash] = make(Logs, len(logs))
+ copy(state.logs[hash], logs)
+ }
return state
}
diff --git a/core/state_transition.go b/core/state_transition.go
index e67abb951..d95cbd35a 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -74,6 +74,19 @@ func MessageGasValue(msg Message) *big.Int {
return new(big.Int).Mul(msg.Gas(), msg.GasPrice())
}
+func IntrinsicGas(msg Message) *big.Int {
+ igas := new(big.Int).Set(params.TxGas)
+ for _, byt := range msg.Data() {
+ if byt != 0 {
+ igas.Add(igas, params.TxDataNonZeroGas)
+ } else {
+ igas.Add(igas, params.TxDataZeroGas)
+ }
+ }
+
+ return igas
+}
+
func ApplyMessage(env vm.Environment, msg Message, coinbase *state.StateObject) ([]byte, *big.Int, error) {
return NewStateTransition(env, msg, coinbase).transitionState()
}
@@ -177,22 +190,8 @@ func (self *StateTransition) transitionState() (ret []byte, usedGas *big.Int, er
sender = self.From()
)
- // Transaction gas
- if err = self.UseGas(params.TxGas); err != nil {
- return nil, nil, InvalidTxError(err)
- }
-
- // Pay data gas
- dgas := new(big.Int)
- for _, byt := range self.data {
- if byt != 0 {
- dgas.Add(dgas, params.TxDataNonZeroGas)
- } else {
- dgas.Add(dgas, params.TxDataZeroGas)
- }
- }
-
- if err = self.UseGas(dgas); err != nil {
+ // Pay intrinsic gas
+ if err = self.UseGas(IntrinsicGas(self.msg)); err != nil {
return nil, nil, InvalidTxError(err)
}
diff --git a/core/transaction_pool.go b/core/transaction_pool.go
index 930efdaec..94a94f93d 100644
--- a/core/transaction_pool.go
+++ b/core/transaction_pool.go
@@ -3,19 +3,24 @@ package core
import (
"errors"
"fmt"
+ "math/big"
"sync"
"github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger"
+ "github.com/ethereum/go-ethereum/logger/glog"
"gopkg.in/fatih/set.v0"
)
var (
- txplogger = logger.NewLogger("TXP")
-
- ErrInvalidSender = errors.New("Invalid sender")
+ ErrInvalidSender = errors.New("Invalid sender")
+ ErrImpossibleNonce = errors.New("Impossible nonce")
+ ErrNonExistentAccount = errors.New("Account does not exist")
+ ErrInsufficientFunds = errors.New("Insufficient funds")
+ ErrIntrinsicGas = errors.New("Intrinsic gas too low")
)
const txPoolQueueSize = 50
@@ -41,52 +46,62 @@ type TxPool struct {
queueChan chan *types.Transaction
// Quiting channel
quit chan bool
+ // The state function which will allow us to do some pre checkes
+ currentState func() *state.StateDB
// The actual pool
- //pool *list.List
txs map[common.Hash]*types.Transaction
invalidHashes *set.Set
- SecondaryProcessor TxProcessor
-
subscribers []chan TxMsg
eventMux *event.TypeMux
}
-func NewTxPool(eventMux *event.TypeMux) *TxPool {
+func NewTxPool(eventMux *event.TypeMux, currentStateFn func() *state.StateDB) *TxPool {
return &TxPool{
txs: make(map[common.Hash]*types.Transaction),
queueChan: make(chan *types.Transaction, txPoolQueueSize),
quit: make(chan bool),
eventMux: eventMux,
invalidHashes: set.New(),
+ currentState: currentStateFn,
}
}
func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error {
// Validate sender
- if _, err := tx.From(); err != nil {
+ var (
+ from common.Address
+ err error
+ )
+
+ if from, err = tx.From(); err != nil {
return ErrInvalidSender
}
+
// Validate curve param
v, _, _ := tx.Curve()
if v > 28 || v < 27 {
return fmt.Errorf("tx.v != (28 || 27) => %v", v)
}
- return nil
- /* 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.
- sender := pool.stateQuery.GetAccount(senderAddr)
- totAmount := new(big.Int).Set(tx.Value())
- // Make sure there's enough in the sender's account. Having insufficient
- // funds won't invalidate this transaction but simple ignores it.
- if sender.Balance().Cmp(totAmount) < 0 {
- return fmt.Errorf("Insufficient amount in sender's (%x) account", tx.From())
+ if !pool.currentState().HasAccount(from) {
+ return ErrNonExistentAccount
}
- */
+
+ if pool.currentState().GetBalance(from).Cmp(new(big.Int).Mul(tx.Price, tx.GasLimit)) < 0 {
+ return ErrInsufficientFunds
+ }
+
+ if tx.GasLimit.Cmp(IntrinsicGas(tx)) < 0 {
+ return ErrIntrinsicGas
+ }
+
+ if pool.currentState().GetNonce(from) > tx.Nonce() {
+ return ErrImpossibleNonce
+ }
+
+ return nil
}
func (self *TxPool) addTx(tx *types.Transaction) {
@@ -96,10 +111,12 @@ func (self *TxPool) addTx(tx *types.Transaction) {
func (self *TxPool) add(tx *types.Transaction) error {
hash := tx.Hash()
+ /* XXX I'm unsure about this. This is extremely dangerous and may result
+ in total black listing of certain transactions
if self.invalidHashes.Has(hash) {
return fmt.Errorf("Invalid transaction (%x)", hash[:4])
}
-
+ */
if self.txs[hash] != nil {
return fmt.Errorf("Known transaction (%x)", hash[:4])
}
@@ -120,7 +137,10 @@ func (self *TxPool) add(tx *types.Transaction) error {
// verified in ValidateTransaction.
f, _ := tx.From()
from := common.Bytes2Hex(f[:4])
- txplogger.Debugf("(t) %x => %s (%v) %x\n", from, toname, tx.Value, tx.Hash())
+
+ if glog.V(logger.Debug) {
+ glog.Infof("(t) %x => %s (%v) %x\n", from, toname, tx.Value, tx.Hash())
+ }
// Notify the subscribers
go self.eventMux.Post(TxPreEvent{tx})
@@ -145,10 +165,10 @@ func (self *TxPool) AddTransactions(txs []*types.Transaction) {
for _, tx := range txs {
if err := self.add(tx); err != nil {
- txplogger.Debugln(err)
+ glog.V(logger.Debug).Infoln(err)
} else {
h := tx.Hash()
- txplogger.Debugf("tx %x\n", h[:4])
+ glog.V(logger.Debug).Infof("tx %x\n", h[:4])
}
}
}
@@ -167,23 +187,6 @@ func (self *TxPool) GetTransactions() (txs types.Transactions) {
return
}
-func (pool *TxPool) RemoveInvalid(query StateQuery) {
- pool.mu.Lock()
-
- var removedTxs types.Transactions
- for _, tx := range pool.txs {
- from, _ := tx.From()
- sender := query.GetAccount(from[:])
- err := pool.ValidateTransaction(tx)
- if err != nil || sender.Nonce() >= tx.Nonce() {
- removedTxs = append(removedTxs, tx)
- }
- }
- pool.mu.Unlock()
-
- pool.RemoveSet(removedTxs)
-}
-
func (self *TxPool) RemoveSet(txs types.Transactions) {
self.mu.Lock()
defer self.mu.Unlock()
@@ -213,5 +216,5 @@ func (pool *TxPool) Start() {
func (pool *TxPool) Stop() {
pool.Flush()
- txplogger.Infoln("Stopped")
+ glog.V(logger.Info).Infoln("TX Pool stopped")
}
diff --git a/core/transaction_pool_test.go b/core/transaction_pool_test.go
index abdc2709f..b7486adb3 100644
--- a/core/transaction_pool_test.go
+++ b/core/transaction_pool_test.go
@@ -13,87 +13,50 @@ import (
"github.com/ethereum/go-ethereum/event"
)
-// State query interface
-type stateQuery struct{ db common.Database }
-
-func SQ() stateQuery {
- db, _ := ethdb.NewMemDatabase()
- return stateQuery{db: db}
-}
-
-func (self stateQuery) GetAccount(addr []byte) *state.StateObject {
- return state.NewStateObject(common.BytesToAddress(addr), self.db)
-}
-
func transaction() *types.Transaction {
- return types.NewTransactionMessage(common.Address{}, common.Big0, common.Big0, common.Big0, nil)
+ return types.NewTransactionMessage(common.Address{}, big.NewInt(100), big.NewInt(100), big.NewInt(100), nil)
}
-func setup() (*TxPool, *ecdsa.PrivateKey) {
+func setupTxPool() (*TxPool, *ecdsa.PrivateKey) {
+ db, _ := ethdb.NewMemDatabase()
+ statedb := state.New(common.Hash{}, db)
+
var m event.TypeMux
key, _ := crypto.GenerateKey()
- return NewTxPool(&m), key
+ return NewTxPool(&m, func() *state.StateDB { return statedb }), 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 TestInvalidTransactions(t *testing.T) {
+ pool, key := setupTxPool()
-func TestAddInvalidTx(t *testing.T) {
- pool, _ := setup()
- tx1 := transaction()
- err := pool.Add(tx1)
- if err == nil {
- t.Error("expected error")
+ tx := transaction()
+ tx.SignECDSA(key)
+ err := pool.Add(tx)
+ if err != ErrNonExistentAccount {
+ t.Error("expected", ErrNonExistentAccount)
}
-}
-func TestRemoveSet(t *testing.T) {
- pool, _ := setup()
- tx1 := transaction()
- pool.addTx(tx1)
- pool.RemoveSet(types.Transactions{tx1})
- if pool.Size() > 0 {
- t.Error("expected pool size to be 0")
+ from, _ := tx.From()
+ pool.currentState().AddBalance(from, big.NewInt(1))
+ err = pool.Add(tx)
+ if err != ErrInsufficientFunds {
+ t.Error("expected", ErrInsufficientFunds)
}
-}
-func TestRemoveInvalid(t *testing.T) {
- pool, key := setup()
- tx1 := transaction()
- pool.addTx(tx1)
- pool.RemoveInvalid(SQ())
- if pool.Size() > 0 {
- t.Error("expected pool size to be 0")
+ pool.currentState().AddBalance(from, big.NewInt(100*100))
+ err = pool.Add(tx)
+ if err != ErrIntrinsicGas {
+ t.Error("expected", ErrIntrinsicGas)
}
- tx1.SetNonce(1)
- tx1.SignECDSA(key)
- pool.addTx(tx1)
- pool.RemoveInvalid(SQ())
- if pool.Size() != 1 {
- t.Error("expected pool size to be 1, is", pool.Size())
- }
-}
+ pool.currentState().SetNonce(from, 1)
+ pool.currentState().AddBalance(from, big.NewInt(0xffffffffffffff))
+ tx.GasLimit = big.NewInt(100000)
+ tx.Price = big.NewInt(1)
+ tx.SignECDSA(key)
-func TestInvalidSender(t *testing.T) {
- pool, _ := setup()
- tx := new(types.Transaction)
- tx.R = new(big.Int)
- tx.S = new(big.Int)
- err := pool.ValidateTransaction(tx)
- if err != ErrInvalidSender {
- t.Errorf("expected %v, got %v", ErrInvalidSender, err)
+ err = pool.Add(tx)
+ if err != ErrImpossibleNonce {
+ t.Error("expected", ErrImpossibleNonce)
}
}
diff --git a/core/types/bloom9.go b/core/types/bloom9.go
index af90679ce..0d37cb19f 100644
--- a/core/types/bloom9.go
+++ b/core/types/bloom9.go
@@ -4,8 +4,8 @@ import (
"math/big"
"github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/core/state"
+ "github.com/ethereum/go-ethereum/crypto"
)
func CreateBloom(receipts Receipts) Bloom {
@@ -20,10 +20,10 @@ func CreateBloom(receipts Receipts) Bloom {
func LogsBloom(logs state.Logs) *big.Int {
bin := new(big.Int)
for _, log := range logs {
- data := make([]common.Hash, len(log.Topics()))
- bin.Or(bin, bloom9(log.Address().Bytes()))
+ data := make([]common.Hash, len(log.Topics))
+ bin.Or(bin, bloom9(log.Address.Bytes()))
- for i, topic := range log.Topics() {
+ for i, topic := range log.Topics {
data[i] = topic
}
diff --git a/core/types/receipt.go b/core/types/receipt.go
index 83c981f93..414e4d364 100644
--- a/core/types/receipt.go
+++ b/core/types/receipt.go
@@ -7,8 +7,8 @@ import (
"math/big"
"github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/core/state"
+ "github.com/ethereum/go-ethereum/rlp"
)
type Receipt struct {
@@ -30,12 +30,6 @@ func (self *Receipt) EncodeRLP(w io.Writer) error {
return rlp.Encode(w, []interface{}{self.PostState, self.CumulativeGasUsed, self.Bloom, self.logs})
}
-/*
-func (self *Receipt) RlpData() interface{} {
- return []interface{}{self.PostState, self.CumulativeGasUsed, self.Bloom, self.logs.RlpData()}
-}
-*/
-
func (self *Receipt) RlpEncode() []byte {
bytes, err := rlp.EncodeToBytes(self)
if err != nil {
@@ -58,17 +52,6 @@ func (self *Receipt) String() string {
type Receipts []*Receipt
-/*
-func (self Receipts) RlpData() interface{} {
- data := make([]interface{}, len(self))
- for i, receipt := range self {
- data[i] = receipt.RlpData()
- }
-
- return data
-}
-*/
-
func (self Receipts) RlpEncode() []byte {
bytes, err := rlp.EncodeToBytes(self)
if err != nil {
diff --git a/core/vm/environment.go b/core/vm/environment.go
index 72e18c353..cc9570fc8 100644
--- a/core/vm/environment.go
+++ b/core/vm/environment.go
@@ -22,7 +22,7 @@ type Environment interface {
Difficulty() *big.Int
GasLimit() *big.Int
Transfer(from, to Account, amount *big.Int) error
- AddLog(state.Log)
+ AddLog(*state.Log)
VmType() Type
diff --git a/core/vm/vm.go b/core/vm/vm.go
index 118f60076..927b67293 100644
--- a/core/vm/vm.go
+++ b/core/vm/vm.go
@@ -557,7 +557,8 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
}
data := mem.Get(mStart.Int64(), mSize.Int64())
- log := &Log{context.Address(), topics, data, self.env.BlockNumber().Uint64()}
+ log := state.NewLog(context.Address(), topics, data, self.env.BlockNumber().Uint64())
+ //log := &Log{context.Address(), topics, data, self.env.BlockNumber().Uint64()}
self.env.AddLog(log)
self.Printf(" => %v", log)
diff --git a/core/vm_env.go b/core/vm_env.go
index 6a604fccd..c439d2946 100644
--- a/core/vm_env.go
+++ b/core/vm_env.go
@@ -47,7 +47,7 @@ func (self *VMEnv) GetHash(n uint64) common.Hash {
return common.Hash{}
}
-func (self *VMEnv) AddLog(log state.Log) {
+func (self *VMEnv) AddLog(log *state.Log) {
self.state.AddLog(log)
}
func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error {
diff --git a/eth/backend.go b/eth/backend.go
index 317ee7373..c7a5b233f 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -195,7 +195,7 @@ func New(config *Config) (*Ethereum, error) {
eth.chainManager = core.NewChainManager(blockDb, stateDb, eth.EventMux())
eth.pow = ethash.New(eth.chainManager)
- eth.txPool = core.NewTxPool(eth.EventMux())
+ eth.txPool = core.NewTxPool(eth.EventMux(), eth.chainManager.State)
eth.blockProcessor = core.NewBlockProcessor(stateDb, extraDb, eth.pow, eth.txPool, eth.chainManager, eth.EventMux())
eth.chainManager.SetProcessor(eth.blockProcessor)
eth.whisper = whisper.New()
@@ -449,7 +449,7 @@ func (self *Ethereum) syncAccounts(tx *types.Transaction) {
if self.accountManager.HasAccount(from.Bytes()) {
if self.chainManager.TxState().GetNonce(from) < tx.Nonce() {
- self.chainManager.TxState().SetNonce(from, tx.Nonce()+1)
+ self.chainManager.TxState().SetNonce(from, tx.Nonce())
}
}
}
diff --git a/miner/worker.go b/miner/worker.go
index 7f2728f9c..b74b67552 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -266,6 +266,8 @@ func (self *worker) commitNewWork() {
)
gasLimit:
for i, tx := range transactions {
+ self.current.state.StartRecord(tx.Hash(), common.Hash{}, 0)
+
err := self.commitTransaction(tx)
switch {
case core.IsNonceErr(err) || core.IsInvalidTxErr(err):
@@ -286,7 +288,7 @@ gasLimit:
tcount++
}
}
- self.eth.TxPool().InvalidateSet(remove)
+ //self.eth.TxPool().InvalidateSet(remove)
var (
uncles []*types.Header
diff --git a/rpc/args.go b/rpc/args.go
index 5b1c271cc..4bc36f5d9 100644
--- a/rpc/args.go
+++ b/rpc/args.go
@@ -279,11 +279,6 @@ func (args *CallArgs) UnmarshalJSON(b []byte) (err error) {
return NewDecodeParamError(err.Error())
}
- if len(ext.From) == 0 {
- return NewValidationError("from", "is required")
- }
- args.From = ext.From
-
if len(ext.To) == 0 {
return NewValidationError("to", "is required")
}
diff --git a/rpc/args_test.go b/rpc/args_test.go
index 050f8e472..cfe6c0c45 100644
--- a/rpc/args_test.go
+++ b/rpc/args_test.go
@@ -671,10 +671,6 @@ func TestCallArgs(t *testing.T) {
t.Error(err)
}
- if expected.From != args.From {
- t.Errorf("From shoud be %#v but is %#v", expected.From, args.From)
- }
-
if expected.To != args.To {
t.Errorf("To shoud be %#v but is %#v", expected.To, args.To)
}
@@ -895,19 +891,8 @@ func TestCallArgsNotStrings(t *testing.T) {
}
}
-func TestCallArgsFromEmpty(t *testing.T) {
- input := `[{"to": "0xb60e8dd61c5d32be8058bb8eb970870f07233155"}]`
-
- args := new(CallArgs)
- str := ExpectValidationError(json.Unmarshal([]byte(input), &args))
- if len(str) > 0 {
- t.Error(str)
- }
-}
-
func TestCallArgsToEmpty(t *testing.T) {
input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155"}]`
-
args := new(CallArgs)
str := ExpectValidationError(json.Unmarshal([]byte(input), &args))
if len(str) > 0 {
diff --git a/rpc/responses.go b/rpc/responses.go
index 52a2f714c..3620f643e 100644
--- a/rpc/responses.go
+++ b/rpc/responses.go
@@ -284,15 +284,19 @@ type LogRes struct {
TransactionIndex *hexnum `json:"transactionIndex"`
}
-func NewLogRes(log state.Log) LogRes {
+func NewLogRes(log *state.Log) LogRes {
var l LogRes
- l.Topics = make([]*hexdata, len(log.Topics()))
- for j, topic := range log.Topics() {
+ l.Topics = make([]*hexdata, len(log.Topics))
+ for j, topic := range log.Topics {
l.Topics[j] = newHexData(topic)
}
- l.Address = newHexData(log.Address())
- l.Data = newHexData(log.Data())
- l.BlockNumber = newHexNum(log.Number())
+ l.Address = newHexData(log.Address)
+ l.Data = newHexData(log.Data)
+ l.BlockNumber = newHexNum(log.Number)
+ l.LogIndex = newHexNum(log.Index)
+ l.TransactionHash = newHexData(log.TxHash)
+ l.TransactionIndex = newHexNum(log.TxIndex)
+ l.BlockHash = newHexData(log.BlockHash)
return l
}
diff --git a/rpc/responses_test.go b/rpc/responses_test.go
index e04a064ce..66323e5f5 100644
--- a/rpc/responses_test.go
+++ b/rpc/responses_test.go
@@ -217,7 +217,7 @@ func TestNewLogRes(t *testing.T) {
}
func TestNewLogsRes(t *testing.T) {
- logs := make([]state.Log, 3)
+ logs := make([]*state.Log, 3)
logs[0] = makeStateLog(1)
logs[1] = makeStateLog(2)
logs[2] = makeStateLog(3)
@@ -235,7 +235,7 @@ func TestNewLogsRes(t *testing.T) {
}
-func makeStateLog(num int) state.Log {
+func makeStateLog(num int) *state.Log {
address := common.HexToAddress("0x0")
data := []byte{1, 2, 3}
number := uint64(num)
diff --git a/tests/helper/vm.go b/tests/helper/vm.go
index 9f62ada95..fb3fb40a5 100644
--- a/tests/helper/vm.go
+++ b/tests/helper/vm.go
@@ -66,7 +66,7 @@ func (self *Env) VmType() vm.Type { return vm.StdVmTy }
func (self *Env) GetHash(n uint64) common.Hash {
return common.BytesToHash(crypto.Sha3([]byte(big.NewInt(int64(n)).String())))
}
-func (self *Env) AddLog(log state.Log) {
+func (self *Env) AddLog(log *state.Log) {
self.logs = append(self.logs, log)
}
func (self *Env) Depth() int { return self.depth }
diff --git a/tests/vm/gh_test.go b/tests/vm/gh_test.go
index a96a3eba6..a5bc273f3 100644
--- a/tests/vm/gh_test.go
+++ b/tests/vm/gh_test.go
@@ -9,10 +9,8 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/logger"
- "github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/tests/helper"
)
@@ -82,13 +80,15 @@ func RunVmTest(p string, t *testing.T) {
tests := make(map[string]VmTest)
helper.CreateFileTests(t, p, &tests)
- vm.Debug = true
- glog.SetV(4)
- glog.SetToStderr(true)
for name, test := range tests {
- if name != "stackLimitPush32_1024" {
- continue
- }
+ /*
+ vm.Debug = true
+ glog.SetV(4)
+ glog.SetToStderr(true)
+ if name != "stackLimitPush32_1024" {
+ continue
+ }
+ */
db, _ := ethdb.NewMemDatabase()
statedb := state.New(common.Hash{}, db)
for addr, account := range test.Pre {
@@ -182,20 +182,20 @@ func RunVmTest(p string, t *testing.T) {
t.Errorf("log length mismatch. Expected %d, got %d", len(test.Logs), len(logs))
} else {
for i, log := range test.Logs {
- if common.HexToAddress(log.AddressF) != logs[i].Address() {
- t.Errorf("'%s' log address expected %v got %x", name, log.AddressF, logs[i].Address())
+ if common.HexToAddress(log.AddressF) != logs[i].Address {
+ t.Errorf("'%s' log address expected %v got %x", name, log.AddressF, logs[i].Address)
}
- if !bytes.Equal(logs[i].Data(), helper.FromHex(log.DataF)) {
- t.Errorf("'%s' log data expected %v got %x", name, log.DataF, logs[i].Data())
+ if !bytes.Equal(logs[i].Data, helper.FromHex(log.DataF)) {
+ t.Errorf("'%s' log data expected %v got %x", name, log.DataF, logs[i].Data)
}
- if len(log.TopicsF) != len(logs[i].Topics()) {
- t.Errorf("'%s' log topics length expected %d got %d", name, len(log.TopicsF), logs[i].Topics())
+ if len(log.TopicsF) != len(logs[i].Topics) {
+ t.Errorf("'%s' log topics length expected %d got %d", name, len(log.TopicsF), logs[i].Topics)
} else {
for j, topic := range log.TopicsF {
- if common.HexToHash(topic) != logs[i].Topics()[j] {
- t.Errorf("'%s' log topic[%d] expected %v got %x", name, j, topic, logs[i].Topics()[j])
+ if common.HexToHash(topic) != logs[i].Topics[j] {
+ t.Errorf("'%s' log topic[%d] expected %v got %x", name, j, topic, logs[i].Topics[j])
}
}
}
diff --git a/xeth/types.go b/xeth/types.go
index 3f96f8f8b..739092474 100644
--- a/xeth/types.go
+++ b/xeth/types.go
@@ -77,15 +77,19 @@ func NewBlock(block *types.Block) *Block {
}
ptxs := make([]*Transaction, len(block.Transactions()))
- for i, tx := range block.Transactions() {
- ptxs[i] = NewTx(tx)
- }
+ /*
+ for i, tx := range block.Transactions() {
+ ptxs[i] = NewTx(tx)
+ }
+ */
txlist := common.NewList(ptxs)
puncles := make([]*Block, len(block.Uncles()))
- for i, uncle := range block.Uncles() {
- puncles[i] = NewBlock(types.NewBlockWithHeader(uncle))
- }
+ /*
+ for i, uncle := range block.Uncles() {
+ puncles[i] = NewBlock(types.NewBlockWithHeader(uncle))
+ }
+ */
ulist := common.NewList(puncles)
return &Block{
diff --git a/xeth/xeth.go b/xeth/xeth.go
index b8d9ecb08..407fe69d5 100644
--- a/xeth/xeth.go
+++ b/xeth/xeth.go
@@ -393,7 +393,7 @@ func (self *XEth) NewFilterString(word string) int {
self.logMut.Lock()
defer self.logMut.Unlock()
- self.logs[id].add(&state.StateLog{})
+ self.logs[id].add(&state.Log{})
}
case "latest":
filter.BlockCallback = func(block *types.Block, logs state.Logs) {
@@ -403,7 +403,7 @@ func (self *XEth) NewFilterString(word string) int {
for _, log := range logs {
self.logs[id].add(log)
}
- self.logs[id].add(&state.StateLog{})
+ self.logs[id].add(&state.Log{})
}
}
@@ -572,8 +572,20 @@ func (self *XEth) PushTx(encodedTx string) (string, error) {
func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr string) (string, error) {
statedb := self.State().State() //self.eth.ChainManager().TransState()
+ var from *state.StateObject
+ if len(fromStr) == 0 {
+ accounts, err := self.backend.AccountManager().Accounts()
+ if err != nil || len(accounts) == 0 {
+ from = statedb.GetOrNewStateObject(common.Address{})
+ } else {
+ from = statedb.GetOrNewStateObject(common.BytesToAddress(accounts[0].Address))
+ }
+ } else {
+ from = statedb.GetOrNewStateObject(common.HexToAddress(fromStr))
+ }
+
msg := callmsg{
- from: statedb.GetOrNewStateObject(common.HexToAddress(fromStr)),
+ from: from,
to: common.HexToAddress(toStr),
gas: common.Big(gasStr),
gasPrice: common.Big(gasPriceStr),
@@ -729,7 +741,7 @@ type logFilter struct {
id int
}
-func (l *logFilter) add(logs ...state.Log) {
+func (l *logFilter) add(logs ...*state.Log) {
l.logs = append(l.logs, logs...)
}