Moved logging to state, proper structured block
* Moved logs to state so it's subject to snapshotting * Split up block header * Removed logs from transactions and made them receipts only
This commit is contained in:
parent
fa890c8c01
commit
df5603de0a
@ -149,10 +149,7 @@ func (block *Block) Hash() ethutil.Bytes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (block *Block) HashNoNonce() []byte {
|
func (block *Block) HashNoNonce() []byte {
|
||||||
return ethcrypto.Sha3(ethutil.Encode([]interface{}{block.PrevHash,
|
return ethcrypto.Sha3(ethutil.Encode(block.miningHeader()))
|
||||||
block.UncleSha, block.Coinbase, block.state.Trie.Root,
|
|
||||||
block.ReceiptSha, block.Difficulty, block.Number, block.MinGasPrice,
|
|
||||||
block.GasLimit, block.GasUsed, block.Time, block.Extra}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (block *Block) State() *ethstate.State {
|
func (block *Block) State() *ethstate.State {
|
||||||
@ -235,31 +232,18 @@ func (block *Block) rlpUncles() interface{} {
|
|||||||
|
|
||||||
func (block *Block) SetUncles(uncles []*Block) {
|
func (block *Block) SetUncles(uncles []*Block) {
|
||||||
block.Uncles = uncles
|
block.Uncles = uncles
|
||||||
|
|
||||||
block.UncleSha = ethcrypto.Sha3(ethutil.Encode(block.rlpUncles()))
|
block.UncleSha = ethcrypto.Sha3(ethutil.Encode(block.rlpUncles()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Block) SetReceipts(receipts Receipts) {
|
func (self *Block) SetReceipts(receipts Receipts) {
|
||||||
self.receipts = receipts
|
self.receipts = receipts
|
||||||
self.SetReceiptHash(receipts)
|
self.ReceiptSha = DeriveSha(receipts)
|
||||||
|
self.LogsBloom = CreateBloom(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Block) SetTransactions(txs Transactions) {
|
func (self *Block) SetTransactions(txs Transactions) {
|
||||||
self.setTransactions(txs)
|
self.transactions = txs
|
||||||
self.SetTransactionHash(txs)
|
self.TxSha = DeriveSha(txs)
|
||||||
}
|
|
||||||
|
|
||||||
func (block *Block) setTransactions(txs Transactions) {
|
|
||||||
block.transactions = txs
|
|
||||||
block.LogsBloom = CreateBloom(block)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Block) SetTransactionHash(transactions Transactions) {
|
|
||||||
self.TxSha = DeriveSha(transactions)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Block) SetReceiptHash(receipts Receipts) {
|
|
||||||
self.ReceiptSha = DeriveSha(receipts)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (block *Block) Value() *ethutil.Value {
|
func (block *Block) Value() *ethutil.Value {
|
||||||
@ -285,10 +269,10 @@ func (block *Block) RlpValueDecode(decoder *ethutil.Value) {
|
|||||||
if decoder.Get(1).IsNil() == false { // Yes explicitness
|
if decoder.Get(1).IsNil() == false { // Yes explicitness
|
||||||
//receipts := decoder.Get(1)
|
//receipts := decoder.Get(1)
|
||||||
//block.receipts = make([]*Receipt, receipts.Len())
|
//block.receipts = make([]*Receipt, receipts.Len())
|
||||||
it := decoder.Get(1).NewIterator()
|
txs := decoder.Get(1)
|
||||||
block.transactions = make(Transactions, it.Len())
|
block.transactions = make(Transactions, txs.Len())
|
||||||
for it.Next() {
|
for i := 0; i < txs.Len(); i++ {
|
||||||
block.transactions[it.Idx()] = NewTransactionFromValue(it.Value())
|
block.transactions[i] = NewTransactionFromValue(txs.Get(i))
|
||||||
//receipt := NewRecieptFromValue(receipts.Get(i))
|
//receipt := NewRecieptFromValue(receipts.Get(i))
|
||||||
//block.transactions[i] = receipt.Tx
|
//block.transactions[i] = receipt.Tx
|
||||||
//block.receipts[i] = receipt
|
//block.receipts[i] = receipt
|
||||||
@ -347,7 +331,7 @@ func (self *Block) Receipts() []*Receipt {
|
|||||||
return self.receipts
|
return self.receipts
|
||||||
}
|
}
|
||||||
|
|
||||||
func (block *Block) header() []interface{} {
|
func (block *Block) miningHeader() []interface{} {
|
||||||
return []interface{}{
|
return []interface{}{
|
||||||
// Sha of the previous block
|
// Sha of the previous block
|
||||||
block.PrevHash,
|
block.PrevHash,
|
||||||
@ -377,11 +361,13 @@ func (block *Block) header() []interface{} {
|
|||||||
block.Time,
|
block.Time,
|
||||||
// Extra data
|
// Extra data
|
||||||
block.Extra,
|
block.Extra,
|
||||||
// Block's Nonce for validation
|
|
||||||
block.Nonce,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (block *Block) header() []interface{} {
|
||||||
|
return append(block.miningHeader(), block.Nonce)
|
||||||
|
}
|
||||||
|
|
||||||
func (block *Block) String() string {
|
func (block *Block) String() string {
|
||||||
return fmt.Sprintf(`
|
return fmt.Sprintf(`
|
||||||
BLOCK(%x): Size: %v
|
BLOCK(%x): Size: %v
|
||||||
|
@ -3,21 +3,21 @@ package ethchain
|
|||||||
import (
|
import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/ethstate"
|
||||||
"github.com/ethereum/go-ethereum/ethutil"
|
"github.com/ethereum/go-ethereum/ethutil"
|
||||||
"github.com/ethereum/go-ethereum/vm"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func CreateBloom(block *Block) []byte {
|
func CreateBloom(block *Block) []byte {
|
||||||
bin := new(big.Int)
|
bin := new(big.Int)
|
||||||
bin.Or(bin, bloom9(block.Coinbase))
|
bin.Or(bin, bloom9(block.Coinbase))
|
||||||
for _, tx := range block.Transactions() {
|
for _, receipt := range block.Receipts() {
|
||||||
bin.Or(bin, LogsBloom(tx.logs))
|
bin.Or(bin, LogsBloom(receipt.logs))
|
||||||
}
|
}
|
||||||
|
|
||||||
return bin.Bytes()
|
return bin.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
func LogsBloom(logs []vm.Log) *big.Int {
|
func LogsBloom(logs ethstate.Logs) *big.Int {
|
||||||
bin := new(big.Int)
|
bin := new(big.Int)
|
||||||
for _, log := range logs {
|
for _, log := range logs {
|
||||||
data := [][]byte{log.Address}
|
data := [][]byte{log.Address}
|
||||||
|
@ -145,6 +145,9 @@ func (self *StateManager) ProcessTransactions(coinbase *ethstate.StateObject, st
|
|||||||
|
|
||||||
done:
|
done:
|
||||||
for i, tx := range txs {
|
for i, tx := range txs {
|
||||||
|
// If we are mining this block and validating we want to set the logs back to 0
|
||||||
|
state.EmptyLogs()
|
||||||
|
|
||||||
txGas := new(big.Int).Set(tx.Gas)
|
txGas := new(big.Int).Set(tx.Gas)
|
||||||
|
|
||||||
cb := state.GetStateObject(coinbase.Address())
|
cb := state.GetStateObject(coinbase.Address())
|
||||||
@ -175,7 +178,7 @@ done:
|
|||||||
txGas.Sub(txGas, st.gas)
|
txGas.Sub(txGas, st.gas)
|
||||||
cumulative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, txGas))
|
cumulative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, txGas))
|
||||||
//receipt := &Receipt{tx, ethutil.CopyBytes(state.Root().([]byte)), accumelative}
|
//receipt := &Receipt{tx, ethutil.CopyBytes(state.Root().([]byte)), accumelative}
|
||||||
receipt := &Receipt{ethutil.CopyBytes(state.Root().([]byte)), cumulative, LogsBloom(tx.logs).Bytes(), tx.logs}
|
receipt := &Receipt{ethutil.CopyBytes(state.Root().([]byte)), cumulative, LogsBloom(state.Logs()).Bytes(), state.Logs()}
|
||||||
|
|
||||||
if i < len(block.Receipts()) {
|
if i < len(block.Receipts()) {
|
||||||
original := block.Receipts()[i]
|
original := block.Receipts()[i]
|
||||||
@ -238,7 +241,7 @@ func (sm *StateManager) Process(block *Block) (err error) {
|
|||||||
|
|
||||||
txSha := DeriveSha(block.transactions)
|
txSha := DeriveSha(block.transactions)
|
||||||
if bytes.Compare(txSha, block.TxSha) != 0 {
|
if bytes.Compare(txSha, block.TxSha) != 0 {
|
||||||
return fmt.Errorf("Error validating transaction sha. Received %x, got %x", block.ReceiptSha, txSha)
|
return fmt.Errorf("Error validating transaction sha. Received %x, got %x", block.TxSha, txSha)
|
||||||
}
|
}
|
||||||
|
|
||||||
receipts, err := sm.ApplyDiff(state, parent, block)
|
receipts, err := sm.ApplyDiff(state, parent, block)
|
||||||
|
@ -232,7 +232,7 @@ func (self *StateTransition) TransitionState() (err error) {
|
|||||||
} else {
|
} else {
|
||||||
// Add default LOG. Default = big(sender.addr) + 1
|
// Add default LOG. Default = big(sender.addr) + 1
|
||||||
addr := ethutil.BigD(receiver.Address())
|
addr := ethutil.BigD(receiver.Address())
|
||||||
tx.addLog(vm.Log{sender.Address(), [][]byte{addr.Add(addr, ethutil.Big1).Bytes()}, nil})
|
self.state.AddLog(ethstate.Log{sender.Address(), [][]byte{ethutil.U256(addr.Add(addr, ethutil.Big1)).Bytes()}, nil})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/ethcrypto"
|
"github.com/ethereum/go-ethereum/ethcrypto"
|
||||||
"github.com/ethereum/go-ethereum/ethstate"
|
"github.com/ethereum/go-ethereum/ethstate"
|
||||||
"github.com/ethereum/go-ethereum/ethutil"
|
"github.com/ethereum/go-ethereum/ethutil"
|
||||||
"github.com/ethereum/go-ethereum/vm"
|
|
||||||
"github.com/obscuren/secp256k1-go"
|
"github.com/obscuren/secp256k1-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -29,8 +28,6 @@ type Transaction struct {
|
|||||||
v byte
|
v byte
|
||||||
r, s []byte
|
r, s []byte
|
||||||
|
|
||||||
logs []vm.Log
|
|
||||||
|
|
||||||
// Indicates whether this tx is a contract creation transaction
|
// Indicates whether this tx is a contract creation transaction
|
||||||
contractCreation bool
|
contractCreation bool
|
||||||
}
|
}
|
||||||
@ -57,10 +54,6 @@ func NewTransactionFromValue(val *ethutil.Value) *Transaction {
|
|||||||
return tx
|
return tx
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Transaction) addLog(log vm.Log) {
|
|
||||||
self.logs = append(self.logs, log)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Transaction) GasValue() *big.Int {
|
func (self *Transaction) GasValue() *big.Int {
|
||||||
return new(big.Int).Mul(self.Gas, self.GasPrice)
|
return new(big.Int).Mul(self.Gas, self.GasPrice)
|
||||||
}
|
}
|
||||||
@ -212,7 +205,7 @@ type Receipt struct {
|
|||||||
PostState []byte
|
PostState []byte
|
||||||
CumulativeGasUsed *big.Int
|
CumulativeGasUsed *big.Int
|
||||||
Bloom []byte
|
Bloom []byte
|
||||||
Logs vm.Logs
|
logs ethstate.Logs
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRecieptFromValue(val *ethutil.Value) *Receipt {
|
func NewRecieptFromValue(val *ethutil.Value) *Receipt {
|
||||||
@ -229,12 +222,12 @@ func (self *Receipt) RlpValueDecode(decoder *ethutil.Value) {
|
|||||||
|
|
||||||
it := decoder.Get(3).NewIterator()
|
it := decoder.Get(3).NewIterator()
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
self.Logs = append(self.Logs, vm.NewLogFromValue(it.Value()))
|
self.logs = append(self.logs, ethstate.NewLogFromValue(it.Value()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Receipt) RlpData() interface{} {
|
func (self *Receipt) RlpData() interface{} {
|
||||||
return []interface{}{self.PostState, self.CumulativeGasUsed, self.Bloom, self.Logs.RlpData()}
|
return []interface{}{self.PostState, self.CumulativeGasUsed, self.Bloom, self.logs.RlpData()}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Receipt) RlpEncode() []byte {
|
func (self *Receipt) RlpEncode() []byte {
|
||||||
|
@ -31,8 +31,8 @@ func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
|
|||||||
func (self *VMEnv) Value() *big.Int { return self.tx.Value }
|
func (self *VMEnv) Value() *big.Int { return self.tx.Value }
|
||||||
func (self *VMEnv) State() *ethstate.State { return self.state }
|
func (self *VMEnv) State() *ethstate.State { return self.state }
|
||||||
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit }
|
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit }
|
||||||
func (self *VMEnv) AddLog(log vm.Log) {
|
func (self *VMEnv) AddLog(log ethstate.Log) {
|
||||||
self.tx.addLog(log)
|
self.state.AddLog(log)
|
||||||
}
|
}
|
||||||
func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error {
|
func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error {
|
||||||
return vm.Transfer(from, to, amount)
|
return vm.Transfer(from, to, amount)
|
||||||
|
@ -185,8 +185,8 @@ func (self *Miner) mineNewBlock() {
|
|||||||
self.ethereum.TxPool().RemoveSet(erroneous)
|
self.ethereum.TxPool().RemoveSet(erroneous)
|
||||||
self.txs = append(txs, unhandledTxs...)
|
self.txs = append(txs, unhandledTxs...)
|
||||||
|
|
||||||
self.block.SetReceipts(receipts)
|
|
||||||
self.block.SetTransactions(txs)
|
self.block.SetTransactions(txs)
|
||||||
|
self.block.SetReceipts(receipts)
|
||||||
|
|
||||||
// Accumulate the rewards included for this block
|
// Accumulate the rewards included for this block
|
||||||
stateManager.AccumelateRewards(self.block.State(), self.block, parent)
|
stateManager.AccumelateRewards(self.block.State(), self.block, parent)
|
||||||
|
@ -34,7 +34,7 @@ func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
|
|||||||
func (self *VMEnv) Value() *big.Int { return self.value }
|
func (self *VMEnv) Value() *big.Int { return self.value }
|
||||||
func (self *VMEnv) State() *ethstate.State { return self.state }
|
func (self *VMEnv) State() *ethstate.State { return self.state }
|
||||||
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit }
|
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit }
|
||||||
func (self *VMEnv) AddLog(vm.Log) {}
|
func (self *VMEnv) AddLog(ethstate.Log) {}
|
||||||
func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error {
|
func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error {
|
||||||
return vm.Transfer(from, to, amount)
|
return vm.Transfer(from, to, amount)
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package vm
|
package ethstate
|
||||||
|
|
||||||
import "github.com/ethereum/go-ethereum/ethutil"
|
import "github.com/ethereum/go-ethereum/ethutil"
|
||||||
|
|
@ -24,6 +24,8 @@ type State struct {
|
|||||||
manifest *Manifest
|
manifest *Manifest
|
||||||
|
|
||||||
refund map[string]*big.Int
|
refund map[string]*big.Int
|
||||||
|
|
||||||
|
logs Logs
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new state from a given trie
|
// Create a new state from a given trie
|
||||||
@ -31,6 +33,18 @@ func New(trie *ethtrie.Trie) *State {
|
|||||||
return &State{Trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string]*big.Int)}
|
return &State{Trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string]*big.Int)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *State) EmptyLogs() {
|
||||||
|
self.logs = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *State) AddLog(log Log) {
|
||||||
|
self.logs = append(self.logs, log)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *State) Logs() Logs {
|
||||||
|
return self.logs
|
||||||
|
}
|
||||||
|
|
||||||
// Retrieve the balance from the given address or 0 if object not found
|
// Retrieve the balance from the given address or 0 if object not found
|
||||||
func (self *State) GetBalance(addr []byte) *big.Int {
|
func (self *State) GetBalance(addr []byte) *big.Int {
|
||||||
stateObject := self.GetStateObject(addr)
|
stateObject := self.GetStateObject(addr)
|
||||||
@ -202,6 +216,10 @@ func (self *State) Copy() *State {
|
|||||||
state.refund[addr] = refund
|
state.refund[addr] = refund
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logs := make(Logs, len(self.logs))
|
||||||
|
copy(logs, self.logs)
|
||||||
|
state.logs = logs
|
||||||
|
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,6 +234,7 @@ func (self *State) Set(state *State) {
|
|||||||
self.Trie = state.Trie
|
self.Trie = state.Trie
|
||||||
self.stateObjects = state.stateObjects
|
self.stateObjects = state.stateObjects
|
||||||
self.refund = state.refund
|
self.refund = state.refund
|
||||||
|
self.logs = state.logs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *State) Root() interface{} {
|
func (s *State) Root() interface{} {
|
||||||
|
@ -35,7 +35,7 @@ func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
|
|||||||
func (self *VMEnv) Value() *big.Int { return self.value }
|
func (self *VMEnv) Value() *big.Int { return self.value }
|
||||||
func (self *VMEnv) State() *ethstate.State { return self.state }
|
func (self *VMEnv) State() *ethstate.State { return self.state }
|
||||||
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit }
|
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit }
|
||||||
func (self *VMEnv) AddLog(vm.Log) {}
|
func (self *VMEnv) AddLog(ethstate.Log) {}
|
||||||
func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error {
|
func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error {
|
||||||
return vm.Transfer(from, to, amount)
|
return vm.Transfer(from, to, amount)
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ type Environment interface {
|
|||||||
BlockHash() []byte
|
BlockHash() []byte
|
||||||
GasLimit() *big.Int
|
GasLimit() *big.Int
|
||||||
Transfer(from, to Account, amount *big.Int) error
|
Transfer(from, to Account, amount *big.Int) error
|
||||||
AddLog(Log)
|
AddLog(ethstate.Log)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Object interface {
|
type Object interface {
|
||||||
@ -43,5 +43,9 @@ func Transfer(from, to Account, amount *big.Int) error {
|
|||||||
from.SubBalance(amount)
|
from.SubBalance(amount)
|
||||||
to.AddBalance(amount)
|
to.AddBalance(amount)
|
||||||
|
|
||||||
|
// Add default LOG. Default = big(sender.addr) + 1
|
||||||
|
//addr := ethutil.BigD(receiver.Address())
|
||||||
|
//tx.addLog(vm.Log{sender.Address(), [][]byte{ethutil.U256(addr.Add(addr, ethutil.Big1)).Bytes()}, nil})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/ethcrypto"
|
"github.com/ethereum/go-ethereum/ethcrypto"
|
||||||
|
"github.com/ethereum/go-ethereum/ethstate"
|
||||||
"github.com/ethereum/go-ethereum/ethutil"
|
"github.com/ethereum/go-ethereum/ethutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -710,7 +711,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
topics[i] = stack.Pop().Bytes()
|
topics[i] = stack.Pop().Bytes()
|
||||||
}
|
}
|
||||||
self.env.AddLog(Log{closure.Address(), topics, data})
|
self.env.AddLog(ethstate.Log{closure.Address(), topics, data})
|
||||||
case MLOAD:
|
case MLOAD:
|
||||||
offset := stack.Pop()
|
offset := stack.Pop()
|
||||||
val := ethutil.BigD(mem.Get(offset.Int64(), 32))
|
val := ethutil.BigD(mem.Get(offset.Int64(), 32))
|
||||||
|
Loading…
Reference in New Issue
Block a user