Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion eth/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,8 @@ func (api *PrivateDebugAPI) GetBadBlocks(ctx context.Context) ([]*BadBlockArgs,
} else {
blockRlp = fmt.Sprintf("0x%x", rlpBytes)
}
if blockJSON, err = ethapi.RPCMarshalBlock(block, true, true, api.eth.APIBackend.ChainConfig()); err != nil {

if blockJSON, err = ethapi.RPCMarshalBlock(block, true, true, api.eth.APIBackend.ChainConfig(), api.eth.chainDb); err != nil {
blockJSON = map[string]interface{}{"error": err.Error()}
}
results = append(results, &BadBlockArgs{
Expand Down
2 changes: 1 addition & 1 deletion eth/tracers/api_bor.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (api *API) traceBorBlock(ctx context.Context, block *types.Block, config *T
}

// block object cannot be converted to JSON since much of the fields are non-public
blockFields, err := ethapi.RPCMarshalBlock(block, true, true, api.backend.ChainConfig())
blockFields, err := ethapi.RPCMarshalBlock(block, true, true, api.backend.ChainConfig(), api.backend.ChainDb())
if err != nil {
return nil, err
}
Expand Down
27 changes: 19 additions & 8 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import (
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/tracers/logger"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/params"
Expand Down Expand Up @@ -1332,7 +1333,7 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} {
// RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are
// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
// transaction hashes.
func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool, config *params.ChainConfig) (map[string]interface{}, error) {
func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool, config *params.ChainConfig, db ethdb.Database) (map[string]interface{}, error) {
fields := RPCMarshalHeader(block.Header())
fields["size"] = hexutil.Uint64(block.Size())

Expand All @@ -1342,7 +1343,7 @@ func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool, config *param
}
if fullTx {
formatTx = func(tx *types.Transaction) (interface{}, error) {
return newRPCTransactionFromBlockHash(block, tx.Hash(), config), nil
return newRPCTransactionFromBlockHash(block, tx.Hash(), config, db), nil
}
}
txs := block.Transactions()
Expand Down Expand Up @@ -1376,7 +1377,7 @@ func (s *PublicBlockChainAPI) rpcMarshalHeader(ctx context.Context, header *type
// rpcMarshalBlock uses the generalized output filler, then adds the total difficulty field, which requires
// a `PublicBlockchainAPI`.
func (s *PublicBlockChainAPI) rpcMarshalBlock(ctx context.Context, b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
fields, err := RPCMarshalBlock(b, inclTx, fullTx, s.b.ChainConfig())
fields, err := RPCMarshalBlock(b, inclTx, fullTx, s.b.ChainConfig(), s.b.ChainDb())
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1469,8 +1470,18 @@ func newRPCPendingTransaction(tx *types.Transaction, current *types.Header, conf
}

// newRPCTransactionFromBlockIndex returns a transaction that will serialize to the RPC representation.
func newRPCTransactionFromBlockIndex(b *types.Block, index uint64, config *params.ChainConfig) *RPCTransaction {
func newRPCTransactionFromBlockIndex(b *types.Block, index uint64, config *params.ChainConfig, db ethdb.Database) *RPCTransaction {
txs := b.Transactions()

borReceipt := rawdb.ReadBorReceipt(db, b.Hash(), b.NumberU64())
if borReceipt != nil {
tx, _, _, _ := rawdb.ReadBorTransaction(db, borReceipt.TxHash)

if tx != nil {
txs = append(txs, tx)
}
}

if index >= uint64(len(txs)) {
return nil
}
Expand All @@ -1488,10 +1499,10 @@ func newRPCRawTransactionFromBlockIndex(b *types.Block, index uint64) hexutil.By
}

// newRPCTransactionFromBlockHash returns a transaction that will serialize to the RPC representation.
func newRPCTransactionFromBlockHash(b *types.Block, hash common.Hash, config *params.ChainConfig) *RPCTransaction {
func newRPCTransactionFromBlockHash(b *types.Block, hash common.Hash, config *params.ChainConfig, db ethdb.Database) *RPCTransaction {
for idx, tx := range b.Transactions() {
if tx.Hash() == hash {
return newRPCTransactionFromBlockIndex(b, uint64(idx), config)
return newRPCTransactionFromBlockIndex(b, uint64(idx), config, db)
}
}
return nil
Expand Down Expand Up @@ -1633,15 +1644,15 @@ func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(ctx context.Co
// GetTransactionByBlockNumberAndIndex returns the transaction for the given block number and index.
func (s *PublicTransactionPoolAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *RPCTransaction {
if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil {
return newRPCTransactionFromBlockIndex(block, uint64(index), s.b.ChainConfig())
return newRPCTransactionFromBlockIndex(block, uint64(index), s.b.ChainConfig(), s.b.ChainDb())
}
return nil
}

// GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index.
func (s *PublicTransactionPoolAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) *RPCTransaction {
if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil {
return newRPCTransactionFromBlockIndex(block, uint64(index), s.b.ChainConfig())
return newRPCTransactionFromBlockIndex(block, uint64(index), s.b.ChainConfig(), s.b.ChainDb())
}
return nil
}
Expand Down
134 changes: 86 additions & 48 deletions tests/bor/bor_api_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build integration

package bor

import (
Expand All @@ -13,13 +15,27 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/eth/ethconfig"
"github.com/ethereum/go-ethereum/internal/ethapi"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"

"github.com/stretchr/testify/assert"
)

var (
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
addr = crypto.PubkeyToAddress(key1.PublicKey)
stack, _ = node.New(&node.DefaultConfig)
backend, _ = eth.New(stack, &ethconfig.Defaults)
db = backend.ChainDb()
hash1 = common.BytesToHash([]byte("topic1"))
hash2 = common.BytesToHash([]byte("topic2"))
hash3 = common.BytesToHash([]byte("topic3"))
hash4 = common.BytesToHash([]byte("topic4"))
hash5 = common.BytesToHash([]byte("topic5"))
)

func duplicateInArray(arr []common.Hash) bool {
visited := make(map[common.Hash]bool, 0)
for i := 0; i < len(arr); i++ {
Expand All @@ -45,21 +61,72 @@ func areDifferentHashes(receipts []map[string]interface{}) bool {
return true
}

func TestGetTransactionReceiptsByBlock(t *testing.T) {
t.Parallel()
func testGetTransactionReceiptsByBlock(t *testing.T, publicBlockchainAPI *ethapi.PublicBlockChainAPI) {
// check 1 : zero transactions
receiptsOut, err := publicBlockchainAPI.GetTransactionReceiptsByBlock(context.Background(), rpc.BlockNumberOrHashWithNumber(1))
if err != nil {
t.Error(err)
}

assert.Equal(t, 0, len(receiptsOut))

// check 2 : one transactions ( normal )
receiptsOut, err = publicBlockchainAPI.GetTransactionReceiptsByBlock(context.Background(), rpc.BlockNumberOrHashWithNumber(2))
if err != nil {
t.Error(err)
}

assert.Equal(t, 1, len(receiptsOut))
assert.True(t, areDifferentHashes(receiptsOut))

// check 3 : two transactions ( both normal )
receiptsOut, err = publicBlockchainAPI.GetTransactionReceiptsByBlock(context.Background(), rpc.BlockNumberOrHashWithNumber(3))
if err != nil {
t.Error(err)
}

assert.Equal(t, 2, len(receiptsOut))
assert.True(t, areDifferentHashes(receiptsOut))

// check 4 : two transactions ( one normal + one state-sync)
receiptsOut, err = publicBlockchainAPI.GetTransactionReceiptsByBlock(context.Background(), rpc.BlockNumberOrHashWithNumber(4))
if err != nil {
t.Error(err)
}

assert.Equal(t, 2, len(receiptsOut))
assert.True(t, areDifferentHashes(receiptsOut))

}

func testGetTransactionByBlockNumberAndIndex(t *testing.T, publicTransactionPoolAPI *ethapi.PublicTransactionPoolAPI) {
// check 1 : False ( no transaction )
tx := publicTransactionPoolAPI.GetTransactionByBlockNumberAndIndex(context.Background(), rpc.BlockNumber(1), 0)
assert.Nil(t, tx)

var (
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
addr = crypto.PubkeyToAddress(key1.PublicKey)
stack, _ = node.New(&node.DefaultConfig)
backend, _ = eth.New(stack, &ethconfig.Defaults)
db = backend.ChainDb()
hash1 = common.BytesToHash([]byte("topic1"))
hash2 = common.BytesToHash([]byte("topic2"))
hash3 = common.BytesToHash([]byte("topic3"))
hash4 = common.BytesToHash([]byte("topic4"))
hash5 = common.BytesToHash([]byte("topic5"))
)
// check 2 : Normal Transaction
tx = publicTransactionPoolAPI.GetTransactionByBlockNumberAndIndex(context.Background(), rpc.BlockNumber(2), 0)
assert.Equal(t, common.HexToAddress("0x24"), *tx.To)

// check 3 : Normal Transaction
tx = publicTransactionPoolAPI.GetTransactionByBlockNumberAndIndex(context.Background(), rpc.BlockNumber(3), 0)
assert.Equal(t, common.HexToAddress("0x992"), *tx.To)

// check 4 : Normal Transaction
tx = publicTransactionPoolAPI.GetTransactionByBlockNumberAndIndex(context.Background(), rpc.BlockNumber(3), 1)
assert.Equal(t, common.HexToAddress("0x993"), *tx.To)

// check 5 : Normal Transaction
tx = publicTransactionPoolAPI.GetTransactionByBlockNumberAndIndex(context.Background(), rpc.BlockNumber(4), 0)
assert.Equal(t, common.HexToAddress("0x1000"), *tx.To)

// check 5 : Normal Transaction
tx = publicTransactionPoolAPI.GetTransactionByBlockNumberAndIndex(context.Background(), rpc.BlockNumber(4), 1)
assert.Equal(t, common.HexToAddress("0x0"), *tx.To)
}

func TestAPIs(t *testing.T) {
t.Parallel()

defer func() {
if err := stack.Close(); err != nil {
Expand Down Expand Up @@ -114,7 +181,7 @@ func TestGetTransactionReceiptsByBlock(t *testing.T) {
},
}
gen.AddUncheckedReceipt(receipt)
gen.AddUncheckedTx(types.NewTransaction(1000, common.HexToAddress("0x0"), big.NewInt(1000), 1000, gen.BaseFee(), nil))
gen.AddUncheckedTx(types.NewTransaction(1000, common.HexToAddress("0x1000"), big.NewInt(1000), 1000, gen.BaseFee(), nil))

// state-sync transaction
receipt2 := types.NewReceipt(nil, false, 0)
Expand Down Expand Up @@ -174,39 +241,10 @@ func TestGetTransactionReceiptsByBlock(t *testing.T) {
}

publicBlockchainAPI := backend.PublicBlockChainAPI()
testGetTransactionReceiptsByBlock(t, publicBlockchainAPI)

// check 1 : zero transactions
receiptsOut, err := publicBlockchainAPI.GetTransactionReceiptsByBlock(context.Background(), rpc.BlockNumberOrHashWithNumber(1))
if err != nil {
t.Error(err)
}

assert.Equal(t, 0, len(receiptsOut))

// check 2 : one transactions ( normal )
receiptsOut, err = publicBlockchainAPI.GetTransactionReceiptsByBlock(context.Background(), rpc.BlockNumberOrHashWithNumber(2))
if err != nil {
t.Error(err)
}

assert.Equal(t, 1, len(receiptsOut))
assert.True(t, areDifferentHashes(receiptsOut))

// check 3 : two transactions ( both normal )
receiptsOut, err = publicBlockchainAPI.GetTransactionReceiptsByBlock(context.Background(), rpc.BlockNumberOrHashWithNumber(3))
if err != nil {
t.Error(err)
}

assert.Equal(t, 2, len(receiptsOut))
assert.True(t, areDifferentHashes(receiptsOut))

// check 4 : two transactions ( one normal + one state-sync)
receiptsOut, err = publicBlockchainAPI.GetTransactionReceiptsByBlock(context.Background(), rpc.BlockNumberOrHashWithNumber(4))
if err != nil {
t.Error(err)
}
nonceLock := new(ethapi.AddrLocker)
publicTransactionPoolAPI := ethapi.NewPublicTransactionPoolAPI(backend.APIBackend, nonceLock)
testGetTransactionByBlockNumberAndIndex(t, publicTransactionPoolAPI)

assert.Equal(t, 2, len(receiptsOut))
assert.True(t, areDifferentHashes(receiptsOut))
}