Skip to content

Commit

Permalink
Changed how logs are being recorded
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
obscuren committed Apr 8, 2015
1 parent 6284604 commit 1c872dd
Show file tree
Hide file tree
Showing 12 changed files with 83 additions and 122 deletions.
11 changes: 7 additions & 4 deletions core/block_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -89,15 +89,16 @@ 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)

// Notify all subscribers
if !transientProcess {
go self.eventMux.Post(TxPostEvent{tx})
logs := statedb.Logs()
go self.eventMux.Post(logs)
}

Expand All @@ -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
Expand Down
6 changes: 3 additions & 3 deletions core/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
88 changes: 16 additions & 72 deletions core/state/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
42 changes: 33 additions & 9 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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
}
Expand Down
8 changes: 4 additions & 4 deletions core/types/bloom9.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
}

Expand Down
19 changes: 1 addition & 18 deletions core/types/receipt.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion core/vm/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
3 changes: 2 additions & 1 deletion core/vm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion core/vm_env.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
16 changes: 10 additions & 6 deletions rpc/responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
6 changes: 3 additions & 3 deletions xeth/xeth.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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{})
}
}

Expand Down Expand Up @@ -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...)
}

Expand Down

0 comments on commit 1c872dd

Please sign in to comment.