Skip to content

Commit

Permalink
Json rpc unit tests (0xPolygonHermez#798)
Browse files Browse the repository at this point in the history
  • Loading branch information
tclemos authored Jun 23, 2022
1 parent 8157cf0 commit 9406a75
Show file tree
Hide file tree
Showing 7 changed files with 1,306 additions and 75 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ require (
github.com/spf13/viper v1.12.0
github.com/stretchr/testify v1.7.4
github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722
github.com/urfave/cli/v2 v2.10.2
github.com/urfave/cli/v2 v2.8.1
go.uber.org/zap v1.21.0
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29
Expand Down
5 changes: 3 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
Expand Down Expand Up @@ -925,8 +926,8 @@ github.com/umbracle/ethgo v0.1.3/go.mod h1:g9zclCLixH8liBI27Py82klDkW7Oo33AxUOr+
github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 h1:10Nbw6cACsnQm7r34zlpJky+IzxVLRk6MKTS2d3Vp0E=
github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722/go.mod h1:c8J0h9aULj2i3umrfyestM6jCq0LK0U6ly6bWy96nd4=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/urfave/cli/v2 v2.10.2 h1:x3p8awjp/2arX+Nl/G2040AZpOCHS/eMJJ1/a+mye4Y=
github.com/urfave/cli/v2 v2.10.2/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo=
github.com/urfave/cli/v2 v2.8.1 h1:CGuYNZF9IKZY/rfBe3lJpccSoIY1ytfvmgQT90cNOl4=
github.com/urfave/cli/v2 v2.8.1/go.mod h1:Z41J9TPoffeoqP0Iza0YbAhGvymRdZAd2uPmZ5JxRdY=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.4.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s=
github.com/valyala/fastjson v1.4.1 h1:hrltpHpIpkaxll8QltMU8c3QZ5+qIiCL8yKqPFJI/yE=
Expand Down
10 changes: 7 additions & 3 deletions jsonrpc/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ const (
LatestBlockNumber = BlockNumber(-2)
// EarliestBlockNumber represents the earliest block number
EarliestBlockNumber = BlockNumber(-1)

Earliest = "earliest"
Latest = "latest"
Pending = "pending"
)

// Request is a jsonrpc request
Expand Down Expand Up @@ -126,11 +130,11 @@ func (b *BlockNumber) getNumericBlockNumber(ctx context.Context, s stateInterfac
func stringToBlockNumber(str string) (BlockNumber, error) {
str = strings.Trim(str, "\"")
switch str {
case "earliest":
case Earliest:
return EarliestBlockNumber, nil
case "pending":
case Pending:
return PendingBlockNumber, nil
case "latest", "":
case Latest, "":
return LatestBlockNumber, nil
}

Expand Down
118 changes: 67 additions & 51 deletions jsonrpc/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ type Eth struct {
storage storageInterface
}

type blockNumberOrHash struct {
BlockNumber *BlockNumber `json:"blockNumber,omitempty"`
BlockHash *common.Hash `json:"blockHash,omitempty"`
}

// BlockNumber returns current block number
func (e *Eth) BlockNumber() (interface{}, error) {
ctx := context.Background()
Expand All @@ -48,13 +43,9 @@ func (e *Eth) BlockNumber() (interface{}, error) {
func (e *Eth) Call(arg *txnArgs, number *BlockNumber) (interface{}, error) {
// If the caller didn't supply the gas limit in the message, then we set it to maximum possible => block gas limit
if arg.Gas == nil || *arg.Gas == argUint64(0) {
filter := blockNumberOrHash{
BlockNumber: number,
}

header, err := e.getHeaderFromBlockNumberOrHash(&filter)
header, err := e.getBatchHeader(*number)
if err != nil {
const errorMessage = "failed to get header from block hash or block number"
const errorMessage = "failed to get block header"
log.Errorf("%v: %v", errorMessage, err)
return nil, newRPCError(defaultErrorCode, errorMessage)
}
Expand Down Expand Up @@ -240,18 +231,21 @@ func (e *Eth) GetFilterChanges(filterID argUint64) (interface{}, error) {
if errors.Is(err, ErrNotFound) {
return nil, nil
} else if err != nil {
return nil, err
}

err = e.storage.UpdateFilterLastPoll(filter.ID)
if err != nil {
return nil, err
const errorMessage = "failed to get filter from storage"
log.Errorf("%v:%v", errorMessage, err)
return nil, newRPCError(defaultErrorCode, errorMessage)
}

switch filter.Type {
case FilterTypeBlock:
{
res, err := e.state.GetBatchHashesSince(context.Background(), filter.LastPoll, "")
if err != nil {
const errorMessage = "failed to get block hashes"
log.Errorf("%v:%v", errorMessage, err)
return nil, newRPCError(defaultErrorCode, errorMessage)
}
err = e.updateFilterLastPoll(filter.ID)
if err != nil {
return nil, err
}
Expand All @@ -263,6 +257,12 @@ func (e *Eth) GetFilterChanges(filterID argUint64) (interface{}, error) {
case FilterTypePendingTx:
{
res, err := e.pool.GetPendingTxHashesSince(context.Background(), filter.LastPoll)
if err != nil {
const errorMessage = "failed to get pending transaction hashes"
log.Errorf("%v:%v", errorMessage, err)
return nil, newRPCError(defaultErrorCode, errorMessage)
}
err = e.updateFilterLastPoll(filter.ID)
if err != nil {
return nil, err
}
Expand All @@ -276,7 +276,9 @@ func (e *Eth) GetFilterChanges(filterID argUint64) (interface{}, error) {
filterParameters := &LogFilter{}
err = json.Unmarshal([]byte(filter.Parameters), filterParameters)
if err != nil {
return nil, err
const errorMessage = "failed to read filter parameters"
log.Errorf("%v:%v", errorMessage, err)
return nil, newRPCError(defaultErrorCode, errorMessage)
}

filterParameters.Since = &filter.LastPoll
Expand All @@ -285,6 +287,10 @@ func (e *Eth) GetFilterChanges(filterID argUint64) (interface{}, error) {
if err != nil {
return nil, err
}
err = e.updateFilterLastPoll(filter.ID)
if err != nil {
return nil, err
}
res := resInterface.([]rpcLog)
if len(res) == 0 {
return nil, nil
Expand All @@ -303,7 +309,9 @@ func (e *Eth) GetFilterLogs(filterID argUint64) (interface{}, error) {
if errors.Is(err, ErrNotFound) {
return nil, nil
} else if err != nil {
return nil, err
const errorMessage = "failed to get filter from storage"
log.Errorf("%v:%v", errorMessage, err)
return nil, newRPCError(defaultErrorCode, errorMessage)
}

if filter.Type != FilterTypeLog {
Expand All @@ -313,7 +321,9 @@ func (e *Eth) GetFilterLogs(filterID argUint64) (interface{}, error) {
filterParameters := &LogFilter{}
err = json.Unmarshal([]byte(filter.Parameters), filterParameters)
if err != nil {
return nil, err
const errorMessage = "failed to read filter parameters"
log.Errorf("%v:%v", errorMessage, err)
return nil, newRPCError(defaultErrorCode, errorMessage)
}

filterParameters.Since = nil
Expand All @@ -338,7 +348,9 @@ func (e *Eth) GetLogs(filter *LogFilter) (interface{}, error) {

logs, err := e.state.GetLogs(ctx, fromBlock, toBlock, filter.Addresses, filter.Topics, filter.BlockHash, filter.Since, "")
if err != nil {
return nil, err
const errorMessage = "failed to get logs from state"
log.Errorf("%v:%v", errorMessage, err)
return nil, newRPCError(defaultErrorCode, errorMessage)
}

result := make([]rpcLog, 0, len(logs))
Expand Down Expand Up @@ -530,7 +542,9 @@ func (e *Eth) GetTransactionReceipt(hash common.Hash) (interface{}, error) {
func (e *Eth) NewBlockFilter() (interface{}, error) {
id, err := e.storage.NewBlockFilter()
if err != nil {
return nil, err
const errorMessage = "failed to create new block filter"
log.Errorf("%v:%v", errorMessage, err)
return nil, newRPCError(defaultErrorCode, errorMessage)
}

return argUint64(id), nil
Expand All @@ -542,7 +556,9 @@ func (e *Eth) NewBlockFilter() (interface{}, error) {
func (e *Eth) NewFilter(filter *LogFilter) (interface{}, error) {
id, err := e.storage.NewLogFilter(*filter)
if err != nil {
return nil, err
const errorMessage = "failed to create new log filter"
log.Errorf("%v:%v", errorMessage, err)
return nil, newRPCError(defaultErrorCode, errorMessage)
}

return argUint64(id), nil
Expand All @@ -554,7 +570,9 @@ func (e *Eth) NewFilter(filter *LogFilter) (interface{}, error) {
func (e *Eth) NewPendingTransactionFilter(filterID argUint64) (interface{}, error) {
id, err := e.storage.NewPendingTransactionFilter()
if err != nil {
return nil, err
const errorMessage = "failed to create new pending transaction filter"
log.Errorf("%v:%v", errorMessage, err)
return nil, newRPCError(defaultErrorCode, errorMessage)
}

return argUint64(id), nil
Expand Down Expand Up @@ -585,7 +603,14 @@ func (e *Eth) SendRawTransaction(input string) (interface{}, error) {
// Filters timeout when they aren’t requested with
// eth_getFilterChanges for a period of time.
func (e *Eth) UninstallFilter(filterID argUint64) (interface{}, error) {
return e.storage.UninstallFilter(uint64(filterID))
uninstalled, err := e.storage.UninstallFilter(uint64(filterID))
if err != nil {
const errorMessage = "failed to uninstall filter"
log.Errorf("%v:%v", errorMessage, err)
return nil, newRPCError(defaultErrorCode, errorMessage)
}

return uninstalled, nil
}

// Syncing returns an object with data about the sync status or false.
Expand Down Expand Up @@ -655,33 +680,10 @@ func hexToTx(str string) (*types.Transaction, error) {
return tx, nil
}

func (e *Eth) getHeaderFromBlockNumberOrHash(bnh *blockNumberOrHash) (*types.Header, error) {
var (
header *types.Header
err error
)

if bnh.BlockNumber != nil {
header, err = e.getBatchHeader(*bnh.BlockNumber)
if err != nil {
return nil, fmt.Errorf("failed to get the header of block %d: %s", *bnh.BlockNumber, err.Error())
}
} else if bnh.BlockHash != nil {
block, err := e.state.GetBatchByHash(context.Background(), *bnh.BlockHash, "")
if err != nil {
return nil, fmt.Errorf("could not find block referenced by the hash %s, err: %v", bnh.BlockHash.String(), err)
}

header = block.Header
}

return header, nil
}

func (e *Eth) getBatchHeader(number BlockNumber) (*types.Header, error) {
switch number {
case LatestBlockNumber:
batch, err := e.state.GetLastBatch(context.Background(), false, "")
batch, err := e.state.GetLastBatch(context.Background(), true, "")
if err != nil {
return nil, err
}
Expand All @@ -699,14 +701,28 @@ func (e *Eth) getBatchHeader(number BlockNumber) (*types.Header, error) {
if err != nil {
return nil, err
}
parentHash := lastBatch.Hash()
number := lastBatch.Number().Uint64() + 1

header := &types.Header{
ParentHash: lastBatch.Hash(),
Number: big.NewInt(0).SetUint64(lastBatch.Number().Uint64() + 1),
ParentHash: parentHash,
Number: big.NewInt(0).SetUint64(number),
Difficulty: big.NewInt(0),
GasLimit: lastBatch.Header.GasLimit,
}
return header, nil

default:
return e.state.GetBatchHeader(context.Background(), uint64(number), "")
}
}

func (e *Eth) updateFilterLastPoll(filterID uint64) rpcError {
err := e.storage.UpdateFilterLastPoll(filterID)
if err != nil {
const errorMessage = "failed to update last time the filter changes were requested"
log.Errorf("%v:%v", errorMessage, err)
return newRPCError(defaultErrorCode, errorMessage)
}
return nil
}
Loading

0 comments on commit 9406a75

Please sign in to comment.