erigon-pulse/cmd/rpcdaemon/commands/eth_block_test.go
Alex Sharov 4594ce5ef7
erigon22: history.v2 flag, align rpcdaemon22 (#5016)
* save

* save

* save

* save

* save
2022-08-12 16:13:14 +07:00

248 lines
9.2 KiB
Go

package commands
import (
"context"
"math/big"
"testing"
"github.com/ledgerwatch/erigon-lib/gointerfaces/txpool"
"github.com/ledgerwatch/erigon-lib/kv/kvcache"
"github.com/ledgerwatch/erigon/cmd/rpcdaemon/rpcdaemontest"
"github.com/ledgerwatch/erigon/common"
"github.com/ledgerwatch/erigon/common/hexutil"
"github.com/ledgerwatch/erigon/core/rawdb"
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/rlp"
"github.com/ledgerwatch/erigon/rpc"
"github.com/ledgerwatch/erigon/turbo/rpchelper"
"github.com/ledgerwatch/erigon/turbo/snapshotsync"
"github.com/ledgerwatch/erigon/turbo/stages"
"github.com/stretchr/testify/assert"
)
// Gets the latest block number with the latest tag
func TestGetBlockByNumberWithLatestTag(t *testing.T) {
db := rpcdaemontest.CreateTestKV(t)
stateCache := kvcache.New(kvcache.DefaultCoherentConfig)
api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000)
b, err := api.GetBlockByNumber(context.Background(), rpc.LatestBlockNumber, false)
expected := common.HexToHash("0x6804117de2f3e6ee32953e78ced1db7b20214e0d8c745a03b8fecf7cc8ee76ef")
if err != nil {
t.Errorf("error getting block number with latest tag: %s", err)
}
assert.Equal(t, expected, b["hash"])
}
func TestGetBlockByNumberWithLatestTag_WithHeadHashInDb(t *testing.T) {
db := rpcdaemontest.CreateTestKV(t)
ctx := context.Background()
stateCache := kvcache.New(kvcache.DefaultCoherentConfig)
tx, err := db.BeginRw(ctx)
if err != nil {
t.Errorf("could not begin read write transaction: %s", err)
}
latestBlockHash := common.HexToHash("0x6804117de2f3e6ee32953e78ced1db7b20214e0d8c745a03b8fecf7cc8ee76ef")
latestBlock, err := rawdb.ReadBlockByHash(tx, latestBlockHash)
if err != nil {
tx.Rollback()
t.Errorf("couldn't retrieve latest block")
}
rawdb.WriteHeaderNumber(tx, latestBlockHash, latestBlock.NonceU64())
rawdb.WriteForkchoiceHead(tx, latestBlockHash)
if safedHeadBlock := rawdb.ReadForkchoiceHead(tx); safedHeadBlock == (common.Hash{}) {
tx.Rollback()
t.Error("didn't find forkchoice head hash")
}
tx.Commit()
api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000)
block, err := api.GetBlockByNumber(ctx, rpc.LatestBlockNumber, false)
if err != nil {
t.Errorf("error retrieving block by number: %s", err)
}
expectedHash := common.HexToHash("0x71b89b6ca7b65debfd2fbb01e4f07de7bba343e6617559fa81df19b605f84662")
assert.Equal(t, expectedHash, block["hash"])
}
func TestGetBlockByNumberWithPendingTag(t *testing.T) {
db := rpcdaemontest.CreateTestKV(t)
m := stages.MockWithTxPool(t)
stateCache := kvcache.New(kvcache.DefaultCoherentConfig)
ctx, conn := rpcdaemontest.CreateTestGrpcConn(t, m)
txPool := txpool.NewTxpoolClient(conn)
ff := rpchelper.New(ctx, nil, txPool, txpool.NewMiningClient(conn), func() {})
expected := 1
header := &types.Header{
Number: big.NewInt(int64(expected)),
}
rlpBlock, err := rlp.EncodeToBytes(types.NewBlockWithHeader(header))
if err != nil {
t.Errorf("failed encoding the block: %s", err)
}
ff.HandlePendingBlock(&txpool.OnPendingBlockReply{
RplBlock: rlpBlock,
})
api := NewEthAPI(NewBaseApi(ff, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000)
b, err := api.GetBlockByNumber(context.Background(), rpc.PendingBlockNumber, false)
if err != nil {
t.Errorf("error getting block number with pending tag: %s", err)
}
assert.Equal(t, (*hexutil.Big)(big.NewInt(int64(expected))), b["number"])
}
func TestGetBlockByNumber_WithFinalizedTag_NoFinalizedBlockInDb(t *testing.T) {
db := rpcdaemontest.CreateTestKV(t)
ctx := context.Background()
stateCache := kvcache.New(kvcache.DefaultCoherentConfig)
api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000)
if _, err := api.GetBlockByNumber(ctx, rpc.FinalizedBlockNumber, false); err != nil {
assert.ErrorIs(t, rpchelper.UnknownBlockError, err)
}
}
func TestGetBlockByNumber_WithFinalizedTag_WithFinalizedBlockInDb(t *testing.T) {
db := rpcdaemontest.CreateTestKV(t)
ctx := context.Background()
stateCache := kvcache.New(kvcache.DefaultCoherentConfig)
tx, err := db.BeginRw(ctx)
if err != nil {
t.Errorf("could not begin read write transaction: %s", err)
}
latestBlockHash := common.HexToHash("0x6804117de2f3e6ee32953e78ced1db7b20214e0d8c745a03b8fecf7cc8ee76ef")
latestBlock, err := rawdb.ReadBlockByHash(tx, latestBlockHash)
if err != nil {
tx.Rollback()
t.Errorf("couldn't retrieve latest block")
}
rawdb.WriteHeaderNumber(tx, latestBlockHash, latestBlock.NonceU64())
rawdb.WriteForkchoiceFinalized(tx, latestBlockHash)
if safedFinalizedBlock := rawdb.ReadForkchoiceFinalized(tx); safedFinalizedBlock == (common.Hash{}) {
tx.Rollback()
t.Error("didn't find forkchoice finalized hash")
}
tx.Commit()
api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000)
block, err := api.GetBlockByNumber(ctx, rpc.FinalizedBlockNumber, false)
if err != nil {
t.Errorf("error retrieving block by number: %s", err)
}
expectedHash := common.HexToHash("0x71b89b6ca7b65debfd2fbb01e4f07de7bba343e6617559fa81df19b605f84662")
assert.Equal(t, expectedHash, block["hash"])
}
func TestGetBlockByNumber_WithSafeTag_NoSafeBlockInDb(t *testing.T) {
db := rpcdaemontest.CreateTestKV(t)
ctx := context.Background()
stateCache := kvcache.New(kvcache.DefaultCoherentConfig)
api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000)
if _, err := api.GetBlockByNumber(ctx, rpc.SafeBlockNumber, false); err != nil {
assert.ErrorIs(t, rpchelper.UnknownBlockError, err)
}
}
func TestGetBlockByNumber_WithSafeTag_WithSafeBlockInDb(t *testing.T) {
db := rpcdaemontest.CreateTestKV(t)
ctx := context.Background()
stateCache := kvcache.New(kvcache.DefaultCoherentConfig)
tx, err := db.BeginRw(ctx)
if err != nil {
t.Errorf("could not begin read write transaction: %s", err)
}
latestBlockHash := common.HexToHash("0x6804117de2f3e6ee32953e78ced1db7b20214e0d8c745a03b8fecf7cc8ee76ef")
latestBlock, err := rawdb.ReadBlockByHash(tx, latestBlockHash)
if err != nil {
tx.Rollback()
t.Errorf("couldn't retrieve latest block")
}
rawdb.WriteHeaderNumber(tx, latestBlockHash, latestBlock.NonceU64())
rawdb.WriteForkchoiceSafe(tx, latestBlockHash)
if safedSafeBlock := rawdb.ReadForkchoiceSafe(tx); safedSafeBlock == (common.Hash{}) {
tx.Rollback()
t.Error("didn't find forkchoice safe block hash")
}
tx.Commit()
api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000)
block, err := api.GetBlockByNumber(ctx, rpc.SafeBlockNumber, false)
if err != nil {
t.Errorf("error retrieving block by number: %s", err)
}
expectedHash := common.HexToHash("0x71b89b6ca7b65debfd2fbb01e4f07de7bba343e6617559fa81df19b605f84662")
assert.Equal(t, expectedHash, block["hash"])
}
func TestGetBlockTransactionCountByHash(t *testing.T) {
db := rpcdaemontest.CreateTestKV(t)
ctx := context.Background()
stateCache := kvcache.New(kvcache.DefaultCoherentConfig)
api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000)
blockHash := common.HexToHash("0x6804117de2f3e6ee32953e78ced1db7b20214e0d8c745a03b8fecf7cc8ee76ef")
tx, err := db.BeginRw(ctx)
if err != nil {
t.Errorf("could not begin read write transaction: %s", err)
}
header, err := rawdb.ReadHeaderByHash(tx, blockHash)
if err != nil {
tx.Rollback()
t.Errorf("failed reading block by hash: %s", err)
}
bodyWithTx, err := rawdb.ReadBodyWithTransactions(tx, blockHash, header.Number.Uint64())
if err != nil {
tx.Rollback()
t.Errorf("failed getting body with transactions: %s", err)
}
tx.Rollback()
expectedAmount := hexutil.Uint(len(bodyWithTx.Transactions))
txAmount, err := api.GetBlockTransactionCountByHash(ctx, blockHash)
if err != nil {
t.Errorf("failed getting the transaction count, err=%s", err)
}
assert.Equal(t, expectedAmount, *txAmount)
}
func TestGetBlockTransactionCountByNumber(t *testing.T) {
db := rpcdaemontest.CreateTestKV(t)
ctx := context.Background()
stateCache := kvcache.New(kvcache.DefaultCoherentConfig)
api := NewEthAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil, nil, nil, 5000000)
blockHash := common.HexToHash("0x6804117de2f3e6ee32953e78ced1db7b20214e0d8c745a03b8fecf7cc8ee76ef")
tx, err := db.BeginRw(ctx)
if err != nil {
t.Errorf("could not begin read write transaction: %s", err)
}
header, err := rawdb.ReadHeaderByHash(tx, blockHash)
if err != nil {
tx.Rollback()
t.Errorf("failed reading block by hash: %s", err)
}
bodyWithTx, err := rawdb.ReadBodyWithTransactions(tx, blockHash, header.Number.Uint64())
if err != nil {
tx.Rollback()
t.Errorf("failed getting body with transactions: %s", err)
}
tx.Rollback()
expectedAmount := hexutil.Uint(len(bodyWithTx.Transactions))
txAmount, err := api.GetBlockTransactionCountByNumber(ctx, rpc.BlockNumber(header.Number.Uint64()))
if err != nil {
t.Errorf("failed getting the transaction count, err=%s", err)
}
assert.Equal(t, expectedAmount, *txAmount)
}