PoC 7 updates
* Bloom * Block restructure * Receipts
This commit is contained in:
parent
665a44646e
commit
fb4113dab4
@ -96,9 +96,10 @@ type Block struct {
|
||||
// Block Nonce for verification
|
||||
Nonce ethutil.Bytes
|
||||
// List of transactions and/or contracts
|
||||
transactions []*Transaction
|
||||
receipts []*Receipt
|
||||
TxSha []byte
|
||||
transactions Transactions
|
||||
receipts Receipts
|
||||
TxSha, ReceiptSha []byte
|
||||
LogsBloom []byte
|
||||
}
|
||||
|
||||
func NewBlockFromBytes(raw []byte) *Block {
|
||||
@ -151,7 +152,7 @@ func (block *Block) Hash() ethutil.Bytes {
|
||||
func (block *Block) HashNoNonce() []byte {
|
||||
return ethcrypto.Sha3(ethutil.Encode([]interface{}{block.PrevHash,
|
||||
block.UncleSha, block.Coinbase, block.state.Trie.Root,
|
||||
block.TxSha, block.Difficulty, block.Number, block.MinGasPrice,
|
||||
block.ReceiptSha, block.Difficulty, block.Number, block.MinGasPrice,
|
||||
block.GasLimit, block.GasUsed, block.Time, block.Extra}))
|
||||
}
|
||||
|
||||
@ -191,9 +192,9 @@ func (block *Block) BlockInfo() BlockInfo {
|
||||
}
|
||||
|
||||
func (self *Block) GetTransaction(hash []byte) *Transaction {
|
||||
for _, receipt := range self.receipts {
|
||||
if bytes.Compare(receipt.Tx.Hash(), hash) == 0 {
|
||||
return receipt.Tx
|
||||
for _, tx := range self.transactions {
|
||||
if bytes.Compare(tx.Hash(), hash) == 0 {
|
||||
return tx
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,10 +237,7 @@ func (block *Block) rlpUncles() interface{} {
|
||||
func (block *Block) SetUncles(uncles []*Block) {
|
||||
block.Uncles = uncles
|
||||
|
||||
// Sha of the concatenated uncles
|
||||
if len(uncles) > 0 {
|
||||
block.UncleSha = ethcrypto.Sha3(ethutil.Encode(block.rlpUncles()))
|
||||
}
|
||||
block.UncleSha = ethcrypto.Sha3(ethutil.Encode(block.rlpUncles()))
|
||||
}
|
||||
|
||||
func (self *Block) SetReceipts(receipts []*Receipt, txs []*Transaction) {
|
||||
@ -249,32 +247,20 @@ func (self *Block) SetReceipts(receipts []*Receipt, txs []*Transaction) {
|
||||
|
||||
func (block *Block) setTransactions(txs []*Transaction) {
|
||||
block.transactions = txs
|
||||
|
||||
block.LogsBloom = CreateBloom(txs)
|
||||
}
|
||||
|
||||
func CreateTxSha(receipts Receipts) (sha []byte) {
|
||||
trie := ethtrie.New(ethutil.Config.Db, "")
|
||||
for i, receipt := range receipts {
|
||||
trie.Update(string(ethutil.NewValue(i).Encode()), string(ethutil.NewValue(receipt.RlpData()).Encode()))
|
||||
}
|
||||
|
||||
switch trie.Root.(type) {
|
||||
case string:
|
||||
sha = []byte(trie.Root.(string))
|
||||
case []byte:
|
||||
sha = trie.Root.([]byte)
|
||||
default:
|
||||
panic(fmt.Sprintf("invalid root type %T", trie.Root))
|
||||
}
|
||||
|
||||
return sha
|
||||
func (self *Block) SetTransactionHash(transactions Transactions) {
|
||||
self.TxSha = DeriveSha(transactions)
|
||||
}
|
||||
|
||||
func (self *Block) SetTxHash(receipts Receipts) {
|
||||
self.TxSha = CreateTxSha(receipts)
|
||||
func (self *Block) SetReceiptHash(receipts Receipts) {
|
||||
self.ReceiptSha = DeriveSha(receipts)
|
||||
}
|
||||
|
||||
func (block *Block) Value() *ethutil.Value {
|
||||
return ethutil.NewValue([]interface{}{block.header(), block.rlpReceipts(), block.rlpUncles()})
|
||||
return ethutil.NewValue([]interface{}{block.header(), block.transactions, block.rlpUncles()})
|
||||
}
|
||||
|
||||
func (block *Block) RlpEncode() []byte {
|
||||
@ -289,33 +275,20 @@ func (block *Block) RlpDecode(data []byte) {
|
||||
}
|
||||
|
||||
func (block *Block) RlpValueDecode(decoder *ethutil.Value) {
|
||||
header := decoder.Get(0)
|
||||
|
||||
block.PrevHash = header.Get(0).Bytes()
|
||||
block.UncleSha = header.Get(1).Bytes()
|
||||
block.Coinbase = header.Get(2).Bytes()
|
||||
block.state = ethstate.New(ethtrie.New(ethutil.Config.Db, header.Get(3).Val))
|
||||
block.TxSha = header.Get(4).Bytes()
|
||||
block.Difficulty = header.Get(5).BigInt()
|
||||
block.Number = header.Get(6).BigInt()
|
||||
//fmt.Printf("#%v : %x\n", block.Number, block.Coinbase)
|
||||
block.MinGasPrice = header.Get(7).BigInt()
|
||||
block.GasLimit = header.Get(8).BigInt()
|
||||
block.GasUsed = header.Get(9).BigInt()
|
||||
block.Time = int64(header.Get(10).BigInt().Uint64())
|
||||
block.Extra = header.Get(11).Str()
|
||||
block.Nonce = header.Get(12).Bytes()
|
||||
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.transactions = make([]*Transaction, receipts.Len())
|
||||
block.receipts = make([]*Receipt, receipts.Len())
|
||||
for i := 0; i < receipts.Len(); i++ {
|
||||
receipt := NewRecieptFromValue(receipts.Get(i))
|
||||
block.transactions[i] = receipt.Tx
|
||||
block.receipts[i] = receipt
|
||||
//receipts := decoder.Get(1)
|
||||
//block.receipts = make([]*Receipt, receipts.Len())
|
||||
it := decoder.Get(1).NewIterator()
|
||||
block.transactions = make(Transactions, it.Len())
|
||||
for it.Next() {
|
||||
block.transactions[it.Idx()] = NewTransactionFromValue(it.Value())
|
||||
//receipt := NewRecieptFromValue(receipts.Get(i))
|
||||
//block.transactions[i] = receipt.Tx
|
||||
//block.receipts[i] = receipt
|
||||
}
|
||||
|
||||
}
|
||||
@ -330,22 +303,27 @@ func (block *Block) RlpValueDecode(decoder *ethutil.Value) {
|
||||
|
||||
}
|
||||
|
||||
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 = ethstate.New(ethtrie.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.MinGasPrice = header.Get(9).BigInt()
|
||||
self.GasLimit = header.Get(10).BigInt()
|
||||
self.GasUsed = header.Get(11).BigInt()
|
||||
self.Time = int64(header.Get(12).BigInt().Uint64())
|
||||
self.Extra = header.Get(13).Str()
|
||||
self.Nonce = header.Get(14).Bytes()
|
||||
}
|
||||
|
||||
func NewUncleBlockFromValue(header *ethutil.Value) *Block {
|
||||
block := &Block{}
|
||||
|
||||
block.PrevHash = header.Get(0).Bytes()
|
||||
block.UncleSha = header.Get(1).Bytes()
|
||||
block.Coinbase = header.Get(2).Bytes()
|
||||
block.state = ethstate.New(ethtrie.New(ethutil.Config.Db, header.Get(3).Val))
|
||||
block.TxSha = header.Get(4).Bytes()
|
||||
block.Difficulty = header.Get(5).BigInt()
|
||||
block.Number = header.Get(6).BigInt()
|
||||
block.MinGasPrice = header.Get(7).BigInt()
|
||||
block.GasLimit = header.Get(8).BigInt()
|
||||
block.GasUsed = header.Get(9).BigInt()
|
||||
block.Time = int64(header.Get(10).BigInt().Uint64())
|
||||
block.Extra = header.Get(11).Str()
|
||||
block.Nonce = header.Get(12).Bytes()
|
||||
block.setHeader(header)
|
||||
|
||||
return block
|
||||
}
|
||||
@ -376,8 +354,12 @@ func (block *Block) header() []interface{} {
|
||||
block.Coinbase,
|
||||
// root state
|
||||
block.state.Trie.Root,
|
||||
// Sha of tx
|
||||
// tx root
|
||||
block.TxSha,
|
||||
// Sha of tx
|
||||
block.ReceiptSha,
|
||||
// Bloom
|
||||
block.LogsBloom,
|
||||
// Current block Difficulty
|
||||
block.Difficulty,
|
||||
// The block number
|
||||
@ -404,7 +386,9 @@ func (block *Block) String() string {
|
||||
UncleSha: %x
|
||||
Coinbase: %x
|
||||
Root: %x
|
||||
TxSha: %x
|
||||
TxSha %x
|
||||
ReceiptSha: %x
|
||||
Bloom: %x
|
||||
Difficulty: %v
|
||||
Number: %v
|
||||
MinGas: %v
|
||||
@ -422,6 +406,8 @@ func (block *Block) String() string {
|
||||
block.Coinbase,
|
||||
block.state.Trie.Root,
|
||||
block.TxSha,
|
||||
block.ReceiptSha,
|
||||
block.LogsBloom,
|
||||
block.Difficulty,
|
||||
block.Number,
|
||||
block.MinGasPrice,
|
||||
@ -437,3 +423,23 @@ func (block *Block) String() string {
|
||||
func (self *Block) Size() ethutil.StorageSize {
|
||||
return ethutil.StorageSize(len(self.RlpEncode()))
|
||||
}
|
||||
|
||||
/*
|
||||
func DeriveReceiptHash(receipts Receipts) (sha []byte) {
|
||||
trie := ethtrie.New(ethutil.Config.Db, "")
|
||||
for i, receipt := range receipts {
|
||||
trie.Update(string(ethutil.NewValue(i).Encode()), string(ethutil.NewValue(receipt.RlpData()).Encode()))
|
||||
}
|
||||
|
||||
switch trie.Root.(type) {
|
||||
case string:
|
||||
sha = []byte(trie.Root.(string))
|
||||
case []byte:
|
||||
sha = trie.Root.([]byte)
|
||||
default:
|
||||
panic(fmt.Sprintf("invalid root type %T", trie.Root))
|
||||
}
|
||||
|
||||
return sha
|
||||
}
|
||||
*/
|
||||
|
@ -1,37 +1,44 @@
|
||||
package ethchain
|
||||
|
||||
import "github.com/ethereum/go-ethereum/vm"
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
func CreateBloom(txs Transactions) uint64 {
|
||||
var bin uint64
|
||||
"github.com/ethereum/go-ethereum/vm"
|
||||
)
|
||||
|
||||
func CreateBloom(txs Transactions) []byte {
|
||||
bin := new(big.Int)
|
||||
for _, tx := range txs {
|
||||
bin |= logsBloom(tx.logs)
|
||||
bin.Or(bin, LogsBloom(tx.logs))
|
||||
}
|
||||
|
||||
return bin
|
||||
return bin.Bytes()
|
||||
}
|
||||
|
||||
func logsBloom(logs []vm.Log) uint64 {
|
||||
var bin uint64
|
||||
func LogsBloom(logs []vm.Log) *big.Int {
|
||||
bin := new(big.Int)
|
||||
for _, log := range logs {
|
||||
data := [][]byte{log.Address}
|
||||
for _, topic := range log.Topics {
|
||||
data = append(data, topic.Bytes())
|
||||
data = append(data, topic)
|
||||
}
|
||||
data = append(data, log.Data)
|
||||
|
||||
for _, b := range data {
|
||||
bin |= bloom9(b)
|
||||
bin.Or(bin, bloom9(b))
|
||||
}
|
||||
}
|
||||
|
||||
return bin
|
||||
}
|
||||
|
||||
func bloom9(b []byte) uint64 {
|
||||
var r uint64
|
||||
func bloom9(b []byte) *big.Int {
|
||||
r := new(big.Int)
|
||||
for _, i := range []int{0, 2, 4} {
|
||||
r |= 1 << (uint64(b[i+1]) + 256*(uint64(b[i])&1))
|
||||
t := big.NewInt(1)
|
||||
|
||||
//r |= 1 << (uint64(b[i+1]) + 256*(uint64(b[i])&1))
|
||||
r.Or(r, t.Rsh(t, uint(b[i+1])+256*(uint(b[i])&1)))
|
||||
}
|
||||
|
||||
return r
|
||||
|
@ -87,8 +87,8 @@ func (bc *ChainManager) Reset() {
|
||||
bc.genesisBlock.state.Trie.Sync()
|
||||
// Prepare the genesis block
|
||||
bc.Add(bc.genesisBlock)
|
||||
fk := append([]byte("bloom"), bc.genesisBlock.Hash()...)
|
||||
bc.Ethereum.Db().Put(fk, make([]byte, 255))
|
||||
//fk := append([]byte("bloom"), bc.genesisBlock.Hash()...)
|
||||
//bc.Ethereum.Db().Put(fk, make([]byte, 255))
|
||||
bc.CurrentBlock = bc.genesisBlock
|
||||
|
||||
bc.SetTotalDifficulty(ethutil.Big("0"))
|
||||
|
@ -2,7 +2,6 @@ package ethchain
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/ethereum/go-ethereum/ethstate"
|
||||
@ -171,13 +170,14 @@ func (self *Filter) FilterMessages(msgs []*ethstate.Message) []*ethstate.Message
|
||||
}
|
||||
|
||||
func (self *Filter) bloomFilter(block *Block) bool {
|
||||
fk := append([]byte("bloom"), block.Hash()...)
|
||||
bin, err := self.eth.Db().Get(fk)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
//fk := append([]byte("bloom"), block.Hash()...)
|
||||
//bin, err := self.eth.Db().Get(fk)
|
||||
//if err != nil {
|
||||
// fmt.Println(err)
|
||||
//}
|
||||
|
||||
bloom := NewBloomFilter(bin)
|
||||
// TODO update to the new bloom filter
|
||||
bloom := NewBloomFilter(nil)
|
||||
|
||||
var fromIncluded, toIncluded bool
|
||||
if len(self.from) > 0 {
|
||||
|
@ -13,19 +13,24 @@ import (
|
||||
|
||||
var ZeroHash256 = make([]byte, 32)
|
||||
var ZeroHash160 = make([]byte, 20)
|
||||
var ZeroHash512 = make([]byte, 64)
|
||||
var EmptyShaList = ethcrypto.Sha3(ethutil.Encode([]interface{}{}))
|
||||
|
||||
var GenesisHeader = []interface{}{
|
||||
// Previous hash (none)
|
||||
ZeroHash256,
|
||||
// Empty uncles
|
||||
"",
|
||||
EmptyShaList,
|
||||
// Coinbase
|
||||
ZeroHash160,
|
||||
// Root state
|
||||
"",
|
||||
EmptyShaList,
|
||||
// tx sha
|
||||
"",
|
||||
EmptyShaList,
|
||||
// receipt list
|
||||
EmptyShaList,
|
||||
// bloom
|
||||
ZeroHash512,
|
||||
// Difficulty
|
||||
//ethutil.BigPow(2, 22),
|
||||
big.NewInt(131072),
|
||||
|
@ -173,8 +173,9 @@ done:
|
||||
state.Update()
|
||||
|
||||
txGas.Sub(txGas, st.gas)
|
||||
accumelative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, txGas))
|
||||
receipt := &Receipt{tx, ethutil.CopyBytes(state.Root().([]byte)), accumelative}
|
||||
cumulative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, txGas))
|
||||
//receipt := &Receipt{tx, ethutil.CopyBytes(state.Root().([]byte)), accumelative}
|
||||
receipt := &Receipt{ethutil.CopyBytes(state.Root().([]byte)), cumulative, LogsBloom(tx.logs).Bytes(), tx.logs}
|
||||
|
||||
if i < len(block.Receipts()) {
|
||||
original := block.Receipts()[i]
|
||||
@ -183,7 +184,7 @@ done:
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
err := fmt.Errorf("#%d receipt failed (r) %v ~ %x <=> (c) %v ~ %x (%x...)", i+1, original.CumulativeGasUsed, original.PostState[0:4], receipt.CumulativeGasUsed, receipt.PostState[0:4], receipt.Tx.Hash()[0:4])
|
||||
err := fmt.Errorf("#%d receipt failed (r) %v ~ %x <=> (c) %v ~ %x (%x...)", i+1, original.CumulativeGasUsed, original.PostState[0:4], receipt.CumulativeGasUsed, receipt.PostState[0:4], tx.Hash()[0:4])
|
||||
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
@ -235,14 +236,19 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
|
||||
fmt.Printf("## %x %x ##\n", block.Hash(), block.Number)
|
||||
}
|
||||
|
||||
txSha := DeriveSha(block.transactions)
|
||||
if bytes.Compare(txSha, block.TxSha) != 0 {
|
||||
return fmt.Errorf("Error validating transaction sha. Received %x, got %x", block.ReceiptSha, txSha)
|
||||
}
|
||||
|
||||
receipts, err := sm.ApplyDiff(state, parent, block)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
txSha := CreateTxSha(receipts)
|
||||
if bytes.Compare(txSha, block.TxSha) != 0 {
|
||||
return fmt.Errorf("Error validating tx sha. Received %x, got %x", block.TxSha, txSha)
|
||||
receiptSha := DeriveSha(receipts)
|
||||
if bytes.Compare(receiptSha, block.ReceiptSha) != 0 {
|
||||
return fmt.Errorf("Error validating receipt sha. Received %x, got %x", block.ReceiptSha, receiptSha)
|
||||
}
|
||||
|
||||
// Block validation
|
||||
@ -271,13 +277,15 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
|
||||
// Add the block to the chain
|
||||
sm.bc.Add(block)
|
||||
|
||||
// TODO at this point we should also insert LOGS in to a database
|
||||
|
||||
sm.transState = state.Copy()
|
||||
|
||||
// Create a bloom bin for this block
|
||||
filter := sm.createBloomFilter(state)
|
||||
//filter := sm.createBloomFilter(state)
|
||||
// Persist the data
|
||||
fk := append([]byte("bloom"), block.Hash()...)
|
||||
sm.eth.Db().Put(fk, filter.Bin())
|
||||
//fk := append([]byte("bloom"), block.Hash()...)
|
||||
//sm.eth.Db().Put(fk, filter.Bin())
|
||||
|
||||
statelogger.Infof("Imported block #%d (%x...)\n", block.Number, block.Hash()[0:4])
|
||||
if dontReact == false {
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/ethstate"
|
||||
"github.com/ethereum/go-ethereum/ethtrie"
|
||||
"github.com/ethereum/go-ethereum/ethutil"
|
||||
"github.com/ethereum/go-ethereum/vm"
|
||||
)
|
||||
@ -231,11 +230,9 @@ func (self *StateTransition) TransitionState() (err error) {
|
||||
|
||||
msg.Output = ret
|
||||
} else {
|
||||
// Add default LOG
|
||||
// PUSH1 1 CALLER ADD LOG1
|
||||
// Add default LOG. Default = big(sender.addr) + 1
|
||||
addr := ethutil.BigD(sender.Address())
|
||||
addr.Add(addr, ethutil.Big1)
|
||||
tx.addLog(vm.Log{sender.Address(), []*big.Int{addr}, nil})
|
||||
tx.addLog(vm.Log{sender.Address(), [][]byte{addr.Add(addr, ethutil.Big1).Bytes()}, nil})
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,9 +247,7 @@ func (self *StateTransition) Eval(msg *ethstate.Message, script []byte, context
|
||||
callerClosure = vm.NewClosure(msg, transactor, context, script, self.gas, self.gasPrice)
|
||||
)
|
||||
|
||||
//vm := vm.New(env, vm.Type(ethutil.Config.VmType))
|
||||
evm := vm.New(env, vm.DebugVmTy)
|
||||
|
||||
ret, _, err = callerClosure.Call(evm, self.tx.Data)
|
||||
|
||||
return
|
||||
@ -264,7 +259,6 @@ func MakeContract(tx *Transaction, state *ethstate.State) *ethstate.StateObject
|
||||
|
||||
contract := state.GetOrNewStateObject(addr)
|
||||
contract.InitCode = tx.Data
|
||||
contract.State = ethstate.New(ethtrie.New(ethutil.Config.Db, ""))
|
||||
|
||||
return contract
|
||||
}
|
||||
|
@ -113,7 +113,8 @@ func (tx *Transaction) PublicKey() []byte {
|
||||
sig := append(r, s...)
|
||||
sig = append(sig, tx.v-27)
|
||||
|
||||
pubkey, _ := secp256k1.RecoverPubkey(hash, sig)
|
||||
pubkey := ethcrypto.Ecrecover(append(hash, sig...))
|
||||
//pubkey, _ := secp256k1.RecoverPubkey(hash, sig)
|
||||
|
||||
return pubkey
|
||||
}
|
||||
@ -208,11 +209,11 @@ func (tx *Transaction) String() string {
|
||||
}
|
||||
|
||||
type Receipt struct {
|
||||
Tx *Transaction
|
||||
PostState []byte
|
||||
CumulativeGasUsed *big.Int
|
||||
Bloom []byte
|
||||
Logs vm.Logs
|
||||
}
|
||||
type Receipts []*Receipt
|
||||
|
||||
func NewRecieptFromValue(val *ethutil.Value) *Receipt {
|
||||
r := &Receipt{}
|
||||
@ -222,25 +223,22 @@ func NewRecieptFromValue(val *ethutil.Value) *Receipt {
|
||||
}
|
||||
|
||||
func (self *Receipt) RlpValueDecode(decoder *ethutil.Value) {
|
||||
self.Tx = NewTransactionFromValue(decoder.Get(0))
|
||||
self.PostState = decoder.Get(1).Bytes()
|
||||
self.CumulativeGasUsed = decoder.Get(2).BigInt()
|
||||
self.PostState = decoder.Get(0).Bytes()
|
||||
self.CumulativeGasUsed = decoder.Get(1).BigInt()
|
||||
self.Bloom = decoder.Get(2).Bytes()
|
||||
|
||||
it := decoder.Get(3).NewIterator()
|
||||
for it.Next() {
|
||||
self.Logs = append(self.Logs, vm.NewLogFromValue(it.Value()))
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Receipt) RlpData() interface{} {
|
||||
return []interface{}{self.Tx.RlpData(), self.PostState, self.CumulativeGasUsed}
|
||||
return []interface{}{self.PostState, self.CumulativeGasUsed, self.Bloom, self.Logs.RlpData()}
|
||||
}
|
||||
|
||||
func (self *Receipt) String() string {
|
||||
return fmt.Sprintf(`
|
||||
R
|
||||
Tx:[ %v]
|
||||
PostState: 0x%x
|
||||
CumulativeGasUsed: %v
|
||||
`,
|
||||
self.Tx,
|
||||
self.PostState,
|
||||
self.CumulativeGasUsed)
|
||||
func (self *Receipt) RlpEncode() []byte {
|
||||
return ethutil.Encode(self.RlpData())
|
||||
}
|
||||
|
||||
func (self *Receipt) Cmp(other *Receipt) bool {
|
||||
@ -251,11 +249,27 @@ func (self *Receipt) Cmp(other *Receipt) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
type Receipts []*Receipt
|
||||
|
||||
func (self Receipts) Len() int { return len(self) }
|
||||
func (self Receipts) GetRlp(i int) []byte { return ethutil.Rlp(self[i]) }
|
||||
|
||||
// Transaction slice type for basic sorting
|
||||
type Transactions []*Transaction
|
||||
|
||||
func (s Transactions) Len() int { return len(s) }
|
||||
func (s Transactions) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (self Transactions) RlpData() interface{} {
|
||||
// Marshal the transactions of this block
|
||||
enc := make([]interface{}, len(self))
|
||||
for i, tx := range self {
|
||||
// Cast it to a string (safe)
|
||||
enc[i] = tx.RlpData()
|
||||
}
|
||||
|
||||
return enc
|
||||
}
|
||||
func (s Transactions) Len() int { return len(s) }
|
||||
func (s Transactions) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (s Transactions) GetRlp(i int) []byte { return ethutil.Rlp(s[i]) }
|
||||
|
||||
type TxByNonce struct{ Transactions }
|
||||
|
||||
|
@ -187,7 +187,7 @@ func (self *Miner) mineNewBlock() {
|
||||
}
|
||||
self.ethereum.TxPool().RemoveSet(erroneous)
|
||||
self.txs = append(txs, unhandledTxs...)
|
||||
self.block.SetTxHash(receipts)
|
||||
self.block.SetReceiptHash(receipts)
|
||||
|
||||
// Set the transactions to the block so the new SHA3 can be calculated
|
||||
self.block.SetReceipts(receipts, txs)
|
||||
|
@ -219,6 +219,17 @@ func (t *Trie) Delete(key string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Trie) GetRoot() []byte {
|
||||
switch self.Root.(type) {
|
||||
case string:
|
||||
return []byte(self.Root.(string))
|
||||
case []byte:
|
||||
return self.Root.([]byte)
|
||||
default:
|
||||
panic(fmt.Sprintf("invalid root type %T", self.Root))
|
||||
}
|
||||
}
|
||||
|
||||
// Simple compare function which creates a rlp value out of the evaluated objects
|
||||
func (t *Trie) Cmp(trie *Trie) bool {
|
||||
return ethutil.NewValue(t.Root).Cmp(ethutil.NewValue(trie.Root))
|
||||
|
@ -15,6 +15,10 @@ type RlpEncodeDecode interface {
|
||||
RlpValue() []interface{}
|
||||
}
|
||||
|
||||
type RlpEncodable interface {
|
||||
RlpData() interface{}
|
||||
}
|
||||
|
||||
func Rlp(encoder RlpEncode) []byte {
|
||||
return encoder.RlpEncode()
|
||||
}
|
||||
@ -100,6 +104,8 @@ func Encode(object interface{}) []byte {
|
||||
switch t := object.(type) {
|
||||
case *Value:
|
||||
buff.Write(Encode(t.Raw()))
|
||||
case RlpEncodable:
|
||||
buff.Write(Encode(t.RlpData()))
|
||||
// Code dup :-/
|
||||
case int:
|
||||
buff.Write(Encode(big.NewInt(int64(t))))
|
||||
|
@ -377,6 +377,10 @@ func (val *Value) NewIterator() *ValueIterator {
|
||||
return &ValueIterator{value: val}
|
||||
}
|
||||
|
||||
func (it *ValueIterator) Len() int {
|
||||
return it.value.Len()
|
||||
}
|
||||
|
||||
func (it *ValueIterator) Next() bool {
|
||||
if it.idx >= it.value.Len() {
|
||||
return false
|
||||
|
33
vm/log.go
33
vm/log.go
@ -1,9 +1,38 @@
|
||||
package vm
|
||||
|
||||
import "math/big"
|
||||
import "github.com/ethereum/go-ethereum/ethutil"
|
||||
|
||||
type Log struct {
|
||||
Address []byte
|
||||
Topics []*big.Int
|
||||
Topics [][]byte
|
||||
Data []byte
|
||||
}
|
||||
|
||||
func NewLogFromValue(decoder *ethutil.Value) Log {
|
||||
log := Log{
|
||||
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 Log) RlpData() interface{} {
|
||||
return []interface{}{self.Address, ethutil.ByteSliceToInterface(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
|
||||
}
|
||||
|
@ -704,11 +704,11 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
self.Printf(" => [%d] %x [0] %x", n, x.Bytes(), y.Bytes())
|
||||
case LOG0, LOG1, LOG2, LOG3, LOG4:
|
||||
n := int(op - LOG0)
|
||||
topics := make([]*big.Int, n)
|
||||
topics := make([][]byte, n)
|
||||
mSize, mStart := stack.Pop().Int64(), stack.Pop().Int64()
|
||||
data := mem.Geti(mStart, mSize)
|
||||
for i := 0; i < n; i++ {
|
||||
topics[i] = stack.Pop()
|
||||
topics[i] = stack.Pop().Bytes()
|
||||
}
|
||||
self.env.AddLog(Log{closure.Address(), topics, data})
|
||||
case MLOAD:
|
||||
|
Loading…
Reference in New Issue
Block a user