Skip to content
This repository has been archived by the owner on Oct 11, 2024. It is now read-only.

Commit

Permalink
Store order validation block (#853)
Browse files Browse the repository at this point in the history
* Add support for storing block metadata for orders in db package

* Set block metadata for orders in order_watcher

* Improve tests for setting last validated block

* Add new fields to Order in database.ts
  • Loading branch information
albrow authored Jul 2, 2020
1 parent 75e90bf commit 25f26f8
Show file tree
Hide file tree
Showing 12 changed files with 474 additions and 203 deletions.
6 changes: 6 additions & 0 deletions common/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ type OrderWithMetadata struct {
ParsedMakerAssetData []*SingleAssetData `json:"parsedMakerAssetData"`
// Same as ParsedMakerAssetData but for MakerFeeAssetData instead of MakerAssetData.
ParsedMakerFeeAssetData []*SingleAssetData `json:"parsedMakerFeeAssetData"`
// LastValidatedBlockNumber is the block number at which the order was
// last validated.
LastValidatedBlockNumber *big.Int `json:"lastValidatedBlockNumber"`
// LastValidatedBlockHash is the hash of the block at which the order was
// last validated.
LastValidatedBlockHash common.Hash `json:"lastValidatedBlockHash"`
}

func (order OrderWithMetadata) SignedOrder() *zeroex.SignedOrder {
Expand Down
2 changes: 2 additions & 0 deletions db/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,8 @@ func newTestOrder() *types.OrderWithMetadata {
TokenID: big.NewInt(567),
},
},
LastValidatedBlockNumber: big.NewInt(int64(rand.Int())),
LastValidatedBlockHash: common.BigToHash(big.NewInt(int64(rand.Int()))),
}
}

Expand Down
6 changes: 6 additions & 0 deletions db/dexietypes/dexietypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ type Order struct {
IsNotPinned uint8 `json:"isNotPinned"` // Used in a compound index in queries related to max expiration time.
ParsedMakerAssetData string `json:"parsedMakerAssetData"`
ParsedMakerFeeAssetData string `json:"parsedMakerFeeAssetData"`
LastValidatedBlockNumber *SortedBigInt `json:"lastValidatedBlockNumber"`
LastValidatedBlockHash common.Hash `json:"lastValidatedBlockHash"`
}

type Metadata struct {
Expand Down Expand Up @@ -196,6 +198,8 @@ func OrderToCommonType(order *Order) *types.OrderWithMetadata {
IsPinned: order.IsPinned == 1,
ParsedMakerAssetData: ParsedAssetDataToCommonType(order.ParsedMakerAssetData),
ParsedMakerFeeAssetData: ParsedAssetDataToCommonType(order.ParsedMakerFeeAssetData),
LastValidatedBlockNumber: order.LastValidatedBlockNumber.Int,
LastValidatedBlockHash: order.LastValidatedBlockHash,
}
}

Expand Down Expand Up @@ -229,6 +233,8 @@ func OrderFromCommonType(order *types.OrderWithMetadata) *Order {
IsNotPinned: BoolToUint8(!order.IsPinned),
ParsedMakerAssetData: ParsedAssetDataFromCommonType(order.ParsedMakerAssetData),
ParsedMakerFeeAssetData: ParsedAssetDataFromCommonType(order.ParsedMakerFeeAssetData),
LastValidatedBlockNumber: NewSortedBigInt(order.LastValidatedBlockNumber),
LastValidatedBlockHash: order.LastValidatedBlockHash,
}
}

