mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 18:02:24 +00:00
add method supportsCodeQuery
This commit is contained in:
parent
56775c5682
commit
2a3b498b7c
1 changed files with 41 additions and 9 deletions
|
|
@ -48,17 +48,24 @@ type Reader interface {
|
||||||
// - The returned storage slot is safe to modify after the call
|
// - The returned storage slot is safe to modify after the call
|
||||||
Storage(addr common.Address, slot common.Hash) (common.Hash, error)
|
Storage(addr common.Address, slot common.Hash) (common.Hash, error)
|
||||||
|
|
||||||
// ContractCode returns the code associated with a particular account.
|
// ContractCode returns the code associated with the given code hash.
|
||||||
//
|
//
|
||||||
// - It returns an error to indicate code doesn't exist
|
// - It returns an error to indicate code doesn't exist or is empty
|
||||||
// - The returned code is safe to modify after the call
|
// - The returned code is safe to modify after the call
|
||||||
ContractCode(addr common.Address, codeHash common.Hash) ([]byte, error)
|
ContractCode(addr common.Address, codeHash common.Hash) ([]byte, error)
|
||||||
|
|
||||||
// ContractCodeSize returns the size of the code associated with a particular account.
|
// ContractCodeSize returns the size of the code associated with the given code hash.
|
||||||
//
|
//
|
||||||
// - It returns an error to indicate code doesn't exist
|
// - It returns an error to indicate code doesn't exist
|
||||||
ContractCodeSize(addr common.Address, codeHash common.Hash) (int, error)
|
ContractCodeSize(addr common.Address, codeHash common.Hash) (int, error)
|
||||||
|
|
||||||
|
// SupportsCodeQuery returns true if the reader supports querying contract code. Right now
|
||||||
|
// the trie reader supports querying contract code but the state reader doesn't. This is
|
||||||
|
// technically an arbitrary distinction as code is not stored either in the snapshot or trie
|
||||||
|
// per se. Important point is that one of them implements the code query to avoid double-lookups
|
||||||
|
// for non-existent code.
|
||||||
|
SupportsCodeQuery() bool
|
||||||
|
|
||||||
// Copy returns a deep-copied state reader.
|
// Copy returns a deep-copied state reader.
|
||||||
Copy() Reader
|
Copy() Reader
|
||||||
}
|
}
|
||||||
|
|
@ -144,6 +151,12 @@ func (r *stateReader) ContractCodeSize(addr common.Address, codeHash common.Hash
|
||||||
return 0, errors.New("not supported")
|
return 0, errors.New("not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SupportsCodeQuery implements Reader, returning false as the state reader
|
||||||
|
// doesn't support querying contract code.
|
||||||
|
func (r *stateReader) SupportsCodeQuery() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// Copy implements Reader, returning a deep-copied snap reader.
|
// Copy implements Reader, returning a deep-copied snap reader.
|
||||||
func (r *stateReader) Copy() Reader {
|
func (r *stateReader) Copy() Reader {
|
||||||
return &stateReader{
|
return &stateReader{
|
||||||
|
|
@ -260,6 +273,12 @@ func (r *trieReader) ContractCodeSize(addr common.Address, codeHash common.Hash)
|
||||||
return r.contractDB.ContractCodeSize(addr, codeHash)
|
return r.contractDB.ContractCodeSize(addr, codeHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SupportsCodeQuery implements Reader, returning true as the trie reader
|
||||||
|
// supports querying contract code.
|
||||||
|
func (r *trieReader) SupportsCodeQuery() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// Copy implements Reader, returning a deep-copied trie reader.
|
// Copy implements Reader, returning a deep-copied trie reader.
|
||||||
func (r *trieReader) Copy() Reader {
|
func (r *trieReader) Copy() Reader {
|
||||||
tries := make(map[common.Address]Trie)
|
tries := make(map[common.Address]Trie)
|
||||||
|
|
@ -336,9 +355,7 @@ func (r *multiReader) Storage(addr common.Address, slot common.Hash) (common.Has
|
||||||
func (r *multiReader) ContractCode(addr common.Address, codeHash common.Hash) ([]byte, error) {
|
func (r *multiReader) ContractCode(addr common.Address, codeHash common.Hash) ([]byte, error) {
|
||||||
var errs []error
|
var errs []error
|
||||||
for _, reader := range r.readers {
|
for _, reader := range r.readers {
|
||||||
// Skip state reader as it doesn't provide contract code and
|
if reader.SupportsCodeQuery() {
|
||||||
// always returns an error.
|
|
||||||
if _, ok := reader.(*trieReader); ok {
|
|
||||||
code, err := reader.ContractCode(addr, codeHash)
|
code, err := reader.ContractCode(addr, codeHash)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return code, nil
|
return code, nil
|
||||||
|
|
@ -346,6 +363,9 @@ func (r *multiReader) ContractCode(addr common.Address, codeHash common.Hash) ([
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(errs) == 0 {
|
||||||
|
return nil, errors.New("not found")
|
||||||
|
}
|
||||||
return nil, errors.Join(errs...)
|
return nil, errors.Join(errs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -353,9 +373,7 @@ func (r *multiReader) ContractCode(addr common.Address, codeHash common.Hash) ([
|
||||||
func (r *multiReader) ContractCodeSize(addr common.Address, codeHash common.Hash) (int, error) {
|
func (r *multiReader) ContractCodeSize(addr common.Address, codeHash common.Hash) (int, error) {
|
||||||
var errs []error
|
var errs []error
|
||||||
for _, reader := range r.readers {
|
for _, reader := range r.readers {
|
||||||
// Skip state reader as it doesn't provide contract code and
|
if reader.SupportsCodeQuery() {
|
||||||
// always returns an error.
|
|
||||||
if _, ok := reader.(*trieReader); ok {
|
|
||||||
size, err := reader.ContractCodeSize(addr, codeHash)
|
size, err := reader.ContractCodeSize(addr, codeHash)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return size, nil
|
return size, nil
|
||||||
|
|
@ -363,9 +381,23 @@ func (r *multiReader) ContractCodeSize(addr common.Address, codeHash common.Hash
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(errs) == 0 {
|
||||||
|
return 0, errors.New("not found")
|
||||||
|
}
|
||||||
return 0, errors.Join(errs...)
|
return 0, errors.Join(errs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SupportsCodeQuery implements Reader, returning true if the reader supports querying contract code.
|
||||||
|
func (r *multiReader) SupportsCodeQuery() bool {
|
||||||
|
// Return true if one of readers supports querying contract code.
|
||||||
|
for _, reader := range r.readers {
|
||||||
|
if reader.SupportsCodeQuery() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// Copy implementing Reader interface, returning a deep-copied state reader.
|
// Copy implementing Reader interface, returning a deep-copied state reader.
|
||||||
func (r *multiReader) Copy() Reader {
|
func (r *multiReader) Copy() Reader {
|
||||||
var readers []Reader
|
var readers []Reader
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue