core, miner: miner header validation, transaction & receipt writing

* Miners do now verify their own header, not their state.
* Changed old putTx and putReceipts to be exported
* Moved writing of transactions and receipts out of the block processer
  in to the chain manager. Closes #1386
* Miner post ChainHeadEvent & ChainEvent. Closes #1388
This commit is contained in:
Jeffrey Wilcke 2015-07-03 11:24:42 +02:00 committed by zelig
parent 9c3db1be1d
commit f680415739
5 changed files with 45 additions and 12 deletions

View file

@ -399,3 +399,15 @@ func ValidateHeader(pow pow.PoW, block *types.Header, parent *types.Block, check
return nil return nil
} }
func getBlockReceipts(db common.Database, bhash common.Hash) (receipts types.Receipts, err error) {
var rdata []byte
rdata, err = db.Get(append(receiptsPre, bhash[:]...))
if err == nil {
err = rlp.DecodeBytes(rdata, &receipts)
} else {
glog.V(logger.Detail).Infof("getBlockReceipts error %v\n", err)
}
return
}

View file

@ -64,9 +64,12 @@ func TestPutReceipt(t *testing.T) {
Index: 0, Index: 0,
}}) }})
PutReceipts(db, types.Receipts{receipt}) PutReceipts(db, hash, types.Receipts{receipt})
receipt = GetReceipt(db, common.Hash{}) receipts, err := getBlockReceipts(db, hash)
if receipt == nil { if err != nil {
t.Error("expected to get 1 receipt, got none.") t.Error("got err:", err)
}
if len(receipts) != 1 {
t.Error("expected to get 1 receipt, got", len(receipts))
} }
} }

View file

@ -632,7 +632,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
// This puts transactions in a extra db for rpc // This puts transactions in a extra db for rpc
PutTransactions(self.extraDb, block, block.Transactions()) PutTransactions(self.extraDb, block, block.Transactions())
// store the receipts // store the receipts
PutReceipts(self.extraDb, receipts) PutReceipts(self.extraDb, block.Hash(), receipts)
case SideStatTy: case SideStatTy:
if glog.V(logger.Detail) { if glog.V(logger.Detail) {
glog.Infof("inserted forked block #%d (TD=%v) (%d TXs %d UNCs) (%x...). Took %v\n", block.Number(), block.Difficulty(), len(block.Transactions()), len(block.Uncles()), block.Hash().Bytes()[0:4], time.Since(bstart)) glog.Infof("inserted forked block #%d (TD=%v) (%d TXs %d UNCs) (%x...). Took %v\n", block.Number(), block.Difficulty(), len(block.Transactions()), len(block.Uncles()), block.Hash().Bytes()[0:4], time.Since(bstart))

View file

@ -8,9 +8,6 @@ import (
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
) )
var receiptsPre = []byte("receipts-")
// PutTransactions stores the transactions in the given database
func PutTransactions(db common.Database, block *types.Block, txs types.Transactions) { func PutTransactions(db common.Database, block *types.Block, txs types.Transactions) {
for i, tx := range block.Transactions() { for i, tx := range block.Transactions() {
rlpEnc, err := rlp.EncodeToBytes(tx) rlpEnc, err := rlp.EncodeToBytes(tx)
@ -37,6 +34,7 @@ func PutTransactions(db common.Database, block *types.Block, txs types.Transacti
} }
} }
<<<<<<< HEAD
// PutReceipts stores the receipts in the current database // PutReceipts stores the receipts in the current database
func PutReceipts(db common.Database, receipts types.Receipts) error { func PutReceipts(db common.Database, receipts types.Receipts) error {
for _, receipt := range receipts { for _, receipt := range receipts {
@ -82,4 +80,20 @@ func GetReceiptsFromBlock(db common.Database, block *types.Block) types.Receipts
} }
return receipts return receipts
=======
func PutReceipts(db common.Database, hash common.Hash, receipts types.Receipts) error {
storageReceipts := make([]*types.ReceiptForStorage, len(receipts))
for i, receipt := range receipts {
storageReceipts[i] = (*types.ReceiptForStorage)(receipt)
}
bytes, err := rlp.EncodeToBytes(storageReceipts)
if err != nil {
return err
}
db.Put(append(receiptsPre, hash[:]...), bytes)
return nil
>>>>>>> core, miner: miner header validation, transaction & receipt writing
} }

View file

@ -240,7 +240,11 @@ func (self *worker) wait() {
glog.V(logger.Error).Infoln("Invalid block found during mining") glog.V(logger.Error).Infoln("Invalid block found during mining")
continue continue
} }
<<<<<<< HEAD
if err := core.ValidateHeader(self.eth.BlockProcessor().Pow, block.Header(), parent, true); err != nil && err != core.BlockFutureErr { if err := core.ValidateHeader(self.eth.BlockProcessor().Pow, block.Header(), parent, true); err != nil && err != core.BlockFutureErr {
=======
if err := core.ValidateHeader(self.eth.BlockProcessor().Pow, block.Header(), parent, true); err != nil {
>>>>>>> core, miner: miner header validation, transaction & receipt writing
glog.V(logger.Error).Infoln("Invalid header on mined block:", err) glog.V(logger.Error).Infoln("Invalid header on mined block:", err)
continue continue
} }
@ -255,7 +259,7 @@ func (self *worker) wait() {
// This puts transactions in a extra db for rpc // This puts transactions in a extra db for rpc
core.PutTransactions(self.extraDb, block, block.Transactions()) core.PutTransactions(self.extraDb, block, block.Transactions())
// store the receipts // store the receipts
core.PutReceipts(self.extraDb, self.current.receipts) core.PutReceipts(self.extraDb, block.Hash(), self.current.receipts)
} }
// check staleness and display confirmation // check staleness and display confirmation
@ -271,13 +275,13 @@ func (self *worker) wait() {
glog.V(logger.Info).Infof("🔨 Mined %sblock (#%v / %x). %s", stale, block.Number(), block.Hash().Bytes()[:4], confirm) glog.V(logger.Info).Infof("🔨 Mined %sblock (#%v / %x). %s", stale, block.Number(), block.Hash().Bytes()[:4], confirm)
// broadcast before waiting for validation // broadcast before waiting for validation
go func(block *types.Block, logs state.Logs) { go func() {
self.mux.Post(core.NewMinedBlockEvent{block}) self.mux.Post(core.NewMinedBlockEvent{block})
self.mux.Post(core.ChainEvent{block, block.Hash(), logs}) self.mux.Post(core.ChainEvent{block, block.Hash(), self.current.state.Logs()})
if stat == core.CanonStatTy { if stat == core.CanonStatTy {
self.mux.Post(core.ChainHeadEvent{block}) self.mux.Post(core.ChainHeadEvent{block})
} }
}(block, self.current.state.Logs()) }()
self.commitNewWork() self.commitNewWork()
} }