Merge pull request #24117 from holiman/db_has

trie, core, eth: use db.has over db.get where possible
pull/24205/head
Péter Szilágyi 3 years ago committed by GitHub
commit af2ca5a654
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      cmd/geth/snapshot.go
  2. 14
      core/rawdb/accessors_state.go
  3. 4
      eth/protocols/snap/sync.go
  4. 7
      trie/sync.go

@ -418,8 +418,7 @@ func traverseRawState(ctx *cli.Context) error {
// Check the present for non-empty hash node(embedded node doesn't // Check the present for non-empty hash node(embedded node doesn't
// have their own hash). // have their own hash).
if node != (common.Hash{}) { if node != (common.Hash{}) {
blob := rawdb.ReadTrieNode(chaindb, node) if !rawdb.HasTrieNode(chaindb, node) {
if len(blob) == 0 {
log.Error("Missing trie node(storage)", "hash", node) log.Error("Missing trie node(storage)", "hash", node)
return errors.New("missing storage") return errors.New("missing storage")
} }

@ -61,6 +61,14 @@ func ReadCodeWithPrefix(db ethdb.KeyValueReader, hash common.Hash) []byte {
return data return data
} }
// HasCodeWithPrefix checks if the contract code corresponding to the
// provided code hash is present in the db. This function will only check
// presence using the prefix-scheme.
func HasCodeWithPrefix(db ethdb.KeyValueReader, hash common.Hash) bool {
ok, _ := db.Has(codeKey(hash))
return ok
}
// WriteCode writes the provided contract code database. // WriteCode writes the provided contract code database.
func WriteCode(db ethdb.KeyValueWriter, hash common.Hash, code []byte) { func WriteCode(db ethdb.KeyValueWriter, hash common.Hash, code []byte) {
if err := db.Put(codeKey(hash), code); err != nil { if err := db.Put(codeKey(hash), code); err != nil {
@ -81,6 +89,12 @@ func ReadTrieNode(db ethdb.KeyValueReader, hash common.Hash) []byte {
return data return data
} }
// HasTrieNode checks if the trie node with the provided hash is present in db.
func HasTrieNode(db ethdb.KeyValueReader, hash common.Hash) bool {
ok, _ := db.Has(hash.Bytes())
return ok
}
// WriteTrieNode writes the provided trie node database. // WriteTrieNode writes the provided trie node database.
func WriteTrieNode(db ethdb.KeyValueWriter, hash common.Hash, node []byte) { func WriteTrieNode(db ethdb.KeyValueWriter, hash common.Hash, node []byte) {
if err := db.Put(hash.Bytes(), node); err != nil { if err := db.Put(hash.Bytes(), node); err != nil {

@ -1781,7 +1781,7 @@ func (s *Syncer) processAccountResponse(res *accountResponse) {
for i, account := range res.accounts { for i, account := range res.accounts {
// Check if the account is a contract with an unknown code // Check if the account is a contract with an unknown code
if !bytes.Equal(account.CodeHash, emptyCode[:]) { if !bytes.Equal(account.CodeHash, emptyCode[:]) {
if code := rawdb.ReadCodeWithPrefix(s.db, common.BytesToHash(account.CodeHash)); code == nil { if !rawdb.HasCodeWithPrefix(s.db, common.BytesToHash(account.CodeHash)) {
res.task.codeTasks[common.BytesToHash(account.CodeHash)] = struct{}{} res.task.codeTasks[common.BytesToHash(account.CodeHash)] = struct{}{}
res.task.needCode[i] = true res.task.needCode[i] = true
res.task.pend++ res.task.pend++
@ -1789,7 +1789,7 @@ func (s *Syncer) processAccountResponse(res *accountResponse) {
} }
// Check if the account is a contract with an unknown storage trie // Check if the account is a contract with an unknown storage trie
if account.Root != emptyRoot { if account.Root != emptyRoot {
if node, err := s.db.Get(account.Root[:]); err != nil || node == nil { if ok, err := s.db.Has(account.Root[:]); err != nil || !ok {
// If there was a previous large state retrieval in progress, // If there was a previous large state retrieval in progress,
// don't restart it from scratch. This happens if a sync cycle // don't restart it from scratch. This happens if a sync cycle
// is interrupted and resumed later. However, *do* update the // is interrupted and resumed later. However, *do* update the

@ -155,8 +155,7 @@ func (s *Sync) AddSubTrie(root common.Hash, path []byte, parent common.Hash, cal
} }
// If database says this is a duplicate, then at least the trie node is // If database says this is a duplicate, then at least the trie node is
// present, and we hold the assumption that it's NOT legacy contract code. // present, and we hold the assumption that it's NOT legacy contract code.
blob := rawdb.ReadTrieNode(s.database, root) if rawdb.HasTrieNode(s.database, root) {
if len(blob) > 0 {
return return
} }
// Assemble the new sub-trie sync request // Assemble the new sub-trie sync request
@ -193,7 +192,7 @@ func (s *Sync) AddCodeEntry(hash common.Hash, path []byte, parent common.Hash) {
// sync is expected to run with a fresh new node. Even there // sync is expected to run with a fresh new node. Even there
// exists the code with legacy format, fetch and store with // exists the code with legacy format, fetch and store with
// new scheme anyway. // new scheme anyway.
if blob := rawdb.ReadCodeWithPrefix(s.database, hash); len(blob) > 0 { if rawdb.HasCodeWithPrefix(s.database, hash) {
return return
} }
// Assemble the new sub-trie sync request // Assemble the new sub-trie sync request
@ -401,7 +400,7 @@ func (s *Sync) children(req *request, object node) ([]*request, error) {
} }
// If database says duplicate, then at least the trie node is present // If database says duplicate, then at least the trie node is present
// and we hold the assumption that it's NOT legacy contract code. // and we hold the assumption that it's NOT legacy contract code.
if blob := rawdb.ReadTrieNode(s.database, hash); len(blob) > 0 { if rawdb.HasTrieNode(s.database, hash) {
continue continue
} }
// Locally unknown node, schedule for retrieval // Locally unknown node, schedule for retrieval

Loading…
Cancel
Save