Fix empty value when contract is deleted.
This commit is contained in:
parent
a1781b1eeb
commit
f09f665b11
@ -1,4 +1,20 @@
|
|||||||
-- +goose Up
|
-- +goose Up
|
||||||
|
|
||||||
|
|
||||||
|
-- +goose StatementBegin
|
||||||
|
-- returns if a storage node at the provided path was removed in the range >= the provided height and <= the provided block hash
|
||||||
|
CREATE OR REPLACE FUNCTION was_state_leaf_removed(state_leaf_key BYTEA, block_num BIGINT) RETURNS BOOLEAN
|
||||||
|
AS $$
|
||||||
|
SELECT exists(SELECT 1
|
||||||
|
FROM eth.state_cids
|
||||||
|
INNER JOIN eth.header_cids ON (state_cids.header_id = header_cids.id)
|
||||||
|
WHERE state_leaf_key = state_leaf_key
|
||||||
|
AND block_number <= block_num
|
||||||
|
AND state_cids.node_type = 3
|
||||||
|
LIMIT 1);
|
||||||
|
$$ LANGUAGE SQL;
|
||||||
|
-- +goose StatementEnd
|
||||||
|
|
||||||
-- +goose StatementBegin
|
-- +goose StatementBegin
|
||||||
CREATE TYPE child_result AS (
|
CREATE TYPE child_result AS (
|
||||||
has_child BOOLEAN,
|
has_child BOOLEAN,
|
||||||
@ -115,6 +131,7 @@ LANGUAGE 'plpgsql';
|
|||||||
-- +goose StatementEnd
|
-- +goose StatementEnd
|
||||||
|
|
||||||
-- +goose Down
|
-- +goose Down
|
||||||
|
DROP FUNCTION was_state_leaf_removed;
|
||||||
DROP FUNCTION canonical_header_id;
|
DROP FUNCTION canonical_header_id;
|
||||||
DROP FUNCTION canonical_header_from_array;
|
DROP FUNCTION canonical_header_from_array;
|
||||||
DROP FUNCTION has_child;
|
DROP FUNCTION has_child;
|
||||||
|
@ -39,6 +39,7 @@ services:
|
|||||||
- vdb_db_eth_server:/var/lib/postgresql/data
|
- vdb_db_eth_server:/var/lib/postgresql/data
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:8077:5432"
|
- "127.0.0.1:8077:5432"
|
||||||
|
command: ["postgres", "-c", "log_statement=all"]
|
||||||
|
|
||||||
eth-server:
|
eth-server:
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
@ -127,7 +127,7 @@ const (
|
|||||||
AND block_number <= $2
|
AND block_number <= $2
|
||||||
ORDER BY block_number DESC
|
ORDER BY block_number DESC
|
||||||
LIMIT 1`
|
LIMIT 1`
|
||||||
RetrieveStorageLeafByAddressHashAndLeafKeyAndBlockNumberPgStr = `SELECT storage_cids.cid, data, storage_cids.node_type
|
RetrieveStorageLeafByAddressHashAndLeafKeyAndBlockNumberPgStr = `SELECT storage_cids.cid, data, storage_cids.node_type, was_state_leaf_removed(state_leaf_key, block_number) AS state_leaf_removed
|
||||||
FROM eth.storage_cids
|
FROM eth.storage_cids
|
||||||
INNER JOIN eth.state_cids ON (storage_cids.state_id = state_cids.id)
|
INNER JOIN eth.state_cids ON (storage_cids.state_id = state_cids.id)
|
||||||
INNER JOIN eth.header_cids ON (state_cids.header_id = header_cids.id)
|
INNER JOIN eth.header_cids ON (state_cids.header_id = header_cids.id)
|
||||||
@ -137,7 +137,7 @@ const (
|
|||||||
AND block_number <= $3
|
AND block_number <= $3
|
||||||
ORDER BY block_number DESC
|
ORDER BY block_number DESC
|
||||||
LIMIT 1`
|
LIMIT 1`
|
||||||
RetrieveStorageLeafByAddressHashAndLeafKeyAndBlockHashPgStr = `SELECT storage_cids.cid, data, storage_cids.node_type
|
RetrieveStorageLeafByAddressHashAndLeafKeyAndBlockHashPgStr = `SELECT storage_cids.cid, data, storage_cids.node_type, was_state_leaf_removed(state_leaf_key, block_number) AS state_leaf_removed
|
||||||
FROM eth.storage_cids
|
FROM eth.storage_cids
|
||||||
INNER JOIN eth.state_cids ON (storage_cids.state_id = state_cids.id)
|
INNER JOIN eth.state_cids ON (storage_cids.state_id = state_cids.id)
|
||||||
INNER JOIN eth.header_cids ON (state_cids.header_id = header_cids.id)
|
INNER JOIN eth.header_cids ON (state_cids.header_id = header_cids.id)
|
||||||
@ -430,6 +430,7 @@ type nodeInfo struct {
|
|||||||
CID string `db:"cid"`
|
CID string `db:"cid"`
|
||||||
Data []byte `db:"data"`
|
Data []byte `db:"data"`
|
||||||
NodeType int `db:"node_type"`
|
NodeType int `db:"node_type"`
|
||||||
|
StateLeafRemoved bool `db:"state_leaf_removed"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// RetrieveAccountByAddressAndBlockHash returns the cid and rlp bytes for the account corresponding to the provided address and block hash
|
// RetrieveAccountByAddressAndBlockHash returns the cid and rlp bytes for the account corresponding to the provided address and block hash
|
||||||
@ -486,7 +487,7 @@ func (r *IPLDRetriever) RetrieveStorageAtByAddressAndStorageSlotAndBlockHash(add
|
|||||||
if err := r.db.Get(storageResult, RetrieveStorageLeafByAddressHashAndLeafKeyAndBlockHashPgStr, stateLeafKey.Hex(), storageHash.Hex(), hash.Hex()); err != nil {
|
if err := r.db.Get(storageResult, RetrieveStorageLeafByAddressHashAndLeafKeyAndBlockHashPgStr, stateLeafKey.Hex(), storageHash.Hex(), hash.Hex()); err != nil {
|
||||||
return "", nil, nil, err
|
return "", nil, nil, err
|
||||||
}
|
}
|
||||||
if storageResult.NodeType == removedNode {
|
if storageResult.StateLeafRemoved || storageResult.NodeType == removedNode {
|
||||||
return "", EmptyNodeValue, EmptyNodeValue, nil
|
return "", EmptyNodeValue, EmptyNodeValue, nil
|
||||||
}
|
}
|
||||||
var i []interface{}
|
var i []interface{}
|
||||||
@ -509,7 +510,7 @@ func (r *IPLDRetriever) RetrieveStorageAtByAddressAndStorageKeyAndBlockNumber(ad
|
|||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if storageResult.NodeType == removedNode {
|
if storageResult.StateLeafRemoved || storageResult.NodeType == removedNode {
|
||||||
return "", EmptyNodeValue, nil
|
return "", EmptyNodeValue, nil
|
||||||
}
|
}
|
||||||
var i []interface{}
|
var i []interface{}
|
||||||
|
@ -5,9 +5,9 @@ set -o xtrace
|
|||||||
docker-compose down --remove-orphans --volumes
|
docker-compose down --remove-orphans --volumes
|
||||||
|
|
||||||
# Build and start the containers.
|
# Build and start the containers.
|
||||||
# Note: Build only if `ipld-eth-server` code is modified. Otherwise comment this line.
|
# Note: Build only if `ipld-eth-server` or other container code is modified. Otherwise comment this line.
|
||||||
docker build -t ipld-eth-server_eth-server:latest .
|
docker-compose -f docker-compose.test.yml -f docker-compose.yml build eth-server
|
||||||
docker-compose -f docker-compose.test.yml -f docker-compose.yml up -d db dapptools contract eth-server
|
docker-compose -f docker-compose.test.yml -f docker-compose.yml up -d db dapptools contract eth-server 2>&1 | tee docker.logs
|
||||||
|
|
||||||
export PGPASSWORD=password
|
export PGPASSWORD=password
|
||||||
export DATABASE_USER=vdbm
|
export DATABASE_USER=vdbm
|
||||||
|
@ -15,6 +15,8 @@ fastify.get('/v1/deployContract', async (req, reply) => {
|
|||||||
const token = await GLDToken.deploy();
|
const token = await GLDToken.deploy();
|
||||||
await token.deployed();
|
await token.deployed();
|
||||||
|
|
||||||
|
console.log(`Deployed block ${token.deployTransaction.blockNumber}`)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
address: token.address,
|
address: token.address,
|
||||||
txHash: token.deployTransaction.hash,
|
txHash: token.deployTransaction.hash,
|
||||||
@ -31,6 +33,8 @@ fastify.get('/v1/destroyContract', async (req, reply) => {
|
|||||||
|
|
||||||
await token.destroy();
|
await token.destroy();
|
||||||
const blockNum = await hre.ethers.provider.getBlockNumber()
|
const blockNum = await hre.ethers.provider.getBlockNumber()
|
||||||
|
console.log(`Destroyed block ${blockNum}`)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
blockNumber: blockNum,
|
blockNumber: blockNum,
|
||||||
}
|
}
|
||||||
|
@ -15,9 +15,7 @@ type ContractDeployed struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ContractDestroyed struct {
|
type ContractDestroyed struct {
|
||||||
TransactionHash string `json:"txHash"`
|
|
||||||
BlockNumber int64 `json:"blockNumber"`
|
BlockNumber int64 `json:"blockNumber"`
|
||||||
BlockHash string `json:"blockHash"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Tx struct {
|
type Tx struct {
|
||||||
@ -56,6 +54,7 @@ func DestroyContract(addr string) (*ContractDestroyed, error) {
|
|||||||
}
|
}
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
fmt.Println(res.Body)
|
||||||
var data ContractDestroyed
|
var data ContractDestroyed
|
||||||
decoder := json.NewDecoder(res.Body)
|
decoder := json.NewDecoder(res.Body)
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package integration_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -317,6 +318,8 @@ var _ = Describe("Integration test", func() {
|
|||||||
contract, contractErr = integration.DeployContract()
|
contract, contractErr = integration.DeployContract()
|
||||||
erc20TotalSupply, bigIntResult = new(big.Int).SetString("1000000000000000000000", 10)
|
erc20TotalSupply, bigIntResult = new(big.Int).SetString("1000000000000000000000", 10)
|
||||||
|
|
||||||
|
fmt.Printf("Deployed address: %d\n", contract.BlockNumber)
|
||||||
|
|
||||||
time.Sleep(sleepInterval)
|
time.Sleep(sleepInterval)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -393,7 +396,7 @@ var _ = Describe("Integration test", func() {
|
|||||||
Expect(gethStorage).To(Equal(ipldStorage))
|
Expect(gethStorage).To(Equal(ipldStorage))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("get storage after self destruct", func() {
|
FIt("get storage after self destruct", func() {
|
||||||
totalSupplyIndex := "0x2"
|
totalSupplyIndex := "0x2"
|
||||||
|
|
||||||
tx, err := integration.DestroyContract(contract.Address)
|
tx, err := integration.DestroyContract(contract.Address)
|
||||||
@ -401,6 +404,10 @@ var _ = Describe("Integration test", func() {
|
|||||||
|
|
||||||
time.Sleep(sleepInterval)
|
time.Sleep(sleepInterval)
|
||||||
|
|
||||||
|
fmt.Printf("Destroyed address: %d\n", tx.BlockNumber)
|
||||||
|
|
||||||
|
fmt.Printf("Contract Address: %s \n", contract.Address)
|
||||||
|
|
||||||
gethStorage1, err := gethClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), big.NewInt(tx.BlockNumber-1))
|
gethStorage1, err := gethClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), big.NewInt(tx.BlockNumber-1))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
gethStorage2, err := gethClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), big.NewInt(tx.BlockNumber))
|
gethStorage2, err := gethClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), big.NewInt(tx.BlockNumber))
|
||||||
@ -416,6 +423,12 @@ var _ = Describe("Integration test", func() {
|
|||||||
|
|
||||||
Expect(ipldStorage1).To(Equal(gethStorage1))
|
Expect(ipldStorage1).To(Equal(gethStorage1))
|
||||||
Expect(ipldStorage2).To(Equal(gethStorage2))
|
Expect(ipldStorage2).To(Equal(gethStorage2))
|
||||||
|
|
||||||
|
// Query the current block
|
||||||
|
ipldStorage3, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
Expect(ipldStorage2).To(Equal(ipldStorage3))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user