From 8754278d180c9a6ef97375311de6fa3e47dcd311 Mon Sep 17 00:00:00 2001 From: i-norden Date: Tue, 28 Feb 2023 11:43:07 -0600 Subject: [PATCH] implement database.StateAccount() --- database.go | 20 +++++++++++++++++++- sql.go | 17 ++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/database.go b/database.go index 5ec8fdd..28ca7f8 100644 --- a/database.go +++ b/database.go @@ -3,6 +3,8 @@ package ipld_eth_statedb import ( "context" "errors" + "github.com/ethereum/go-ethereum/crypto" + "math/big" "github.com/VictoriaMetrics/fastcache" "github.com/ethereum/go-ethereum/common" @@ -81,7 +83,23 @@ func (sd *stateDatabase) ContractCodeSize(_, codeHash common.Hash) (int, error) } func (sd *stateDatabase) StateAccount(address common.Address) (*types.StateAccount, error) { - panic("implement me") + res := StateAccountResult{} + key := crypto.Keccak256Hash(address.Bytes()) + if err := sd.pgdb.QueryRow(context.Background(), GetStateAccount, key.Hex()).Scan(&res); err != nil { + return nil, errNotFound + } + if res.Removed { + // TODO: check expected behavior for deleted/non existing accounts + return nil, nil + } + bal := new(big.Int) + bal.SetString(res.Balance, 10) + return &types.StateAccount{ + Nonce: res.Nonce, + Balance: bal, + Root: common.HexToHash(res.StorageRoot), + CodeHash: res.CodeHash, + }, nil } func (sd *stateDatabase) StorageSlot(addressHash, slotHash common.Hash) ([]byte, error) { diff --git a/sql.go b/sql.go index 9d62626..c929d45 100644 --- a/sql.go +++ b/sql.go @@ -14,7 +14,7 @@ const ( AND header_cids.block_hash = (SELECT canonical_header_hash(header_cids.block_number)) ORDER BY header_cids.block_number DESC LIMIT 1` - GetStorageSlot = `SELECT value, removed FROM eth.storage_cids + GetStorageSlot = `SELECT val, removed FROM eth.storage_cids INNER JOIN eth.header_cids ON ( storage_cids.header_id = header_cids.block_hash AND storage_cids.block_number = header_cids.block_number @@ -25,3 +25,18 @@ const ( ORDER BY header_cids.block_number DESC LIMIT 1` ) + +// StorageSlotResult struct for unpacking GetStorageSlot result +type StorageSlotResult struct { + Value string `db:"val"` + Removed bool `db:"removed"` +} + +// StateAccountResult struct for unpacking GetStateAccount result +type StateAccountResult struct { + Balance string `db:"balance"` + Nonce uint64 `db:"nonce"` + CodeHash []byte `db:"code_hash"` + StorageRoot string `db:"storage_root"` + Removed bool `db:"removed"` +}