From d1696dbf0746929c0ab719ef0807dc7b700bb85a Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 5 Aug 2016 23:12:52 +0200 Subject: [release/1.4.11] core/vm: hide ecrecover error message Fixes #2825 (cherry picked from commit e4736fe46938008b7fa88879f728fa81c6ce09e8) --- core/vm/contracts.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'core') diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 5cc9f903b..b45f14724 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -95,7 +95,7 @@ func ecrecoverFunc(in []byte) []byte { // tighter sig s values in homestead only apply to tx sigs if !crypto.ValidateSignatureValues(v, r, s, false) { - glog.V(logger.Debug).Infof("EC RECOVER FAIL: v, r or s value invalid") + glog.V(logger.Detail).Infof("ECRECOVER error: v, r or s value invalid") return nil } @@ -106,7 +106,7 @@ func ecrecoverFunc(in []byte) []byte { pubKey, err := crypto.Ecrecover(in[:32], rsv) // make sure the public key is a valid one if err != nil { - glog.V(logger.Error).Infof("EC RECOVER FAIL: ", err) + glog.V(logger.Detail).Infoln("ECRECOVER error: ", err) return nil } -- cgit v1.2.3 From c4ed34f008ae508549c03ec286467f48b188272f Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Tue, 26 Jul 2016 16:37:04 +0200 Subject: [release/1.4.11] core: ensure the canonical block is written before the canonical hash is set (cherry picked from commit bb8059f6aa86d1052d7c2dd75a6985982cb278f4) Conflicts: core/blockchain.go core/database_util.go core/headerchain.go eth/filters/filter.go --- core/blockchain.go | 19 +++++++++---------- core/blockchain_test.go | 38 ++++++++++++++++++++++++++++++++++++++ core/database_util.go | 6 +++++- core/headerchain.go | 17 ++++++++++------- 4 files changed, 62 insertions(+), 18 deletions(-) (limited to 'core') diff --git a/core/blockchain.go b/core/blockchain.go index 3fbb117d3..8f00f2cc4 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -770,6 +770,14 @@ func (self *BlockChain) WriteBlock(block *types.Block) (status WriteStatus, err localTd := self.GetTd(self.currentBlock.Hash()) externTd := new(big.Int).Add(block.Difficulty(), ptd) + // Irrelevant of the canonical status, write the block itself to the database + if err := self.hc.WriteTd(block.Hash(), externTd); err != nil { + glog.Fatalf("failed to write block total difficulty: %v", err) + } + if err := WriteBlock(self.chainDb, block); err != nil { + glog.Fatalf("failed to write block contents: %v", err) + } + // If the total difficulty is higher than our known, add it to the canonical chain // Second clause in the if statement reduces the vulnerability to selfish mining. // Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf @@ -780,20 +788,11 @@ func (self *BlockChain) WriteBlock(block *types.Block) (status WriteStatus, err return NonStatTy, err } } - // Insert the block as the new head of the chain - self.insert(block) + self.insert(block) // Insert the block as the new head of the chain status = CanonStatTy } else { status = SideStatTy } - // Irrelevant of the canonical status, write the block itself to the database - if err := self.hc.WriteTd(block.Hash(), externTd); err != nil { - glog.Fatalf("failed to write block total difficulty: %v", err) - } - if err := WriteBlock(self.chainDb, block); err != nil { - glog.Fatalf("failed to write block contents: %v", err) - } - self.futureBlocks.Remove(block.Hash()) return diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 2f6ddf9c9..18fe30f18 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -1090,3 +1090,41 @@ done: } } + +// Tests if the canonical block can be fetched from the database during chain insertion. +func TestCanonicalBlockRetrieval(t *testing.T) { + var ( + db, _ = ethdb.NewMemDatabase() + genesis = WriteGenesisBlockForTesting(db) + ) + + evmux := &event.TypeMux{} + blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux) + + chain, _ := GenerateChain(nil, genesis, db, 10, func(i int, gen *BlockGen) {}) + + for i, _ := range chain { + go func(block *types.Block) { + // try to retrieve a block by its canonical hash and see if the block data can be retrieved. + for { + ch := GetCanonicalHash(db, block.NumberU64()) + if ch == (common.Hash{}) { + continue // busy wait for canonical hash to be written + } + if ch != block.Hash() { + t.Fatalf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex()) + } + fb := GetBlock(db, ch) + if fb == nil { + t.Fatalf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex()) + } + if fb.Hash() != block.Hash() { + t.Fatalf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex()) + } + return + } + }(chain[i]) + + blockchain.InsertChain(types.Blocks{chain[i]}) + } +} diff --git a/core/database_util.go b/core/database_util.go index 3ba80062c..3a110f7d0 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -157,7 +157,11 @@ func GetTd(db ethdb.Database, hash common.Hash) *big.Int { } // GetBlock retrieves an entire block corresponding to the hash, assembling it -// back from the stored header and body. +// back from the stored header and body. If either the header or body could not +// be retrieved nil is returned. +// +// Note, due to concurrent download of header and block body the header and thus +// canonical hash can be stored in the database but the body data not (yet). func GetBlock(db ethdb.Database, hash common.Hash) *types.Block { // Retrieve the block header and body contents header := GetHeader(db, hash) diff --git a/core/headerchain.go b/core/headerchain.go index 5e0fbfb08..3503a1c33 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -129,6 +129,14 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er localTd := hc.GetTd(hc.currentHeaderHash) externTd := new(big.Int).Add(header.Difficulty, ptd) + // Irrelevant of the canonical status, write the td and header to the database + if err := hc.WriteTd(hash, externTd); err != nil { + glog.Fatalf("failed to write header total difficulty: %v", err) + } + if err := WriteHeader(hc.chainDb, header); err != nil { + glog.Fatalf("failed to write header contents: %v", err) + } + // If the total difficulty is higher than our known, add it to the canonical chain // Second clause in the if statement reduces the vulnerability to selfish mining. // Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf @@ -150,6 +158,7 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er headHeader = hc.GetHeader(headHash) headNumber = headHeader.Number.Uint64() } + // Extend the canonical chain with the new header if err := WriteCanonicalHash(hc.chainDb, hash, number); err != nil { glog.Fatalf("failed to insert header number: %v", err) @@ -157,19 +166,13 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er if err := WriteHeadHeaderHash(hc.chainDb, hash); err != nil { glog.Fatalf("failed to insert head header hash: %v", err) } + hc.currentHeaderHash, hc.currentHeader = hash, types.CopyHeader(header) status = CanonStatTy } else { status = SideStatTy } - // Irrelevant of the canonical status, write the header itself to the database - if err := hc.WriteTd(hash, externTd); err != nil { - glog.Fatalf("failed to write header total difficulty: %v", err) - } - if err := WriteHeader(hc.chainDb, header); err != nil { - glog.Fatalf("failed to write header contents: %v", err) - } hc.headerCache.Add(hash, header) return -- cgit v1.2.3