mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
fix #18254, Need to throw error when methods are called at future blocks
-[x] add unit test for StorageAt rpc call -[x] Return error message on future block -[x] add TransactionCount rpc call unit testing Signed-off-by: Deshi Xiao <xiaods@gmail.com>
This commit is contained in:
parent
05d21438de
commit
3508efc3af
2 changed files with 182 additions and 2 deletions
|
|
@ -18,6 +18,7 @@ package eth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
|
|
@ -94,9 +95,12 @@ func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.
|
||||||
}
|
}
|
||||||
// Otherwise resolve the block number and return its state
|
// Otherwise resolve the block number and return its state
|
||||||
header, err := b.HeaderByNumber(ctx, blockNr)
|
header, err := b.HeaderByNumber(ctx, blockNr)
|
||||||
if header == nil || err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
if header == nil {
|
||||||
|
return nil, nil, errors.New("header not found at future block")
|
||||||
|
}
|
||||||
stateDb, err := b.eth.BlockChain().StateAt(header.Root)
|
stateDb, err := b.eth.BlockChain().StateAt(header.Root)
|
||||||
return stateDb, header, err
|
return stateDb, header, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,16 @@
|
||||||
package ethclient
|
package ethclient
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum"
|
ethereum "github.com/ethereum/go-ethereum"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Verify that Client implements the ethereum interfaces.
|
// Verify that Client implements the ethereum interfaces.
|
||||||
|
|
@ -150,3 +153,176 @@ func TestToFilterArg(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNewClient(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
c *rpc.Client
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want *Client
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"new Client",
|
||||||
|
args{},
|
||||||
|
&Client{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := NewClient(tt.args.c); !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("NewClient() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_StorageAt(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
type fields struct {
|
||||||
|
c *rpc.Client
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
account common.Address
|
||||||
|
key common.Hash
|
||||||
|
blockNumber *big.Int
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
want []byte
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"call StorageAt at future block",
|
||||||
|
fields{
|
||||||
|
c: &rpc.Client{},
|
||||||
|
},
|
||||||
|
args{
|
||||||
|
ctx: ctx,
|
||||||
|
account: common.HexToAddress("0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2"),
|
||||||
|
key: common.HexToHash("0x0"),
|
||||||
|
blockNumber: big.NewInt(1000000000),
|
||||||
|
},
|
||||||
|
[]byte(nil),
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
ec := &Client{
|
||||||
|
c: tt.fields.c,
|
||||||
|
}
|
||||||
|
got, err := ec.StorageAt(tt.args.ctx, tt.args.account, tt.args.key, tt.args.blockNumber)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("Client.StorageAt() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("Client.StorageAt() = %#v, want %#v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_TransactionCount(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
type fields struct {
|
||||||
|
c *rpc.Client
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
blockHash common.Hash
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
want uint
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"call TransactionCount at future block",
|
||||||
|
fields{
|
||||||
|
c: &rpc.Client{},
|
||||||
|
},
|
||||||
|
args{
|
||||||
|
ctx: ctx,
|
||||||
|
blockHash: common.HexToHash("0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"),
|
||||||
|
},
|
||||||
|
0,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
ec := &Client{
|
||||||
|
c: tt.fields.c,
|
||||||
|
}
|
||||||
|
got, err := ec.TransactionCount(tt.args.ctx, tt.args.blockHash)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("Client.TransactionCount() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("Client.TransactionCount() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_PendingTransactionCount(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
type fields struct {
|
||||||
|
c *rpc.Client
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
want uint
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"call TransactionCount at pending block",
|
||||||
|
fields{
|
||||||
|
c: &rpc.Client{},
|
||||||
|
},
|
||||||
|
args{
|
||||||
|
ctx: ctx,
|
||||||
|
},
|
||||||
|
0,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
ec := &Client{
|
||||||
|
c: tt.fields.c,
|
||||||
|
}
|
||||||
|
got, err := ec.PendingTransactionCount(tt.args.ctx)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("Client.PendingTransactionCount() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("Client.PendingTransactionCount() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue