Merge pull request #7 from cerc-io/ian/v5
Use `get_storage_at` procedures
This commit is contained in:
commit
c09bc65a92
@ -123,11 +123,11 @@ func (sd *stateDatabase) StorageValue(addressHash, slotHash, blockHash common.Ha
|
||||
res := StorageSlotResult{}
|
||||
err := sd.pgdb.QueryRow(context.Background(), GetStorageSlot,
|
||||
addressHash.Hex(), slotHash.Hex(), blockHash.Hex()).
|
||||
Scan(&res.Value, &res.Removed)
|
||||
Scan(&res.Value, &res.Removed, &res.StateLeafRemoved)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if res.Removed {
|
||||
if res.Removed || res.StateLeafRemoved {
|
||||
// TODO: check expected behavior for deleted/non existing accounts
|
||||
return nil, nil
|
||||
}
|
||||
|
19
sql.go
19
sql.go
@ -14,25 +14,14 @@ 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 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
|
||||
)
|
||||
WHERE state_leaf_key = $1
|
||||
AND storage_leaf_key = $2
|
||||
AND header_cids.block_number <= (SELECT block_number
|
||||
FROM eth.header_cids
|
||||
WHERE block_hash = $3)
|
||||
AND header_cids.block_hash = (SELECT canonical_header_hash(header_cids.block_number))
|
||||
ORDER BY header_cids.block_number DESC
|
||||
LIMIT 1`
|
||||
GetStorageSlot = `SELECT val, removed, state_leaf_removed FROM get_storage_at_by_hash($1, $2, $3)`
|
||||
)
|
||||
|
||||
// StorageSlotResult struct for unpacking GetStorageSlot result
|
||||
type StorageSlotResult struct {
|
||||
Value []byte `db:"val"`
|
||||
Removed bool `db:"removed"`
|
||||
Value []byte `db:"val"`
|
||||
Removed bool `db:"removed"`
|
||||
StateLeafRemoved bool `db:"state_leaf_removed"`
|
||||
}
|
||||
|
||||
// StateAccountResult struct for unpacking GetStateAccount result
|
||||
|
181
statedb_test.go
181
statedb_test.go
@ -28,12 +28,19 @@ var (
|
||||
BlockNumber = big.NewInt(1337)
|
||||
Header = types.Header{Number: BlockNumber}
|
||||
BlockHash = Header.Hash()
|
||||
BlockHash2 = crypto.Keccak256Hash([]byte("I am a random hash"))
|
||||
BlockNumber2 = BlockNumber.Uint64() + 1
|
||||
BlockHash3 = crypto.Keccak256Hash([]byte("I am another random hash"))
|
||||
BlockNumber3 = BlockNumber.Uint64() + 2
|
||||
BlockHash4 = crypto.Keccak256Hash([]byte("I am"))
|
||||
BlockNumber4 = BlockNumber.Uint64() + 3
|
||||
BlockHash5 = crypto.Keccak256Hash([]byte("I"))
|
||||
BlockNumber5 = BlockNumber.Uint64() + 4
|
||||
BlockParentHash = common.HexToHash("0123456701234567012345670123456701234567012345670123456701234567")
|
||||
|
||||
AccountPK, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
|
||||
AccountAddress = crypto.PubkeyToAddress(AccountPK.PublicKey) //0x703c4b2bD70c169f5717101CaeE543299Fc946C7
|
||||
AccountLeafKey = crypto.Keccak256Hash(AccountAddress.Bytes())
|
||||
AccountPath = []byte{AccountLeafKey[0] & 0xf0} // first nibble of path
|
||||
|
||||
AccountCode = []byte{0, 1, 2, 3, 4, 5, 6, 7}
|
||||
AccountCodeHash = crypto.Keccak256Hash(AccountCode)
|
||||
@ -58,9 +65,13 @@ var (
|
||||
AccountCID, _ = ipld.RawdataToCid(ipld.MEthStateTrie, accountAndLeafRLP, multihash.KECCAK_256)
|
||||
AccountCodeCID, _ = util.Keccak256ToCid(ipld.RawBinary, AccountCodeHash.Bytes())
|
||||
|
||||
StoredValueRLP, _ = rlp.EncodeToBytes(StoredValue)
|
||||
StorageRLP, _ = rlp.EncodeToBytes(&[]interface{}{StoragePartialPath, StoredValueRLP})
|
||||
StorageCID, _ = ipld.RawdataToCid(ipld.MEthStorageTrie, StorageRLP, multihash.KECCAK_256)
|
||||
StoredValueRLP, _ = rlp.EncodeToBytes(StoredValue)
|
||||
StoredValueRLP2, _ = rlp.EncodeToBytes("something")
|
||||
StorageRLP, _ = rlp.EncodeToBytes(&[]interface{}{StoragePartialPath, StoredValueRLP})
|
||||
StorageCID, _ = ipld.RawdataToCid(ipld.MEthStorageTrie, StorageRLP, multihash.KECCAK_256)
|
||||
|
||||
RemovedNodeStateCID = "baglacgzayxjemamg64rtzet6pwznzrydydsqbnstzkbcoo337lmaixmfurya"
|
||||
RemovedNodeStorageCID = "bagmacgzayxjemamg64rtzet6pwznzrydydsqbnstzkbcoo337lmaixmfurya"
|
||||
)
|
||||
|
||||
func TestSuite(t *testing.T) {
|
||||
@ -87,9 +98,61 @@ func TestSuite(t *testing.T) {
|
||||
require.NoError(t, tx.Commit(testCtx))
|
||||
})
|
||||
|
||||
require.NoError(t, insertHeaderCID(pool))
|
||||
require.NoError(t, insertStateCID(pool))
|
||||
require.NoError(t, insertStorageCID(pool))
|
||||
require.NoError(t, insertHeaderCID(pool, BlockHash.String(), BlockNumber.Uint64()))
|
||||
require.NoError(t, insertHeaderCID(pool, BlockHash2.String(), BlockNumber2))
|
||||
require.NoError(t, insertHeaderCID(pool, BlockHash3.String(), BlockNumber3))
|
||||
require.NoError(t, insertHeaderCID(pool, BlockHash4.String(), BlockNumber4))
|
||||
require.NoError(t, insertHeaderCID(pool, BlockHash5.String(), BlockNumber5))
|
||||
require.NoError(t, insertStateCID(pool, stateModel{
|
||||
BlockNumber: BlockNumber.Uint64(),
|
||||
BlockHash: BlockHash.String(),
|
||||
LeafKey: AccountLeafKey.String(),
|
||||
CID: AccountCID.String(),
|
||||
Diff: true,
|
||||
Balance: Account.Balance.Uint64(),
|
||||
Nonce: Account.Nonce,
|
||||
CodeHash: AccountCodeHash.String(),
|
||||
StorageRoot: Account.Root.String(),
|
||||
Removed: false,
|
||||
}))
|
||||
require.NoError(t, insertStateCID(pool, stateModel{
|
||||
BlockNumber: BlockNumber5,
|
||||
BlockHash: BlockHash5.String(),
|
||||
LeafKey: AccountLeafKey.String(),
|
||||
CID: RemovedNodeStateCID,
|
||||
Diff: true,
|
||||
Removed: true,
|
||||
}))
|
||||
require.NoError(t, insertStorageCID(pool, storageModel{
|
||||
BlockNumber: BlockNumber.Uint64(),
|
||||
BlockHash: BlockHash.String(),
|
||||
LeafKey: AccountLeafKey.String(),
|
||||
StorageLeafKey: StorageLeafKey.String(),
|
||||
StorageCID: StorageCID.String(),
|
||||
Diff: true,
|
||||
Value: StoredValueRLP,
|
||||
Removed: false,
|
||||
}))
|
||||
require.NoError(t, insertStorageCID(pool, storageModel{
|
||||
BlockNumber: BlockNumber2,
|
||||
BlockHash: BlockHash2.String(),
|
||||
LeafKey: AccountLeafKey.String(),
|
||||
StorageLeafKey: StorageLeafKey.String(),
|
||||
StorageCID: RemovedNodeStorageCID,
|
||||
Diff: true,
|
||||
Value: []byte{},
|
||||
Removed: true,
|
||||
}))
|
||||
require.NoError(t, insertStorageCID(pool, storageModel{
|
||||
BlockNumber: BlockNumber3,
|
||||
BlockHash: BlockHash3.String(),
|
||||
LeafKey: AccountLeafKey.String(),
|
||||
StorageLeafKey: StorageLeafKey.String(),
|
||||
StorageCID: StorageCID.String(),
|
||||
Diff: true,
|
||||
Value: StoredValueRLP2,
|
||||
Removed: false,
|
||||
}))
|
||||
require.NoError(t, insertContractCode(pool))
|
||||
|
||||
db, err := statedb.NewStateDatabaseWithPool(pool)
|
||||
@ -108,9 +171,41 @@ func TestSuite(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, &Account, acct)
|
||||
|
||||
acct2, err := db.StateAccount(AccountLeafKey, BlockHash2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, &Account, acct2)
|
||||
|
||||
acct3, err := db.StateAccount(AccountLeafKey, BlockHash3)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, &Account, acct3)
|
||||
|
||||
acct4, err := db.StateAccount(AccountLeafKey, BlockHash4)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, &Account, acct4)
|
||||
|
||||
acct5, err := db.StateAccount(AccountLeafKey, BlockHash5)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, acct5)
|
||||
|
||||
val, err := db.StorageValue(AccountLeafKey, StorageLeafKey, BlockHash)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, StoredValueRLP, val)
|
||||
|
||||
val2, err := db.StorageValue(AccountLeafKey, StorageLeafKey, BlockHash2)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, val2)
|
||||
|
||||
val3, err := db.StorageValue(AccountLeafKey, StorageLeafKey, BlockHash3)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, StoredValueRLP2, val3)
|
||||
|
||||
val4, err := db.StorageValue(AccountLeafKey, StorageLeafKey, BlockHash4)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, StoredValueRLP2, val4)
|
||||
|
||||
val5, err := db.StorageValue(AccountLeafKey, StorageLeafKey, BlockHash5)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, val5)
|
||||
})
|
||||
|
||||
t.Run("StateDB", func(t *testing.T) {
|
||||
@ -162,7 +257,7 @@ func TestSuite(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func insertHeaderCID(db *pgxpool.Pool) error {
|
||||
func insertHeaderCID(db *pgxpool.Pool, blockHash string, blockNumber uint64) error {
|
||||
sql := `INSERT INTO eth.header_cids (
|
||||
block_number,
|
||||
block_hash,
|
||||
@ -180,15 +275,15 @@ func insertHeaderCID(db *pgxpool.Pool) error {
|
||||
coinbase
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)`
|
||||
_, err := db.Exec(testCtx, sql,
|
||||
BlockNumber.Uint64(),
|
||||
BlockHash.String(),
|
||||
blockNumber,
|
||||
blockHash,
|
||||
BlockParentHash.String(),
|
||||
HeaderCID.String(),
|
||||
0, []string{}, 0,
|
||||
Header.Root.String(),
|
||||
Header.TxHash.String(),
|
||||
Header.ReceiptHash.String(),
|
||||
common.HexToHash("0").String(),
|
||||
Header.UncleHash.String(),
|
||||
[]byte{},
|
||||
Header.Time,
|
||||
Header.Coinbase.String(),
|
||||
@ -196,7 +291,20 @@ func insertHeaderCID(db *pgxpool.Pool) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func insertStateCID(db *pgxpool.Pool) error {
|
||||
type stateModel struct {
|
||||
BlockNumber uint64
|
||||
BlockHash string
|
||||
LeafKey string
|
||||
CID string
|
||||
Diff bool
|
||||
Balance uint64
|
||||
Nonce uint64
|
||||
CodeHash string
|
||||
StorageRoot string
|
||||
Removed bool
|
||||
}
|
||||
|
||||
func insertStateCID(db *pgxpool.Pool, cidModel stateModel) error {
|
||||
sql := `INSERT INTO eth.state_cids (
|
||||
block_number,
|
||||
header_id,
|
||||
@ -210,21 +318,32 @@ func insertStateCID(db *pgxpool.Pool) error {
|
||||
removed
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)`
|
||||
_, err := db.Exec(testCtx, sql,
|
||||
BlockNumber.Uint64(),
|
||||
BlockHash.String(),
|
||||
AccountLeafKey.String(),
|
||||
AccountCID.String(),
|
||||
false,
|
||||
Account.Balance.Uint64(),
|
||||
Account.Nonce,
|
||||
AccountCodeHash.String(),
|
||||
Account.Root.String(),
|
||||
false,
|
||||
cidModel.BlockNumber,
|
||||
cidModel.BlockHash,
|
||||
cidModel.LeafKey,
|
||||
cidModel.CID,
|
||||
cidModel.Diff,
|
||||
cidModel.Balance,
|
||||
cidModel.Nonce,
|
||||
cidModel.CodeHash,
|
||||
cidModel.StorageRoot,
|
||||
cidModel.Removed,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
func insertStorageCID(db *pgxpool.Pool) error {
|
||||
type storageModel struct {
|
||||
BlockNumber uint64
|
||||
BlockHash string
|
||||
LeafKey string
|
||||
StorageLeafKey string
|
||||
StorageCID string
|
||||
Diff bool
|
||||
Value []byte
|
||||
Removed bool
|
||||
}
|
||||
|
||||
func insertStorageCID(db *pgxpool.Pool, cidModel storageModel) error {
|
||||
sql := `INSERT INTO eth.storage_cids (
|
||||
block_number,
|
||||
header_id,
|
||||
@ -236,14 +355,14 @@ func insertStorageCID(db *pgxpool.Pool) error {
|
||||
removed
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`
|
||||
_, err := db.Exec(testCtx, sql,
|
||||
BlockNumber.Uint64(),
|
||||
BlockHash.String(),
|
||||
AccountLeafKey.String(),
|
||||
StorageLeafKey.String(),
|
||||
StorageCID.String(),
|
||||
false,
|
||||
StoredValueRLP,
|
||||
false,
|
||||
cidModel.BlockNumber,
|
||||
cidModel.BlockHash,
|
||||
cidModel.LeafKey,
|
||||
cidModel.StorageLeafKey,
|
||||
cidModel.StorageCID,
|
||||
cidModel.Diff,
|
||||
cidModel.Value,
|
||||
cidModel.Removed,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user