Expand Down
16 changes: 12 additions & 4 deletions db/sql_implementation.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ CREATE TABLE IF NOT EXISTS orders (
isRemoved BOOLEAN NOT NULL,
isPinned BOOLEAN NOT NULL,
parsedMakerAssetData TEXT NOT NULL,
parsedMakerFeeAssetData TEXT NOT NULL
parsedMakerFeeAssetData TEXT NOT NULL,
lastValidatedBlockNumber TEXT NOT NULL,
lastValidatedBlockHash TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS miniHeaders (
Expand Down Expand Up @@ -163,7 +165,9 @@ const insertOrderQuery = `INSERT INTO orders (
isRemoved,
isPinned,
parsedMakerAssetData,
parsedMakerFeeAssetData
parsedMakerFeeAssetData,
lastValidatedBlockNumber,
lastValidatedBlockHash
) VALUES (
:hash,
:chainID,
Expand All @@ -188,7 +192,9 @@ const insertOrderQuery = `INSERT INTO orders (
:isRemoved,
:isPinned,
:parsedMakerAssetData,
:parsedMakerFeeAssetData
:parsedMakerFeeAssetData,
:lastValidatedBlockNumber,
:lastValidatedBlockHash
) ON CONFLICT DO NOTHING
`

Expand All @@ -215,7 +221,9 @@ const updateOrderQuery = `UPDATE orders SET
isRemoved = :isRemoved,
isPinned = :isPinned,
parsedMakerAssetData = :parsedMakerAssetData,
parsedMakerFeeAssetData = :parsedMakerFeeAssetData
parsedMakerFeeAssetData = :parsedMakerFeeAssetData,
lastValidatedBlockNumber = :lastValidatedBlockNumber,
lastValidatedBlockHash = :lastValidatedBlockHash
WHERE orders.hash = :hash
`

Expand Down
6 changes: 6 additions & 0 deletions db/sqltypes/sqltypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ type Order struct {
IsPinned bool `db:"isPinned"`
ParsedMakerAssetData *ParsedAssetData `db:"parsedMakerAssetData"`
ParsedMakerFeeAssetData *ParsedAssetData `db:"parsedMakerFeeAssetData"`
LastValidatedBlockNumber *SortedBigInt `db:"lastValidatedBlockNumber"`
LastValidatedBlockHash common.Hash `db:"lastValidatedBlockHash"`
}

// EventLogs is a wrapper around []*ethtypes.Log that implements the
Expand Down Expand Up @@ -328,6 +330,8 @@ func OrderToCommonType(order *Order) *types.OrderWithMetadata {
IsPinned: order.IsPinned,
ParsedMakerAssetData: ParsedAssetDataToCommonType(order.ParsedMakerAssetData),
ParsedMakerFeeAssetData: ParsedAssetDataToCommonType(order.ParsedMakerFeeAssetData),
LastValidatedBlockNumber: order.LastValidatedBlockNumber.Int,
LastValidatedBlockHash: order.LastValidatedBlockHash,
}
}

Expand Down Expand Up @@ -360,6 +364,8 @@ func OrderFromCommonType(order *types.OrderWithMetadata) *Order {
IsPinned: order.IsPinned,
ParsedMakerAssetData: ParsedAssetDataFromCommonType(order.ParsedMakerAssetData),
ParsedMakerFeeAssetData: ParsedAssetDataFromCommonType(order.ParsedMakerFeeAssetData),
LastValidatedBlockNumber: NewSortedBigInt(order.LastValidatedBlockNumber),
LastValidatedBlockHash: order.LastValidatedBlockHash,
}
}

Expand Down
18 changes: 9 additions & 9 deletions ethereum/ethrpcclient/eth_rpc_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ import (
"sync/atomic"
"time"

"github.com/0xProject/0x-mesh/ethereum/miniheader"
"github.com/0xProject/0x-mesh/common/types"
"github.com/0xProject/0x-mesh/ethereum/ratelimit"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
)

// Client defines the methods needed to satisfy the subsdet of ETH JSON-RPC client
// methods used by Mesh
type Client interface {
HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error)
HeaderByNumber(ctx context.Context, number *big.Int) (*miniheader.MiniHeader, error)
FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error)
HeaderByHash(ctx context.Context, hash common.Hash) (*ethtypes.Header, error)
HeaderByNumber(ctx context.Context, number *big.Int) (*types.MiniHeader, error)
FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]ethtypes.Log, error)
CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error
CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error)
CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)
Expand Down Expand Up @@ -72,7 +72,7 @@ func (ec *client) CallContext(ctx context.Context, result interface{}, method st

// HeaderByHash fetches a block header by its block hash. If no block exists with this number it will return
// a `ethereum.NotFound` error.
func (ec *client) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
func (ec *client) HeaderByHash(ctx context.Context, hash common.Hash) (*ethtypes.Header, error) {
err := ec.rateLimiter.Wait(ctx)
if err != nil {
atomic.AddInt64(&ec.rateLimitDroppedRequests, 1)
Expand All @@ -89,7 +89,7 @@ func (ec *client) HeaderByHash(ctx context.Context, hash common.Hash) (*types.He
return header, nil
}

func (ec *client) HeaderByNumber(ctx context.Context, number *big.Int) (*miniheader.MiniHeader, error) {
func (ec *client) HeaderByNumber(ctx context.Context, number *big.Int) (*types.MiniHeader, error) {
err := ec.rateLimiter.Wait(ctx)
if err != nil {
atomic.AddInt64(&ec.rateLimitDroppedRequests, 1)
Expand All @@ -101,7 +101,7 @@ func (ec *client) HeaderByNumber(ctx context.Context, number *big.Int) (*minihea
if err != nil {
return nil, err
}
miniHeader := &miniheader.MiniHeader{
miniHeader := &types.MiniHeader{
Hash: header.Hash(),
Parent: header.ParentHash,
Number: header.Number,
Expand Down Expand Up @@ -140,7 +140,7 @@ func (ec *client) CallContract(ctx context.Context, call ethereum.CallMsg, block
}

// FilterLogs returns the logs that satisfy the supplied filter query.
func (ec *client) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) {
func (ec *client) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]ethtypes.Log, error) {
err := ec.rateLimiter.Wait(ctx)
if err != nil {
atomic.AddInt64(&ec.rateLimitDroppedRequests, 1)
Expand Down
27 changes: 0 additions & 27 deletions ethereum/miniheader/miniheader.go

This file was deleted.

4 changes: 3 additions & 1 deletion packages/mesh-browser-lite/src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ export interface Order {
isNotPinned: number; // Used in a compound index in queries related to max expiration time.
parsedMakerAssetData: string;
parsedMakerFeeAssetData: string;
lastValidatedBlockNumber: string;
lastValidatedBlockHash: string;
}

export type OrderField = keyof Order;
Expand Down Expand Up @@ -152,7 +154,7 @@ export class Database {

this._db.version(1).stores({
orders:
'&hash,chainId,makerAddress,makerAssetData,makerAssetAmount,makerFee,makerFeeAssetData,takerAddress,takerAssetData,takerFeeAssetData,takerAssetAmount,takerFee,senderAddress,feeRecipientAddress,expirationTimeSeconds,salt,signature,exchangeAddress,fillableTakerAssetAmount,lastUpdated,isRemoved,isPinned,parsedMakerAssetData,parsedMakerFeeAssetData,[isNotPinned+expirationTimeSeconds]',
'&hash,chainId,makerAddress,makerAssetData,makerAssetAmount,makerFee,makerFeeAssetData,takerAddress,takerAssetData,takerFeeAssetData,takerAssetAmount,takerFee,senderAddress,feeRecipientAddress,expirationTimeSeconds,salt,signature,exchangeAddress,fillableTakerAssetAmount,lastUpdated,isRemoved,isPinned,parsedMakerAssetData,parsedMakerFeeAssetData,lastValidatedBlockNumber,lastValidatedBlockHash,[isNotPinned+expirationTimeSeconds]',
miniHeaders: '&hash,parent,number,timestamp',
metadata: '&ethereumChainID',
});
Expand Down
9 changes: 5 additions & 4 deletions zeroex/ordervalidator/order_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"sync"
"time"

"github.com/0xProject/0x-mesh/common/types"
"github.com/0xProject/0x-mesh/constants"
"github.com/0xProject/0x-mesh/ethereum"
"github.com/0xProject/0x-mesh/ethereum/wrappers"
Expand Down Expand Up @@ -266,9 +267,9 @@ func New(contractCaller bind.ContractCaller, chainID int, maxRequestContentLengt
// requests concurrently. If a request fails, re-attempt it up to four times before giving up.
// If some requests fail, this method still returns whatever order information it was able to
// retrieve up until the failure.
// The `blockNumber` parameter lets the caller specify a specific block height at which to validate
// the orders. This can be set to the `latest` block or any other historical block number.
func (o *OrderValidator) BatchValidate(ctx context.Context, rawSignedOrders []*zeroex.SignedOrder, areNewOrders bool, blockNumber *big.Int) *ValidationResults {
// The `validationBlock` parameter lets the caller specify a specific block at which to validate
// the orders. This can be set to the `latest` block or any other historical block.
func (o *OrderValidator) BatchValidate(ctx context.Context, rawSignedOrders []*zeroex.SignedOrder, areNewOrders bool, validationBlock *types.MiniHeader) *ValidationResults {
if len(rawSignedOrders) == 0 {
return &ValidationResults{}
}
Expand Down Expand Up @@ -330,7 +331,7 @@ func (o *OrderValidator) BatchValidate(ctx context.Context, rawSignedOrders []*z
Pending: false,
Context: ctx,
}
opts.BlockNumber = blockNumber
opts.BlockNumber = validationBlock.Number

results, err := o.devUtils.GetOrderRelevantStates(opts, trimmedOrders, signatures)
if err != nil {
Expand Down
10 changes: 5 additions & 5 deletions zeroex/ordervalidator/order_validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ func TestBatchValidateAValidOrder(t *testing.T) {
ctx := context.Background()
latestBlock, err := ethRPCClient.HeaderByNumber(ctx, nil)
require.NoError(t, err)
validationResults := orderValidator.BatchValidate(ctx, signedOrders, areNewOrders, latestBlock.Number)
validationResults := orderValidator.BatchValidate(ctx, signedOrders, areNewOrders, latestBlock)
assert.Len(t, validationResults.Accepted, 1)
require.Len(t, validationResults.Rejected, 0)
orderHash, err := signedOrder.ComputeOrderHash()
Expand Down Expand Up @@ -290,7 +290,7 @@ func TestBatchValidateMaxGasPriceOrder(t *testing.T) {
ctx := context.Background()
latestBlock, err := ethRPCClient.HeaderByNumber(ctx, nil)
require.NoError(t, err)
validationResults := orderValidator.BatchValidate(ctx, signedOrders, areNewOrders, latestBlock.Number)
validationResults := orderValidator.BatchValidate(ctx, signedOrders, areNewOrders, latestBlock)
assert.Len(t, validationResults.Accepted, 1)
require.Len(t, validationResults.Rejected, 0)
expectedOrderHash, err := signedOrder.ComputeOrderHash()
Expand All @@ -315,7 +315,7 @@ func TestBatchValidateSignatureInvalid(t *testing.T) {
ctx := context.Background()
latestBlock, err := ethRPCClient.HeaderByNumber(ctx, nil)
require.NoError(t, err)
validationResults := orderValidator.BatchValidate(ctx, signedOrders, areNewOrders, latestBlock.Number)
validationResults := orderValidator.BatchValidate(ctx, signedOrders, areNewOrders, latestBlock)
assert.Len(t, validationResults.Accepted, 0)
require.Len(t, validationResults.Rejected, 1)
assert.Equal(t, ROInvalidSignature, validationResults.Rejected[0].Status)
Expand All @@ -338,7 +338,7 @@ func TestBatchValidateUnregisteredCoordinator(t *testing.T) {
ctx := context.Background()
latestBlock, err := ethRPCClient.HeaderByNumber(ctx, nil)
require.NoError(t, err)
validationResults := orderValidator.BatchValidate(ctx, signedOrders, areNewOrders, latestBlock.Number)
validationResults := orderValidator.BatchValidate(ctx, signedOrders, areNewOrders, latestBlock)
assert.Len(t, validationResults.Accepted, 0)
require.Len(t, validationResults.Rejected, 1)
assert.Equal(t, ROCoordinatorEndpointNotFound, validationResults.Rejected[0].Status)
Expand Down Expand Up @@ -399,7 +399,7 @@ func TestBatchValidateCoordinatorSoftCancels(t *testing.T) {
ctx = context.Background()
latestBlock, err := ethRPCClient.HeaderByNumber(ctx, nil)
require.NoError(t, err)
validationResults := orderValidator.BatchValidate(ctx, signedOrders, areNewOrders, latestBlock.Number)
validationResults := orderValidator.BatchValidate(ctx, signedOrders, areNewOrders, latestBlock)
assert.Len(t, validationResults.Accepted, 0)
require.Len(t, validationResults.Rejected, 1)
assert.Equal(t, ROCoordinatorSoftCancelled, validationResults.Rejected[0].Status)
Expand Down
Loading

0 comments on commit 25f26f8

Please sign in to comment.