diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go
index 2b5c5fc4a4..76c51a40c1 100644
--- a/accounts/abi/bind/backends/simulated.go
+++ b/accounts/abi/bind/backends/simulated.go
@@ -31,6 +31,7 @@ import (
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
@@ -159,7 +160,7 @@ func (b *SimulatedBackend) StorageAt(ctx context.Context, contract common.Addres
// TransactionReceipt returns the receipt of a transaction.
func (b *SimulatedBackend) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
- receipt, _, _, _ := core.GetReceipt(b.database, txHash)
+ receipt, _, _, _ := rawdb.ReadReceipt(b.database, txHash)
return receipt, nil
}
@@ -430,11 +431,19 @@ func (fb *filterBackend) HeaderByNumber(ctx context.Context, block rpc.BlockNumb
}
func (fb *filterBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
- return core.GetBlockReceipts(fb.db, hash, core.GetBlockNumber(fb.db, hash)), nil
+ number := rawdb.ReadHeaderNumber(fb.db, hash)
+ if number == nil {
+ return nil, nil
+ }
+ return rawdb.ReadReceipts(fb.db, hash, *number), nil
}
func (fb *filterBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) {
- receipts := core.GetBlockReceipts(fb.db, hash, core.GetBlockNumber(fb.db, hash))
+ number := rawdb.ReadHeaderNumber(fb.db, hash)
+ if number == nil {
+ return nil, nil
+ }
+ receipts := rawdb.ReadReceipts(fb.db, hash, *number)
if receipts == nil {
return nil, nil
}
diff --git a/accounts/keystore/keystore_passphrase.go b/accounts/keystore/keystore_passphrase.go
index eaec39f7df..da632fe345 100644
--- a/accounts/keystore/keystore_passphrase.go
+++ b/accounts/keystore/keystore_passphrase.go
@@ -108,9 +108,8 @@ func (ks keyStorePassphrase) StoreKey(filename string, key *Key, auth string) er
func (ks keyStorePassphrase) JoinPath(filename string) string {
if filepath.IsAbs(filename) {
return filename
- } else {
- return filepath.Join(ks.keysDirPath, filename)
}
+ return filepath.Join(ks.keysDirPath, filename)
}
// EncryptKey encrypts a key using the specified scrypt parameters into a json
diff --git a/accounts/keystore/keystore_plain.go b/accounts/keystore/keystore_plain.go
index b490ca72b8..f62a133ce1 100644
--- a/accounts/keystore/keystore_plain.go
+++ b/accounts/keystore/keystore_plain.go
@@ -56,7 +56,6 @@ func (ks keyStorePlain) StoreKey(filename string, key *Key, auth string) error {
func (ks keyStorePlain) JoinPath(filename string) string {
if filepath.IsAbs(filename) {
return filename
- } else {
- return filepath.Join(ks.keysDirPath, filename)
}
+ return filepath.Join(ks.keysDirPath, filename)
}
diff --git a/cmd/geth/dao_test.go b/cmd/geth/dao_test.go
index a8dbc51630..52983ff2af 100644
--- a/cmd/geth/dao_test.go
+++ b/cmd/geth/dao_test.go
@@ -24,7 +24,7 @@ import (
"testing"
"github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/params"
)
@@ -131,8 +131,8 @@ func testDAOForkBlockNewChain(t *testing.T, test int, genesis string, expectBloc
if genesis != "" {
genesisHash = daoGenesisHash
}
- config, err := core.GetChainConfig(db, genesisHash)
- if err != nil {
+ config := rawdb.ReadChainConfig(db, genesisHash)
+ if config == nil {
t.Errorf("test %d: failed to retrieve chain config: %v", test, err)
return // we want to return here, the other checks can't make it past this point (nil panic).
}
diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go
index c0af4c13e7..58d72f32ba 100644
--- a/cmd/utils/cmd.go
+++ b/cmd/utils/cmd.go
@@ -29,6 +29,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
@@ -271,15 +272,13 @@ func ImportPreimages(db *ethdb.LDBDatabase, fn string) error {
// Accumulate the preimages and flush when enough ws gathered
preimages[crypto.Keccak256Hash(blob)] = common.CopyBytes(blob)
if len(preimages) > 1024 {
- if err := core.WritePreimages(db, 0, preimages); err != nil {
- return err
- }
+ rawdb.WritePreimages(db, 0, preimages)
preimages = make(map[common.Hash][]byte)
}
}
// Flush the last batch preimage data
if len(preimages) > 0 {
- return core.WritePreimages(db, 0, preimages)
+ rawdb.WritePreimages(db, 0, preimages)
}
return nil
}
diff --git a/cmd/wnode/main.go b/cmd/wnode/main.go
index 988c50ce3d..5031a088cb 100644
--- a/cmd/wnode/main.go
+++ b/cmd/wnode/main.go
@@ -271,7 +271,9 @@ func initialize() {
if *mailServerMode {
shh.RegisterServer(&mailServer)
- mailServer.Init(shh, *argDBPath, msPassword, *argServerPoW)
+ if err := mailServer.Init(shh, *argDBPath, msPassword, *argServerPoW); err != nil {
+ utils.Fatalf("Failed to init MailServer: %s", err)
+ }
}
server = &p2p.Server{
diff --git a/common/bytes.go b/common/bytes.go
index ba00e8a4b2..e2adc80059 100644
--- a/common/bytes.go
+++ b/common/bytes.go
@@ -87,15 +87,13 @@ func Hex2BytesFixed(str string, flen int) []byte {
h, _ := hex.DecodeString(str)
if len(h) == flen {
return h
- } else {
- if len(h) > flen {
- return h[len(h)-flen:]
- } else {
- hh := make([]byte, flen)
- copy(hh[flen-len(h):flen], h[:])
- return hh
- }
}
+ if len(h) > flen {
+ return h[len(h)-flen:]
+ }
+ hh := make([]byte, flen)
+ copy(hh[flen-len(h):flen], h[:])
+ return hh
}
func RightPadBytes(slice []byte, l int) []byte {
diff --git a/consensus/clique/snapshot_test.go b/consensus/clique/snapshot_test.go
index 8b51e6e094..91fafcbe07 100644
--- a/consensus/clique/snapshot_test.go
+++ b/consensus/clique/snapshot_test.go
@@ -24,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
@@ -81,7 +82,7 @@ func (r *testerChainReader) GetBlock(common.Hash, uint64) *types.Block { panic
func (r *testerChainReader) GetHeaderByHash(common.Hash) *types.Header { panic("not supported") }
func (r *testerChainReader) GetHeaderByNumber(number uint64) *types.Header {
if number == 0 {
- return core.GetHeader(r.db, core.GetCanonicalHash(r.db, 0), 0)
+ return rawdb.ReadHeader(r.db, rawdb.ReadCanonicalHash(r.db, 0), 0)
}
panic("not supported")
}
diff --git a/consensus/ethash/ethash.go b/consensus/ethash/ethash.go
index 1b3dcee302..ac049f9c36 100644
--- a/consensus/ethash/ethash.go
+++ b/consensus/ethash/ethash.go
@@ -156,7 +156,7 @@ type lru struct {
futureItem interface{}
}
-// newlru create a new least-recently-used cache for ither the verification caches
+// newlru create a new least-recently-used cache for either the verification caches
// or the mining datasets.
func newlru(what string, maxItems int, new func(epoch uint64) interface{}) *lru {
if maxItems <= 0 {
diff --git a/core/bench_test.go b/core/bench_test.go
index e23f0d19d1..ee30cfed0e 100644
--- a/core/bench_test.go
+++ b/core/bench_test.go
@@ -26,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/consensus/ethash"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
@@ -234,13 +235,15 @@ func makeChainForBench(db ethdb.Database, full bool, count uint64) {
ReceiptHash: types.EmptyRootHash,
}
hash = header.Hash()
- WriteHeader(db, header)
- WriteCanonicalHash(db, hash, n)
- WriteTd(db, hash, n, big.NewInt(int64(n+1)))
+
+ rawdb.WriteHeader(db, header)
+ rawdb.WriteCanonicalHash(db, hash, n)
+ rawdb.WriteTd(db, hash, n, big.NewInt(int64(n+1)))
+
if full || n == 0 {
block := types.NewBlockWithHeader(header)
- WriteBody(db, hash, n, block.Body())
- WriteBlockReceipts(db, hash, n, nil)
+ rawdb.WriteBody(db, hash, n, block.Body())
+ rawdb.WriteReceipts(db, hash, n, nil)
}
}
}
@@ -292,11 +295,10 @@ func benchReadChain(b *testing.B, full bool, count uint64) {
header := chain.GetHeaderByNumber(n)
if full {
hash := header.Hash()
- GetBody(db, hash, n)
- GetBlockReceipts(db, hash, n)
+ rawdb.ReadBody(db, hash, n)
+ rawdb.ReadReceipts(db, hash, n)
}
}
-
chain.Stop()
db.Close()
}
diff --git a/core/blockchain.go b/core/blockchain.go
index b33eb85a44..f74a0f5b27 100644
--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -30,6 +30,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/mclock"
"github.com/ethereum/go-ethereum/consensus"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
@@ -202,7 +203,7 @@ func (bc *BlockChain) getProcInterrupt() bool {
// assumes that the chain manager mutex is held.
func (bc *BlockChain) loadLastState() error {
// Restore the last known head block
- head := GetHeadBlockHash(bc.db)
+ head := rawdb.ReadHeadBlockHash(bc.db)
if head == (common.Hash{}) {
// Corrupt or empty database, init from scratch
log.Warn("Empty database, resetting chain")
@@ -228,7 +229,7 @@ func (bc *BlockChain) loadLastState() error {
// Restore the last known head header
currentHeader := currentBlock.Header()
- if head := GetHeadHeaderHash(bc.db); head != (common.Hash{}) {
+ if head := rawdb.ReadHeadHeaderHash(bc.db); head != (common.Hash{}) {
if header := bc.GetHeaderByHash(head); header != nil {
currentHeader = header
}
@@ -237,7 +238,7 @@ func (bc *BlockChain) loadLastState() error {
// Restore the last known head fast block
bc.currentFastBlock.Store(currentBlock)
- if head := GetHeadFastBlockHash(bc.db); head != (common.Hash{}) {
+ if head := rawdb.ReadHeadFastBlockHash(bc.db); head != (common.Hash{}) {
if block := bc.GetBlockByHash(head); block != nil {
bc.currentFastBlock.Store(block)
}
@@ -269,7 +270,7 @@ func (bc *BlockChain) SetHead(head uint64) error {
// Rewind the header chain, deleting all block bodies until then
delFn := func(hash common.Hash, num uint64) {
- DeleteBody(bc.db, hash, num)
+ rawdb.DeleteBody(bc.db, hash, num)
}
bc.hc.SetHead(head, delFn)
currentHeader := bc.hc.CurrentHeader()
@@ -303,12 +304,10 @@ func (bc *BlockChain) SetHead(head uint64) error {
}
currentBlock := bc.CurrentBlock()
currentFastBlock := bc.CurrentFastBlock()
- if err := WriteHeadBlockHash(bc.db, currentBlock.Hash()); err != nil {
- log.Crit("Failed to reset head full block", "err", err)
- }
- if err := WriteHeadFastBlockHash(bc.db, currentFastBlock.Hash()); err != nil {
- log.Crit("Failed to reset head fast block", "err", err)
- }
+
+ rawdb.WriteHeadBlockHash(bc.db, currentBlock.Hash())
+ rawdb.WriteHeadFastBlockHash(bc.db, currentFastBlock.Hash())
+
return bc.loadLastState()
}
@@ -406,9 +405,8 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error {
if err := bc.hc.WriteTd(genesis.Hash(), genesis.NumberU64(), genesis.Difficulty()); err != nil {
log.Crit("Failed to write genesis block TD", "err", err)
}
- if err := WriteBlock(bc.db, genesis); err != nil {
- log.Crit("Failed to write genesis block", "err", err)
- }
+ rawdb.WriteBlock(bc.db, genesis)
+
bc.genesisBlock = genesis
bc.insert(bc.genesisBlock)
bc.currentBlock.Store(bc.genesisBlock)
@@ -474,24 +472,19 @@ func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error {
// Note, this function assumes that the `mu` mutex is held!
func (bc *BlockChain) insert(block *types.Block) {
// If the block is on a side chain or an unknown one, force other heads onto it too
- updateHeads := GetCanonicalHash(bc.db, block.NumberU64()) != block.Hash()
+ updateHeads := rawdb.ReadCanonicalHash(bc.db, block.NumberU64()) != block.Hash()
// Add the block to the canonical chain number scheme and mark as the head
- if err := WriteCanonicalHash(bc.db, block.Hash(), block.NumberU64()); err != nil {
- log.Crit("Failed to insert block number", "err", err)
- }
- if err := WriteHeadBlockHash(bc.db, block.Hash()); err != nil {
- log.Crit("Failed to insert head block hash", "err", err)
- }
+ rawdb.WriteCanonicalHash(bc.db, block.Hash(), block.NumberU64())
+ rawdb.WriteHeadBlockHash(bc.db, block.Hash())
+
bc.currentBlock.Store(block)
// If the block is better than our head or is on a different chain, force update heads
if updateHeads {
bc.hc.SetCurrentHeader(block.Header())
+ rawdb.WriteHeadFastBlockHash(bc.db, block.Hash())
- if err := WriteHeadFastBlockHash(bc.db, block.Hash()); err != nil {
- log.Crit("Failed to insert head fast block hash", "err", err)
- }
bc.currentFastBlock.Store(block)
}
}
@@ -509,7 +502,11 @@ func (bc *BlockChain) GetBody(hash common.Hash) *types.Body {
body := cached.(*types.Body)
return body
}
- body := GetBody(bc.db, hash, bc.hc.GetBlockNumber(hash))
+ number := bc.hc.GetBlockNumber(hash)
+ if number == nil {
+ return nil
+ }
+ body := rawdb.ReadBody(bc.db, hash, *number)
if body == nil {
return nil
}
@@ -525,7 +522,11 @@ func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue {
if cached, ok := bc.bodyRLPCache.Get(hash); ok {
return cached.(rlp.RawValue)
}
- body := GetBodyRLP(bc.db, hash, bc.hc.GetBlockNumber(hash))
+ number := bc.hc.GetBlockNumber(hash)
+ if number == nil {
+ return nil
+ }
+ body := rawdb.ReadBodyRLP(bc.db, hash, *number)
if len(body) == 0 {
return nil
}
@@ -539,8 +540,7 @@ func (bc *BlockChain) HasBlock(hash common.Hash, number uint64) bool {
if bc.blockCache.Contains(hash) {
return true
}
- ok, _ := bc.db.Has(blockBodyKey(hash, number))
- return ok
+ return rawdb.HasBody(bc.db, hash, number)
}
// HasState checks if state trie is fully present in the database or not.
@@ -567,7 +567,7 @@ func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
if block, ok := bc.blockCache.Get(hash); ok {
return block.(*types.Block)
}
- block := GetBlock(bc.db, hash, number)
+ block := rawdb.ReadBlock(bc.db, hash, number)
if block == nil {
return nil
}
@@ -578,13 +578,17 @@ func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
// GetBlockByHash retrieves a block from the database by hash, caching it if found.
func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block {
- return bc.GetBlock(hash, bc.hc.GetBlockNumber(hash))
+ number := bc.hc.GetBlockNumber(hash)
+ if number == nil {
+ return nil
+ }
+ return bc.GetBlock(hash, *number)
}
// GetBlockByNumber retrieves a block from the database by number, caching it
// (associated with its hash) if found.
func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block {
- hash := GetCanonicalHash(bc.db, number)
+ hash := rawdb.ReadCanonicalHash(bc.db, number)
if hash == (common.Hash{}) {
return nil
}
@@ -593,21 +597,28 @@ func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block {
// GetReceiptsByHash retrieves the receipts for all transactions in a given block.
func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
- return GetBlockReceipts(bc.db, hash, GetBlockNumber(bc.db, hash))
+ number := rawdb.ReadHeaderNumber(bc.db, hash)
+ if number == nil {
+ return nil
+ }
+ return rawdb.ReadReceipts(bc.db, hash, *number)
}
// GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors.
// [deprecated by eth/62]
func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) {
number := bc.hc.GetBlockNumber(hash)
+ if number == nil {
+ return nil
+ }
for i := 0; i < n; i++ {
- block := bc.GetBlock(hash, number)
+ block := bc.GetBlock(hash, *number)
if block == nil {
break
}
blocks = append(blocks, block)
hash = block.ParentHash()
- number--
+ *number--
}
return
}
@@ -712,12 +723,12 @@ func (bc *BlockChain) Rollback(chain []common.Hash) {
if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock.Hash() == hash {
newFastBlock := bc.GetBlock(currentFastBlock.ParentHash(), currentFastBlock.NumberU64()-1)
bc.currentFastBlock.Store(newFastBlock)
- WriteHeadFastBlockHash(bc.db, newFastBlock.Hash())
+ rawdb.WriteHeadFastBlockHash(bc.db, newFastBlock.Hash())
}
if currentBlock := bc.CurrentBlock(); currentBlock.Hash() == hash {
newBlock := bc.GetBlock(currentBlock.ParentHash(), currentBlock.NumberU64()-1)
bc.currentBlock.Store(newBlock)
- WriteHeadBlockHash(bc.db, newBlock.Hash())
+ rawdb.WriteHeadBlockHash(bc.db, newBlock.Hash())
}
}
}
@@ -802,15 +813,10 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
return i, fmt.Errorf("failed to set receipts data: %v", err)
}
// Write all the data out into the database
- if err := WriteBody(batch, block.Hash(), block.NumberU64(), block.Body()); err != nil {
- return i, fmt.Errorf("failed to write block body: %v", err)
- }
- if err := WriteBlockReceipts(batch, block.Hash(), block.NumberU64(), receipts); err != nil {
- return i, fmt.Errorf("failed to write block receipts: %v", err)
- }
- if err := WriteTxLookupEntries(batch, block); err != nil {
- return i, fmt.Errorf("failed to write lookup metadata: %v", err)
- }
+ rawdb.WriteBody(batch, block.Hash(), block.NumberU64(), block.Body())
+ rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receipts)
+ rawdb.WriteTxLookupEntries(batch, block)
+
stats.processed++
if batch.ValueSize() >= ethdb.IdealBatchSize {
@@ -834,9 +840,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
if td := bc.GetTd(head.Hash(), head.NumberU64()); td != nil { // Rewind may have occurred, skip in that case
currentFastBlock := bc.CurrentFastBlock()
if bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64()).Cmp(td) < 0 {
- if err := WriteHeadFastBlockHash(bc.db, head.Hash()); err != nil {
- log.Crit("Failed to update head fast block hash", "err", err)
- }
+ rawdb.WriteHeadFastBlockHash(bc.db, head.Hash())
bc.currentFastBlock.Store(head)
}
}
@@ -864,9 +868,8 @@ func (bc *BlockChain) WriteBlockWithoutState(block *types.Block, td *big.Int) (e
if err := bc.hc.WriteTd(block.Hash(), block.NumberU64(), td); err != nil {
return err
}
- if err := WriteBlock(bc.db, block); err != nil {
- return err
- }
+ rawdb.WriteBlock(bc.db, block)
+
return nil
}
@@ -894,9 +897,8 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
}
// Write other block data using a batch.
batch := bc.db.NewBatch()
- if err := WriteBlock(batch, block); err != nil {
- return NonStatTy, err
- }
+ rawdb.WriteBlock(batch, block)
+
root, err := state.Commit(bc.chainConfig.IsEIP158(block.Number()))
if err != nil {
return NonStatTy, err
@@ -953,9 +955,8 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
}
}
}
- if err := WriteBlockReceipts(batch, block.Hash(), block.NumberU64(), receipts); err != nil {
- return NonStatTy, err
- }
+ rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receipts)
+
// 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
@@ -972,14 +973,10 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
return NonStatTy, err
}
}
- // Write the positional metadata for transaction and receipt lookups
- if err := WriteTxLookupEntries(batch, block); err != nil {
- return NonStatTy, err
- }
- // Write hash preimages
- if err := WritePreimages(bc.db, block.NumberU64(), state.Preimages()); err != nil {
- return NonStatTy, err
- }
+ // Write the positional metadata for transaction/receipt lookups and preimages
+ rawdb.WriteTxLookupEntries(batch, block)
+ rawdb.WritePreimages(batch, block.NumberU64(), state.Preimages())
+
status = CanonStatTy
} else {
status = SideStatTy
@@ -1256,9 +1253,13 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
// collectLogs collects the logs that were generated during the
// processing of the block that corresponds with the given hash.
// These logs are later announced as deleted.
- collectLogs = func(h common.Hash) {
+ collectLogs = func(hash common.Hash) {
// Coalesce logs and set 'Removed'.
- receipts := GetBlockReceipts(bc.db, h, bc.hc.GetBlockNumber(h))
+ number := bc.hc.GetBlockNumber(hash)
+ if number == nil {
+ return
+ }
+ receipts := rawdb.ReadReceipts(bc.db, hash, *number)
for _, receipt := range receipts {
for _, log := range receipt.Logs {
del := *log
@@ -1327,9 +1328,7 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
// insert the block in the canonical way, re-writing history
bc.insert(newChain[i])
// write lookup entries for hash based transaction/receipt searches
- if err := WriteTxLookupEntries(bc.db, newChain[i]); err != nil {
- return err
- }
+ rawdb.WriteTxLookupEntries(bc.db, newChain[i])
addedTxs = append(addedTxs, newChain[i].Transactions()...)
}
// calculate the difference between deleted and added transactions
@@ -1337,7 +1336,7 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
// When transactions get deleted from the database that means the
// receipts that were created in the fork must also be deleted
for _, tx := range diff {
- DeleteTxLookupEntry(bc.db, tx.Hash())
+ rawdb.DeleteTxLookupEntry(bc.db, tx.Hash())
}
if len(deletedLogs) > 0 {
go bc.rmLogsFeed.Send(RemovedLogsEvent{deletedLogs})
diff --git a/core/blockchain_test.go b/core/blockchain_test.go
index 375823b57b..c1638c31f8 100644
--- a/core/blockchain_test.go
+++ b/core/blockchain_test.go
@@ -26,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/ethash"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
@@ -128,8 +129,8 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
return err
}
blockchain.mu.Lock()
- WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTdByHash(block.ParentHash())))
- WriteBlock(blockchain.db, block)
+ rawdb.WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTdByHash(block.ParentHash())))
+ rawdb.WriteBlock(blockchain.db, block)
statedb.Commit(false)
blockchain.mu.Unlock()
}
@@ -146,8 +147,8 @@ func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error
}
// Manually insert the header into the database, but don't reorganise (allows subsequent testing)
blockchain.mu.Lock()
- WriteTd(blockchain.db, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, blockchain.GetTdByHash(header.ParentHash)))
- WriteHeader(blockchain.db, header)
+ rawdb.WriteTd(blockchain.db, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, blockchain.GetTdByHash(header.ParentHash)))
+ rawdb.WriteHeader(blockchain.db, header)
blockchain.mu.Unlock()
}
return nil
@@ -173,7 +174,7 @@ func TestLastBlock(t *testing.T) {
if _, err := blockchain.InsertChain(blocks); err != nil {
t.Fatalf("Failed to insert block: %v", err)
}
- if blocks[len(blocks)-1].Hash() != GetHeadBlockHash(blockchain.db) {
+ if blocks[len(blocks)-1].Hash() != rawdb.ReadHeadBlockHash(blockchain.db) {
t.Fatalf("Write/Get HeadBlockHash failed")
}
}
@@ -639,13 +640,13 @@ func TestFastVsFullChains(t *testing.T) {
} else if types.CalcUncleHash(fblock.Uncles()) != types.CalcUncleHash(ablock.Uncles()) {
t.Errorf("block #%d [%x]: uncles mismatch: have %v, want %v", num, hash, fblock.Uncles(), ablock.Uncles())
}
- if freceipts, areceipts := GetBlockReceipts(fastDb, hash, GetBlockNumber(fastDb, hash)), GetBlockReceipts(archiveDb, hash, GetBlockNumber(archiveDb, hash)); types.DeriveSha(freceipts) != types.DeriveSha(areceipts) {
+ if freceipts, areceipts := rawdb.ReadReceipts(fastDb, hash, *rawdb.ReadHeaderNumber(fastDb, hash)), rawdb.ReadReceipts(archiveDb, hash, *rawdb.ReadHeaderNumber(archiveDb, hash)); types.DeriveSha(freceipts) != types.DeriveSha(areceipts) {
t.Errorf("block #%d [%x]: receipts mismatch: have %v, want %v", num, hash, freceipts, areceipts)
}
}
// Check that the canonical chains are the same between the databases
for i := 0; i < len(blocks)+1; i++ {
- if fhash, ahash := GetCanonicalHash(fastDb, uint64(i)), GetCanonicalHash(archiveDb, uint64(i)); fhash != ahash {
+ if fhash, ahash := rawdb.ReadCanonicalHash(fastDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); fhash != ahash {
t.Errorf("block #%d: canonical hash mismatch: have %v, want %v", i, fhash, ahash)
}
}
@@ -821,28 +822,28 @@ func TestChainTxReorgs(t *testing.T) {
// removed tx
for i, tx := range (types.Transactions{pastDrop, freshDrop}) {
- if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn != nil {
+ if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn != nil {
t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn)
}
- if rcpt, _, _, _ := GetReceipt(db, tx.Hash()); rcpt != nil {
+ if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt != nil {
t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt)
}
}
// added tx
for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) {
- if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn == nil {
+ if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
t.Errorf("add %d: expected tx to be found", i)
}
- if rcpt, _, _, _ := GetReceipt(db, tx.Hash()); rcpt == nil {
+ if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt == nil {
t.Errorf("add %d: expected receipt to be found", i)
}
}
// shared tx
for i, tx := range (types.Transactions{postponed, swapped}) {
- if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn == nil {
+ if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
t.Errorf("share %d: expected tx to be found", i)
}
- if rcpt, _, _, _ := GetReceipt(db, tx.Hash()); rcpt == nil {
+ if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt == nil {
t.Errorf("share %d: expected receipt to be found", i)
}
}
@@ -997,14 +998,14 @@ func TestCanonicalBlockRetrieval(t *testing.T) {
// try to retrieve a block by its canonical hash and see if the block data can be retrieved.
for {
- ch := GetCanonicalHash(blockchain.db, block.NumberU64())
+ ch := rawdb.ReadCanonicalHash(blockchain.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(blockchain.db, ch, block.NumberU64())
+ fb := rawdb.ReadBlock(blockchain.db, ch, block.NumberU64())
if fb == nil {
t.Fatalf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex())
}
diff --git a/core/chain_indexer.go b/core/chain_indexer.go
index 158ed83245..0b927116d0 100644
--- a/core/chain_indexer.go
+++ b/core/chain_indexer.go
@@ -24,6 +24,7 @@ import (
"time"
"github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
@@ -206,7 +207,7 @@ func (c *ChainIndexer) eventLoop(currentHeader *types.Header, events chan ChainE
// TODO(karalabe): This operation is expensive and might block, causing the event system to
// potentially also lock up. We need to do with on a different thread somehow.
- if h := FindCommonAncestor(c.chainDb, prevHeader, header); h != nil {
+ if h := rawdb.FindCommonAncestor(c.chainDb, prevHeader, header); h != nil {
c.newHead(h.Number.Uint64(), true)
}
}
@@ -349,11 +350,11 @@ func (c *ChainIndexer) processSection(section uint64, lastHead common.Hash) (com
}
for number := section * c.sectionSize; number < (section+1)*c.sectionSize; number++ {
- hash := GetCanonicalHash(c.chainDb, number)
+ hash := rawdb.ReadCanonicalHash(c.chainDb, number)
if hash == (common.Hash{}) {
return common.Hash{}, fmt.Errorf("canonical block #%d unknown", number)
}
- header := GetHeader(c.chainDb, hash, number)
+ header := rawdb.ReadHeader(c.chainDb, hash, number)
if header == nil {
return common.Hash{}, fmt.Errorf("block #%d [%x…] not found", number, hash[:4])
} else if header.ParentHash != lastHead {
diff --git a/core/chain_indexer_test.go b/core/chain_indexer_test.go
index 9fc09eda51..3205616e8d 100644
--- a/core/chain_indexer_test.go
+++ b/core/chain_indexer_test.go
@@ -24,6 +24,7 @@ import (
"time"
"github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
)
@@ -92,10 +93,10 @@ func testChainIndexer(t *testing.T, count int) {
inject := func(number uint64) {
header := &types.Header{Number: big.NewInt(int64(number)), Extra: big.NewInt(rand.Int63()).Bytes()}
if number > 0 {
- header.ParentHash = GetCanonicalHash(db, number-1)
+ header.ParentHash = rawdb.ReadCanonicalHash(db, number-1)
}
- WriteHeader(db, header)
- WriteCanonicalHash(db, header.Hash(), number)
+ rawdb.WriteHeader(db, header)
+ rawdb.WriteCanonicalHash(db, header.Hash(), number)
}
// Start indexer with an already existing chain
for i := uint64(0); i <= 100; i++ {
diff --git a/core/database_util.go b/core/database_util.go
deleted file mode 100644
index 8c46989854..0000000000
--- a/core/database_util.go
+++ /dev/null
@@ -1,652 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package core
-
-import (
- "bytes"
- "encoding/binary"
- "encoding/json"
- "errors"
- "fmt"
- "math/big"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/metrics"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
-)
-
-// DatabaseReader wraps the Get method of a backing data store.
-type DatabaseReader interface {
- Get(key []byte) (value []byte, err error)
-}
-
-// DatabaseDeleter wraps the Delete method of a backing data store.
-type DatabaseDeleter interface {
- Delete(key []byte) error
-}
-
-var (
- headHeaderKey = []byte("LastHeader")
- headBlockKey = []byte("LastBlock")
- headFastKey = []byte("LastFast")
- trieSyncKey = []byte("TrieSync")
-
- // Data item prefixes (use single byte to avoid mixing data types, avoid `i`).
- headerPrefix = []byte("h") // headerPrefix + num (uint64 big endian) + hash -> header
- tdSuffix = []byte("t") // headerPrefix + num (uint64 big endian) + hash + tdSuffix -> td
- numSuffix = []byte("n") // headerPrefix + num (uint64 big endian) + numSuffix -> hash
- blockHashPrefix = []byte("H") // blockHashPrefix + hash -> num (uint64 big endian)
- bodyPrefix = []byte("b") // bodyPrefix + num (uint64 big endian) + hash -> block body
- blockReceiptsPrefix = []byte("r") // blockReceiptsPrefix + num (uint64 big endian) + hash -> block receipts
- lookupPrefix = []byte("l") // lookupPrefix + hash -> transaction/receipt lookup metadata
- bloomBitsPrefix = []byte("B") // bloomBitsPrefix + bit (uint16 big endian) + section (uint64 big endian) + hash -> bloom bits
-
- preimagePrefix = "secure-key-" // preimagePrefix + hash -> preimage
- configPrefix = []byte("ethereum-config-") // config prefix for the db
-
- // Chain index prefixes (use `i` + single byte to avoid mixing data types).
- BloomBitsIndexPrefix = []byte("iB") // BloomBitsIndexPrefix is the data table of a chain indexer to track its progress
-
- // used by old db, now only used for conversion
- oldReceiptsPrefix = []byte("receipts-")
- oldTxMetaSuffix = []byte{0x01}
-
- ErrChainConfigNotFound = errors.New("ChainConfig not found") // general config not found error
-
- preimageCounter = metrics.NewRegisteredCounter("db/preimage/total", nil)
- preimageHitCounter = metrics.NewRegisteredCounter("db/preimage/hits", nil)
-)
-
-// TxLookupEntry is a positional metadata to help looking up the data content of
-// a transaction or receipt given only its hash.
-type TxLookupEntry struct {
- BlockHash common.Hash
- BlockIndex uint64
- Index uint64
-}
-
-// encodeBlockNumber encodes a block number as big endian uint64
-func encodeBlockNumber(number uint64) []byte {
- enc := make([]byte, 8)
- binary.BigEndian.PutUint64(enc, number)
- return enc
-}
-
-// GetCanonicalHash retrieves a hash assigned to a canonical block number.
-func GetCanonicalHash(db DatabaseReader, number uint64) common.Hash {
- data, _ := db.Get(append(append(headerPrefix, encodeBlockNumber(number)...), numSuffix...))
- if len(data) == 0 {
- return common.Hash{}
- }
- return common.BytesToHash(data)
-}
-
-// missingNumber is returned by GetBlockNumber if no header with the
-// given block hash has been stored in the database
-const missingNumber = uint64(0xffffffffffffffff)
-
-// GetBlockNumber returns the block number assigned to a block hash
-// if the corresponding header is present in the database
-func GetBlockNumber(db DatabaseReader, hash common.Hash) uint64 {
- data, _ := db.Get(append(blockHashPrefix, hash.Bytes()...))
- if len(data) != 8 {
- return missingNumber
- }
- return binary.BigEndian.Uint64(data)
-}
-
-// GetHeadHeaderHash retrieves the hash of the current canonical head block's
-// header. The difference between this and GetHeadBlockHash is that whereas the
-// last block hash is only updated upon a full block import, the last header
-// hash is updated already at header import, allowing head tracking for the
-// light synchronization mechanism.
-func GetHeadHeaderHash(db DatabaseReader) common.Hash {
- data, _ := db.Get(headHeaderKey)
- if len(data) == 0 {
- return common.Hash{}
- }
- return common.BytesToHash(data)
-}
-
-// GetHeadBlockHash retrieves the hash of the current canonical head block.
-func GetHeadBlockHash(db DatabaseReader) common.Hash {
- data, _ := db.Get(headBlockKey)
- if len(data) == 0 {
- return common.Hash{}
- }
- return common.BytesToHash(data)
-}
-
-// GetHeadFastBlockHash retrieves the hash of the current canonical head block during
-// fast synchronization. The difference between this and GetHeadBlockHash is that
-// whereas the last block hash is only updated upon a full block import, the last
-// fast hash is updated when importing pre-processed blocks.
-func GetHeadFastBlockHash(db DatabaseReader) common.Hash {
- data, _ := db.Get(headFastKey)
- if len(data) == 0 {
- return common.Hash{}
- }
- return common.BytesToHash(data)
-}
-
-// GetTrieSyncProgress retrieves the number of tries nodes fast synced to allow
-// reportinc correct numbers across restarts.
-func GetTrieSyncProgress(db DatabaseReader) uint64 {
- data, _ := db.Get(trieSyncKey)
- if len(data) == 0 {
- return 0
- }
- return new(big.Int).SetBytes(data).Uint64()
-}
-
-// GetHeaderRLP retrieves a block header in its raw RLP database encoding, or nil
-// if the header's not found.
-func GetHeaderRLP(db DatabaseReader, hash common.Hash, number uint64) rlp.RawValue {
- data, _ := db.Get(headerKey(hash, number))
- return data
-}
-
-// GetHeader retrieves the block header corresponding to the hash, nil if none
-// found.
-func GetHeader(db DatabaseReader, hash common.Hash, number uint64) *types.Header {
- data := GetHeaderRLP(db, hash, number)
- if len(data) == 0 {
- return nil
- }
- header := new(types.Header)
- if err := rlp.Decode(bytes.NewReader(data), header); err != nil {
- log.Error("Invalid block header RLP", "hash", hash, "err", err)
- return nil
- }
- return header
-}
-
-// GetBodyRLP retrieves the block body (transactions and uncles) in RLP encoding.
-func GetBodyRLP(db DatabaseReader, hash common.Hash, number uint64) rlp.RawValue {
- data, _ := db.Get(blockBodyKey(hash, number))
- return data
-}
-
-func headerKey(hash common.Hash, number uint64) []byte {
- return append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...)
-}
-
-func blockBodyKey(hash common.Hash, number uint64) []byte {
- return append(append(bodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...)
-}
-
-// GetBody retrieves the block body (transactons, uncles) corresponding to the
-// hash, nil if none found.
-func GetBody(db DatabaseReader, hash common.Hash, number uint64) *types.Body {
- data := GetBodyRLP(db, hash, number)
- if len(data) == 0 {
- return nil
- }
- body := new(types.Body)
- if err := rlp.Decode(bytes.NewReader(data), body); err != nil {
- log.Error("Invalid block body RLP", "hash", hash, "err", err)
- return nil
- }
- return body
-}
-
-// GetTd retrieves a block's total difficulty corresponding to the hash, nil if
-// none found.
-func GetTd(db DatabaseReader, hash common.Hash, number uint64) *big.Int {
- data, _ := db.Get(append(append(append(headerPrefix, encodeBlockNumber(number)...), hash[:]...), tdSuffix...))
- if len(data) == 0 {
- return nil
- }
- td := new(big.Int)
- if err := rlp.Decode(bytes.NewReader(data), td); err != nil {
- log.Error("Invalid block total difficulty RLP", "hash", hash, "err", err)
- return nil
- }
- return td
-}
-
-// GetBlock retrieves an entire block corresponding to the hash, assembling it
-// 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 DatabaseReader, hash common.Hash, number uint64) *types.Block {
- // Retrieve the block header and body contents
- header := GetHeader(db, hash, number)
- if header == nil {
- return nil
- }
- body := GetBody(db, hash, number)
- if body == nil {
- return nil
- }
- // Reassemble the block and return
- return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles)
-}
-
-// GetBlockReceipts retrieves the receipts generated by the transactions included
-// in a block given by its hash.
-func GetBlockReceipts(db DatabaseReader, hash common.Hash, number uint64) types.Receipts {
- data, _ := db.Get(append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash[:]...))
- if len(data) == 0 {
- return nil
- }
- storageReceipts := []*types.ReceiptForStorage{}
- if err := rlp.DecodeBytes(data, &storageReceipts); err != nil {
- log.Error("Invalid receipt array RLP", "hash", hash, "err", err)
- return nil
- }
- receipts := make(types.Receipts, len(storageReceipts))
- for i, receipt := range storageReceipts {
- receipts[i] = (*types.Receipt)(receipt)
- }
- return receipts
-}
-
-// GetTxLookupEntry retrieves the positional metadata associated with a transaction
-// hash to allow retrieving the transaction or receipt by hash.
-func GetTxLookupEntry(db DatabaseReader, hash common.Hash) (common.Hash, uint64, uint64) {
- // Load the positional metadata from disk and bail if it fails
- data, _ := db.Get(append(lookupPrefix, hash.Bytes()...))
- if len(data) == 0 {
- return common.Hash{}, 0, 0
- }
- // Parse and return the contents of the lookup entry
- var entry TxLookupEntry
- if err := rlp.DecodeBytes(data, &entry); err != nil {
- log.Error("Invalid lookup entry RLP", "hash", hash, "err", err)
- return common.Hash{}, 0, 0
- }
- return entry.BlockHash, entry.BlockIndex, entry.Index
-}
-
-// GetTransaction retrieves a specific transaction from the database, along with
-// its added positional metadata.
-func GetTransaction(db DatabaseReader, hash common.Hash) (*types.Transaction, common.Hash, uint64, uint64) {
- // Retrieve the lookup metadata and resolve the transaction from the body
- blockHash, blockNumber, txIndex := GetTxLookupEntry(db, hash)
-
- if blockHash != (common.Hash{}) {
- body := GetBody(db, blockHash, blockNumber)
- if body == nil || len(body.Transactions) <= int(txIndex) {
- log.Error("Transaction referenced missing", "number", blockNumber, "hash", blockHash, "index", txIndex)
- return nil, common.Hash{}, 0, 0
- }
- return body.Transactions[txIndex], blockHash, blockNumber, txIndex
- }
- // Old transaction representation, load the transaction and it's metadata separately
- data, _ := db.Get(hash.Bytes())
- if len(data) == 0 {
- return nil, common.Hash{}, 0, 0
- }
- var tx types.Transaction
- if err := rlp.DecodeBytes(data, &tx); err != nil {
- return nil, common.Hash{}, 0, 0
- }
- // Retrieve the blockchain positional metadata
- data, _ = db.Get(append(hash.Bytes(), oldTxMetaSuffix...))
- if len(data) == 0 {
- return nil, common.Hash{}, 0, 0
- }
- var entry TxLookupEntry
- if err := rlp.DecodeBytes(data, &entry); err != nil {
- return nil, common.Hash{}, 0, 0
- }
- return &tx, entry.BlockHash, entry.BlockIndex, entry.Index
-}
-
-// GetReceipt retrieves a specific transaction receipt from the database, along with
-// its added positional metadata.
-func GetReceipt(db DatabaseReader, hash common.Hash) (*types.Receipt, common.Hash, uint64, uint64) {
- // Retrieve the lookup metadata and resolve the receipt from the receipts
- blockHash, blockNumber, receiptIndex := GetTxLookupEntry(db, hash)
-
- if blockHash != (common.Hash{}) {
- receipts := GetBlockReceipts(db, blockHash, blockNumber)
- if len(receipts) <= int(receiptIndex) {
- log.Error("Receipt refereced missing", "number", blockNumber, "hash", blockHash, "index", receiptIndex)
- return nil, common.Hash{}, 0, 0
- }
- return receipts[receiptIndex], blockHash, blockNumber, receiptIndex
- }
- // Old receipt representation, load the receipt and set an unknown metadata
- data, _ := db.Get(append(oldReceiptsPrefix, hash[:]...))
- if len(data) == 0 {
- return nil, common.Hash{}, 0, 0
- }
- var receipt types.ReceiptForStorage
- err := rlp.DecodeBytes(data, &receipt)
- if err != nil {
- log.Error("Invalid receipt RLP", "hash", hash, "err", err)
- }
- return (*types.Receipt)(&receipt), common.Hash{}, 0, 0
-}
-
-// GetBloomBits retrieves the compressed bloom bit vector belonging to the given
-// section and bit index from the.
-func GetBloomBits(db DatabaseReader, bit uint, section uint64, head common.Hash) ([]byte, error) {
- key := append(append(bloomBitsPrefix, make([]byte, 10)...), head.Bytes()...)
-
- binary.BigEndian.PutUint16(key[1:], uint16(bit))
- binary.BigEndian.PutUint64(key[3:], section)
-
- return db.Get(key)
-}
-
-// WriteCanonicalHash stores the canonical hash for the given block number.
-func WriteCanonicalHash(db ethdb.Putter, hash common.Hash, number uint64) error {
- key := append(append(headerPrefix, encodeBlockNumber(number)...), numSuffix...)
- if err := db.Put(key, hash.Bytes()); err != nil {
- log.Crit("Failed to store number to hash mapping", "err", err)
- }
- return nil
-}
-
-// WriteHeadHeaderHash stores the head header's hash.
-func WriteHeadHeaderHash(db ethdb.Putter, hash common.Hash) error {
- if err := db.Put(headHeaderKey, hash.Bytes()); err != nil {
- log.Crit("Failed to store last header's hash", "err", err)
- }
- return nil
-}
-
-// WriteHeadBlockHash stores the head block's hash.
-func WriteHeadBlockHash(db ethdb.Putter, hash common.Hash) error {
- if err := db.Put(headBlockKey, hash.Bytes()); err != nil {
- log.Crit("Failed to store last block's hash", "err", err)
- }
- return nil
-}
-
-// WriteHeadFastBlockHash stores the fast head block's hash.
-func WriteHeadFastBlockHash(db ethdb.Putter, hash common.Hash) error {
- if err := db.Put(headFastKey, hash.Bytes()); err != nil {
- log.Crit("Failed to store last fast block's hash", "err", err)
- }
- return nil
-}
-
-// WriteTrieSyncProgress stores the fast sync trie process counter to support
-// retrieving it across restarts.
-func WriteTrieSyncProgress(db ethdb.Putter, count uint64) error {
- if err := db.Put(trieSyncKey, new(big.Int).SetUint64(count).Bytes()); err != nil {
- log.Crit("Failed to store fast sync trie progress", "err", err)
- }
- return nil
-}
-
-// WriteHeader serializes a block header into the database.
-func WriteHeader(db ethdb.Putter, header *types.Header) error {
- data, err := rlp.EncodeToBytes(header)
- if err != nil {
- return err
- }
- hash := header.Hash().Bytes()
- num := header.Number.Uint64()
- encNum := encodeBlockNumber(num)
- key := append(blockHashPrefix, hash...)
- if err := db.Put(key, encNum); err != nil {
- log.Crit("Failed to store hash to number mapping", "err", err)
- }
- key = append(append(headerPrefix, encNum...), hash...)
- if err := db.Put(key, data); err != nil {
- log.Crit("Failed to store header", "err", err)
- }
- return nil
-}
-
-// WriteBody serializes the body of a block into the database.
-func WriteBody(db ethdb.Putter, hash common.Hash, number uint64, body *types.Body) error {
- data, err := rlp.EncodeToBytes(body)
- if err != nil {
- return err
- }
- return WriteBodyRLP(db, hash, number, data)
-}
-
-// WriteBodyRLP writes a serialized body of a block into the database.
-func WriteBodyRLP(db ethdb.Putter, hash common.Hash, number uint64, rlp rlp.RawValue) error {
- key := append(append(bodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...)
- if err := db.Put(key, rlp); err != nil {
- log.Crit("Failed to store block body", "err", err)
- }
- return nil
-}
-
-// WriteTd serializes the total difficulty of a block into the database.
-func WriteTd(db ethdb.Putter, hash common.Hash, number uint64, td *big.Int) error {
- data, err := rlp.EncodeToBytes(td)
- if err != nil {
- return err
- }
- key := append(append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...), tdSuffix...)
- if err := db.Put(key, data); err != nil {
- log.Crit("Failed to store block total difficulty", "err", err)
- }
- return nil
-}
-
-// WriteBlock serializes a block into the database, header and body separately.
-func WriteBlock(db ethdb.Putter, block *types.Block) error {
- // Store the body first to retain database consistency
- if err := WriteBody(db, block.Hash(), block.NumberU64(), block.Body()); err != nil {
- return err
- }
- // Store the header too, signaling full block ownership
- if err := WriteHeader(db, block.Header()); err != nil {
- return err
- }
- return nil
-}
-
-// WriteBlockReceipts stores all the transaction receipts belonging to a block
-// as a single receipt slice. This is used during chain reorganisations for
-// rescheduling dropped transactions.
-func WriteBlockReceipts(db ethdb.Putter, hash common.Hash, number uint64, receipts types.Receipts) error {
- // Convert the receipts into their storage form and serialize them
- 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
- }
- // Store the flattened receipt slice
- key := append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash.Bytes()...)
- if err := db.Put(key, bytes); err != nil {
- log.Crit("Failed to store block receipts", "err", err)
- }
- return nil
-}
-
-// WriteTxLookupEntries stores a positional metadata for every transaction from
-// a block, enabling hash based transaction and receipt lookups.
-func WriteTxLookupEntries(db ethdb.Putter, block *types.Block) error {
- // Iterate over each transaction and encode its metadata
- for i, tx := range block.Transactions() {
- entry := TxLookupEntry{
- BlockHash: block.Hash(),
- BlockIndex: block.NumberU64(),
- Index: uint64(i),
- }
- data, err := rlp.EncodeToBytes(entry)
- if err != nil {
- return err
- }
- if err := db.Put(append(lookupPrefix, tx.Hash().Bytes()...), data); err != nil {
- return err
- }
- }
- return nil
-}
-
-// WriteBloomBits writes the compressed bloom bits vector belonging to the given
-// section and bit index.
-func WriteBloomBits(db ethdb.Putter, bit uint, section uint64, head common.Hash, bits []byte) {
- key := append(append(bloomBitsPrefix, make([]byte, 10)...), head.Bytes()...)
-
- binary.BigEndian.PutUint16(key[1:], uint16(bit))
- binary.BigEndian.PutUint64(key[3:], section)
-
- if err := db.Put(key, bits); err != nil {
- log.Crit("Failed to store bloom bits", "err", err)
- }
-}
-
-// DeleteCanonicalHash removes the number to hash canonical mapping.
-func DeleteCanonicalHash(db DatabaseDeleter, number uint64) {
- db.Delete(append(append(headerPrefix, encodeBlockNumber(number)...), numSuffix...))
-}
-
-// DeleteHeader removes all block header data associated with a hash.
-func DeleteHeader(db DatabaseDeleter, hash common.Hash, number uint64) {
- db.Delete(append(blockHashPrefix, hash.Bytes()...))
- db.Delete(append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...))
-}
-
-// DeleteBody removes all block body data associated with a hash.
-func DeleteBody(db DatabaseDeleter, hash common.Hash, number uint64) {
- db.Delete(append(append(bodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...))
-}
-
-// DeleteTd removes all block total difficulty data associated with a hash.
-func DeleteTd(db DatabaseDeleter, hash common.Hash, number uint64) {
- db.Delete(append(append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...), tdSuffix...))
-}
-
-// DeleteBlock removes all block data associated with a hash.
-func DeleteBlock(db DatabaseDeleter, hash common.Hash, number uint64) {
- DeleteBlockReceipts(db, hash, number)
- DeleteHeader(db, hash, number)
- DeleteBody(db, hash, number)
- DeleteTd(db, hash, number)
-}
-
-// DeleteBlockReceipts removes all receipt data associated with a block hash.
-func DeleteBlockReceipts(db DatabaseDeleter, hash common.Hash, number uint64) {
- db.Delete(append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash.Bytes()...))
-}
-
-// DeleteTxLookupEntry removes all transaction data associated with a hash.
-func DeleteTxLookupEntry(db DatabaseDeleter, hash common.Hash) {
- db.Delete(append(lookupPrefix, hash.Bytes()...))
-}
-
-// PreimageTable returns a Database instance with the key prefix for preimage entries.
-func PreimageTable(db ethdb.Database) ethdb.Database {
- return ethdb.NewTable(db, preimagePrefix)
-}
-
-// WritePreimages writes the provided set of preimages to the database. `number` is the
-// current block number, and is used for debug messages only.
-func WritePreimages(db ethdb.Database, number uint64, preimages map[common.Hash][]byte) error {
- table := PreimageTable(db)
- batch := table.NewBatch()
- hitCount := 0
- for hash, preimage := range preimages {
- if _, err := table.Get(hash.Bytes()); err != nil {
- batch.Put(hash.Bytes(), preimage)
- hitCount++
- }
- }
- preimageCounter.Inc(int64(len(preimages)))
- preimageHitCounter.Inc(int64(hitCount))
- if hitCount > 0 {
- if err := batch.Write(); err != nil {
- return fmt.Errorf("preimage write fail for block %d: %v", number, err)
- }
- }
- return nil
-}
-
-// GetBlockChainVersion reads the version number from db.
-func GetBlockChainVersion(db DatabaseReader) int {
- var vsn uint
- enc, _ := db.Get([]byte("BlockchainVersion"))
- rlp.DecodeBytes(enc, &vsn)
- return int(vsn)
-}
-
-// WriteBlockChainVersion writes vsn as the version number to db.
-func WriteBlockChainVersion(db ethdb.Putter, vsn int) {
- enc, _ := rlp.EncodeToBytes(uint(vsn))
- db.Put([]byte("BlockchainVersion"), enc)
-}
-
-// WriteChainConfig writes the chain config settings to the database.
-func WriteChainConfig(db ethdb.Putter, hash common.Hash, cfg *params.ChainConfig) error {
- // short circuit and ignore if nil config. GetChainConfig
- // will return a default.
- if cfg == nil {
- return nil
- }
-
- jsonChainConfig, err := json.Marshal(cfg)
- if err != nil {
- return err
- }
-
- return db.Put(append(configPrefix, hash[:]...), jsonChainConfig)
-}
-
-// GetChainConfig will fetch the network settings based on the given hash.
-func GetChainConfig(db DatabaseReader, hash common.Hash) (*params.ChainConfig, error) {
- jsonChainConfig, _ := db.Get(append(configPrefix, hash[:]...))
- if len(jsonChainConfig) == 0 {
- return nil, ErrChainConfigNotFound
- }
-
- var config params.ChainConfig
- if err := json.Unmarshal(jsonChainConfig, &config); err != nil {
- return nil, err
- }
-
- return &config, nil
-}
-
-// FindCommonAncestor returns the last common ancestor of two block headers
-func FindCommonAncestor(db DatabaseReader, a, b *types.Header) *types.Header {
- for bn := b.Number.Uint64(); a.Number.Uint64() > bn; {
- a = GetHeader(db, a.ParentHash, a.Number.Uint64()-1)
- if a == nil {
- return nil
- }
- }
- for an := a.Number.Uint64(); an < b.Number.Uint64(); {
- b = GetHeader(db, b.ParentHash, b.Number.Uint64()-1)
- if b == nil {
- return nil
- }
- }
- for a.Hash() != b.Hash() {
- a = GetHeader(db, a.ParentHash, a.Number.Uint64()-1)
- if a == nil {
- return nil
- }
- b = GetHeader(db, b.ParentHash, b.Number.Uint64()-1)
- if b == nil {
- return nil
- }
- }
- return a
-}
diff --git a/core/genesis.go b/core/genesis.go
index b6ead2250a..c0a636ab2d 100644
--- a/core/genesis.go
+++ b/core/genesis.go
@@ -28,6 +28,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
@@ -155,7 +156,7 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig
}
// Just commit the new block if there is no stored genesis block.
- stored := GetCanonicalHash(db, 0)
+ stored := rawdb.ReadCanonicalHash(db, 0)
if (stored == common.Hash{}) {
if genesis == nil {
log.Info("Writing default main-net genesis block")
@@ -177,14 +178,11 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig
// Get the existing chain configuration.
newcfg := genesis.configOrDefault(stored)
- storedcfg, err := GetChainConfig(db, stored)
- if err != nil {
- if err == ErrChainConfigNotFound {
- // This case happens if a genesis write was interrupted.
- log.Warn("Found genesis block without chain config")
- err = WriteChainConfig(db, stored, newcfg)
- }
- return newcfg, stored, err
+ storedcfg := rawdb.ReadChainConfig(db, stored)
+ if storedcfg == nil {
+ log.Warn("Found genesis block without chain config")
+ rawdb.WriteChainConfig(db, stored, newcfg)
+ return newcfg, stored, nil
}
// Special case: don't change the existing config of a non-mainnet chain if no new
// config is supplied. These chains would get AllProtocolChanges (and a compat error)
@@ -195,15 +193,16 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig
// Check config compatibility and write the config. Compatibility errors
// are returned to the caller unless we're already at block zero.
- height := GetBlockNumber(db, GetHeadHeaderHash(db))
- if height == missingNumber {
+ height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db))
+ if height == nil {
return newcfg, stored, fmt.Errorf("missing block number for head header hash")
}
- compatErr := storedcfg.CheckCompatible(newcfg, height)
- if compatErr != nil && height != 0 && compatErr.RewindTo != 0 {
+ compatErr := storedcfg.CheckCompatible(newcfg, *height)
+ if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 {
return newcfg, stored, compatErr
}
- return newcfg, stored, WriteChainConfig(db, stored, newcfg)
+ rawdb.WriteChainConfig(db, stored, newcfg)
+ return newcfg, stored, nil
}
func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
@@ -267,29 +266,19 @@ func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) {
if block.Number().Sign() != 0 {
return nil, fmt.Errorf("can't commit genesis block with number > 0")
}
- if err := WriteTd(db, block.Hash(), block.NumberU64(), g.Difficulty); err != nil {
- return nil, err
- }
- if err := WriteBlock(db, block); err != nil {
- return nil, err
- }
- if err := WriteBlockReceipts(db, block.Hash(), block.NumberU64(), nil); err != nil {
- return nil, err
- }
- if err := WriteCanonicalHash(db, block.Hash(), block.NumberU64()); err != nil {
- return nil, err
- }
- if err := WriteHeadBlockHash(db, block.Hash()); err != nil {
- return nil, err
- }
- if err := WriteHeadHeaderHash(db, block.Hash()); err != nil {
- return nil, err
- }
+ rawdb.WriteTd(db, block.Hash(), block.NumberU64(), g.Difficulty)
+ rawdb.WriteBlock(db, block)
+ rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), nil)
+ rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64())
+ rawdb.WriteHeadBlockHash(db, block.Hash())
+ rawdb.WriteHeadHeaderHash(db, block.Hash())
+
config := g.Config
if config == nil {
config = params.AllEthashProtocolChanges
}
- return block, WriteChainConfig(db, block.Hash(), config)
+ rawdb.WriteChainConfig(db, block.Hash(), config)
+ return block, nil
}
// MustCommit writes the genesis block and state to db, panicking on error.
diff --git a/core/genesis_test.go b/core/genesis_test.go
index 052ded6991..613434e208 100644
--- a/core/genesis_test.go
+++ b/core/genesis_test.go
@@ -24,6 +24,7 @@ import (
"github.com/davecgh/go-spew/spew"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/ethash"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/params"
@@ -154,7 +155,7 @@ func TestSetupGenesis(t *testing.T) {
t.Errorf("%s: returned hash %s, want %s", test.name, hash.Hex(), test.wantHash.Hex())
} else if err == nil {
// Check database content.
- stored := GetBlock(db, test.wantHash, 0)
+ stored := rawdb.ReadBlock(db, test.wantHash, 0)
if stored.Hash() != test.wantHash {
t.Errorf("%s: block in DB has hash %s, want %s", test.name, stored.Hash(), test.wantHash)
}
diff --git a/core/headerchain.go b/core/headerchain.go
index 2d1b0a2a18..2ac0cccc72 100644
--- a/core/headerchain.go
+++ b/core/headerchain.go
@@ -28,6 +28,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
@@ -97,7 +98,7 @@ func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine c
}
hc.currentHeader.Store(hc.genesisHeader)
- if head := GetHeadBlockHash(chainDb); head != (common.Hash{}) {
+ if head := rawdb.ReadHeadBlockHash(chainDb); head != (common.Hash{}) {
if chead := hc.GetHeaderByHash(head); chead != nil {
hc.currentHeader.Store(chead)
}
@@ -109,13 +110,14 @@ func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine c
// GetBlockNumber retrieves the block number belonging to the given hash
// from the cache or database
-func (hc *HeaderChain) GetBlockNumber(hash common.Hash) uint64 {
+func (hc *HeaderChain) GetBlockNumber(hash common.Hash) *uint64 {
if cached, ok := hc.numberCache.Get(hash); ok {
- return cached.(uint64)
+ number := cached.(uint64)
+ return &number
}
- number := GetBlockNumber(hc.chainDb, hash)
- if number != missingNumber {
- hc.numberCache.Add(hash, number)
+ number := rawdb.ReadHeaderNumber(hc.chainDb, hash)
+ if number != nil {
+ hc.numberCache.Add(hash, *number)
}
return number
}
@@ -147,20 +149,19 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er
if err := hc.WriteTd(hash, number, externTd); err != nil {
log.Crit("Failed to write header total difficulty", "err", err)
}
- if err := WriteHeader(hc.chainDb, header); err != nil {
- log.Crit("Failed to write header content", "err", err)
- }
+ rawdb.WriteHeader(hc.chainDb, header)
+
// 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
if externTd.Cmp(localTd) > 0 || (externTd.Cmp(localTd) == 0 && mrand.Float64() < 0.5) {
// Delete any canonical number assignments above the new head
for i := number + 1; ; i++ {
- hash := GetCanonicalHash(hc.chainDb, i)
+ hash := rawdb.ReadCanonicalHash(hc.chainDb, i)
if hash == (common.Hash{}) {
break
}
- DeleteCanonicalHash(hc.chainDb, i)
+ rawdb.DeleteCanonicalHash(hc.chainDb, i)
}
// Overwrite any stale canonical number assignments
var (
@@ -168,20 +169,17 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er
headNumber = header.Number.Uint64() - 1
headHeader = hc.GetHeader(headHash, headNumber)
)
- for GetCanonicalHash(hc.chainDb, headNumber) != headHash {
- WriteCanonicalHash(hc.chainDb, headHash, headNumber)
+ for rawdb.ReadCanonicalHash(hc.chainDb, headNumber) != headHash {
+ rawdb.WriteCanonicalHash(hc.chainDb, headHash, headNumber)
headHash = headHeader.ParentHash
headNumber = headHeader.Number.Uint64() - 1
headHeader = hc.GetHeader(headHash, headNumber)
}
// Extend the canonical chain with the new header
- if err := WriteCanonicalHash(hc.chainDb, hash, number); err != nil {
- log.Crit("Failed to insert header number", "err", err)
- }
- if err := WriteHeadHeaderHash(hc.chainDb, hash); err != nil {
- log.Crit("Failed to insert head header hash", "err", err)
- }
+ rawdb.WriteCanonicalHash(hc.chainDb, hash, number)
+ rawdb.WriteHeadHeaderHash(hc.chainDb, hash)
+
hc.currentHeaderHash = hash
hc.currentHeader.Store(types.CopyHeader(header))
@@ -316,7 +314,7 @@ func (hc *HeaderChain) GetTd(hash common.Hash, number uint64) *big.Int {
if cached, ok := hc.tdCache.Get(hash); ok {
return cached.(*big.Int)
}
- td := GetTd(hc.chainDb, hash, number)
+ td := rawdb.ReadTd(hc.chainDb, hash, number)
if td == nil {
return nil
}
@@ -328,15 +326,17 @@ func (hc *HeaderChain) GetTd(hash common.Hash, number uint64) *big.Int {
// GetTdByHash retrieves a block's total difficulty in the canonical chain from the
// database by hash, caching it if found.
func (hc *HeaderChain) GetTdByHash(hash common.Hash) *big.Int {
- return hc.GetTd(hash, hc.GetBlockNumber(hash))
+ number := hc.GetBlockNumber(hash)
+ if number == nil {
+ return nil
+ }
+ return hc.GetTd(hash, *number)
}
// WriteTd stores a block's total difficulty into the database, also caching it
// along the way.
func (hc *HeaderChain) WriteTd(hash common.Hash, number uint64, td *big.Int) error {
- if err := WriteTd(hc.chainDb, hash, number, td); err != nil {
- return err
- }
+ rawdb.WriteTd(hc.chainDb, hash, number, td)
hc.tdCache.Add(hash, new(big.Int).Set(td))
return nil
}
@@ -348,7 +348,7 @@ func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header
if header, ok := hc.headerCache.Get(hash); ok {
return header.(*types.Header)
}
- header := GetHeader(hc.chainDb, hash, number)
+ header := rawdb.ReadHeader(hc.chainDb, hash, number)
if header == nil {
return nil
}
@@ -360,7 +360,11 @@ func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header
// GetHeaderByHash retrieves a block header from the database by hash, caching it if
// found.
func (hc *HeaderChain) GetHeaderByHash(hash common.Hash) *types.Header {
- return hc.GetHeader(hash, hc.GetBlockNumber(hash))
+ number := hc.GetBlockNumber(hash)
+ if number == nil {
+ return nil
+ }
+ return hc.GetHeader(hash, *number)
}
// HasHeader checks if a block header is present in the database or not.
@@ -368,14 +372,13 @@ func (hc *HeaderChain) HasHeader(hash common.Hash, number uint64) bool {
if hc.numberCache.Contains(hash) || hc.headerCache.Contains(hash) {
return true
}
- ok, _ := hc.chainDb.Has(headerKey(hash, number))
- return ok
+ return rawdb.HasHeader(hc.chainDb, hash, number)
}
// GetHeaderByNumber retrieves a block header from the database by number,
// caching it (associated with its hash) if found.
func (hc *HeaderChain) GetHeaderByNumber(number uint64) *types.Header {
- hash := GetCanonicalHash(hc.chainDb, number)
+ hash := rawdb.ReadCanonicalHash(hc.chainDb, number)
if hash == (common.Hash{}) {
return nil
}
@@ -390,9 +393,8 @@ func (hc *HeaderChain) CurrentHeader() *types.Header {
// SetCurrentHeader sets the current head header of the canonical chain.
func (hc *HeaderChain) SetCurrentHeader(head *types.Header) {
- if err := WriteHeadHeaderHash(hc.chainDb, head.Hash()); err != nil {
- log.Crit("Failed to insert head header hash", "err", err)
- }
+ rawdb.WriteHeadHeaderHash(hc.chainDb, head.Hash())
+
hc.currentHeader.Store(head)
hc.currentHeaderHash = head.Hash()
}
@@ -416,13 +418,14 @@ func (hc *HeaderChain) SetHead(head uint64, delFn DeleteCallback) {
if delFn != nil {
delFn(hash, num)
}
- DeleteHeader(hc.chainDb, hash, num)
- DeleteTd(hc.chainDb, hash, num)
+ rawdb.DeleteHeader(hc.chainDb, hash, num)
+ rawdb.DeleteTd(hc.chainDb, hash, num)
+
hc.currentHeader.Store(hc.GetHeader(hdr.ParentHash, hdr.Number.Uint64()-1))
}
// Roll back the canonical chain numbering
for i := height; i > head; i-- {
- DeleteCanonicalHash(hc.chainDb, i)
+ rawdb.DeleteCanonicalHash(hc.chainDb, i)
}
// Clear out any stale content from the caches
hc.headerCache.Purge()
@@ -434,9 +437,7 @@ func (hc *HeaderChain) SetHead(head uint64, delFn DeleteCallback) {
}
hc.currentHeaderHash = hc.CurrentHeader().Hash()
- if err := WriteHeadHeaderHash(hc.chainDb, hc.currentHeaderHash); err != nil {
- log.Crit("Failed to reset head header hash", "err", err)
- }
+ rawdb.WriteHeadHeaderHash(hc.chainDb, hc.currentHeaderHash)
}
// SetGenesis sets a new genesis block header for the chain
diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go
new file mode 100644
index 0000000000..a26a42ba7c
--- /dev/null
+++ b/core/rawdb/accessors_chain.go
@@ -0,0 +1,381 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package rawdb
+
+import (
+ "bytes"
+ "encoding/binary"
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/rlp"
+)
+
+// ReadCanonicalHash retrieves the hash assigned to a canonical block number.
+func ReadCanonicalHash(db DatabaseReader, number uint64) common.Hash {
+ data, _ := db.Get(append(append(headerPrefix, encodeBlockNumber(number)...), headerHashSuffix...))
+ if len(data) == 0 {
+ return common.Hash{}
+ }
+ return common.BytesToHash(data)
+}
+
+// WriteCanonicalHash stores the hash assigned to a canonical block number.
+func WriteCanonicalHash(db DatabaseWriter, hash common.Hash, number uint64) {
+ key := append(append(headerPrefix, encodeBlockNumber(number)...), headerHashSuffix...)
+ if err := db.Put(key, hash.Bytes()); err != nil {
+ log.Crit("Failed to store number to hash mapping", "err", err)
+ }
+}
+
+// DeleteCanonicalHash removes the number to hash canonical mapping.
+func DeleteCanonicalHash(db DatabaseDeleter, number uint64) {
+ if err := db.Delete(append(append(headerPrefix, encodeBlockNumber(number)...), headerHashSuffix...)); err != nil {
+ log.Crit("Failed to delete number to hash mapping", "err", err)
+ }
+}
+
+// ReadHeaderNumber returns the header number assigned to a hash.
+func ReadHeaderNumber(db DatabaseReader, hash common.Hash) *uint64 {
+ data, _ := db.Get(append(headerNumberPrefix, hash.Bytes()...))
+ if len(data) != 8 {
+ return nil
+ }
+ number := binary.BigEndian.Uint64(data)
+ return &number
+}
+
+// ReadHeadHeaderHash retrieves the hash of the current canonical head header.
+func ReadHeadHeaderHash(db DatabaseReader) common.Hash {
+ data, _ := db.Get(headHeaderKey)
+ if len(data) == 0 {
+ return common.Hash{}
+ }
+ return common.BytesToHash(data)
+}
+
+// WriteHeadHeaderHash stores the hash of the current canonical head header.
+func WriteHeadHeaderHash(db DatabaseWriter, hash common.Hash) {
+ if err := db.Put(headHeaderKey, hash.Bytes()); err != nil {
+ log.Crit("Failed to store last header's hash", "err", err)
+ }
+}
+
+// ReadHeadBlockHash retrieves the hash of the current canonical head block.
+func ReadHeadBlockHash(db DatabaseReader) common.Hash {
+ data, _ := db.Get(headBlockKey)
+ if len(data) == 0 {
+ return common.Hash{}
+ }
+ return common.BytesToHash(data)
+}
+
+// WriteHeadBlockHash stores the head block's hash.
+func WriteHeadBlockHash(db DatabaseWriter, hash common.Hash) {
+ if err := db.Put(headBlockKey, hash.Bytes()); err != nil {
+ log.Crit("Failed to store last block's hash", "err", err)
+ }
+}
+
+// ReadHeadFastBlockHash retrieves the hash of the current fast-sync head block.
+func ReadHeadFastBlockHash(db DatabaseReader) common.Hash {
+ data, _ := db.Get(headFastBlockKey)
+ if len(data) == 0 {
+ return common.Hash{}
+ }
+ return common.BytesToHash(data)
+}
+
+// WriteHeadFastBlockHash stores the hash of the current fast-sync head block.
+func WriteHeadFastBlockHash(db DatabaseWriter, hash common.Hash) {
+ if err := db.Put(headFastBlockKey, hash.Bytes()); err != nil {
+ log.Crit("Failed to store last fast block's hash", "err", err)
+ }
+}
+
+// ReadFastTrieProgress retrieves the number of tries nodes fast synced to allow
+// reporting correct numbers across restarts.
+func ReadFastTrieProgress(db DatabaseReader) uint64 {
+ data, _ := db.Get(fastTrieProgressKey)
+ if len(data) == 0 {
+ return 0
+ }
+ return new(big.Int).SetBytes(data).Uint64()
+}
+
+// WriteFastTrieProgress stores the fast sync trie process counter to support
+// retrieving it across restarts.
+func WriteFastTrieProgress(db DatabaseWriter, count uint64) {
+ if err := db.Put(fastTrieProgressKey, new(big.Int).SetUint64(count).Bytes()); err != nil {
+ log.Crit("Failed to store fast sync trie progress", "err", err)
+ }
+}
+
+// ReadHeaderRLP retrieves a block header in its raw RLP database encoding.
+func ReadHeaderRLP(db DatabaseReader, hash common.Hash, number uint64) rlp.RawValue {
+ data, _ := db.Get(append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...))
+ return data
+}
+
+// HasHeader verifies the existence of a block header corresponding to the hash.
+func HasHeader(db DatabaseReader, hash common.Hash, number uint64) bool {
+ key := append(append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...))
+ if has, err := db.Has(key); !has || err != nil {
+ return false
+ }
+ return true
+}
+
+// ReadHeader retrieves the block header corresponding to the hash.
+func ReadHeader(db DatabaseReader, hash common.Hash, number uint64) *types.Header {
+ data := ReadHeaderRLP(db, hash, number)
+ if len(data) == 0 {
+ return nil
+ }
+ header := new(types.Header)
+ if err := rlp.Decode(bytes.NewReader(data), header); err != nil {
+ log.Error("Invalid block header RLP", "hash", hash, "err", err)
+ return nil
+ }
+ return header
+}
+
+// WriteHeader stores a block header into the database and also stores the hash-
+// to-number mapping.
+func WriteHeader(db DatabaseWriter, header *types.Header) {
+ // Write the hash -> number mapping
+ var (
+ hash = header.Hash().Bytes()
+ number = header.Number.Uint64()
+ encoded = encodeBlockNumber(number)
+ )
+ key := append(headerNumberPrefix, hash...)
+ if err := db.Put(key, encoded); err != nil {
+ log.Crit("Failed to store hash to number mapping", "err", err)
+ }
+ // Write the encoded header
+ data, err := rlp.EncodeToBytes(header)
+ if err != nil {
+ log.Crit("Failed to RLP encode header", "err", err)
+ }
+ key = append(append(headerPrefix, encoded...), hash...)
+ if err := db.Put(key, data); err != nil {
+ log.Crit("Failed to store header", "err", err)
+ }
+}
+
+// DeleteHeader removes all block header data associated with a hash.
+func DeleteHeader(db DatabaseDeleter, hash common.Hash, number uint64) {
+ if err := db.Delete(append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...)); err != nil {
+ log.Crit("Failed to delete header", "err", err)
+ }
+ if err := db.Delete(append(headerNumberPrefix, hash.Bytes()...)); err != nil {
+ log.Crit("Failed to delete hash to number mapping", "err", err)
+ }
+}
+
+// ReadBodyRLP retrieves the block body (transactions and uncles) in RLP encoding.
+func ReadBodyRLP(db DatabaseReader, hash common.Hash, number uint64) rlp.RawValue {
+ data, _ := db.Get(append(append(blockBodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...))
+ return data
+}
+
+// WriteBodyRLP stores an RLP encoded block body into the database.
+func WriteBodyRLP(db DatabaseWriter, hash common.Hash, number uint64, rlp rlp.RawValue) {
+ key := append(append(blockBodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...)
+ if err := db.Put(key, rlp); err != nil {
+ log.Crit("Failed to store block body", "err", err)
+ }
+}
+
+// HasBody verifies the existence of a block body corresponding to the hash.
+func HasBody(db DatabaseReader, hash common.Hash, number uint64) bool {
+ key := append(append(blockBodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...)
+ if has, err := db.Has(key); !has || err != nil {
+ return false
+ }
+ return true
+}
+
+// ReadBody retrieves the block body corresponding to the hash.
+func ReadBody(db DatabaseReader, hash common.Hash, number uint64) *types.Body {
+ data := ReadBodyRLP(db, hash, number)
+ if len(data) == 0 {
+ return nil
+ }
+ body := new(types.Body)
+ if err := rlp.Decode(bytes.NewReader(data), body); err != nil {
+ log.Error("Invalid block body RLP", "hash", hash, "err", err)
+ return nil
+ }
+ return body
+}
+
+// WriteBody storea a block body into the database.
+func WriteBody(db DatabaseWriter, hash common.Hash, number uint64, body *types.Body) {
+ data, err := rlp.EncodeToBytes(body)
+ if err != nil {
+ log.Crit("Failed to RLP encode body", "err", err)
+ }
+ WriteBodyRLP(db, hash, number, data)
+}
+
+// DeleteBody removes all block body data associated with a hash.
+func DeleteBody(db DatabaseDeleter, hash common.Hash, number uint64) {
+ if err := db.Delete(append(append(blockBodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...)); err != nil {
+ log.Crit("Failed to delete block body", "err", err)
+ }
+}
+
+// ReadTd retrieves a block's total difficulty corresponding to the hash.
+func ReadTd(db DatabaseReader, hash common.Hash, number uint64) *big.Int {
+ data, _ := db.Get(append(append(append(headerPrefix, encodeBlockNumber(number)...), hash[:]...), headerTDSuffix...))
+ if len(data) == 0 {
+ return nil
+ }
+ td := new(big.Int)
+ if err := rlp.Decode(bytes.NewReader(data), td); err != nil {
+ log.Error("Invalid block total difficulty RLP", "hash", hash, "err", err)
+ return nil
+ }
+ return td
+}
+
+// WriteTd stores the total difficulty of a block into the database.
+func WriteTd(db DatabaseWriter, hash common.Hash, number uint64, td *big.Int) {
+ data, err := rlp.EncodeToBytes(td)
+ if err != nil {
+ log.Crit("Failed to RLP encode block total difficulty", "err", err)
+ }
+ key := append(append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...), headerTDSuffix...)
+ if err := db.Put(key, data); err != nil {
+ log.Crit("Failed to store block total difficulty", "err", err)
+ }
+}
+
+// DeleteTd removes all block total difficulty data associated with a hash.
+func DeleteTd(db DatabaseDeleter, hash common.Hash, number uint64) {
+ if err := db.Delete(append(append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...), headerTDSuffix...)); err != nil {
+ log.Crit("Failed to delete block total difficulty", "err", err)
+ }
+}
+
+// ReadReceipts retrieves all the transaction receipts belonging to a block.
+func ReadReceipts(db DatabaseReader, hash common.Hash, number uint64) types.Receipts {
+ // Retrieve the flattened receipt slice
+ data, _ := db.Get(append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash[:]...))
+ if len(data) == 0 {
+ return nil
+ }
+ // Convert the revceipts from their storage form to their internal representation
+ storageReceipts := []*types.ReceiptForStorage{}
+ if err := rlp.DecodeBytes(data, &storageReceipts); err != nil {
+ log.Error("Invalid receipt array RLP", "hash", hash, "err", err)
+ return nil
+ }
+ receipts := make(types.Receipts, len(storageReceipts))
+ for i, receipt := range storageReceipts {
+ receipts[i] = (*types.Receipt)(receipt)
+ }
+ return receipts
+}
+
+// WriteReceipts stores all the transaction receipts belonging to a block.
+func WriteReceipts(db DatabaseWriter, hash common.Hash, number uint64, receipts types.Receipts) {
+ // Convert the receipts into their storage form and serialize them
+ storageReceipts := make([]*types.ReceiptForStorage, len(receipts))
+ for i, receipt := range receipts {
+ storageReceipts[i] = (*types.ReceiptForStorage)(receipt)
+ }
+ bytes, err := rlp.EncodeToBytes(storageReceipts)
+ if err != nil {
+ log.Crit("Failed to encode block receipts", "err", err)
+ }
+ // Store the flattened receipt slice
+ key := append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash.Bytes()...)
+ if err := db.Put(key, bytes); err != nil {
+ log.Crit("Failed to store block receipts", "err", err)
+ }
+}
+
+// DeleteReceipts removes all receipt data associated with a block hash.
+func DeleteReceipts(db DatabaseDeleter, hash common.Hash, number uint64) {
+ if err := db.Delete(append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash.Bytes()...)); err != nil {
+ log.Crit("Failed to delete block receipts", "err", err)
+ }
+}
+
+// ReadBlock retrieves an entire block corresponding to the hash, assembling it
+// 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 ReadBlock(db DatabaseReader, hash common.Hash, number uint64) *types.Block {
+ header := ReadHeader(db, hash, number)
+ if header == nil {
+ return nil
+ }
+ body := ReadBody(db, hash, number)
+ if body == nil {
+ return nil
+ }
+ return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles)
+}
+
+// WriteBlock serializes a block into the database, header and body separately.
+func WriteBlock(db DatabaseWriter, block *types.Block) {
+ WriteBody(db, block.Hash(), block.NumberU64(), block.Body())
+ WriteHeader(db, block.Header())
+}
+
+// DeleteBlock removes all block data associated with a hash.
+func DeleteBlock(db DatabaseDeleter, hash common.Hash, number uint64) {
+ DeleteReceipts(db, hash, number)
+ DeleteHeader(db, hash, number)
+ DeleteBody(db, hash, number)
+ DeleteTd(db, hash, number)
+}
+
+// FindCommonAncestor returns the last common ancestor of two block headers
+func FindCommonAncestor(db DatabaseReader, a, b *types.Header) *types.Header {
+ for bn := b.Number.Uint64(); a.Number.Uint64() > bn; {
+ a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1)
+ if a == nil {
+ return nil
+ }
+ }
+ for an := a.Number.Uint64(); an < b.Number.Uint64(); {
+ b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1)
+ if b == nil {
+ return nil
+ }
+ }
+ for a.Hash() != b.Hash() {
+ a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1)
+ if a == nil {
+ return nil
+ }
+ b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1)
+ if b == nil {
+ return nil
+ }
+ }
+ return a
+}
diff --git a/core/database_util_test.go b/core/rawdb/accessors_chain_test.go
similarity index 61%
rename from core/database_util_test.go
rename to core/rawdb/accessors_chain_test.go
index aa87fa6f86..84c9c9aeb2 100644
--- a/core/database_util_test.go
+++ b/core/rawdb/accessors_chain_test.go
@@ -1,4 +1,4 @@
-// Copyright 2015 The go-ethereum Authors
+// Copyright 2018 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see .
-package core
+package rawdb
import (
"bytes"
@@ -34,19 +34,17 @@ func TestHeaderStorage(t *testing.T) {
// Create a test header to move around the database and make sure it's really new
header := &types.Header{Number: big.NewInt(42), Extra: []byte("test header")}
- if entry := GetHeader(db, header.Hash(), header.Number.Uint64()); entry != nil {
+ if entry := ReadHeader(db, header.Hash(), header.Number.Uint64()); entry != nil {
t.Fatalf("Non existent header returned: %v", entry)
}
// Write and verify the header in the database
- if err := WriteHeader(db, header); err != nil {
- t.Fatalf("Failed to write header into database: %v", err)
- }
- if entry := GetHeader(db, header.Hash(), header.Number.Uint64()); entry == nil {
+ WriteHeader(db, header)
+ if entry := ReadHeader(db, header.Hash(), header.Number.Uint64()); entry == nil {
t.Fatalf("Stored header not found")
} else if entry.Hash() != header.Hash() {
t.Fatalf("Retrieved header mismatch: have %v, want %v", entry, header)
}
- if entry := GetHeaderRLP(db, header.Hash(), header.Number.Uint64()); entry == nil {
+ if entry := ReadHeaderRLP(db, header.Hash(), header.Number.Uint64()); entry == nil {
t.Fatalf("Stored header RLP not found")
} else {
hasher := sha3.NewKeccak256()
@@ -58,7 +56,7 @@ func TestHeaderStorage(t *testing.T) {
}
// Delete the header and verify the execution
DeleteHeader(db, header.Hash(), header.Number.Uint64())
- if entry := GetHeader(db, header.Hash(), header.Number.Uint64()); entry != nil {
+ if entry := ReadHeader(db, header.Hash(), header.Number.Uint64()); entry != nil {
t.Fatalf("Deleted header returned: %v", entry)
}
}
@@ -74,19 +72,17 @@ func TestBodyStorage(t *testing.T) {
rlp.Encode(hasher, body)
hash := common.BytesToHash(hasher.Sum(nil))
- if entry := GetBody(db, hash, 0); entry != nil {
+ if entry := ReadBody(db, hash, 0); entry != nil {
t.Fatalf("Non existent body returned: %v", entry)
}
// Write and verify the body in the database
- if err := WriteBody(db, hash, 0, body); err != nil {
- t.Fatalf("Failed to write body into database: %v", err)
- }
- if entry := GetBody(db, hash, 0); entry == nil {
+ WriteBody(db, hash, 0, body)
+ if entry := ReadBody(db, hash, 0); entry == nil {
t.Fatalf("Stored body not found")
} else if types.DeriveSha(types.Transactions(entry.Transactions)) != types.DeriveSha(types.Transactions(body.Transactions)) || types.CalcUncleHash(entry.Uncles) != types.CalcUncleHash(body.Uncles) {
t.Fatalf("Retrieved body mismatch: have %v, want %v", entry, body)
}
- if entry := GetBodyRLP(db, hash, 0); entry == nil {
+ if entry := ReadBodyRLP(db, hash, 0); entry == nil {
t.Fatalf("Stored body RLP not found")
} else {
hasher := sha3.NewKeccak256()
@@ -98,7 +94,7 @@ func TestBodyStorage(t *testing.T) {
}
// Delete the body and verify the execution
DeleteBody(db, hash, 0)
- if entry := GetBody(db, hash, 0); entry != nil {
+ if entry := ReadBody(db, hash, 0); entry != nil {
t.Fatalf("Deleted body returned: %v", entry)
}
}
@@ -114,43 +110,41 @@ func TestBlockStorage(t *testing.T) {
TxHash: types.EmptyRootHash,
ReceiptHash: types.EmptyRootHash,
})
- if entry := GetBlock(db, block.Hash(), block.NumberU64()); entry != nil {
+ if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil {
t.Fatalf("Non existent block returned: %v", entry)
}
- if entry := GetHeader(db, block.Hash(), block.NumberU64()); entry != nil {
+ if entry := ReadHeader(db, block.Hash(), block.NumberU64()); entry != nil {
t.Fatalf("Non existent header returned: %v", entry)
}
- if entry := GetBody(db, block.Hash(), block.NumberU64()); entry != nil {
+ if entry := ReadBody(db, block.Hash(), block.NumberU64()); entry != nil {
t.Fatalf("Non existent body returned: %v", entry)
}
// Write and verify the block in the database
- if err := WriteBlock(db, block); err != nil {
- t.Fatalf("Failed to write block into database: %v", err)
- }
- if entry := GetBlock(db, block.Hash(), block.NumberU64()); entry == nil {
+ WriteBlock(db, block)
+ if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry == nil {
t.Fatalf("Stored block not found")
} else if entry.Hash() != block.Hash() {
t.Fatalf("Retrieved block mismatch: have %v, want %v", entry, block)
}
- if entry := GetHeader(db, block.Hash(), block.NumberU64()); entry == nil {
+ if entry := ReadHeader(db, block.Hash(), block.NumberU64()); entry == nil {
t.Fatalf("Stored header not found")
} else if entry.Hash() != block.Header().Hash() {
t.Fatalf("Retrieved header mismatch: have %v, want %v", entry, block.Header())
}
- if entry := GetBody(db, block.Hash(), block.NumberU64()); entry == nil {
+ if entry := ReadBody(db, block.Hash(), block.NumberU64()); entry == nil {
t.Fatalf("Stored body not found")
} else if types.DeriveSha(types.Transactions(entry.Transactions)) != types.DeriveSha(block.Transactions()) || types.CalcUncleHash(entry.Uncles) != types.CalcUncleHash(block.Uncles()) {
t.Fatalf("Retrieved body mismatch: have %v, want %v", entry, block.Body())
}
// Delete the block and verify the execution
DeleteBlock(db, block.Hash(), block.NumberU64())
- if entry := GetBlock(db, block.Hash(), block.NumberU64()); entry != nil {
+ if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil {
t.Fatalf("Deleted block returned: %v", entry)
}
- if entry := GetHeader(db, block.Hash(), block.NumberU64()); entry != nil {
+ if entry := ReadHeader(db, block.Hash(), block.NumberU64()); entry != nil {
t.Fatalf("Deleted header returned: %v", entry)
}
- if entry := GetBody(db, block.Hash(), block.NumberU64()); entry != nil {
+ if entry := ReadBody(db, block.Hash(), block.NumberU64()); entry != nil {
t.Fatalf("Deleted body returned: %v", entry)
}
}
@@ -165,31 +159,24 @@ func TestPartialBlockStorage(t *testing.T) {
ReceiptHash: types.EmptyRootHash,
})
// Store a header and check that it's not recognized as a block
- if err := WriteHeader(db, block.Header()); err != nil {
- t.Fatalf("Failed to write header into database: %v", err)
- }
- if entry := GetBlock(db, block.Hash(), block.NumberU64()); entry != nil {
+ WriteHeader(db, block.Header())
+ if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil {
t.Fatalf("Non existent block returned: %v", entry)
}
DeleteHeader(db, block.Hash(), block.NumberU64())
// Store a body and check that it's not recognized as a block
- if err := WriteBody(db, block.Hash(), block.NumberU64(), block.Body()); err != nil {
- t.Fatalf("Failed to write body into database: %v", err)
- }
- if entry := GetBlock(db, block.Hash(), block.NumberU64()); entry != nil {
+ WriteBody(db, block.Hash(), block.NumberU64(), block.Body())
+ if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil {
t.Fatalf("Non existent block returned: %v", entry)
}
DeleteBody(db, block.Hash(), block.NumberU64())
// Store a header and a body separately and check reassembly
- if err := WriteHeader(db, block.Header()); err != nil {
- t.Fatalf("Failed to write header into database: %v", err)
- }
- if err := WriteBody(db, block.Hash(), block.NumberU64(), block.Body()); err != nil {
- t.Fatalf("Failed to write body into database: %v", err)
- }
- if entry := GetBlock(db, block.Hash(), block.NumberU64()); entry == nil {
+ WriteHeader(db, block.Header())
+ WriteBody(db, block.Hash(), block.NumberU64(), block.Body())
+
+ if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry == nil {
t.Fatalf("Stored block not found")
} else if entry.Hash() != block.Hash() {
t.Fatalf("Retrieved block mismatch: have %v, want %v", entry, block)
@@ -202,21 +189,19 @@ func TestTdStorage(t *testing.T) {
// Create a test TD to move around the database and make sure it's really new
hash, td := common.Hash{}, big.NewInt(314)
- if entry := GetTd(db, hash, 0); entry != nil {
+ if entry := ReadTd(db, hash, 0); entry != nil {
t.Fatalf("Non existent TD returned: %v", entry)
}
// Write and verify the TD in the database
- if err := WriteTd(db, hash, 0, td); err != nil {
- t.Fatalf("Failed to write TD into database: %v", err)
- }
- if entry := GetTd(db, hash, 0); entry == nil {
+ WriteTd(db, hash, 0, td)
+ if entry := ReadTd(db, hash, 0); entry == nil {
t.Fatalf("Stored TD not found")
} else if entry.Cmp(td) != 0 {
t.Fatalf("Retrieved TD mismatch: have %v, want %v", entry, td)
}
// Delete the TD and verify the execution
DeleteTd(db, hash, 0)
- if entry := GetTd(db, hash, 0); entry != nil {
+ if entry := ReadTd(db, hash, 0); entry != nil {
t.Fatalf("Deleted TD returned: %v", entry)
}
}
@@ -227,21 +212,19 @@ func TestCanonicalMappingStorage(t *testing.T) {
// Create a test canonical number and assinged hash to move around
hash, number := common.Hash{0: 0xff}, uint64(314)
- if entry := GetCanonicalHash(db, number); entry != (common.Hash{}) {
+ if entry := ReadCanonicalHash(db, number); entry != (common.Hash{}) {
t.Fatalf("Non existent canonical mapping returned: %v", entry)
}
// Write and verify the TD in the database
- if err := WriteCanonicalHash(db, hash, number); err != nil {
- t.Fatalf("Failed to write canonical mapping into database: %v", err)
- }
- if entry := GetCanonicalHash(db, number); entry == (common.Hash{}) {
+ WriteCanonicalHash(db, hash, number)
+ if entry := ReadCanonicalHash(db, number); entry == (common.Hash{}) {
t.Fatalf("Stored canonical mapping not found")
} else if entry != hash {
t.Fatalf("Retrieved canonical mapping mismatch: have %v, want %v", entry, hash)
}
// Delete the TD and verify the execution
DeleteCanonicalHash(db, number)
- if entry := GetCanonicalHash(db, number); entry != (common.Hash{}) {
+ if entry := ReadCanonicalHash(db, number); entry != (common.Hash{}) {
t.Fatalf("Deleted canonical mapping returned: %v", entry)
}
}
@@ -255,82 +238,32 @@ func TestHeadStorage(t *testing.T) {
blockFast := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block fast")})
// Check that no head entries are in a pristine database
- if entry := GetHeadHeaderHash(db); entry != (common.Hash{}) {
+ if entry := ReadHeadHeaderHash(db); entry != (common.Hash{}) {
t.Fatalf("Non head header entry returned: %v", entry)
}
- if entry := GetHeadBlockHash(db); entry != (common.Hash{}) {
+ if entry := ReadHeadBlockHash(db); entry != (common.Hash{}) {
t.Fatalf("Non head block entry returned: %v", entry)
}
- if entry := GetHeadFastBlockHash(db); entry != (common.Hash{}) {
+ if entry := ReadHeadFastBlockHash(db); entry != (common.Hash{}) {
t.Fatalf("Non fast head block entry returned: %v", entry)
}
// Assign separate entries for the head header and block
- if err := WriteHeadHeaderHash(db, blockHead.Hash()); err != nil {
- t.Fatalf("Failed to write head header hash: %v", err)
- }
- if err := WriteHeadBlockHash(db, blockFull.Hash()); err != nil {
- t.Fatalf("Failed to write head block hash: %v", err)
- }
- if err := WriteHeadFastBlockHash(db, blockFast.Hash()); err != nil {
- t.Fatalf("Failed to write fast head block hash: %v", err)
- }
+ WriteHeadHeaderHash(db, blockHead.Hash())
+ WriteHeadBlockHash(db, blockFull.Hash())
+ WriteHeadFastBlockHash(db, blockFast.Hash())
+
// Check that both heads are present, and different (i.e. two heads maintained)
- if entry := GetHeadHeaderHash(db); entry != blockHead.Hash() {
+ if entry := ReadHeadHeaderHash(db); entry != blockHead.Hash() {
t.Fatalf("Head header hash mismatch: have %v, want %v", entry, blockHead.Hash())
}
- if entry := GetHeadBlockHash(db); entry != blockFull.Hash() {
+ if entry := ReadHeadBlockHash(db); entry != blockFull.Hash() {
t.Fatalf("Head block hash mismatch: have %v, want %v", entry, blockFull.Hash())
}
- if entry := GetHeadFastBlockHash(db); entry != blockFast.Hash() {
+ if entry := ReadHeadFastBlockHash(db); entry != blockFast.Hash() {
t.Fatalf("Fast head block hash mismatch: have %v, want %v", entry, blockFast.Hash())
}
}
-// Tests that positional lookup metadata can be stored and retrieved.
-func TestLookupStorage(t *testing.T) {
- db, _ := ethdb.NewMemDatabase()
-
- tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11})
- tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22})
- tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33})
- txs := []*types.Transaction{tx1, tx2, tx3}
-
- block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, txs, nil, nil)
-
- // Check that no transactions entries are in a pristine database
- for i, tx := range txs {
- if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn != nil {
- t.Fatalf("tx #%d [%x]: non existent transaction returned: %v", i, tx.Hash(), txn)
- }
- }
- // Insert all the transactions into the database, and verify contents
- if err := WriteBlock(db, block); err != nil {
- t.Fatalf("failed to write block contents: %v", err)
- }
- if err := WriteTxLookupEntries(db, block); err != nil {
- t.Fatalf("failed to write transactions: %v", err)
- }
- for i, tx := range txs {
- if txn, hash, number, index := GetTransaction(db, tx.Hash()); txn == nil {
- t.Fatalf("tx #%d [%x]: transaction not found", i, tx.Hash())
- } else {
- if hash != block.Hash() || number != block.NumberU64() || index != uint64(i) {
- t.Fatalf("tx #%d [%x]: positional metadata mismatch: have %x/%d/%d, want %x/%v/%v", i, tx.Hash(), hash, number, index, block.Hash(), block.NumberU64(), i)
- }
- if tx.Hash() != txn.Hash() {
- t.Fatalf("tx #%d [%x]: transaction mismatch: have %v, want %v", i, tx.Hash(), txn, tx)
- }
- }
- }
- // Delete the transactions and check purge
- for i, tx := range txs {
- DeleteTxLookupEntry(db, tx.Hash())
- if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn != nil {
- t.Fatalf("tx #%d [%x]: deleted transaction returned: %v", i, tx.Hash(), txn)
- }
- }
-}
-
// Tests that receipts associated with a single block can be stored and retrieved.
func TestBlockReceiptStorage(t *testing.T) {
db, _ := ethdb.NewMemDatabase()
@@ -361,14 +294,12 @@ func TestBlockReceiptStorage(t *testing.T) {
// Check that no receipt entries are in a pristine database
hash := common.BytesToHash([]byte{0x03, 0x14})
- if rs := GetBlockReceipts(db, hash, 0); len(rs) != 0 {
+ if rs := ReadReceipts(db, hash, 0); len(rs) != 0 {
t.Fatalf("non existent receipts returned: %v", rs)
}
// Insert the receipt slice into the database and check presence
- if err := WriteBlockReceipts(db, hash, 0, receipts); err != nil {
- t.Fatalf("failed to write block receipts: %v", err)
- }
- if rs := GetBlockReceipts(db, hash, 0); len(rs) == 0 {
+ WriteReceipts(db, hash, 0, receipts)
+ if rs := ReadReceipts(db, hash, 0); len(rs) == 0 {
t.Fatalf("no receipts returned")
} else {
for i := 0; i < len(receipts); i++ {
@@ -381,8 +312,8 @@ func TestBlockReceiptStorage(t *testing.T) {
}
}
// Delete the receipt slice and check purge
- DeleteBlockReceipts(db, hash, 0)
- if rs := GetBlockReceipts(db, hash, 0); len(rs) != 0 {
+ DeleteReceipts(db, hash, 0)
+ if rs := ReadReceipts(db, hash, 0); len(rs) != 0 {
t.Fatalf("deleted receipts returned: %v", rs)
}
}
diff --git a/core/rawdb/accessors_indexes.go b/core/rawdb/accessors_indexes.go
new file mode 100644
index 0000000000..9abad14e0c
--- /dev/null
+++ b/core/rawdb/accessors_indexes.go
@@ -0,0 +1,119 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package rawdb
+
+import (
+ "encoding/binary"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/rlp"
+)
+
+// ReadTxLookupEntry retrieves the positional metadata associated with a transaction
+// hash to allow retrieving the transaction or receipt by hash.
+func ReadTxLookupEntry(db DatabaseReader, hash common.Hash) (common.Hash, uint64, uint64) {
+ data, _ := db.Get(append(txLookupPrefix, hash.Bytes()...))
+ if len(data) == 0 {
+ return common.Hash{}, 0, 0
+ }
+ var entry TxLookupEntry
+ if err := rlp.DecodeBytes(data, &entry); err != nil {
+ log.Error("Invalid transaction lookup entry RLP", "hash", hash, "err", err)
+ return common.Hash{}, 0, 0
+ }
+ return entry.BlockHash, entry.BlockIndex, entry.Index
+}
+
+// WriteTxLookupEntries stores a positional metadata for every transaction from
+// a block, enabling hash based transaction and receipt lookups.
+func WriteTxLookupEntries(db DatabaseWriter, block *types.Block) {
+ for i, tx := range block.Transactions() {
+ entry := TxLookupEntry{
+ BlockHash: block.Hash(),
+ BlockIndex: block.NumberU64(),
+ Index: uint64(i),
+ }
+ data, err := rlp.EncodeToBytes(entry)
+ if err != nil {
+ log.Crit("Failed to encode transaction lookup entry", "err", err)
+ }
+ if err := db.Put(append(txLookupPrefix, tx.Hash().Bytes()...), data); err != nil {
+ log.Crit("Failed to store transaction lookup entry", "err", err)
+ }
+ }
+}
+
+// DeleteTxLookupEntry removes all transaction data associated with a hash.
+func DeleteTxLookupEntry(db DatabaseDeleter, hash common.Hash) {
+ db.Delete(append(txLookupPrefix, hash.Bytes()...))
+}
+
+// ReadTransaction retrieves a specific transaction from the database, along with
+// its added positional metadata.
+func ReadTransaction(db DatabaseReader, hash common.Hash) (*types.Transaction, common.Hash, uint64, uint64) {
+ blockHash, blockNumber, txIndex := ReadTxLookupEntry(db, hash)
+ if blockHash == (common.Hash{}) {
+ return nil, common.Hash{}, 0, 0
+ }
+ body := ReadBody(db, blockHash, blockNumber)
+ if body == nil || len(body.Transactions) <= int(txIndex) {
+ log.Error("Transaction referenced missing", "number", blockNumber, "hash", blockHash, "index", txIndex)
+ return nil, common.Hash{}, 0, 0
+ }
+ return body.Transactions[txIndex], blockHash, blockNumber, txIndex
+}
+
+// ReadReceipt retrieves a specific transaction receipt from the database, along with
+// its added positional metadata.
+func ReadReceipt(db DatabaseReader, hash common.Hash) (*types.Receipt, common.Hash, uint64, uint64) {
+ blockHash, blockNumber, receiptIndex := ReadTxLookupEntry(db, hash)
+ if blockHash == (common.Hash{}) {
+ return nil, common.Hash{}, 0, 0
+ }
+ receipts := ReadReceipts(db, blockHash, blockNumber)
+ if len(receipts) <= int(receiptIndex) {
+ log.Error("Receipt refereced missing", "number", blockNumber, "hash", blockHash, "index", receiptIndex)
+ return nil, common.Hash{}, 0, 0
+ }
+ return receipts[receiptIndex], blockHash, blockNumber, receiptIndex
+}
+
+// ReadBloomBits retrieves the compressed bloom bit vector belonging to the given
+// section and bit index from the.
+func ReadBloomBits(db DatabaseReader, bit uint, section uint64, head common.Hash) ([]byte, error) {
+ key := append(append(bloomBitsPrefix, make([]byte, 10)...), head.Bytes()...)
+
+ binary.BigEndian.PutUint16(key[1:], uint16(bit))
+ binary.BigEndian.PutUint64(key[3:], section)
+
+ return db.Get(key)
+}
+
+// WriteBloomBits stores the compressed bloom bits vector belonging to the given
+// section and bit index.
+func WriteBloomBits(db DatabaseWriter, bit uint, section uint64, head common.Hash, bits []byte) {
+ key := append(append(bloomBitsPrefix, make([]byte, 10)...), head.Bytes()...)
+
+ binary.BigEndian.PutUint16(key[1:], uint16(bit))
+ binary.BigEndian.PutUint64(key[3:], section)
+
+ if err := db.Put(key, bits); err != nil {
+ log.Crit("Failed to store bloom bits", "err", err)
+ }
+}
diff --git a/core/rawdb/accessors_indexes_test.go b/core/rawdb/accessors_indexes_test.go
new file mode 100644
index 0000000000..d9c1291634
--- /dev/null
+++ b/core/rawdb/accessors_indexes_test.go
@@ -0,0 +1,68 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package rawdb
+
+import (
+ "math/big"
+ "testing"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/ethdb"
+)
+
+// Tests that positional lookup metadata can be stored and retrieved.
+func TestLookupStorage(t *testing.T) {
+ db, _ := ethdb.NewMemDatabase()
+
+ tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11})
+ tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22})
+ tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33})
+ txs := []*types.Transaction{tx1, tx2, tx3}
+
+ block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, txs, nil, nil)
+
+ // Check that no transactions entries are in a pristine database
+ for i, tx := range txs {
+ if txn, _, _, _ := ReadTransaction(db, tx.Hash()); txn != nil {
+ t.Fatalf("tx #%d [%x]: non existent transaction returned: %v", i, tx.Hash(), txn)
+ }
+ }
+ // Insert all the transactions into the database, and verify contents
+ WriteBlock(db, block)
+ WriteTxLookupEntries(db, block)
+
+ for i, tx := range txs {
+ if txn, hash, number, index := ReadTransaction(db, tx.Hash()); txn == nil {
+ t.Fatalf("tx #%d [%x]: transaction not found", i, tx.Hash())
+ } else {
+ if hash != block.Hash() || number != block.NumberU64() || index != uint64(i) {
+ t.Fatalf("tx #%d [%x]: positional metadata mismatch: have %x/%d/%d, want %x/%v/%v", i, tx.Hash(), hash, number, index, block.Hash(), block.NumberU64(), i)
+ }
+ if tx.Hash() != txn.Hash() {
+ t.Fatalf("tx #%d [%x]: transaction mismatch: have %v, want %v", i, tx.Hash(), txn, tx)
+ }
+ }
+ }
+ // Delete the transactions and check purge
+ for i, tx := range txs {
+ DeleteTxLookupEntry(db, tx.Hash())
+ if txn, _, _, _ := ReadTransaction(db, tx.Hash()); txn != nil {
+ t.Fatalf("tx #%d [%x]: deleted transaction returned: %v", i, tx.Hash(), txn)
+ }
+ }
+}
diff --git a/core/rawdb/accessors_metadata.go b/core/rawdb/accessors_metadata.go
new file mode 100644
index 0000000000..73ab983f2b
--- /dev/null
+++ b/core/rawdb/accessors_metadata.go
@@ -0,0 +1,90 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package rawdb
+
+import (
+ "encoding/json"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/params"
+ "github.com/ethereum/go-ethereum/rlp"
+)
+
+// ReadDatabaseVersion retrieves the version number of the database.
+func ReadDatabaseVersion(db DatabaseReader) int {
+ var version int
+
+ enc, _ := db.Get(databaseVerisionKey)
+ rlp.DecodeBytes(enc, &version)
+
+ return version
+}
+
+// WriteDatabaseVersion stores the version number of the database
+func WriteDatabaseVersion(db DatabaseWriter, version int) {
+ enc, _ := rlp.EncodeToBytes(version)
+ if err := db.Put(databaseVerisionKey, enc); err != nil {
+ log.Crit("Failed to store the database version", "err", err)
+ }
+}
+
+// ReadChainConfig retrieves the consensus settings based on the given genesis hash.
+func ReadChainConfig(db DatabaseReader, hash common.Hash) *params.ChainConfig {
+ data, _ := db.Get(append(configPrefix, hash[:]...))
+ if len(data) == 0 {
+ return nil
+ }
+ var config params.ChainConfig
+ if err := json.Unmarshal(data, &config); err != nil {
+ log.Error("Invalid chain config JSON", "hash", hash, "err", err)
+ return nil
+ }
+ return &config
+}
+
+// WriteChainConfig writes the chain config settings to the database.
+func WriteChainConfig(db DatabaseWriter, hash common.Hash, cfg *params.ChainConfig) {
+ if cfg == nil {
+ return
+ }
+ data, err := json.Marshal(cfg)
+ if err != nil {
+ log.Crit("Failed to JSON encode chain config", "err", err)
+ }
+ if err := db.Put(append(configPrefix, hash[:]...), data); err != nil {
+ log.Crit("Failed to store chain config", "err", err)
+ }
+}
+
+// ReadPreimage retrieves a single preimage of the provided hash.
+func ReadPreimage(db DatabaseReader, hash common.Hash) []byte {
+ data, _ := db.Get(append(preimagePrefix, hash.Bytes()...))
+ return data
+}
+
+// WritePreimages writes the provided set of preimages to the database. `number` is the
+// current block number, and is used for debug messages only.
+func WritePreimages(db DatabaseWriter, number uint64, preimages map[common.Hash][]byte) {
+ for hash, preimage := range preimages {
+ if err := db.Put(append(preimagePrefix, hash.Bytes()...), preimage); err != nil {
+ log.Crit("Failed to store trie preimage", "err", err)
+ }
+ }
+ preimageCounter.Inc(int64(len(preimages)))
+ preimageHitCounter.Inc(int64(len(preimages)))
+}
diff --git a/core/rawdb/interfaces.go b/core/rawdb/interfaces.go
new file mode 100644
index 0000000000..3bdf55124a
--- /dev/null
+++ b/core/rawdb/interfaces.go
@@ -0,0 +1,33 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package rawdb
+
+// DatabaseReader wraps the Has and Get method of a backing data store.
+type DatabaseReader interface {
+ Has(key []byte) (bool, error)
+ Get(key []byte) ([]byte, error)
+}
+
+// DatabaseWriter wraps the Put method of a backing data store.
+type DatabaseWriter interface {
+ Put(key []byte, value []byte) error
+}
+
+// DatabaseDeleter wraps the Delete method of a backing data store.
+type DatabaseDeleter interface {
+ Delete(key []byte) error
+}
diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go
new file mode 100644
index 0000000000..a4b1596fde
--- /dev/null
+++ b/core/rawdb/schema.go
@@ -0,0 +1,79 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+// Package rawdb contains a collection of low level database accessors.
+package rawdb
+
+import (
+ "encoding/binary"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/metrics"
+)
+
+// The fields below define the low level database schema prefixing.
+var (
+ // databaseVerisionKey tracks the current database version.
+ databaseVerisionKey = []byte("DatabaseVersion")
+
+ // headHeaderKey tracks the latest know header's hash.
+ headHeaderKey = []byte("LastHeader")
+
+ // headBlockKey tracks the latest know full block's hash.
+ headBlockKey = []byte("LastBlock")
+
+ // headFastBlockKey tracks the latest known incomplete block's hash duirng fast sync.
+ headFastBlockKey = []byte("LastFast")
+
+ // fastTrieProgressKey tracks the number of trie entries imported during fast sync.
+ fastTrieProgressKey = []byte("TrieSync")
+
+ // Data item prefixes (use single byte to avoid mixing data types, avoid `i`, used for indexes).
+ headerPrefix = []byte("h") // headerPrefix + num (uint64 big endian) + hash -> header
+ headerTDSuffix = []byte("t") // headerPrefix + num (uint64 big endian) + hash + headerTDSuffix -> td
+ headerHashSuffix = []byte("n") // headerPrefix + num (uint64 big endian) + headerHashSuffix -> hash
+ headerNumberPrefix = []byte("H") // headerNumberPrefix + hash -> num (uint64 big endian)
+
+ blockBodyPrefix = []byte("b") // blockBodyPrefix + num (uint64 big endian) + hash -> block body
+ blockReceiptsPrefix = []byte("r") // blockReceiptsPrefix + num (uint64 big endian) + hash -> block receipts
+
+ txLookupPrefix = []byte("l") // txLookupPrefix + hash -> transaction/receipt lookup metadata
+ bloomBitsPrefix = []byte("B") // bloomBitsPrefix + bit (uint16 big endian) + section (uint64 big endian) + hash -> bloom bits
+
+ preimagePrefix = []byte("secure-key-") // preimagePrefix + hash -> preimage
+ configPrefix = []byte("ethereum-config-") // config prefix for the db
+
+ // Chain index prefixes (use `i` + single byte to avoid mixing data types).
+ BloomBitsIndexPrefix = []byte("iB") // BloomBitsIndexPrefix is the data table of a chain indexer to track its progress
+
+ preimageCounter = metrics.NewRegisteredCounter("db/preimage/total", nil)
+ preimageHitCounter = metrics.NewRegisteredCounter("db/preimage/hits", nil)
+)
+
+// TxLookupEntry is a positional metadata to help looking up the data content of
+// a transaction or receipt given only its hash.
+type TxLookupEntry struct {
+ BlockHash common.Hash
+ BlockIndex uint64
+ Index uint64
+}
+
+// encodeBlockNumber encodes a block number as big endian uint64
+func encodeBlockNumber(number uint64) []byte {
+ enc := make([]byte, 8)
+ binary.BigEndian.PutUint64(enc, number)
+ return enc
+}
diff --git a/eth/api.go b/eth/api.go
index a345b57e49..247ca7485c 100644
--- a/eth/api.go
+++ b/eth/api.go
@@ -19,6 +19,7 @@ package eth
import (
"compress/gzip"
"context"
+ "errors"
"fmt"
"io"
"math/big"
@@ -28,6 +29,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
@@ -343,8 +345,10 @@ func NewPrivateDebugAPI(config *params.ChainConfig, eth *Ethereum) *PrivateDebug
// Preimage is a debug API function that returns the preimage for a sha3 hash, if known.
func (api *PrivateDebugAPI) Preimage(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) {
- db := core.PreimageTable(api.eth.ChainDb())
- return db.Get(hash.Bytes())
+ if preimage := rawdb.ReadPreimage(api.eth.ChainDb(), hash); preimage != nil {
+ return preimage, nil
+ }
+ return nil, errors.New("unknown preimage")
}
// GetBadBLocks returns a list of the last 'bad blocks' that the client has seen on the network
diff --git a/eth/api_backend.go b/eth/api_backend.go
index ecd5488a24..532cd5c334 100644
--- a/eth/api_backend.go
+++ b/eth/api_backend.go
@@ -25,6 +25,7 @@ import (
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
@@ -96,16 +97,23 @@ func (b *EthApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.
return stateDb, header, err
}
-func (b *EthApiBackend) GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) {
- return b.eth.blockchain.GetBlockByHash(blockHash), nil
+func (b *EthApiBackend) GetBlock(ctx context.Context, hash common.Hash) (*types.Block, error) {
+ return b.eth.blockchain.GetBlockByHash(hash), nil
}
-func (b *EthApiBackend) GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error) {
- return core.GetBlockReceipts(b.eth.chainDb, blockHash, core.GetBlockNumber(b.eth.chainDb, blockHash)), nil
+func (b *EthApiBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
+ if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != nil {
+ return rawdb.ReadReceipts(b.eth.chainDb, hash, *number), nil
+ }
+ return nil, nil
}
-func (b *EthApiBackend) GetLogs(ctx context.Context, blockHash common.Hash) ([][]*types.Log, error) {
- receipts := core.GetBlockReceipts(b.eth.chainDb, blockHash, core.GetBlockNumber(b.eth.chainDb, blockHash))
+func (b *EthApiBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) {
+ number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash)
+ if number == nil {
+ return nil, nil
+ }
+ receipts := rawdb.ReadReceipts(b.eth.chainDb, hash, *number)
if receipts == nil {
return nil, nil
}
diff --git a/eth/api_tracer.go b/eth/api_tracer.go
index 80a3ab719d..45a819022a 100644
--- a/eth/api_tracer.go
+++ b/eth/api_tracer.go
@@ -29,6 +29,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
@@ -533,7 +534,7 @@ func (api *PrivateDebugAPI) computeStateDB(block *types.Block, reexec uint64) (*
// and returns them as a JSON object.
func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, hash common.Hash, config *TraceConfig) (interface{}, error) {
// Retrieve the transaction and assemble its EVM context
- tx, blockHash, _, index := core.GetTransaction(api.eth.ChainDb(), hash)
+ tx, blockHash, _, index := rawdb.ReadTransaction(api.eth.ChainDb(), hash)
if tx == nil {
return nil, fmt.Errorf("transaction %x not found", hash)
}
diff --git a/eth/backend.go b/eth/backend.go
index ffd5d85421..e4c5fef3e4 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -33,6 +33,7 @@ import (
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/eth/downloader"
@@ -63,8 +64,7 @@ type Ethereum struct {
chainConfig *params.ChainConfig
// Channel for shutting down the service
- shutdownChan chan bool // Channel for shutting down the Ethereum
- stopDbUpgrade func() error // stop chain db sequential key upgrade
+ shutdownChan chan bool // Channel for shutting down the Ethereum
// Handlers
txPool *core.TxPool
@@ -112,7 +112,6 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
if err != nil {
return nil, err
}
- stopDbUpgrade := upgradeDeduplicateData(chainDb)
chainConfig, genesisHash, genesisErr := core.SetupGenesisBlock(chainDb, config.Genesis)
if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
return nil, genesisErr
@@ -127,7 +126,6 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
accountManager: ctx.AccountManager,
engine: CreateConsensusEngine(ctx, &config.Ethash, chainConfig, chainDb),
shutdownChan: make(chan bool),
- stopDbUpgrade: stopDbUpgrade,
networkId: config.NetworkId,
gasPrice: config.GasPrice,
etherbase: config.Etherbase,
@@ -138,11 +136,11 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
log.Info("Initialising Ethereum protocol", "versions", ProtocolVersions, "network", config.NetworkId)
if !config.SkipBcVersionCheck {
- bcVersion := core.GetBlockChainVersion(chainDb)
+ bcVersion := rawdb.ReadDatabaseVersion(chainDb)
if bcVersion != core.BlockChainVersion && bcVersion != 0 {
return nil, fmt.Errorf("Blockchain DB version mismatch (%d / %d). Run geth upgradedb.\n", bcVersion, core.BlockChainVersion)
}
- core.WriteBlockChainVersion(chainDb, core.BlockChainVersion)
+ rawdb.WriteDatabaseVersion(chainDb, core.BlockChainVersion)
}
var (
vmConfig = vm.Config{EnablePreimageRecording: config.EnablePreimageRecording}
@@ -156,7 +154,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
if compat, ok := genesisErr.(*params.ConfigCompatError); ok {
log.Warn("Rewinding chain to upgrade configuration", "err", compat)
eth.blockchain.SetHead(compat.RewindTo)
- core.WriteChainConfig(chainDb, genesisHash, chainConfig)
+ rawdb.WriteChainConfig(chainDb, genesisHash, chainConfig)
}
eth.bloomIndexer.Start(eth.blockchain)
@@ -325,13 +323,13 @@ func (s *Ethereum) Etherbase() (eb common.Address, err error) {
return common.Address{}, fmt.Errorf("etherbase must be explicitly specified")
}
-// set in js console via admin interface or wrapper from cli flags
-func (self *Ethereum) SetEtherbase(etherbase common.Address) {
- self.lock.Lock()
- self.etherbase = etherbase
- self.lock.Unlock()
+// SetEtherbase sets the mining reward address.
+func (s *Ethereum) SetEtherbase(etherbase common.Address) {
+ s.lock.Lock()
+ s.etherbase = etherbase
+ s.lock.Unlock()
- self.miner.SetEtherbase(etherbase)
+ s.miner.SetEtherbase(etherbase)
}
func (s *Ethereum) StartMining(local bool) error {
@@ -411,9 +409,6 @@ func (s *Ethereum) Start(srvr *p2p.Server) error {
// Stop implements node.Service, terminating all internal goroutines used by the
// Ethereum protocol.
func (s *Ethereum) Stop() error {
- if s.stopDbUpgrade != nil {
- s.stopDbUpgrade()
- }
s.bloomIndexer.Close()
s.blockchain.Stop()
s.protocolManager.Stop()
diff --git a/eth/bloombits.go b/eth/bloombits.go
index c5597391c5..954239d141 100644
--- a/eth/bloombits.go
+++ b/eth/bloombits.go
@@ -23,6 +23,7 @@ import (
"github.com/ethereum/go-ethereum/common/bitutil"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/params"
@@ -60,8 +61,8 @@ func (eth *Ethereum) startBloomHandlers() {
task := <-request
task.Bitsets = make([][]byte, len(task.Sections))
for i, section := range task.Sections {
- head := core.GetCanonicalHash(eth.chainDb, (section+1)*params.BloomBitsBlocks-1)
- if compVector, err := core.GetBloomBits(eth.chainDb, task.Bit, section, head); err == nil {
+ head := rawdb.ReadCanonicalHash(eth.chainDb, (section+1)*params.BloomBitsBlocks-1)
+ if compVector, err := rawdb.ReadBloomBits(eth.chainDb, task.Bit, section, head); err == nil {
if blob, err := bitutil.DecompressBytes(compVector, int(params.BloomBitsBlocks)/8); err == nil {
task.Bitsets[i] = blob
} else {
@@ -107,7 +108,7 @@ func NewBloomIndexer(db ethdb.Database, size uint64) *core.ChainIndexer {
db: db,
size: size,
}
- table := ethdb.NewTable(db, string(core.BloomBitsIndexPrefix))
+ table := ethdb.NewTable(db, string(rawdb.BloomBitsIndexPrefix))
return core.NewChainIndexer(db, table, backend, size, bloomConfirms, bloomThrottling, "bloombits")
}
@@ -137,7 +138,7 @@ func (b *BloomIndexer) Commit() error {
if err != nil {
return err
}
- core.WriteBloomBits(batch, uint(i), b.section, b.head, bitutil.CompressBytes(bits))
+ rawdb.WriteBloomBits(batch, uint(i), b.section, b.head, bitutil.CompressBytes(bits))
}
return batch.Write()
}
diff --git a/eth/db_upgrade.go b/eth/db_upgrade.go
deleted file mode 100644
index 96c584ac64..0000000000
--- a/eth/db_upgrade.go
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Package eth implements the Ethereum protocol.
-package eth
-
-import (
- "bytes"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/rlp"
-)
-
-var deduplicateData = []byte("dbUpgrade_20170714deduplicateData")
-
-// upgradeDeduplicateData checks the chain database version and
-// starts a background process to make upgrades if necessary.
-// Returns a stop function that blocks until the process has
-// been safely stopped.
-func upgradeDeduplicateData(db ethdb.Database) func() error {
- // If the database is already converted or empty, bail out
- data, _ := db.Get(deduplicateData)
- if len(data) > 0 && data[0] == 42 {
- return nil
- }
- if data, _ := db.Get([]byte("LastHeader")); len(data) == 0 {
- db.Put(deduplicateData, []byte{42})
- return nil
- }
- // Start the deduplication upgrade on a new goroutine
- log.Warn("Upgrading database to use lookup entries")
- stop := make(chan chan error)
-
- go func() {
- // Create an iterator to read the entire database and covert old lookup entires
- it := db.(*ethdb.LDBDatabase).NewIterator()
- defer func() {
- if it != nil {
- it.Release()
- }
- }()
-
- var (
- converted uint64
- failed error
- )
- for failed == nil && it.Next() {
- // Skip any entries that don't look like old transaction meta entries (0x01)
- key := it.Key()
- if len(key) != common.HashLength+1 || key[common.HashLength] != 0x01 {
- continue
- }
- // Skip any entries that don't contain metadata (name clash between 0x01 and )
- var meta struct {
- BlockHash common.Hash
- BlockIndex uint64
- Index uint64
- }
- if err := rlp.DecodeBytes(it.Value(), &meta); err != nil {
- continue
- }
- // Skip any already upgraded entries (clash due to ending with 0x01 (old suffix))
- hash := key[:common.HashLength]
-
- if hash[0] == byte('l') {
- // Potential clash, the "old" `hash` must point to a live transaction.
- if tx, _, _, _ := core.GetTransaction(db, common.BytesToHash(hash)); tx == nil || !bytes.Equal(tx.Hash().Bytes(), hash) {
- continue
- }
- }
- // Convert the old metadata to a new lookup entry, delete duplicate data
- if failed = db.Put(append([]byte("l"), hash...), it.Value()); failed == nil { // Write the new lookup entry
- if failed = db.Delete(hash); failed == nil { // Delete the duplicate transaction data
- if failed = db.Delete(append([]byte("receipts-"), hash...)); failed == nil { // Delete the duplicate receipt data
- if failed = db.Delete(key); failed != nil { // Delete the old transaction metadata
- break
- }
- }
- }
- }
- // Bump the conversion counter, and recreate the iterator occasionally to
- // avoid too high memory consumption.
- converted++
- if converted%100000 == 0 {
- it.Release()
- it = db.(*ethdb.LDBDatabase).NewIterator()
- it.Seek(key)
-
- log.Info("Deduplicating database entries", "deduped", converted)
- }
- // Check for termination, or continue after a bit of a timeout
- select {
- case errc := <-stop:
- errc <- nil
- return
- case <-time.After(time.Microsecond * 100):
- }
- }
- // Upgrade finished, mark a such and terminate
- if failed == nil {
- log.Info("Database deduplication successful", "deduped", converted)
- db.Put(deduplicateData, []byte{42})
- } else {
- log.Error("Database deduplication failed", "deduped", converted, "err", failed)
- }
- it.Release()
- it = nil
-
- errc := <-stop
- errc <- failed
- }()
- // Assembly the cancellation callback
- return func() error {
- errc := make(chan error)
- stop <- errc
- return <-errc
- }
-}
diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go
index 43f0e3db97..dc23354929 100644
--- a/eth/downloader/downloader.go
+++ b/eth/downloader/downloader.go
@@ -27,7 +27,7 @@ import (
ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
@@ -224,7 +224,7 @@ func New(mode SyncMode, stateDb ethdb.Database, mux *event.TypeMux, chain BlockC
stateCh: make(chan dataPack),
stateSyncStart: make(chan *stateSync),
syncStatsState: stateSyncStats{
- processed: core.GetTrieSyncProgress(stateDb),
+ processed: rawdb.ReadFastTrieProgress(stateDb),
},
trackStateReq: make(chan *stateReq),
}
diff --git a/eth/downloader/fakepeer.go b/eth/downloader/fakepeer.go
index 5248e7fb0c..59832facaa 100644
--- a/eth/downloader/fakepeer.go
+++ b/eth/downloader/fakepeer.go
@@ -21,6 +21,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
)
@@ -126,7 +127,7 @@ func (p *FakePeer) RequestBodies(hashes []common.Hash) error {
uncles [][]*types.Header
)
for _, hash := range hashes {
- block := core.GetBlock(p.db, hash, p.hc.GetBlockNumber(hash))
+ block := rawdb.ReadBlock(p.db, hash, *p.hc.GetBlockNumber(hash))
txs = append(txs, block.Transactions())
uncles = append(uncles, block.Uncles())
@@ -140,7 +141,7 @@ func (p *FakePeer) RequestBodies(hashes []common.Hash) error {
func (p *FakePeer) RequestReceipts(hashes []common.Hash) error {
var receipts [][]*types.Receipt
for _, hash := range hashes {
- receipts = append(receipts, core.GetBlockReceipts(p.db, hash, p.hc.GetBlockNumber(hash)))
+ receipts = append(receipts, rawdb.ReadReceipts(p.db, hash, *p.hc.GetBlockNumber(hash)))
}
p.dl.DeliverReceipts(p.id, receipts)
return nil
diff --git a/eth/downloader/statesync.go b/eth/downloader/statesync.go
index 521ee25a02..5b4b9ba1b7 100644
--- a/eth/downloader/statesync.go
+++ b/eth/downloader/statesync.go
@@ -23,7 +23,7 @@ import (
"time"
"github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/crypto/sha3"
"github.com/ethereum/go-ethereum/ethdb"
@@ -476,6 +476,6 @@ func (s *stateSync) updateStats(written, duplicate, unexpected int, duration tim
log.Info("Imported new state entries", "count", written, "elapsed", common.PrettyDuration(duration), "processed", s.d.syncStatsState.processed, "pending", s.d.syncStatsState.pending, "retry", len(s.tasks), "duplicate", s.d.syncStatsState.duplicate, "unexpected", s.d.syncStatsState.unexpected)
}
if written > 0 {
- core.WriteTrieSyncProgress(s.d.stateDB, s.d.syncStatsState.processed)
+ rawdb.WriteFastTrieProgress(s.d.stateDB, s.d.syncStatsState.processed)
}
}
diff --git a/eth/filters/bench_test.go b/eth/filters/bench_test.go
index 0a0929bc10..faffaa70b7 100644
--- a/eth/filters/bench_test.go
+++ b/eth/filters/bench_test.go
@@ -25,8 +25,8 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/bitutil"
- "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
@@ -71,20 +71,20 @@ func benchmarkBloomBits(b *testing.B, sectionSize uint64) {
if err != nil {
b.Fatalf("error opening database at %v: %v", benchDataDir, err)
}
- head := core.GetHeadBlockHash(db)
+ head := rawdb.ReadHeadBlockHash(db)
if head == (common.Hash{}) {
b.Fatalf("chain data not found at %v", benchDataDir)
}
clearBloomBits(db)
fmt.Println("Generating bloombits data...")
- headNum := core.GetBlockNumber(db, head)
- if headNum < sectionSize+512 {
+ headNum := rawdb.ReadHeaderNumber(db, head)
+ if headNum == nil || *headNum < sectionSize+512 {
b.Fatalf("not enough blocks for running a benchmark")
}
start := time.Now()
- cnt := (headNum - 512) / sectionSize
+ cnt := (*headNum - 512) / sectionSize
var dataSize, compSize uint64
for sectionIdx := uint64(0); sectionIdx < cnt; sectionIdx++ {
bc, err := bloombits.NewGenerator(uint(sectionSize))
@@ -93,14 +93,14 @@ func benchmarkBloomBits(b *testing.B, sectionSize uint64) {
}
var header *types.Header
for i := sectionIdx * sectionSize; i < (sectionIdx+1)*sectionSize; i++ {
- hash := core.GetCanonicalHash(db, i)
- header = core.GetHeader(db, hash, i)
+ hash := rawdb.ReadCanonicalHash(db, i)
+ header = rawdb.ReadHeader(db, hash, i)
if header == nil {
b.Fatalf("Error creating bloomBits data")
}
bc.AddBloom(uint(i-sectionIdx*sectionSize), header.Bloom)
}
- sectionHead := core.GetCanonicalHash(db, (sectionIdx+1)*sectionSize-1)
+ sectionHead := rawdb.ReadCanonicalHash(db, (sectionIdx+1)*sectionSize-1)
for i := 0; i < types.BloomBitLength; i++ {
data, err := bc.Bitset(uint(i))
if err != nil {
@@ -109,7 +109,7 @@ func benchmarkBloomBits(b *testing.B, sectionSize uint64) {
comp := bitutil.CompressBytes(data)
dataSize += uint64(len(data))
compSize += uint64(len(comp))
- core.WriteBloomBits(db, uint(i), sectionIdx, sectionHead, comp)
+ rawdb.WriteBloomBits(db, uint(i), sectionIdx, sectionHead, comp)
}
//if sectionIdx%50 == 0 {
// fmt.Println(" section", sectionIdx, "/", cnt)
@@ -180,11 +180,11 @@ func BenchmarkNoBloomBits(b *testing.B) {
if err != nil {
b.Fatalf("error opening database at %v: %v", benchDataDir, err)
}
- head := core.GetHeadBlockHash(db)
+ head := rawdb.ReadHeadBlockHash(db)
if head == (common.Hash{}) {
b.Fatalf("chain data not found at %v", benchDataDir)
}
- headNum := core.GetBlockNumber(db, head)
+ headNum := rawdb.ReadHeaderNumber(db, head)
clearBloomBits(db)
@@ -192,10 +192,10 @@ func BenchmarkNoBloomBits(b *testing.B) {
start := time.Now()
mux := new(event.TypeMux)
backend := &testBackend{mux, db, 0, new(event.Feed), new(event.Feed), new(event.Feed), new(event.Feed)}
- filter := New(backend, 0, int64(headNum), []common.Address{{}}, nil)
+ filter := New(backend, 0, int64(*headNum), []common.Address{{}}, nil)
filter.Logs(context.Background())
d := time.Since(start)
fmt.Println("Finished running filter benchmarks")
- fmt.Println(" ", d, "total ", d*time.Duration(1000000)/time.Duration(headNum+1), "per million blocks")
+ fmt.Println(" ", d, "total ", d*time.Duration(1000000)/time.Duration(*headNum+1), "per million blocks")
db.Close()
}
diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go
index f8097c7b95..6d16f572d0 100644
--- a/eth/filters/filter_system.go
+++ b/eth/filters/filter_system.go
@@ -28,6 +28,7 @@ import (
ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/rpc"
@@ -348,11 +349,11 @@ func (es *EventSystem) lightFilterNewHead(newHeader *types.Header, callBack func
for oldh.Hash() != newh.Hash() {
if oldh.Number.Uint64() >= newh.Number.Uint64() {
oldHeaders = append(oldHeaders, oldh)
- oldh = core.GetHeader(es.backend.ChainDb(), oldh.ParentHash, oldh.Number.Uint64()-1)
+ oldh = rawdb.ReadHeader(es.backend.ChainDb(), oldh.ParentHash, oldh.Number.Uint64()-1)
}
if oldh.Number.Uint64() < newh.Number.Uint64() {
newHeaders = append(newHeaders, newh)
- newh = core.GetHeader(es.backend.ChainDb(), newh.ParentHash, newh.Number.Uint64()-1)
+ newh = rawdb.ReadHeader(es.backend.ChainDb(), newh.ParentHash, newh.Number.Uint64()-1)
if newh == nil {
// happens when CHT syncing, nothing to do
newh = oldh
diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go
index 61761151a2..73819eadc0 100644
--- a/eth/filters/filter_system_test.go
+++ b/eth/filters/filter_system_test.go
@@ -30,6 +30,7 @@ import (
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
@@ -56,26 +57,37 @@ func (b *testBackend) EventMux() *event.TypeMux {
}
func (b *testBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) {
- var hash common.Hash
- var num uint64
+ var (
+ hash common.Hash
+ num uint64
+ )
if blockNr == rpc.LatestBlockNumber {
- hash = core.GetHeadBlockHash(b.db)
- num = core.GetBlockNumber(b.db, hash)
+ hash = rawdb.ReadHeadBlockHash(b.db)
+ number := rawdb.ReadHeaderNumber(b.db, hash)
+ if number == nil {
+ return nil, nil
+ }
+ num = *number
} else {
num = uint64(blockNr)
- hash = core.GetCanonicalHash(b.db, num)
+ hash = rawdb.ReadCanonicalHash(b.db, num)
}
- return core.GetHeader(b.db, hash, num), nil
+ return rawdb.ReadHeader(b.db, hash, num), nil
}
-func (b *testBackend) GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error) {
- number := core.GetBlockNumber(b.db, blockHash)
- return core.GetBlockReceipts(b.db, blockHash, number), nil
+func (b *testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
+ if number := rawdb.ReadHeaderNumber(b.db, hash); number != nil {
+ return rawdb.ReadReceipts(b.db, hash, *number), nil
+ }
+ return nil, nil
}
-func (b *testBackend) GetLogs(ctx context.Context, blockHash common.Hash) ([][]*types.Log, error) {
- number := core.GetBlockNumber(b.db, blockHash)
- receipts := core.GetBlockReceipts(b.db, blockHash, number)
+func (b *testBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) {
+ number := rawdb.ReadHeaderNumber(b.db, hash)
+ if number == nil {
+ return nil, nil
+ }
+ receipts := rawdb.ReadReceipts(b.db, hash, *number)
logs := make([][]*types.Log, len(receipts))
for i, receipt := range receipts {
@@ -121,8 +133,8 @@ func (b *testBackend) ServiceFilter(ctx context.Context, session *bloombits.Matc
task.Bitsets = make([][]byte, len(task.Sections))
for i, section := range task.Sections {
if rand.Int()%4 != 0 { // Handle occasional missing deliveries
- head := core.GetCanonicalHash(b.db, (section+1)*params.BloomBitsBlocks-1)
- task.Bitsets[i], _ = core.GetBloomBits(b.db, task.Bit, section, head)
+ head := rawdb.ReadCanonicalHash(b.db, (section+1)*params.BloomBitsBlocks-1)
+ task.Bitsets[i], _ = rawdb.ReadBloomBits(b.db, task.Bit, section, head)
}
}
request <- task
diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go
index 0018142c46..ccabe955cf 100644
--- a/eth/filters/filter_test.go
+++ b/eth/filters/filter_test.go
@@ -26,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
@@ -84,16 +85,10 @@ func BenchmarkFilters(b *testing.B) {
}
})
for i, block := range chain {
- core.WriteBlock(db, block)
- if err := core.WriteCanonicalHash(db, block.Hash(), block.NumberU64()); err != nil {
- b.Fatalf("failed to insert block number: %v", err)
- }
- if err := core.WriteHeadBlockHash(db, block.Hash()); err != nil {
- b.Fatalf("failed to insert block number: %v", err)
- }
- if err := core.WriteBlockReceipts(db, block.Hash(), block.NumberU64(), receipts[i]); err != nil {
- b.Fatal("error writing block receipts:", err)
- }
+ rawdb.WriteBlock(db, block)
+ rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64())
+ rawdb.WriteHeadBlockHash(db, block.Hash())
+ rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), receipts[i])
}
b.ResetTimer()
@@ -174,16 +169,10 @@ func TestFilters(t *testing.T) {
}
})
for i, block := range chain {
- core.WriteBlock(db, block)
- if err := core.WriteCanonicalHash(db, block.Hash(), block.NumberU64()); err != nil {
- t.Fatalf("failed to insert block number: %v", err)
- }
- if err := core.WriteHeadBlockHash(db, block.Hash()); err != nil {
- t.Fatalf("failed to insert block number: %v", err)
- }
- if err := core.WriteBlockReceipts(db, block.Hash(), block.NumberU64(), receipts[i]); err != nil {
- t.Fatal("error writing block receipts:", err)
- }
+ rawdb.WriteBlock(db, block)
+ rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64())
+ rawdb.WriteHeadBlockHash(db, block.Hash())
+ rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), receipts[i])
}
filter := New(backend, 0, -1, []common.Address{addr}, [][]common.Hash{{hash1, hash2, hash3, hash4}})
diff --git a/eth/handler.go b/eth/handler.go
index 4069359c9e..c8f7e13f16 100644
--- a/eth/handler.go
+++ b/eth/handler.go
@@ -725,25 +725,25 @@ func (pm *ProtocolManager) BroadcastTx(hash common.Hash, tx *types.Transaction)
}
// Mined broadcast loop
-func (self *ProtocolManager) minedBroadcastLoop() {
+func (pm *ProtocolManager) minedBroadcastLoop() {
// automatically stops if unsubscribe
- for obj := range self.minedBlockSub.Chan() {
+ for obj := range pm.minedBlockSub.Chan() {
switch ev := obj.Data.(type) {
case core.NewMinedBlockEvent:
- self.BroadcastBlock(ev.Block, true) // First propagate block to peers
- self.BroadcastBlock(ev.Block, false) // Only then announce to the rest
+ pm.BroadcastBlock(ev.Block, true) // First propagate block to peers
+ pm.BroadcastBlock(ev.Block, false) // Only then announce to the rest
}
}
}
-func (self *ProtocolManager) txBroadcastLoop() {
+func (pm *ProtocolManager) txBroadcastLoop() {
for {
select {
- case event := <-self.txCh:
- self.BroadcastTx(event.Tx.Hash(), event.Tx)
+ case event := <-pm.txCh:
+ pm.BroadcastTx(event.Tx.Hash(), event.Tx)
// Err() channel will be closed when unsubscribing.
- case <-self.txSub.Err():
+ case <-pm.txSub.Err():
return
}
}
@@ -760,13 +760,13 @@ type NodeInfo struct {
}
// NodeInfo retrieves some protocol metadata about the running host node.
-func (self *ProtocolManager) NodeInfo() *NodeInfo {
- currentBlock := self.blockchain.CurrentBlock()
+func (pm *ProtocolManager) NodeInfo() *NodeInfo {
+ currentBlock := pm.blockchain.CurrentBlock()
return &NodeInfo{
- Network: self.networkId,
- Difficulty: self.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64()),
- Genesis: self.blockchain.Genesis().Hash(),
- Config: self.blockchain.Config(),
+ Network: pm.networkId,
+ Difficulty: pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64()),
+ Genesis: pm.blockchain.Genesis().Hash(),
+ Config: pm.blockchain.Config(),
Head: currentBlock.Hash(),
}
}
diff --git a/event/filter/filter.go b/event/filter/filter.go
index b1fbf30ee4..a6fe46d6a0 100644
--- a/event/filter/filter.go
+++ b/event/filter/filter.go
@@ -45,37 +45,37 @@ func New() *Filters {
}
}
-func (self *Filters) Start() {
- go self.loop()
+func (f *Filters) Start() {
+ go f.loop()
}
-func (self *Filters) Stop() {
- close(self.quit)
+func (f *Filters) Stop() {
+ close(f.quit)
}
-func (self *Filters) Notify(filter Filter, data interface{}) {
- self.ch <- FilterEvent{filter, data}
+func (f *Filters) Notify(filter Filter, data interface{}) {
+ f.ch <- FilterEvent{filter, data}
}
-func (self *Filters) Install(watcher Filter) int {
- self.watchers[self.id] = watcher
- self.id++
+func (f *Filters) Install(watcher Filter) int {
+ f.watchers[f.id] = watcher
+ f.id++
- return self.id - 1
+ return f.id - 1
}
-func (self *Filters) Uninstall(id int) {
- delete(self.watchers, id)
+func (f *Filters) Uninstall(id int) {
+ delete(f.watchers, id)
}
-func (self *Filters) loop() {
+func (f *Filters) loop() {
out:
for {
select {
- case <-self.quit:
+ case <-f.quit:
break out
- case event := <-self.ch:
- for _, watcher := range self.watchers {
+ case event := <-f.ch:
+ for _, watcher := range f.watchers {
if reflect.TypeOf(watcher) == reflect.TypeOf(event.filter) {
if watcher.Compare(event.filter) {
watcher.Trigger(event.data)
@@ -86,10 +86,10 @@ out:
}
}
-func (self *Filters) Match(a, b Filter) bool {
+func (f *Filters) Match(a, b Filter) bool {
return reflect.TypeOf(a) == reflect.TypeOf(b) && a.Compare(b)
}
-func (self *Filters) Get(i int) Filter {
- return self.watchers[i]
+func (f *Filters) Get(i int) Filter {
+ return f.watchers[i]
}
diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go
index e2bfbaf307..a524dbadd8 100644
--- a/internal/ethapi/api.go
+++ b/internal/ethapi/api.go
@@ -33,6 +33,7 @@ import (
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
@@ -1006,7 +1007,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, addr
// GetTransactionByHash returns the transaction for the given hash
func (s *PublicTransactionPoolAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) *RPCTransaction {
// Try to return an already finalized transaction
- if tx, blockHash, blockNumber, index := core.GetTransaction(s.b.ChainDb(), hash); tx != nil {
+ if tx, blockHash, blockNumber, index := rawdb.ReadTransaction(s.b.ChainDb(), hash); tx != nil {
return newRPCTransaction(tx, blockHash, blockNumber, index)
}
// No finalized transaction, try to retrieve it from the pool
@@ -1022,7 +1023,7 @@ func (s *PublicTransactionPoolAPI) GetRawTransactionByHash(ctx context.Context,
var tx *types.Transaction
// Retrieve a finalized transaction, or a pooled otherwise
- if tx, _, _, _ = core.GetTransaction(s.b.ChainDb(), hash); tx == nil {
+ if tx, _, _, _ = rawdb.ReadTransaction(s.b.ChainDb(), hash); tx == nil {
if tx = s.b.GetPoolTransaction(hash); tx == nil {
// Transaction not found anywhere, abort
return nil, nil
@@ -1034,7 +1035,7 @@ func (s *PublicTransactionPoolAPI) GetRawTransactionByHash(ctx context.Context,
// GetTransactionReceipt returns the transaction receipt for the given transaction hash.
func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) {
- tx, blockHash, blockNumber, index := core.GetTransaction(s.b.ChainDb(), hash)
+ tx, blockHash, blockNumber, index := rawdb.ReadTransaction(s.b.ChainDb(), hash)
if tx == nil {
return nil, nil
}
diff --git a/les/api_backend.go b/les/api_backend.go
index 3fc5c33a44..1d3c995134 100644
--- a/les/api_backend.go
+++ b/les/api_backend.go
@@ -25,6 +25,7 @@ import (
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
@@ -83,16 +84,22 @@ func (b *LesApiBackend) GetBlock(ctx context.Context, blockHash common.Hash) (*t
return b.eth.blockchain.GetBlockByHash(ctx, blockHash)
}
-func (b *LesApiBackend) GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error) {
- return light.GetBlockReceipts(ctx, b.eth.odr, blockHash, core.GetBlockNumber(b.eth.chainDb, blockHash))
+func (b *LesApiBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
+ if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != nil {
+ return light.GetBlockReceipts(ctx, b.eth.odr, hash, *number)
+ }
+ return nil, nil
}
-func (b *LesApiBackend) GetLogs(ctx context.Context, blockHash common.Hash) ([][]*types.Log, error) {
- return light.GetBlockLogs(ctx, b.eth.odr, blockHash, core.GetBlockNumber(b.eth.chainDb, blockHash))
+func (b *LesApiBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) {
+ if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != nil {
+ return light.GetBlockLogs(ctx, b.eth.odr, hash, *number)
+ }
+ return nil, nil
}
-func (b *LesApiBackend) GetTd(blockHash common.Hash) *big.Int {
- return b.eth.blockchain.GetTdByHash(blockHash)
+func (b *LesApiBackend) GetTd(hash common.Hash) *big.Int {
+ return b.eth.blockchain.GetTdByHash(hash)
}
func (b *LesApiBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, vmCfg vm.Config) (*vm.EVM, func() error, error) {
diff --git a/les/backend.go b/les/backend.go
index 6a324cb04b..2d8ada7b0e 100644
--- a/les/backend.go
+++ b/les/backend.go
@@ -28,6 +28,7 @@ import (
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/eth/downloader"
@@ -122,7 +123,7 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) {
if compat, ok := genesisErr.(*params.ConfigCompatError); ok {
log.Warn("Rewinding chain to upgrade configuration", "err", compat)
leth.blockchain.SetHead(compat.RewindTo)
- core.WriteChainConfig(chainDb, genesisHash, chainConfig)
+ rawdb.WriteChainConfig(chainDb, genesisHash, chainConfig)
}
leth.txPool = light.NewTxPool(leth.chainConfig, leth.blockchain, leth.relay)
diff --git a/les/distributor_test.go b/les/distributor_test.go
index 55defb69be..2891bcab49 100644
--- a/les/distributor_test.go
+++ b/les/distributor_test.go
@@ -97,9 +97,8 @@ func (p *testDistPeer) waitBefore(cost uint64) (time.Duration, float64) {
p.lock.RUnlock()
if sumCost < testDistBufLimit {
return 0, float64(testDistBufLimit-sumCost) / float64(testDistBufLimit)
- } else {
- return time.Duration(sumCost - testDistBufLimit), 0
}
+ return time.Duration(sumCost - testDistBufLimit), 0
}
func (p *testDistPeer) canQueue() bool {
diff --git a/les/fetcher.go b/les/fetcher.go
index e12a2c78a2..59d3a2aa3c 100644
--- a/les/fetcher.go
+++ b/les/fetcher.go
@@ -25,7 +25,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/mclock"
"github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/light"
"github.com/ethereum/go-ethereum/log"
@@ -280,7 +280,7 @@ func (f *lightFetcher) announce(p *peer, head *announceData) {
// if one of root's children is canonical, keep it, delete other branches and root itself
var newRoot *fetcherTreeNode
for i, nn := range fp.root.children {
- if core.GetCanonicalHash(f.pm.chainDb, nn.number) == nn.hash {
+ if rawdb.ReadCanonicalHash(f.pm.chainDb, nn.number) == nn.hash {
fp.root.children = append(fp.root.children[:i], fp.root.children[i+1:]...)
nn.parent = nil
newRoot = nn
@@ -363,7 +363,7 @@ func (f *lightFetcher) peerHasBlock(p *peer, hash common.Hash, number uint64) bo
//
// when syncing, just check if it is part of the known chain, there is nothing better we
// can do since we do not know the most recent block hash yet
- return core.GetCanonicalHash(f.pm.chainDb, fp.root.number) == fp.root.hash && core.GetCanonicalHash(f.pm.chainDb, number) == hash
+ return rawdb.ReadCanonicalHash(f.pm.chainDb, fp.root.number) == fp.root.hash && rawdb.ReadCanonicalHash(f.pm.chainDb, number) == hash
}
// requestAmount calculates the amount of headers to be downloaded starting
diff --git a/les/handler.go b/les/handler.go
index 9627f392be..22899eb1bc 100644
--- a/les/handler.go
+++ b/les/handler.go
@@ -29,6 +29,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth/downloader"
@@ -528,9 +529,11 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
break
}
// Retrieve the requested block body, stopping if enough was found
- if data := core.GetBodyRLP(pm.chainDb, hash, core.GetBlockNumber(pm.chainDb, hash)); len(data) != 0 {
- bodies = append(bodies, data)
- bytes += len(data)
+ if number := rawdb.ReadHeaderNumber(pm.chainDb, hash); number != nil {
+ if data := rawdb.ReadBodyRLP(pm.chainDb, hash, *number); len(data) != 0 {
+ bodies = append(bodies, data)
+ bytes += len(data)
+ }
}
}
bv, rcost := p.fcClient.RequestProcessed(costs.baseCost + uint64(reqCnt)*costs.reqCost)
@@ -579,20 +582,22 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
}
for _, req := range req.Reqs {
// Retrieve the requested state entry, stopping if enough was found
- if header := core.GetHeader(pm.chainDb, req.BHash, core.GetBlockNumber(pm.chainDb, req.BHash)); header != nil {
- statedb, err := pm.blockchain.State()
- if err != nil {
- continue
- }
- account, err := pm.getAccount(statedb, header.Root, common.BytesToHash(req.AccKey))
- if err != nil {
- continue
- }
- code, _ := statedb.Database().TrieDB().Node(common.BytesToHash(account.CodeHash))
+ if number := rawdb.ReadHeaderNumber(pm.chainDb, req.BHash); number != nil {
+ if header := rawdb.ReadHeader(pm.chainDb, req.BHash, *number); header != nil {
+ statedb, err := pm.blockchain.State()
+ if err != nil {
+ continue
+ }
+ account, err := pm.getAccount(statedb, header.Root, common.BytesToHash(req.AccKey))
+ if err != nil {
+ continue
+ }
+ code, _ := statedb.Database().TrieDB().Node(common.BytesToHash(account.CodeHash))
- data = append(data, code)
- if bytes += len(code); bytes >= softResponseLimit {
- break
+ data = append(data, code)
+ if bytes += len(code); bytes >= softResponseLimit {
+ break
+ }
}
}
}
@@ -645,7 +650,10 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
break
}
// Retrieve the requested block's receipts, skipping if unknown to us
- results := core.GetBlockReceipts(pm.chainDb, hash, core.GetBlockNumber(pm.chainDb, hash))
+ var results types.Receipts
+ if number := rawdb.ReadHeaderNumber(pm.chainDb, hash); number != nil {
+ results = rawdb.ReadReceipts(pm.chainDb, hash, *number)
+ }
if results == nil {
if header := pm.blockchain.GetHeaderByHash(hash); header == nil || header.ReceiptHash != types.EmptyRootHash {
continue
@@ -705,28 +713,30 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
}
for _, req := range req.Reqs {
// Retrieve the requested state entry, stopping if enough was found
- if header := core.GetHeader(pm.chainDb, req.BHash, core.GetBlockNumber(pm.chainDb, req.BHash)); header != nil {
- statedb, err := pm.blockchain.State()
- if err != nil {
- continue
- }
- var trie state.Trie
- if len(req.AccKey) > 0 {
- account, err := pm.getAccount(statedb, header.Root, common.BytesToHash(req.AccKey))
+ if number := rawdb.ReadHeaderNumber(pm.chainDb, req.BHash); number != nil {
+ if header := rawdb.ReadHeader(pm.chainDb, req.BHash, *number); header != nil {
+ statedb, err := pm.blockchain.State()
if err != nil {
continue
}
- trie, _ = statedb.Database().OpenStorageTrie(common.BytesToHash(req.AccKey), account.Root)
- } else {
- trie, _ = statedb.Database().OpenTrie(header.Root)
- }
- if trie != nil {
- var proof light.NodeList
- trie.Prove(req.Key, 0, &proof)
+ var trie state.Trie
+ if len(req.AccKey) > 0 {
+ account, err := pm.getAccount(statedb, header.Root, common.BytesToHash(req.AccKey))
+ if err != nil {
+ continue
+ }
+ trie, _ = statedb.Database().OpenStorageTrie(common.BytesToHash(req.AccKey), account.Root)
+ } else {
+ trie, _ = statedb.Database().OpenTrie(header.Root)
+ }
+ if trie != nil {
+ var proof light.NodeList
+ trie.Prove(req.Key, 0, &proof)
- proofs = append(proofs, proof)
- if bytes += proof.DataSize(); bytes >= softResponseLimit {
- break
+ proofs = append(proofs, proof)
+ if bytes += proof.DataSize(); bytes >= softResponseLimit {
+ break
+ }
}
}
}
@@ -763,9 +773,11 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
if statedb == nil || req.BHash != lastBHash {
statedb, root, lastBHash = nil, common.Hash{}, req.BHash
- if header := core.GetHeader(pm.chainDb, req.BHash, core.GetBlockNumber(pm.chainDb, req.BHash)); header != nil {
- statedb, _ = pm.blockchain.State()
- root = header.Root
+ if number := rawdb.ReadHeaderNumber(pm.chainDb, req.BHash); number != nil {
+ if header := rawdb.ReadHeader(pm.chainDb, req.BHash, *number); header != nil {
+ statedb, _ = pm.blockchain.State()
+ root = header.Root
+ }
}
}
if statedb == nil {
@@ -859,7 +871,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
trieDb := trie.NewDatabase(ethdb.NewTable(pm.chainDb, light.ChtTablePrefix))
for _, req := range req.Reqs {
if header := pm.blockchain.GetHeaderByNumber(req.BlockNum); header != nil {
- sectionHead := core.GetCanonicalHash(pm.chainDb, req.ChtNum*light.CHTFrequencyServer-1)
+ sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, req.ChtNum*light.CHTFrequencyServer-1)
if root := light.GetChtRoot(pm.chainDb, req.ChtNum-1, sectionHead); root != (common.Hash{}) {
trie, err := trie.New(root, trieDb)
if err != nil {
@@ -1114,10 +1126,10 @@ func (pm *ProtocolManager) getAccount(statedb *state.StateDB, root, hash common.
func (pm *ProtocolManager) getHelperTrie(id uint, idx uint64) (common.Hash, string) {
switch id {
case htCanonical:
- sectionHead := core.GetCanonicalHash(pm.chainDb, (idx+1)*light.CHTFrequencyClient-1)
+ sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, (idx+1)*light.CHTFrequencyClient-1)
return light.GetChtV2Root(pm.chainDb, idx, sectionHead), light.ChtTablePrefix
case htBloomBits:
- sectionHead := core.GetCanonicalHash(pm.chainDb, (idx+1)*light.BloomTrieFrequency-1)
+ sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, (idx+1)*light.BloomTrieFrequency-1)
return light.GetBloomTrieRoot(pm.chainDb, idx, sectionHead), light.BloomTrieTablePrefix
}
return common.Hash{}, ""
@@ -1128,8 +1140,8 @@ func (pm *ProtocolManager) getHelperTrieAuxData(req HelperTrieReq) []byte {
switch {
case req.Type == htCanonical && req.AuxReq == auxHeader && len(req.Key) == 8:
blockNum := binary.BigEndian.Uint64(req.Key)
- hash := core.GetCanonicalHash(pm.chainDb, blockNum)
- return core.GetHeaderRLP(pm.chainDb, hash, blockNum)
+ hash := rawdb.ReadCanonicalHash(pm.chainDb, blockNum)
+ return rawdb.ReadHeaderRLP(pm.chainDb, hash, blockNum)
}
return nil
}
@@ -1142,9 +1154,9 @@ func (pm *ProtocolManager) txStatus(hashes []common.Hash) []txStatus {
// If the transaction is unknown to the pool, try looking it up locally
if stat == core.TxStatusUnknown {
- if block, number, index := core.GetTxLookupEntry(pm.chainDb, hashes[i]); block != (common.Hash{}) {
+ if block, number, index := rawdb.ReadTxLookupEntry(pm.chainDb, hashes[i]); block != (common.Hash{}) {
stats[i].Status = core.TxStatusIncluded
- stats[i].Lookup = &core.TxLookupEntry{BlockHash: block, BlockIndex: number, Index: index}
+ stats[i].Lookup = &rawdb.TxLookupEntry{BlockHash: block, BlockIndex: number, Index: index}
}
}
}
diff --git a/les/handler_test.go b/les/handler_test.go
index 9468032f67..fa38d1d4f7 100644
--- a/les/handler_test.go
+++ b/les/handler_test.go
@@ -26,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/downloader"
@@ -304,7 +305,7 @@ func testGetReceipt(t *testing.T, protocol int) {
block := bc.GetBlockByNumber(i)
hashes = append(hashes, block.Hash())
- receipts = append(receipts, core.GetBlockReceipts(db, block.Hash(), block.NumberU64()))
+ receipts = append(receipts, rawdb.ReadReceipts(db, block.Hash(), block.NumberU64()))
}
// Send the hash request and verify the response
cost := peer.GetRequestCost(GetReceiptsMsg, len(hashes))
@@ -555,9 +556,9 @@ func TestTransactionStatusLes2(t *testing.T) {
}
// check if their status is included now
- block1hash := core.GetCanonicalHash(db, 1)
- test(tx1, false, txStatus{Status: core.TxStatusIncluded, Lookup: &core.TxLookupEntry{BlockHash: block1hash, BlockIndex: 1, Index: 0}})
- test(tx2, false, txStatus{Status: core.TxStatusIncluded, Lookup: &core.TxLookupEntry{BlockHash: block1hash, BlockIndex: 1, Index: 1}})
+ block1hash := rawdb.ReadCanonicalHash(db, 1)
+ test(tx1, false, txStatus{Status: core.TxStatusIncluded, Lookup: &rawdb.TxLookupEntry{BlockHash: block1hash, BlockIndex: 1, Index: 0}})
+ test(tx2, false, txStatus{Status: core.TxStatusIncluded, Lookup: &rawdb.TxLookupEntry{BlockHash: block1hash, BlockIndex: 1, Index: 1}})
// create a reorg that rolls them back
gchain, _ = core.GenerateChain(params.TestChainConfig, chain.GetBlockByNumber(0), ethash.NewFaker(), db, 2, func(i int, block *core.BlockGen) {})
diff --git a/les/odr_requests.go b/les/odr_requests.go
index 34d759dd2a..c7f06df94d 100644
--- a/les/odr_requests.go
+++ b/les/odr_requests.go
@@ -24,7 +24,7 @@ import (
"fmt"
"github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
@@ -110,7 +110,7 @@ func (r *BlockRequest) Validate(db ethdb.Database, msg *Msg) error {
body := bodies[0]
// Retrieve our stored header and validate block content against it
- header := core.GetHeader(db, r.Hash, r.Number)
+ header := rawdb.ReadHeader(db, r.Hash, r.Number)
if header == nil {
return errHeaderUnavailable
}
@@ -166,7 +166,7 @@ func (r *ReceiptsRequest) Validate(db ethdb.Database, msg *Msg) error {
receipt := receipts[0]
// Retrieve our stored header and validate receipt content against it
- header := core.GetHeader(db, r.Hash, r.Number)
+ header := rawdb.ReadHeader(db, r.Hash, r.Number)
if header == nil {
return errHeaderUnavailable
}
diff --git a/les/odr_test.go b/les/odr_test.go
index 88e121cda6..9973df0430 100644
--- a/les/odr_test.go
+++ b/les/odr_test.go
@@ -26,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
@@ -63,9 +64,13 @@ func TestOdrGetReceiptsLes2(t *testing.T) { testOdr(t, 2, 1, odrGetReceipts) }
func odrGetReceipts(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte {
var receipts types.Receipts
if bc != nil {
- receipts = core.GetBlockReceipts(db, bhash, core.GetBlockNumber(db, bhash))
+ if number := rawdb.ReadHeaderNumber(db, bhash); number != nil {
+ receipts = rawdb.ReadReceipts(db, bhash, *number)
+ }
} else {
- receipts, _ = light.GetBlockReceipts(ctx, lc.Odr(), bhash, core.GetBlockNumber(db, bhash))
+ if number := rawdb.ReadHeaderNumber(db, bhash); number != nil {
+ receipts, _ = light.GetBlockReceipts(ctx, lc.Odr(), bhash, *number)
+ }
}
if receipts == nil {
return nil
@@ -178,7 +183,7 @@ func testOdr(t *testing.T, protocol int, expFail uint64, fn odrTestFn) {
test := func(expFail uint64) {
for i := uint64(0); i <= pm.blockchain.CurrentHeader().Number.Uint64(); i++ {
- bhash := core.GetCanonicalHash(db, i)
+ bhash := rawdb.ReadCanonicalHash(db, i)
b1 := fn(light.NoOdr, db, pm.chainConfig, pm.blockchain.(*core.BlockChain), nil, bhash)
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
diff --git a/les/protocol.go b/les/protocol.go
index e1c4625bce..ee4c223988 100644
--- a/les/protocol.go
+++ b/les/protocol.go
@@ -28,6 +28,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
"github.com/ethereum/go-ethereum/rlp"
@@ -160,9 +161,8 @@ func (a *announceData) checkSignature(pubKey *ecdsa.PublicKey) error {
pbytes := elliptic.Marshal(pubKey.Curve, pubKey.X, pubKey.Y)
if bytes.Equal(pbytes, recPubkey) {
return nil
- } else {
- return errors.New("Wrong signature")
}
+ return errors.New("Wrong signature")
}
type blockInfo struct {
@@ -224,6 +224,6 @@ type proofsData [][]rlp.RawValue
type txStatus struct {
Status core.TxStatus
- Lookup *core.TxLookupEntry `rlp:"nil"`
+ Lookup *rawdb.TxLookupEntry `rlp:"nil"`
Error string
}
diff --git a/les/randselect.go b/les/randselect.go
index 1a9d0695bd..1cc1d3d3e0 100644
--- a/les/randselect.go
+++ b/les/randselect.go
@@ -118,17 +118,16 @@ func (n *wrsNode) insert(item wrsItem, weight int64) int {
if n.level == 0 {
n.items[branch] = item
return branch
- } else {
- var subNode *wrsNode
- if n.items[branch] == nil {
- subNode = &wrsNode{maxItems: n.maxItems / wrsBranches, level: n.level - 1}
- n.items[branch] = subNode
- } else {
- subNode = n.items[branch].(*wrsNode)
- }
- subIdx := subNode.insert(item, weight)
- return subNode.maxItems*branch + subIdx
}
+ var subNode *wrsNode
+ if n.items[branch] == nil {
+ subNode = &wrsNode{maxItems: n.maxItems / wrsBranches, level: n.level - 1}
+ n.items[branch] = subNode
+ } else {
+ subNode = n.items[branch].(*wrsNode)
+ }
+ subIdx := subNode.insert(item, weight)
+ return subNode.maxItems*branch + subIdx
}
// setWeight updates the weight of a certain item (which should exist) and returns
@@ -162,12 +161,10 @@ func (n *wrsNode) choose(val int64) (wrsItem, int64) {
if val < w {
if n.level == 0 {
return n.items[i].(wrsItem), n.weights[i]
- } else {
- return n.items[i].(*wrsNode).choose(val)
}
- } else {
- val -= w
+ return n.items[i].(*wrsNode).choose(val)
}
+ val -= w
}
panic(nil)
}
diff --git a/les/request_test.go b/les/request_test.go
index c13625de8e..d4282a5927 100644
--- a/les/request_test.go
+++ b/les/request_test.go
@@ -22,7 +22,7 @@ import (
"time"
"github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethdb"
@@ -58,15 +58,22 @@ func TestTrieEntryAccessLes1(t *testing.T) { testAccess(t, 1, tfTrieEntryAccess)
func TestTrieEntryAccessLes2(t *testing.T) { testAccess(t, 2, tfTrieEntryAccess) }
func tfTrieEntryAccess(db ethdb.Database, bhash common.Hash, number uint64) light.OdrRequest {
- return &light.TrieRequest{Id: light.StateTrieID(core.GetHeader(db, bhash, core.GetBlockNumber(db, bhash))), Key: testBankSecureTrieKey}
+ if number := rawdb.ReadHeaderNumber(db, bhash); number != nil {
+ return &light.TrieRequest{Id: light.StateTrieID(rawdb.ReadHeader(db, bhash, *number)), Key: testBankSecureTrieKey}
+ }
+ return nil
}
func TestCodeAccessLes1(t *testing.T) { testAccess(t, 1, tfCodeAccess) }
func TestCodeAccessLes2(t *testing.T) { testAccess(t, 2, tfCodeAccess) }
-func tfCodeAccess(db ethdb.Database, bhash common.Hash, number uint64) light.OdrRequest {
- header := core.GetHeader(db, bhash, core.GetBlockNumber(db, bhash))
+func tfCodeAccess(db ethdb.Database, bhash common.Hash, num uint64) light.OdrRequest {
+ number := rawdb.ReadHeaderNumber(db, bhash)
+ if number != nil {
+ return nil
+ }
+ header := rawdb.ReadHeader(db, bhash, *number)
if header.Number.Uint64() < testContractDeployed {
return nil
}
@@ -99,7 +106,7 @@ func testAccess(t *testing.T, protocol int, fn accessTestFn) {
test := func(expFail uint64) {
for i := uint64(0); i <= pm.blockchain.CurrentHeader().Number.Uint64(); i++ {
- bhash := core.GetCanonicalHash(db, i)
+ bhash := rawdb.ReadCanonicalHash(db, i)
if req := fn(ldb, bhash, i); req != nil {
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
defer cancel()
diff --git a/les/server.go b/les/server.go
index 28b87008a0..9eb8ee7f97 100644
--- a/les/server.go
+++ b/les/server.go
@@ -25,6 +25,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethdb"
@@ -329,11 +330,11 @@ func (pm *ProtocolManager) blockLoop() {
header := ev.Block.Header()
hash := header.Hash()
number := header.Number.Uint64()
- td := core.GetTd(pm.chainDb, hash, number)
+ td := rawdb.ReadTd(pm.chainDb, hash, number)
if td != nil && td.Cmp(lastBroadcastTd) > 0 {
var reorg uint64
if lastHead != nil {
- reorg = lastHead.Number.Uint64() - core.FindCommonAncestor(pm.chainDb, header, lastHead).Number.Uint64()
+ reorg = lastHead.Number.Uint64() - rawdb.FindCommonAncestor(pm.chainDb, header, lastHead).Number.Uint64()
}
lastHead = header
lastBroadcastTd = td
diff --git a/les/serverpool.go b/les/serverpool.go
index da73b4b3c5..a39f883554 100644
--- a/les/serverpool.go
+++ b/les/serverpool.go
@@ -601,9 +601,8 @@ func (e *discoveredEntry) Weight() int64 {
t := time.Duration(mclock.Now() - e.lastDiscovered)
if t <= discoverExpireStart {
return 1000000000
- } else {
- return int64(1000000000 * math.Exp(-float64(t-discoverExpireStart)/float64(discoverExpireConst)))
}
+ return int64(1000000000 * math.Exp(-float64(t-discoverExpireStart)/float64(discoverExpireConst)))
}
// knownEntry implements wrsItem
diff --git a/les/sync.go b/les/sync.go
index c3d37e2f3f..1ac6455852 100644
--- a/les/sync.go
+++ b/les/sync.go
@@ -20,7 +20,7 @@ import (
"context"
"time"
- "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/eth/downloader"
"github.com/ethereum/go-ethereum/light"
)
@@ -56,7 +56,7 @@ func (pm *ProtocolManager) syncer() {
func (pm *ProtocolManager) needToSync(peerHead blockInfo) bool {
head := pm.blockchain.CurrentHeader()
- currentTd := core.GetTd(pm.chainDb, head.Hash(), head.Number.Uint64())
+ currentTd := rawdb.ReadTd(pm.chainDb, head.Hash(), head.Number.Uint64())
return currentTd != nil && peerHead.Td.Cmp(currentTd) > 0
}
diff --git a/light/lightchain.go b/light/lightchain.go
index 2784615d35..9d0a4e4f73 100644
--- a/light/lightchain.go
+++ b/light/lightchain.go
@@ -27,6 +27,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
@@ -142,7 +143,7 @@ func (self *LightChain) Odr() OdrBackend {
// loadLastState loads the last known chain state from the database. This method
// assumes that the chain manager mutex is held.
func (self *LightChain) loadLastState() error {
- if head := core.GetHeadHeaderHash(self.chainDb); head == (common.Hash{}) {
+ if head := rawdb.ReadHeadHeaderHash(self.chainDb); head == (common.Hash{}) {
// Corrupt or empty database, init from scratch
self.Reset()
} else {
@@ -189,12 +190,9 @@ func (bc *LightChain) ResetWithGenesisBlock(genesis *types.Block) {
defer bc.mu.Unlock()
// Prepare the genesis block and reinitialise the chain
- if err := core.WriteTd(bc.chainDb, genesis.Hash(), genesis.NumberU64(), genesis.Difficulty()); err != nil {
- log.Crit("Failed to write genesis block TD", "err", err)
- }
- if err := core.WriteBlock(bc.chainDb, genesis); err != nil {
- log.Crit("Failed to write genesis block", "err", err)
- }
+ rawdb.WriteTd(bc.chainDb, genesis.Hash(), genesis.NumberU64(), genesis.Difficulty())
+ rawdb.WriteBlock(bc.chainDb, genesis)
+
bc.genesisBlock = genesis
bc.hc.SetGenesis(bc.genesisBlock.Header())
bc.hc.SetCurrentHeader(bc.genesisBlock.Header())
@@ -223,7 +221,11 @@ func (self *LightChain) GetBody(ctx context.Context, hash common.Hash) (*types.B
body := cached.(*types.Body)
return body, nil
}
- body, err := GetBody(ctx, self.odr, hash, self.hc.GetBlockNumber(hash))
+ number := self.hc.GetBlockNumber(hash)
+ if number == nil {
+ return nil, errors.New("unknown block")
+ }
+ body, err := GetBody(ctx, self.odr, hash, *number)
if err != nil {
return nil, err
}
@@ -239,7 +241,11 @@ func (self *LightChain) GetBodyRLP(ctx context.Context, hash common.Hash) (rlp.R
if cached, ok := self.bodyRLPCache.Get(hash); ok {
return cached.(rlp.RawValue), nil
}
- body, err := GetBodyRLP(ctx, self.odr, hash, self.hc.GetBlockNumber(hash))
+ number := self.hc.GetBlockNumber(hash)
+ if number == nil {
+ return nil, errors.New("unknown block")
+ }
+ body, err := GetBodyRLP(ctx, self.odr, hash, *number)
if err != nil {
return nil, err
}
@@ -274,7 +280,11 @@ func (self *LightChain) GetBlock(ctx context.Context, hash common.Hash, number u
// GetBlockByHash retrieves a block from the database or ODR service by hash,
// caching it if found.
func (self *LightChain) GetBlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
- return self.GetBlock(ctx, hash, self.hc.GetBlockNumber(hash))
+ number := self.hc.GetBlockNumber(hash)
+ if number == nil {
+ return nil, errors.New("unknown block")
+ }
+ return self.GetBlock(ctx, hash, *number)
}
// GetBlockByNumber retrieves a block from the database or ODR service by
diff --git a/light/lightchain_test.go b/light/lightchain_test.go
index 0af7551d41..b8ab1c51cf 100644
--- a/light/lightchain_test.go
+++ b/light/lightchain_test.go
@@ -24,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/params"
@@ -122,8 +123,8 @@ func testHeaderChainImport(chain []*types.Header, lightchain *LightChain) error
}
// Manually insert the header into the database, but don't reorganize (allows subsequent testing)
lightchain.mu.Lock()
- core.WriteTd(lightchain.chainDb, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, lightchain.GetTdByHash(header.ParentHash)))
- core.WriteHeader(lightchain.chainDb, header)
+ rawdb.WriteTd(lightchain.chainDb, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, lightchain.GetTdByHash(header.ParentHash)))
+ rawdb.WriteHeader(lightchain.chainDb, header)
lightchain.mu.Unlock()
}
return nil
diff --git a/light/odr.go b/light/odr.go
index e2c3d9c5a4..8f1e50b817 100644
--- a/light/odr.go
+++ b/light/odr.go
@@ -24,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
)
@@ -112,7 +113,7 @@ type BlockRequest struct {
// StoreResult stores the retrieved data in local database
func (req *BlockRequest) StoreResult(db ethdb.Database) {
- core.WriteBodyRLP(db, req.Hash, req.Number, req.Rlp)
+ rawdb.WriteBodyRLP(db, req.Hash, req.Number, req.Rlp)
}
// ReceiptsRequest is the ODR request type for retrieving block bodies
@@ -125,7 +126,7 @@ type ReceiptsRequest struct {
// StoreResult stores the retrieved data in local database
func (req *ReceiptsRequest) StoreResult(db ethdb.Database) {
- core.WriteBlockReceipts(db, req.Hash, req.Number, req.Receipts)
+ rawdb.WriteReceipts(db, req.Hash, req.Number, req.Receipts)
}
// ChtRequest is the ODR request type for state/storage trie entries
@@ -140,11 +141,11 @@ type ChtRequest struct {
// StoreResult stores the retrieved data in local database
func (req *ChtRequest) StoreResult(db ethdb.Database) {
- // if there is a canonical hash, there is a header too
- core.WriteHeader(db, req.Header)
hash, num := req.Header.Hash(), req.Header.Number.Uint64()
- core.WriteTd(db, hash, num, req.Td)
- core.WriteCanonicalHash(db, hash, num)
+
+ rawdb.WriteHeader(db, req.Header)
+ rawdb.WriteTd(db, hash, num, req.Td)
+ rawdb.WriteCanonicalHash(db, hash, num)
}
// BloomRequest is the ODR request type for retrieving bloom filters from a CHT structure
@@ -161,11 +162,11 @@ type BloomRequest struct {
// StoreResult stores the retrieved data in local database
func (req *BloomRequest) StoreResult(db ethdb.Database) {
for i, sectionIdx := range req.SectionIdxList {
- sectionHead := core.GetCanonicalHash(db, (sectionIdx+1)*BloomTrieFrequency-1)
+ sectionHead := rawdb.ReadCanonicalHash(db, (sectionIdx+1)*BloomTrieFrequency-1)
// if we don't have the canonical hash stored for this section head number, we'll still store it under
// a key with a zero sectionHead. GetBloomBits will look there too if we still don't have the canonical
// hash. In the unlikely case we've retrieved the section head hash since then, we'll just retrieve the
// bit vector again from the network.
- core.WriteBloomBits(db, req.BitIdx, sectionIdx, sectionHead, req.BloomBits[i])
+ rawdb.WriteBloomBits(db, req.BitIdx, sectionIdx, sectionHead, req.BloomBits[i])
}
}
diff --git a/light/odr_test.go b/light/odr_test.go
index d3f9374fd8..cc7475df38 100644
--- a/light/odr_test.go
+++ b/light/odr_test.go
@@ -28,6 +28,7 @@ import (
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
@@ -70,9 +71,15 @@ func (odr *testOdr) Retrieve(ctx context.Context, req OdrRequest) error {
}
switch req := req.(type) {
case *BlockRequest:
- req.Rlp = core.GetBodyRLP(odr.sdb, req.Hash, core.GetBlockNumber(odr.sdb, req.Hash))
+ number := rawdb.ReadHeaderNumber(odr.sdb, req.Hash)
+ if number != nil {
+ req.Rlp = rawdb.ReadBodyRLP(odr.sdb, req.Hash, *number)
+ }
case *ReceiptsRequest:
- req.Receipts = core.GetBlockReceipts(odr.sdb, req.Hash, core.GetBlockNumber(odr.sdb, req.Hash))
+ number := rawdb.ReadHeaderNumber(odr.sdb, req.Hash)
+ if number != nil {
+ req.Receipts = rawdb.ReadReceipts(odr.sdb, req.Hash, *number)
+ }
case *TrieRequest:
t, _ := trie.New(req.Id.Root, trie.NewDatabase(odr.sdb))
nodes := NewNodeSet()
@@ -108,9 +115,15 @@ func TestOdrGetReceiptsLes1(t *testing.T) { testChainOdr(t, 1, odrGetReceipts) }
func odrGetReceipts(ctx context.Context, db ethdb.Database, bc *core.BlockChain, lc *LightChain, bhash common.Hash) ([]byte, error) {
var receipts types.Receipts
if bc != nil {
- receipts = core.GetBlockReceipts(db, bhash, core.GetBlockNumber(db, bhash))
+ number := rawdb.ReadHeaderNumber(db, bhash)
+ if number != nil {
+ receipts = rawdb.ReadReceipts(db, bhash, *number)
+ }
} else {
- receipts, _ = GetBlockReceipts(ctx, lc.Odr(), bhash, core.GetBlockNumber(db, bhash))
+ number := rawdb.ReadHeaderNumber(db, bhash)
+ if number != nil {
+ receipts, _ = GetBlockReceipts(ctx, lc.Odr(), bhash, *number)
+ }
}
if receipts == nil {
return nil, nil
@@ -260,7 +273,7 @@ func testChainOdr(t *testing.T, protocol int, fn odrTestFn) {
test := func(expFail int) {
for i := uint64(0); i <= blockchain.CurrentHeader().Number.Uint64(); i++ {
- bhash := core.GetCanonicalHash(sdb, i)
+ bhash := rawdb.ReadCanonicalHash(sdb, i)
b1, err := fn(NoOdr, sdb, blockchain, nil, bhash)
if err != nil {
t.Fatalf("error in full-node test for block %d: %v", i, err)
diff --git a/light/odr_util.go b/light/odr_util.go
index d56330e36b..620af63835 100644
--- a/light/odr_util.go
+++ b/light/odr_util.go
@@ -22,6 +22,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
@@ -31,10 +32,10 @@ var sha3_nil = crypto.Keccak256Hash(nil)
func GetHeaderByNumber(ctx context.Context, odr OdrBackend, number uint64) (*types.Header, error) {
db := odr.Database()
- hash := core.GetCanonicalHash(db, number)
+ hash := rawdb.ReadCanonicalHash(db, number)
if (hash != common.Hash{}) {
// if there is a canonical hash, there is a header too
- header := core.GetHeader(db, hash, number)
+ header := rawdb.ReadHeader(db, hash, number)
if header == nil {
panic("Canonical hash present but header not found")
}
@@ -47,14 +48,14 @@ func GetHeaderByNumber(ctx context.Context, odr OdrBackend, number uint64) (*typ
)
if odr.ChtIndexer() != nil {
chtCount, sectionHeadNum, sectionHead = odr.ChtIndexer().Sections()
- canonicalHash := core.GetCanonicalHash(db, sectionHeadNum)
+ canonicalHash := rawdb.ReadCanonicalHash(db, sectionHeadNum)
// if the CHT was injected as a trusted checkpoint, we have no canonical hash yet so we accept zero hash too
for chtCount > 0 && canonicalHash != sectionHead && canonicalHash != (common.Hash{}) {
chtCount--
if chtCount > 0 {
sectionHeadNum = chtCount*CHTFrequencyClient - 1
sectionHead = odr.ChtIndexer().SectionHead(chtCount - 1)
- canonicalHash = core.GetCanonicalHash(db, sectionHeadNum)
+ canonicalHash = rawdb.ReadCanonicalHash(db, sectionHeadNum)
}
}
}
@@ -69,7 +70,7 @@ func GetHeaderByNumber(ctx context.Context, odr OdrBackend, number uint64) (*typ
}
func GetCanonicalHash(ctx context.Context, odr OdrBackend, number uint64) (common.Hash, error) {
- hash := core.GetCanonicalHash(odr.Database(), number)
+ hash := rawdb.ReadCanonicalHash(odr.Database(), number)
if (hash != common.Hash{}) {
return hash, nil
}
@@ -82,7 +83,7 @@ func GetCanonicalHash(ctx context.Context, odr OdrBackend, number uint64) (commo
// GetBodyRLP retrieves the block body (transactions and uncles) in RLP encoding.
func GetBodyRLP(ctx context.Context, odr OdrBackend, hash common.Hash, number uint64) (rlp.RawValue, error) {
- if data := core.GetBodyRLP(odr.Database(), hash, number); data != nil {
+ if data := rawdb.ReadBodyRLP(odr.Database(), hash, number); data != nil {
return data, nil
}
r := &BlockRequest{Hash: hash, Number: number}
@@ -111,7 +112,7 @@ func GetBody(ctx context.Context, odr OdrBackend, hash common.Hash, number uint6
// back from the stored header and body.
func GetBlock(ctx context.Context, odr OdrBackend, hash common.Hash, number uint64) (*types.Block, error) {
// Retrieve the block header and body contents
- header := core.GetHeader(odr.Database(), hash, number)
+ header := rawdb.ReadHeader(odr.Database(), hash, number)
if header == nil {
return nil, ErrNoHeader
}
@@ -127,7 +128,7 @@ func GetBlock(ctx context.Context, odr OdrBackend, hash common.Hash, number uint
// in a block given by its hash.
func GetBlockReceipts(ctx context.Context, odr OdrBackend, hash common.Hash, number uint64) (types.Receipts, error) {
// Retrieve the potentially incomplete receipts from disk or network
- receipts := core.GetBlockReceipts(odr.Database(), hash, number)
+ receipts := rawdb.ReadReceipts(odr.Database(), hash, number)
if receipts == nil {
r := &ReceiptsRequest{Hash: hash, Number: number}
if err := odr.Retrieve(ctx, r); err != nil {
@@ -141,13 +142,13 @@ func GetBlockReceipts(ctx context.Context, odr OdrBackend, hash common.Hash, num
if err != nil {
return nil, err
}
- genesis := core.GetCanonicalHash(odr.Database(), 0)
- config, _ := core.GetChainConfig(odr.Database(), genesis)
+ genesis := rawdb.ReadCanonicalHash(odr.Database(), 0)
+ config := rawdb.ReadChainConfig(odr.Database(), genesis)
if err := core.SetReceiptsData(config, block, receipts); err != nil {
return nil, err
}
- core.WriteBlockReceipts(odr.Database(), hash, number, receipts)
+ rawdb.WriteReceipts(odr.Database(), hash, number, receipts)
}
return receipts, nil
}
@@ -156,7 +157,7 @@ func GetBlockReceipts(ctx context.Context, odr OdrBackend, hash common.Hash, num
// block given by its hash.
func GetBlockLogs(ctx context.Context, odr OdrBackend, hash common.Hash, number uint64) ([][]*types.Log, error) {
// Retrieve the potentially incomplete receipts from disk or network
- receipts := core.GetBlockReceipts(odr.Database(), hash, number)
+ receipts := rawdb.ReadReceipts(odr.Database(), hash, number)
if receipts == nil {
r := &ReceiptsRequest{Hash: hash, Number: number}
if err := odr.Retrieve(ctx, r); err != nil {
@@ -187,24 +188,24 @@ func GetBloomBits(ctx context.Context, odr OdrBackend, bitIdx uint, sectionIdxLi
)
if odr.BloomTrieIndexer() != nil {
bloomTrieCount, sectionHeadNum, sectionHead = odr.BloomTrieIndexer().Sections()
- canonicalHash := core.GetCanonicalHash(db, sectionHeadNum)
+ canonicalHash := rawdb.ReadCanonicalHash(db, sectionHeadNum)
// if the BloomTrie was injected as a trusted checkpoint, we have no canonical hash yet so we accept zero hash too
for bloomTrieCount > 0 && canonicalHash != sectionHead && canonicalHash != (common.Hash{}) {
bloomTrieCount--
if bloomTrieCount > 0 {
sectionHeadNum = bloomTrieCount*BloomTrieFrequency - 1
sectionHead = odr.BloomTrieIndexer().SectionHead(bloomTrieCount - 1)
- canonicalHash = core.GetCanonicalHash(db, sectionHeadNum)
+ canonicalHash = rawdb.ReadCanonicalHash(db, sectionHeadNum)
}
}
}
for i, sectionIdx := range sectionIdxList {
- sectionHead := core.GetCanonicalHash(db, (sectionIdx+1)*BloomTrieFrequency-1)
+ sectionHead := rawdb.ReadCanonicalHash(db, (sectionIdx+1)*BloomTrieFrequency-1)
// if we don't have the canonical hash stored for this section head number, we'll still look for
// an entry with a zero sectionHead (we store it with zero section head too if we don't know it
// at the time of the retrieval)
- bloomBits, err := core.GetBloomBits(db, bitIdx, sectionIdx, sectionHead)
+ bloomBits, err := rawdb.ReadBloomBits(db, bitIdx, sectionIdx, sectionHead)
if err == nil {
result[i] = bloomBits
} else {
diff --git a/light/postprocess.go b/light/postprocess.go
index 702eb53c86..8b9a029112 100644
--- a/light/postprocess.go
+++ b/light/postprocess.go
@@ -25,6 +25,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/bitutil"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
@@ -161,7 +162,7 @@ func (c *ChtIndexerBackend) Process(header *types.Header) {
hash, num := header.Hash(), header.Number.Uint64()
c.lastHash = hash
- td := core.GetTd(c.diskdb, hash, num)
+ td := rawdb.ReadTd(c.diskdb, hash, num)
if td == nil {
panic(nil)
}
@@ -272,7 +273,7 @@ func (b *BloomTrieIndexerBackend) Commit() error {
binary.BigEndian.PutUint64(encKey[2:10], b.section)
var decomp []byte
for j := uint64(0); j < b.bloomTrieRatio; j++ {
- data, err := core.GetBloomBits(b.diskdb, i, b.section*b.bloomTrieRatio+j, b.sectionHeads[j])
+ data, err := rawdb.ReadBloomBits(b.diskdb, i, b.section*b.bloomTrieRatio+j, b.sectionHeads[j])
if err != nil {
return err
}
diff --git a/light/txpool.go b/light/txpool.go
index ca41490bdc..94c8139cbd 100644
--- a/light/txpool.go
+++ b/light/txpool.go
@@ -24,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
@@ -183,9 +184,8 @@ func (pool *TxPool) checkMinedTxs(ctx context.Context, hash common.Hash, number
if _, err := GetBlockReceipts(ctx, pool.odr, hash, number); err != nil { // ODR caches, ignore results
return err
}
- if err := core.WriteTxLookupEntries(pool.chainDb, block); err != nil {
- return err
- }
+ rawdb.WriteTxLookupEntries(pool.chainDb, block)
+
// Update the transaction pool's state
for _, tx := range list {
delete(pool.pending, tx.Hash())
@@ -202,7 +202,7 @@ func (pool *TxPool) rollbackTxs(hash common.Hash, txc txStateChanges) {
if list, ok := pool.mined[hash]; ok {
for _, tx := range list {
txHash := tx.Hash()
- core.DeleteTxLookupEntry(pool.chainDb, txHash)
+ rawdb.DeleteTxLookupEntry(pool.chainDb, txHash)
pool.pending[txHash] = tx
txc.setState(txHash, false)
}
@@ -258,7 +258,7 @@ func (pool *TxPool) reorgOnNewHead(ctx context.Context, newHeader *types.Header)
idx2 := idx - txPermanent
if len(pool.mined) > 0 {
for i := pool.clearIdx; i < idx2; i++ {
- hash := core.GetCanonicalHash(pool.chainDb, i)
+ hash := rawdb.ReadCanonicalHash(pool.chainDb, i)
if list, ok := pool.mined[hash]; ok {
hashes := make([]common.Hash, len(list))
for i, tx := range list {
diff --git a/log/handler.go b/log/handler.go
index d5594b853d..41d5718ddb 100644
--- a/log/handler.go
+++ b/log/handler.go
@@ -234,9 +234,8 @@ func FailoverHandler(hs ...Handler) Handler {
err = h.Log(r)
if err == nil {
return nil
- } else {
- r.Ctx = append(r.Ctx, fmt.Sprintf("failover_err_%d", i), err)
}
+ r.Ctx = append(r.Ctx, fmt.Sprintf("failover_err_%d", i), err)
}
return err
@@ -320,13 +319,12 @@ func evaluateLazy(lz Lazy) (interface{}, error) {
results := value.Call([]reflect.Value{})
if len(results) == 1 {
return results[0].Interface(), nil
- } else {
- values := make([]interface{}, len(results))
- for i, v := range results {
- values[i] = v.Interface()
- }
- return values, nil
}
+ values := make([]interface{}, len(results))
+ for i, v := range results {
+ values[i] = v.Interface()
+ }
+ return values, nil
}
// DiscardHandler reports success for all writes but does nothing.
diff --git a/metrics/librato/client.go b/metrics/librato/client.go
index 8c0c850e38..1f8920cb1a 100644
--- a/metrics/librato/client.go
+++ b/metrics/librato/client.go
@@ -65,7 +65,7 @@ type Batch struct {
Source string `json:"source"`
}
-func (self *LibratoClient) PostMetrics(batch Batch) (err error) {
+func (c *LibratoClient) PostMetrics(batch Batch) (err error) {
var (
js []byte
req *http.Request
@@ -85,7 +85,7 @@ func (self *LibratoClient) PostMetrics(batch Batch) (err error) {
}
req.Header.Set("Content-Type", "application/json")
- req.SetBasicAuth(self.Email, self.Token)
+ req.SetBasicAuth(c.Email, c.Token)
if resp, err = http.DefaultClient.Do(req); err != nil {
return
diff --git a/metrics/librato/librato.go b/metrics/librato/librato.go
index f8c8c9ecb7..2138e01ae8 100644
--- a/metrics/librato/librato.go
+++ b/metrics/librato/librato.go
@@ -40,14 +40,14 @@ func Librato(r metrics.Registry, d time.Duration, e string, t string, s string,
NewReporter(r, d, e, t, s, p, u).Run()
}
-func (self *Reporter) Run() {
+func (rep *Reporter) Run() {
log.Printf("WARNING: This client has been DEPRECATED! It has been moved to https://github.com/mihasya/go-metrics-librato and will be removed from rcrowley/go-metrics on August 5th 2015")
- ticker := time.Tick(self.Interval)
- metricsApi := &LibratoClient{self.Email, self.Token}
+ ticker := time.Tick(rep.Interval)
+ metricsApi := &LibratoClient{rep.Email, rep.Token}
for now := range ticker {
var metrics Batch
var err error
- if metrics, err = self.BuildRequest(now, self.Registry); err != nil {
+ if metrics, err = rep.BuildRequest(now, rep.Registry); err != nil {
log.Printf("ERROR constructing librato request body %s", err)
continue
}
@@ -79,21 +79,21 @@ func sumSquaresTimer(t metrics.Timer) float64 {
return sumSquares
}
-func (self *Reporter) BuildRequest(now time.Time, r metrics.Registry) (snapshot Batch, err error) {
+func (rep *Reporter) BuildRequest(now time.Time, r metrics.Registry) (snapshot Batch, err error) {
snapshot = Batch{
// coerce timestamps to a stepping fn so that they line up in Librato graphs
- MeasureTime: (now.Unix() / self.intervalSec) * self.intervalSec,
- Source: self.Source,
+ MeasureTime: (now.Unix() / rep.intervalSec) * rep.intervalSec,
+ Source: rep.Source,
}
snapshot.Gauges = make([]Measurement, 0)
snapshot.Counters = make([]Measurement, 0)
- histogramGaugeCount := 1 + len(self.Percentiles)
+ histogramGaugeCount := 1 + len(rep.Percentiles)
r.Each(func(name string, metric interface{}) {
- if self.Namespace != "" {
- name = fmt.Sprintf("%s.%s", self.Namespace, name)
+ if rep.Namespace != "" {
+ name = fmt.Sprintf("%s.%s", rep.Namespace, name)
}
measurement := Measurement{}
- measurement[Period] = self.Interval.Seconds()
+ measurement[Period] = rep.Interval.Seconds()
switch m := metric.(type) {
case metrics.Counter:
if m.Count() > 0 {
@@ -125,7 +125,7 @@ func (self *Reporter) BuildRequest(now time.Time, r metrics.Registry) (snapshot
measurement[Sum] = float64(s.Sum())
measurement[SumSquares] = sumSquares(s)
gauges[0] = measurement
- for i, p := range self.Percentiles {
+ for i, p := range rep.Percentiles {
gauges[i+1] = Measurement{
Name: fmt.Sprintf("%s.%.2f", measurement[Name], p),
Value: s.Percentile(p),
@@ -142,7 +142,7 @@ func (self *Reporter) BuildRequest(now time.Time, r metrics.Registry) (snapshot
Measurement{
Name: fmt.Sprintf("%s.%s", name, "1min"),
Value: m.Rate1(),
- Period: int64(self.Interval.Seconds()),
+ Period: int64(rep.Interval.Seconds()),
Attributes: map[string]interface{}{
DisplayUnitsLong: Operations,
DisplayUnitsShort: OperationsShort,
@@ -152,7 +152,7 @@ func (self *Reporter) BuildRequest(now time.Time, r metrics.Registry) (snapshot
Measurement{
Name: fmt.Sprintf("%s.%s", name, "5min"),
Value: m.Rate5(),
- Period: int64(self.Interval.Seconds()),
+ Period: int64(rep.Interval.Seconds()),
Attributes: map[string]interface{}{
DisplayUnitsLong: Operations,
DisplayUnitsShort: OperationsShort,
@@ -162,7 +162,7 @@ func (self *Reporter) BuildRequest(now time.Time, r metrics.Registry) (snapshot
Measurement{
Name: fmt.Sprintf("%s.%s", name, "15min"),
Value: m.Rate15(),
- Period: int64(self.Interval.Seconds()),
+ Period: int64(rep.Interval.Seconds()),
Attributes: map[string]interface{}{
DisplayUnitsLong: Operations,
DisplayUnitsShort: OperationsShort,
@@ -184,15 +184,15 @@ func (self *Reporter) BuildRequest(now time.Time, r metrics.Registry) (snapshot
Max: float64(m.Max()),
Min: float64(m.Min()),
SumSquares: sumSquaresTimer(m),
- Period: int64(self.Interval.Seconds()),
- Attributes: self.TimerAttributes,
+ Period: int64(rep.Interval.Seconds()),
+ Attributes: rep.TimerAttributes,
}
- for i, p := range self.Percentiles {
+ for i, p := range rep.Percentiles {
gauges[i+1] = Measurement{
Name: fmt.Sprintf("%s.timer.%2.0f", name, p*100),
Value: m.Percentile(p),
- Period: int64(self.Interval.Seconds()),
- Attributes: self.TimerAttributes,
+ Period: int64(rep.Interval.Seconds()),
+ Attributes: rep.TimerAttributes,
}
}
snapshot.Gauges = append(snapshot.Gauges, gauges...)
@@ -200,7 +200,7 @@ func (self *Reporter) BuildRequest(now time.Time, r metrics.Registry) (snapshot
Measurement{
Name: fmt.Sprintf("%s.%s", name, "rate.1min"),
Value: m.Rate1(),
- Period: int64(self.Interval.Seconds()),
+ Period: int64(rep.Interval.Seconds()),
Attributes: map[string]interface{}{
DisplayUnitsLong: Operations,
DisplayUnitsShort: OperationsShort,
@@ -210,7 +210,7 @@ func (self *Reporter) BuildRequest(now time.Time, r metrics.Registry) (snapshot
Measurement{
Name: fmt.Sprintf("%s.%s", name, "rate.5min"),
Value: m.Rate5(),
- Period: int64(self.Interval.Seconds()),
+ Period: int64(rep.Interval.Seconds()),
Attributes: map[string]interface{}{
DisplayUnitsLong: Operations,
DisplayUnitsShort: OperationsShort,
@@ -220,7 +220,7 @@ func (self *Reporter) BuildRequest(now time.Time, r metrics.Registry) (snapshot
Measurement{
Name: fmt.Sprintf("%s.%s", name, "rate.15min"),
Value: m.Rate15(),
- Period: int64(self.Interval.Seconds()),
+ Period: int64(rep.Interval.Seconds()),
Attributes: map[string]interface{}{
DisplayUnitsLong: Operations,
DisplayUnitsShort: OperationsShort,
diff --git a/mobile/types.go b/mobile/types.go
index 196c7839f5..f32b4918f3 100644
--- a/mobile/types.go
+++ b/mobile/types.go
@@ -329,6 +329,7 @@ func (r *Receipt) EncodeJSON() (string, error) {
return string(data), err
}
+func (r *Receipt) GetStatus() int { return int(r.receipt.Status) }
func (r *Receipt) GetPostState() []byte { return r.receipt.PostState }
func (r *Receipt) GetCumulativeGasUsed() int64 { return int64(r.receipt.CumulativeGasUsed) }
func (r *Receipt) GetBloom() *Bloom { return &Bloom{r.receipt.Bloom} }
diff --git a/p2p/message.go b/p2p/message.go
index c588270925..a4eac54d33 100644
--- a/p2p/message.go
+++ b/p2p/message.go
@@ -229,21 +229,20 @@ func ExpectMsg(r MsgReader, code uint64, content interface{}) error {
}
if content == nil {
return msg.Discard()
- } else {
- contentEnc, err := rlp.EncodeToBytes(content)
- if err != nil {
- panic("content encode error: " + err.Error())
- }
- if int(msg.Size) != len(contentEnc) {
- return fmt.Errorf("message size mismatch: got %d, want %d", msg.Size, len(contentEnc))
- }
- actualContent, err := ioutil.ReadAll(msg.Payload)
- if err != nil {
- return err
- }
- if !bytes.Equal(actualContent, contentEnc) {
- return fmt.Errorf("message payload mismatch:\ngot: %x\nwant: %x", actualContent, contentEnc)
- }
+ }
+ contentEnc, err := rlp.EncodeToBytes(content)
+ if err != nil {
+ panic("content encode error: " + err.Error())
+ }
+ if int(msg.Size) != len(contentEnc) {
+ return fmt.Errorf("message size mismatch: got %d, want %d", msg.Size, len(contentEnc))
+ }
+ actualContent, err := ioutil.ReadAll(msg.Payload)
+ if err != nil {
+ return err
+ }
+ if !bytes.Equal(actualContent, contentEnc) {
+ return fmt.Errorf("message payload mismatch:\ngot: %x\nwant: %x", actualContent, contentEnc)
}
return nil
}
diff --git a/rpc/http.go b/rpc/http.go
index 0c2e060fb4..feaa7348c4 100644
--- a/rpc/http.go
+++ b/rpc/http.go
@@ -191,7 +191,7 @@ func (srv *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
defer codec.Close()
w.Header().Set("content-type", contentType)
- srv.ServeSingleRequest(codec, OptionMethodInvocation, ctx)
+ srv.ServeSingleRequest(ctx, codec, OptionMethodInvocation)
}
// validateRequest returns a non-zero response code and error message if the
diff --git a/rpc/inproc.go b/rpc/inproc.go
index 595a7ca651..cbe65d10e7 100644
--- a/rpc/inproc.go
+++ b/rpc/inproc.go
@@ -21,7 +21,7 @@ import (
"net"
)
-// NewInProcClient attaches an in-process connection to the given RPC server.
+// DialInProc attaches an in-process connection to the given RPC server.
func DialInProc(handler *Server) *Client {
initctx := context.Background()
c, _ := newClient(initctx, func(context.Context) (net.Conn, error) {
diff --git a/rpc/server.go b/rpc/server.go
index 0f29035edb..7f304d8d93 100644
--- a/rpc/server.go
+++ b/rpc/server.go
@@ -125,7 +125,7 @@ func (s *Server) RegisterName(name string, rcvr interface{}) error {
// If singleShot is true it will process a single request, otherwise it will handle
// requests until the codec returns an error when reading a request (in most cases
// an EOF). It executes requests in parallel when singleShot is false.
-func (s *Server) serveRequest(codec ServerCodec, singleShot bool, options CodecOption, ctx context.Context) error {
+func (s *Server) serveRequest(ctx context.Context, codec ServerCodec, singleShot bool, options CodecOption) error {
var pend sync.WaitGroup
defer func() {
@@ -216,14 +216,14 @@ func (s *Server) serveRequest(codec ServerCodec, singleShot bool, options CodecO
// stopped. In either case the codec is closed.
func (s *Server) ServeCodec(codec ServerCodec, options CodecOption) {
defer codec.Close()
- s.serveRequest(codec, false, options, context.Background())
+ s.serveRequest(context.Background(), codec, false, options)
}
// ServeSingleRequest reads and processes a single RPC request from the given codec. It will not
// close the codec unless a non-recoverable error has occurred. Note, this method will return after
// a single request has been processed!
-func (s *Server) ServeSingleRequest(codec ServerCodec, options CodecOption, ctx context.Context) {
- s.serveRequest(codec, true, options, ctx)
+func (s *Server) ServeSingleRequest(ctx context.Context, codec ServerCodec, options CodecOption) {
+ s.serveRequest(ctx, codec, true, options)
}
// Stop will stop reading new requests, wait for stopPendingRequestTimeout to allow pending requests to finish,
diff --git a/signer/core/abihelper.go b/signer/core/abihelper.go
index 2674c7346a..1d4fbc7dc2 100644
--- a/signer/core/abihelper.go
+++ b/signer/core/abihelper.go
@@ -94,13 +94,12 @@ func parseCallData(calldata []byte, abidata string) (*decodedCallData, error) {
for n, argument := range method.Inputs {
if err != nil {
return nil, fmt.Errorf("Failed to decode argument %d (signature %v): %v", n, method.Sig(), err)
- } else {
- decodedArg := decodedArgument{
- soltype: argument,
- value: v[n],
- }
- decoded.inputs = append(decoded.inputs, decodedArg)
}
+ decodedArg := decodedArgument{
+ soltype: argument,
+ value: v[n],
+ }
+ decoded.inputs = append(decoded.inputs, decodedArg)
}
// We're finished decoding the data. At this point, we encode the decoded data to see if it matches with the
@@ -240,7 +239,7 @@ func (db *AbiDb) saveCustomAbi(selector, signature string) error {
return err
}
-// Adds a signature to the database, if custom database saving is enabled.
+// AddSignature to the database, if custom database saving is enabled.
// OBS: This method does _not_ validate the correctness of the data,
// it is assumed that the caller has already done so
func (db *AbiDb) AddSignature(selector string, data []byte) error {
diff --git a/signer/core/api.go b/signer/core/api.go
index 1387041cc3..45933284bf 100644
--- a/signer/core/api.go
+++ b/signer/core/api.go
@@ -474,7 +474,7 @@ func (api *SignerAPI) Export(ctx context.Context, addr common.Address) (json.Raw
return ioutil.ReadFile(wallet.URL().Path)
}
-// Imports tries to import the given keyJSON in the local keystore. The keyJSON data is expected to be
+// Import tries to import the given keyJSON in the local keystore. The keyJSON data is expected to be
// in web3 keystore format. It will decrypt the keyJSON with the given passphrase and on successful
// decryption it will encrypt the key with the given newPassphrase and store it in the keystore.
func (api *SignerAPI) Import(ctx context.Context, keyJSON json.RawMessage) (Account, error) {
diff --git a/signer/core/cliui.go b/signer/core/cliui.go
index 0d9b5f3d36..2f969669c2 100644
--- a/signer/core/cliui.go
+++ b/signer/core/cliui.go
@@ -13,6 +13,7 @@
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see .
+
package core
import (
diff --git a/signer/core/types.go b/signer/core/types.go
index 8386bd44e7..2acc0a4f4a 100644
--- a/signer/core/types.go
+++ b/signer/core/types.go
@@ -73,8 +73,8 @@ type SendTxArgs struct {
Input *hexutil.Bytes `json:"input"`
}
-func (t SendTxArgs) String() string {
- s, err := json.Marshal(t)
+func (args SendTxArgs) String() string {
+ s, err := json.Marshal(args)
if err == nil {
return string(s)
}
diff --git a/signer/core/validation.go b/signer/core/validation.go
index 97bb3b6850..288456df87 100644
--- a/signer/core/validation.go
+++ b/signer/core/validation.go
@@ -128,7 +128,7 @@ func (v *Validator) validate(msgs *ValidationMessages, txargs *SendTxArgs, metho
if len(data) == 0 {
if txargs.Value.ToInt().Cmp(big.NewInt(0)) > 0 {
// Sending ether into black hole
- return errors.New(`Tx will create contract with value but empty code!`)
+ return errors.New("Tx will create contract with value but empty code!")
}
// No value submitted at least
msgs.crit("Tx will create contract with empty code!")
diff --git a/signer/rules/rules.go b/signer/rules/rules.go
index fa270436df..711e2dddec 100644
--- a/signer/rules/rules.go
+++ b/signer/rules/rules.go
@@ -46,17 +46,17 @@ func consoleOutput(call otto.FunctionCall) otto.Value {
return otto.Value{}
}
-// rulesetUi provides an implementation of SignerUI that evaluates a javascript
+// rulesetUI provides an implementation of SignerUI that evaluates a javascript
// file for each defined UI-method
-type rulesetUi struct {
+type rulesetUI struct {
next core.SignerUI // The next handler, for manual processing
storage storage.Storage
credentials storage.Storage
jsRules string // The rules to use
}
-func NewRuleEvaluator(next core.SignerUI, jsbackend, credentialsBackend storage.Storage) (*rulesetUi, error) {
- c := &rulesetUi{
+func NewRuleEvaluator(next core.SignerUI, jsbackend, credentialsBackend storage.Storage) (*rulesetUI, error) {
+ c := &rulesetUI{
next: next,
storage: jsbackend,
credentials: credentialsBackend,
@@ -66,11 +66,11 @@ func NewRuleEvaluator(next core.SignerUI, jsbackend, credentialsBackend storage.
return c, nil
}
-func (r *rulesetUi) Init(javascriptRules string) error {
+func (r *rulesetUI) Init(javascriptRules string) error {
r.jsRules = javascriptRules
return nil
}
-func (r *rulesetUi) execute(jsfunc string, jsarg interface{}) (otto.Value, error) {
+func (r *rulesetUI) execute(jsfunc string, jsarg interface{}) (otto.Value, error) {
// Instantiate a fresh vm engine every time
vm := otto.New()
@@ -115,7 +115,7 @@ func (r *rulesetUi) execute(jsfunc string, jsarg interface{}) (otto.Value, error
return vm.Run(call)
}
-func (r *rulesetUi) checkApproval(jsfunc string, jsarg []byte, err error) (bool, error) {
+func (r *rulesetUI) checkApproval(jsfunc string, jsarg []byte, err error) (bool, error) {
if err != nil {
return false, err
}
@@ -139,7 +139,7 @@ func (r *rulesetUi) checkApproval(jsfunc string, jsarg []byte, err error) (bool,
return false, fmt.Errorf("Unknown response")
}
-func (r *rulesetUi) ApproveTx(request *core.SignTxRequest) (core.SignTxResponse, error) {
+func (r *rulesetUI) ApproveTx(request *core.SignTxRequest) (core.SignTxResponse, error) {
jsonreq, err := json.Marshal(request)
approved, err := r.checkApproval("ApproveTx", jsonreq, err)
if err != nil {
@@ -158,11 +158,11 @@ func (r *rulesetUi) ApproveTx(request *core.SignTxRequest) (core.SignTxResponse,
return core.SignTxResponse{Approved: false}, err
}
-func (r *rulesetUi) lookupPassword(address common.Address) string {
+func (r *rulesetUI) lookupPassword(address common.Address) string {
return r.credentials.Get(strings.ToLower(address.String()))
}
-func (r *rulesetUi) ApproveSignData(request *core.SignDataRequest) (core.SignDataResponse, error) {
+func (r *rulesetUI) ApproveSignData(request *core.SignDataRequest) (core.SignDataResponse, error) {
jsonreq, err := json.Marshal(request)
approved, err := r.checkApproval("ApproveSignData", jsonreq, err)
if err != nil {
@@ -175,7 +175,7 @@ func (r *rulesetUi) ApproveSignData(request *core.SignDataRequest) (core.SignDat
return core.SignDataResponse{Approved: false, Password: ""}, err
}
-func (r *rulesetUi) ApproveExport(request *core.ExportRequest) (core.ExportResponse, error) {
+func (r *rulesetUI) ApproveExport(request *core.ExportRequest) (core.ExportResponse, error) {
jsonreq, err := json.Marshal(request)
approved, err := r.checkApproval("ApproveExport", jsonreq, err)
if err != nil {
@@ -188,13 +188,13 @@ func (r *rulesetUi) ApproveExport(request *core.ExportRequest) (core.ExportRespo
return core.ExportResponse{Approved: false}, err
}
-func (r *rulesetUi) ApproveImport(request *core.ImportRequest) (core.ImportResponse, error) {
+func (r *rulesetUI) ApproveImport(request *core.ImportRequest) (core.ImportResponse, error) {
// This cannot be handled by rules, requires setting a password
// dispatch to next
return r.next.ApproveImport(request)
}
-func (r *rulesetUi) ApproveListing(request *core.ListRequest) (core.ListResponse, error) {
+func (r *rulesetUI) ApproveListing(request *core.ListRequest) (core.ListResponse, error) {
jsonreq, err := json.Marshal(request)
approved, err := r.checkApproval("ApproveListing", jsonreq, err)
if err != nil {
@@ -207,22 +207,22 @@ func (r *rulesetUi) ApproveListing(request *core.ListRequest) (core.ListResponse
return core.ListResponse{}, err
}
-func (r *rulesetUi) ApproveNewAccount(request *core.NewAccountRequest) (core.NewAccountResponse, error) {
+func (r *rulesetUI) ApproveNewAccount(request *core.NewAccountRequest) (core.NewAccountResponse, error) {
// This cannot be handled by rules, requires setting a password
// dispatch to next
return r.next.ApproveNewAccount(request)
}
-func (r *rulesetUi) ShowError(message string) {
+func (r *rulesetUI) ShowError(message string) {
log.Error(message)
r.next.ShowError(message)
}
-func (r *rulesetUi) ShowInfo(message string) {
+func (r *rulesetUI) ShowInfo(message string) {
log.Info(message)
r.next.ShowInfo(message)
}
-func (r *rulesetUi) OnSignerStartup(info core.StartupInfo) {
+func (r *rulesetUI) OnSignerStartup(info core.StartupInfo) {
jsonInfo, err := json.Marshal(info)
if err != nil {
log.Warn("failed marshalling data", "data", info)
@@ -235,7 +235,7 @@ func (r *rulesetUi) OnSignerStartup(info core.StartupInfo) {
}
}
-func (r *rulesetUi) OnApprovedTx(tx ethapi.SignTransactionResult) {
+func (r *rulesetUI) OnApprovedTx(tx ethapi.SignTransactionResult) {
jsonTx, err := json.Marshal(tx)
if err != nil {
log.Warn("failed marshalling transaction", "tx", tx)
diff --git a/signer/rules/rules_test.go b/signer/rules/rules_test.go
index 6a04035004..b6060eba73 100644
--- a/signer/rules/rules_test.go
+++ b/signer/rules/rules_test.go
@@ -33,18 +33,18 @@ import (
const JS = `
/**
-This is an example implementation of a Javascript rule file.
+This is an example implementation of a Javascript rule file.
-When the signer receives a request over the external API, the corresponding method is evaluated.
-Three things can happen:
+When the signer receives a request over the external API, the corresponding method is evaluated.
+Three things can happen:
-1. The method returns "Approve". This means the operation is permitted.
-2. The method returns "Reject". This means the operation is rejected.
+1. The method returns "Approve". This means the operation is permitted.
+2. The method returns "Reject". This means the operation is rejected.
3. Anything else; other return values [*], method not implemented or exception occurred during processing. This means
-that the operation will continue to manual processing, via the regular UI method chosen by the user.
+that the operation will continue to manual processing, via the regular UI method chosen by the user.
-[*] Note: Future version of the ruleset may use more complex json-based returnvalues, making it possible to not
-only respond Approve/Reject/Manual, but also modify responses. For example, choose to list only one, but not all
+[*] Note: Future version of the ruleset may use more complex json-based returnvalues, making it possible to not
+only respond Approve/Reject/Manual, but also modify responses. For example, choose to list only one, but not all
accounts in a list-request. The points above will continue to hold for non-json based responses ("Approve"/"Reject").
**/
@@ -72,49 +72,49 @@ func mixAddr(a string) (*common.MixedcaseAddress, error) {
return common.NewMixedcaseAddressFromString(a)
}
-type alwaysDenyUi struct{}
+type alwaysDenyUI struct{}
-func (alwaysDenyUi) OnSignerStartup(info core.StartupInfo) {
+func (alwaysDenyUI) OnSignerStartup(info core.StartupInfo) {
}
-func (alwaysDenyUi) ApproveTx(request *core.SignTxRequest) (core.SignTxResponse, error) {
+func (alwaysDenyUI) ApproveTx(request *core.SignTxRequest) (core.SignTxResponse, error) {
return core.SignTxResponse{Transaction: request.Transaction, Approved: false, Password: ""}, nil
}
-func (alwaysDenyUi) ApproveSignData(request *core.SignDataRequest) (core.SignDataResponse, error) {
+func (alwaysDenyUI) ApproveSignData(request *core.SignDataRequest) (core.SignDataResponse, error) {
return core.SignDataResponse{Approved: false, Password: ""}, nil
}
-func (alwaysDenyUi) ApproveExport(request *core.ExportRequest) (core.ExportResponse, error) {
+func (alwaysDenyUI) ApproveExport(request *core.ExportRequest) (core.ExportResponse, error) {
return core.ExportResponse{Approved: false}, nil
}
-func (alwaysDenyUi) ApproveImport(request *core.ImportRequest) (core.ImportResponse, error) {
+func (alwaysDenyUI) ApproveImport(request *core.ImportRequest) (core.ImportResponse, error) {
return core.ImportResponse{Approved: false, OldPassword: "", NewPassword: ""}, nil
}
-func (alwaysDenyUi) ApproveListing(request *core.ListRequest) (core.ListResponse, error) {
+func (alwaysDenyUI) ApproveListing(request *core.ListRequest) (core.ListResponse, error) {
return core.ListResponse{Accounts: nil}, nil
}
-func (alwaysDenyUi) ApproveNewAccount(request *core.NewAccountRequest) (core.NewAccountResponse, error) {
+func (alwaysDenyUI) ApproveNewAccount(request *core.NewAccountRequest) (core.NewAccountResponse, error) {
return core.NewAccountResponse{Approved: false, Password: ""}, nil
}
-func (alwaysDenyUi) ShowError(message string) {
+func (alwaysDenyUI) ShowError(message string) {
panic("implement me")
}
-func (alwaysDenyUi) ShowInfo(message string) {
+func (alwaysDenyUI) ShowInfo(message string) {
panic("implement me")
}
-func (alwaysDenyUi) OnApprovedTx(tx ethapi.SignTransactionResult) {
+func (alwaysDenyUI) OnApprovedTx(tx ethapi.SignTransactionResult) {
panic("implement me")
}
-func initRuleEngine(js string) (*rulesetUi, error) {
- r, err := NewRuleEvaluator(&alwaysDenyUi{}, storage.NewEphemeralStorage(), storage.NewEphemeralStorage())
+func initRuleEngine(js string) (*rulesetUI, error) {
+ r, err := NewRuleEvaluator(&alwaysDenyUI{}, storage.NewEphemeralStorage(), storage.NewEphemeralStorage())
if err != nil {
return nil, fmt.Errorf("failed to create js engine: %v", err)
}
@@ -196,59 +196,59 @@ func TestSignTxRequest(t *testing.T) {
}
}
-type dummyUi struct {
+type dummyUI struct {
calls []string
}
-func (d *dummyUi) ApproveTx(request *core.SignTxRequest) (core.SignTxResponse, error) {
+func (d *dummyUI) ApproveTx(request *core.SignTxRequest) (core.SignTxResponse, error) {
d.calls = append(d.calls, "ApproveTx")
return core.SignTxResponse{}, core.ErrRequestDenied
}
-func (d *dummyUi) ApproveSignData(request *core.SignDataRequest) (core.SignDataResponse, error) {
+func (d *dummyUI) ApproveSignData(request *core.SignDataRequest) (core.SignDataResponse, error) {
d.calls = append(d.calls, "ApproveSignData")
return core.SignDataResponse{}, core.ErrRequestDenied
}
-func (d *dummyUi) ApproveExport(request *core.ExportRequest) (core.ExportResponse, error) {
+func (d *dummyUI) ApproveExport(request *core.ExportRequest) (core.ExportResponse, error) {
d.calls = append(d.calls, "ApproveExport")
return core.ExportResponse{}, core.ErrRequestDenied
}
-func (d *dummyUi) ApproveImport(request *core.ImportRequest) (core.ImportResponse, error) {
+func (d *dummyUI) ApproveImport(request *core.ImportRequest) (core.ImportResponse, error) {
d.calls = append(d.calls, "ApproveImport")
return core.ImportResponse{}, core.ErrRequestDenied
}
-func (d *dummyUi) ApproveListing(request *core.ListRequest) (core.ListResponse, error) {
+func (d *dummyUI) ApproveListing(request *core.ListRequest) (core.ListResponse, error) {
d.calls = append(d.calls, "ApproveListing")
return core.ListResponse{}, core.ErrRequestDenied
}
-func (d *dummyUi) ApproveNewAccount(request *core.NewAccountRequest) (core.NewAccountResponse, error) {
+func (d *dummyUI) ApproveNewAccount(request *core.NewAccountRequest) (core.NewAccountResponse, error) {
d.calls = append(d.calls, "ApproveNewAccount")
return core.NewAccountResponse{}, core.ErrRequestDenied
}
-func (d *dummyUi) ShowError(message string) {
+func (d *dummyUI) ShowError(message string) {
d.calls = append(d.calls, "ShowError")
}
-func (d *dummyUi) ShowInfo(message string) {
+func (d *dummyUI) ShowInfo(message string) {
d.calls = append(d.calls, "ShowInfo")
}
-func (d *dummyUi) OnApprovedTx(tx ethapi.SignTransactionResult) {
+func (d *dummyUI) OnApprovedTx(tx ethapi.SignTransactionResult) {
d.calls = append(d.calls, "OnApprovedTx")
}
-func (d *dummyUi) OnSignerStartup(info core.StartupInfo) {
+func (d *dummyUI) OnSignerStartup(info core.StartupInfo) {
}
//TestForwarding tests that the rule-engine correctly dispatches requests to the next caller
func TestForwarding(t *testing.T) {
js := ""
- ui := &dummyUi{make([]string, 0)}
+ ui := &dummyUI{make([]string, 0)}
jsBackend := storage.NewEphemeralStorage()
credBackend := storage.NewEphemeralStorage()
r, err := NewRuleEvaluator(ui, jsBackend, credBackend)
@@ -308,22 +308,22 @@ func TestStorage(t *testing.T) {
function testStorage(){
storage.Put("mykey", "myvalue")
a = storage.Get("mykey")
-
+
storage.Put("mykey", ["a", "list"]) // Should result in "a,list"
a += storage.Get("mykey")
-
+
storage.Put("mykey", {"an": "object"}) // Should result in "[object Object]"
a += storage.Get("mykey")
-
+
storage.Put("mykey", JSON.stringify({"an": "object"})) // Should result in '{"an":"object"}'
a += storage.Get("mykey")
a += storage.Get("missingkey") //Missing keys should result in empty string
storage.Put("","missing key==noop") // Can't store with 0-length key
a += storage.Get("") // Should result in ''
-
+
var b = new BigNumber(2)
var c = new BigNumber(16)//"0xf0",16)
var d = b.plus(c)
@@ -361,7 +361,7 @@ const ExampleTxWindow = `
if(str.slice(0,2) == "0x"){ return new BigNumber(str.slice(2),16)}
return new BigNumber(str)
}
-
+
// Time window: 1 week
var window = 1000* 3600*24*7;
@@ -370,7 +370,7 @@ const ExampleTxWindow = `
function isLimitOk(transaction){
var value = big(transaction.value)
- // Start of our window function
+ // Start of our window function
var windowstart = new Date().getTime() - window;
var txs = [];
@@ -382,17 +382,17 @@ const ExampleTxWindow = `
// First, remove all that have passed out of the time-window
var newtxs = txs.filter(function(tx){return tx.tstamp > windowstart});
console.log(txs, newtxs.length);
-
+
// Secondly, aggregate the current sum
sum = new BigNumber(0)
sum = newtxs.reduce(function(agg, tx){ return big(tx.value).plus(agg)}, sum);
console.log("ApproveTx > Sum so far", sum);
console.log("ApproveTx > Requested", value.toNumber());
-
+
// Would we exceed weekly limit ?
return sum.plus(value).lt(limit)
-
+
}
function ApproveTx(r){
console.log(r)
@@ -405,14 +405,14 @@ const ExampleTxWindow = `
/**
* OnApprovedTx(str) is called when a transaction has been approved and signed. The parameter
- * 'response_str' contains the return value that will be sent to the external caller.
- * The return value from this method is ignore - the reason for having this callback is to allow the
- * ruleset to keep track of approved transactions.
+ * 'response_str' contains the return value that will be sent to the external caller.
+ * The return value from this method is ignore - the reason for having this callback is to allow the
+ * ruleset to keep track of approved transactions.
*
- * When implementing rate-limited rules, this callback should be used.
+ * When implementing rate-limited rules, this callback should be used.
* If a rule responds with neither 'Approve' nor 'Reject' - the tx goes to manual processing. If the user
* then accepts the transaction, this method will be called.
- *
+ *
* TLDR; Use this method to keep track of signed transactions, instead of using the data in ApproveTx.
*/
function OnApprovedTx(resp){
diff --git a/signer/storage/aes_gcm_storage.go b/signer/storage/aes_gcm_storage.go
index 1ac3475588..225276667f 100644
--- a/signer/storage/aes_gcm_storage.go
+++ b/signer/storage/aes_gcm_storage.go
@@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see .
//
+
package storage
import (
@@ -106,10 +107,8 @@ func (s *AESEncryptedStorage) readEncryptedStorage() (map[string]storedCredentia
if os.IsNotExist(err) {
// Doesn't exist yet
return creds, nil
-
- } else {
- log.Warn("Failed to read encrypted storage", "err", err, "file", s.filename)
}
+ log.Warn("Failed to read encrypted storage", "err", err, "file", s.filename)
}
if err = json.Unmarshal(raw, &creds); err != nil {
log.Warn("Failed to unmarshal encrypted storage", "err", err, "file", s.filename)
diff --git a/whisper/mailserver/mailserver.go b/whisper/mailserver/mailserver.go
index 57e6505ad1..d32eaddec3 100644
--- a/whisper/mailserver/mailserver.go
+++ b/whisper/mailserver/mailserver.go
@@ -20,7 +20,6 @@ import (
"encoding/binary"
"fmt"
- "github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
@@ -54,19 +53,19 @@ func NewDbKey(t uint32, h common.Hash) *DBKey {
return &k
}
-func (s *WMailServer) Init(shh *whisper.Whisper, path string, password string, pow float64) {
+func (s *WMailServer) Init(shh *whisper.Whisper, path string, password string, pow float64) error {
var err error
if len(path) == 0 {
- utils.Fatalf("DB file is not specified")
+ return fmt.Errorf("DB file is not specified")
}
if len(password) == 0 {
- utils.Fatalf("Password is not specified for MailServer")
+ return fmt.Errorf("password is not specified")
}
s.db, err = leveldb.OpenFile(path, nil)
if err != nil {
- utils.Fatalf("Failed to open DB file: %s", err)
+ return fmt.Errorf("open DB file: %s", err)
}
s.w = shh
@@ -74,12 +73,13 @@ func (s *WMailServer) Init(shh *whisper.Whisper, path string, password string, p
MailServerKeyID, err := s.w.AddSymKeyFromPassword(password)
if err != nil {
- utils.Fatalf("Failed to create symmetric key for MailServer: %s", err)
+ return fmt.Errorf("create symmetric key: %s", err)
}
s.key, err = s.w.GetSymKey(MailServerKeyID)
if err != nil {
- utils.Fatalf("Failed to save symmetric key for MailServer")
+ return fmt.Errorf("save symmetric key: %s", err)
}
+ return nil
}
func (s *WMailServer) Close() {
diff --git a/whisper/mailserver/server_test.go b/whisper/mailserver/server_test.go
index d5b993afb9..edb817cc75 100644
--- a/whisper/mailserver/server_test.go
+++ b/whisper/mailserver/server_test.go
@@ -92,7 +92,10 @@ func TestMailServer(t *testing.T) {
shh = whisper.New(&whisper.DefaultConfig)
shh.RegisterServer(&server)
- server.Init(shh, dir, password, powRequirement)
+ err = server.Init(shh, dir, password, powRequirement)
+ if err != nil {
+ t.Fatal(err)
+ }
defer server.Close()
keyID, err = shh.AddSymKeyFromPassword(password)