aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2015-04-08 23:14:58 +0800
committerobscuren <geffobscura@gmail.com>2015-04-08 23:15:45 +0800
commit1c872ddf4b1db51847a5d9d020e13d432e847f52 (patch)
tree72ec461427269a25165b58043f328fd374e143ee
parent6284604b52e075e454e61f2933cadaaf9ded364b (diff)
downloaddexon-1c872ddf4b1db51847a5d9d020e13d432e847f52.tar
dexon-1c872ddf4b1db51847a5d9d020e13d432e847f52.tar.gz
dexon-1c872ddf4b1db51847a5d9d020e13d432e847f52.tar.bz2
dexon-1c872ddf4b1db51847a5d9d020e13d432e847f52.tar.lz
dexon-1c872ddf4b1db51847a5d9d020e13d432e847f52.tar.xz
dexon-1c872ddf4b1db51847a5d9d020e13d432e847f52.tar.zst
dexon-1c872ddf4b1db51847a5d9d020e13d432e847f52.zip
Changed how logs are being recorded
Logs are now recorded per transactions instead of tossing them out after each transaction. This should also fix an issue with `eth_getFilterLogs` (#629) Also now implemented are the `transactionHash, blockHash, transactionIndex, logIndex` on logs. Closes #654.
-rw-r--r--core/block_processor.go11
-rw-r--r--core/filter.go6
-rw-r--r--core/state/log.go88
-rw-r--r--core/state/statedb.go42
-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--miner/worker.go2
-rw-r--r--rpc/responses.go16
-rw-r--r--xeth/xeth.go6
12 files changed, 83 insertions, 122 deletions
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/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/statedb.go b/core/state/statedb.go
index 065cbd607..0651365f0 100644
--- a/core/state/statedb.go
+++ b/core/state/statedb.go
@@ -23,30 +23,53 @@ 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 {
+ var logs Logs
+ for _, lgs := range self.logs {
+ logs = append(logs, lgs...)
+ }
+ return logs
+}
+
+/*
+func (self *StateDB) Logs(txHash, blockHash common.Hash, txIndex uint) Logs {
+ self.logs.SetInfo(txHash, blockHash, txIndex)
+
return self.logs
}
+*/
func (self *StateDB) Refund(address common.Address, gas *big.Int) {
addr := address.Str()
@@ -253,9 +276,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/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/miner/worker.go b/miner/worker.go
index 7f2728f9c..25ea95347 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):
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/xeth/xeth.go b/xeth/xeth.go
index b8d9ecb08..94014763a 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{})
}
}
@@ -729,7 +729,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...)
}