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

Commit

Permalink
Merge pull request #676 from 0xProject/release/8.2.0
Browse files Browse the repository at this point in the history
Release 8.2.0
  • Loading branch information
fabioberger authored Jan 27, 2020
2 parents 7854825 + c86ee07 commit 0ca1efd
Show file tree
Hide file tree
Showing 25 changed files with 1,380 additions and 812 deletions.
4 changes: 2 additions & 2 deletions .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ steps:
from_secret: docker_username
password:
from_secret: docker_password
dockerfile: dockerfiles/mesh/Dockerfile
dockerfile: dockerfiles/mesh-bootstrap/Dockerfile
node_selector:
drone-builds: true
---
Expand Down Expand Up @@ -74,7 +74,7 @@ steps:
from_secret: docker_username
password:
from_secret: docker_password
dockerfile: dockerfiles/mesh/Dockerfile
dockerfile: dockerfiles/mesh-bootstrap/Dockerfile
trigger:
branch:
- development
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

This changelog is a work in progress and may contain notes for versions which have not actually been released. Check the [Releases](https://github.com/0xProject/0x-mesh/releases) page to see full release notes and more information about the latest released versions.

## v8.2.0

### Features ✅

- Added `getStatsAsync` to the `@0x/mesh-browser` package. ([#654](https://github.com/0xProject/0x-mesh/pull/654)).
- Added `getOrdersAsync` and `getOrdersForPageAsync` to the `@0x/mesh-browser` package. ([#655](https://github.com/0xProject/0x-mesh/pull/655)).

### Bug fixes 🐞

- Update DevUtils contract address to fix intermittent revert issues. ([#671](https://github.com/0xProject/0x-mesh/pull/671)).


## v8.1.2

### Bug fixes 🐞
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[![Version](https://img.shields.io/badge/version-8.1.2-orange.svg)](https://github.com/0xProject/0x-mesh/releases)
[![Version](https://img.shields.io/badge/version-8.2.0-orange.svg)](https://github.com/0xProject/0x-mesh/releases)
[![Docs](https://img.shields.io/badge/docs-website-yellow.svg)](https://0x-org.gitbook.io/mesh)
[![Chat with us on Discord](https://img.shields.io/badge/chat-Discord-blueViolet.svg)](https://discord.gg/HF7fHwk)
[![Circle CI](https://img.shields.io/circleci/project/0xProject/0x-mesh/master.svg)](https://circleci.com/gh/0xProject/0x-mesh/tree/master)
Expand Down
39 changes: 39 additions & 0 deletions browser/go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,27 @@ func (cw *MeshWrapper) AddOrders(rawOrders js.Value, pinned bool) (js.Value, err
return resultsJS, nil
}

// GetStats calls core.GetStats, converts the result to a js.Value and returns
// it.
func (cw *MeshWrapper) GetStats() (js.Value, error) {
stats, err := cw.app.GetStats()
if err != nil {
return js.Undefined(), err
}
return js.ValueOf(stats), nil
}

// GetOrders converts raw JavaScript parameters into the appropriate type, calls
// core.App.GetOrders, converts the result into basic JavaScript types (string,
// int, etc.) and returns it.
func (cw *MeshWrapper) GetOrders(page int, perPage int, snapshotID string) (js.Value, error) {
ordersResponse, err := cw.app.GetOrders(page, perPage, snapshotID)
if err != nil {
return js.Undefined(), err
}
return js.ValueOf(ordersResponse), nil
}

// JSValue satisfies the js.Wrapper interface. The return value is a JavaScript
// object consisting of named functions. They act like methods by capturing the
// MeshWrapper through a closure.
Expand All @@ -248,6 +269,24 @@ func (cw *MeshWrapper) JSValue() js.Value {
cw.orderEventsHandler = handler
return nil
}),
// getStatsAsync(): Promise<Stats>
"getStatsAsync": js.FuncOf(func(this js.Value, args []js.Value) interface{} {
return wrapInPromise(func() (interface{}, error) {
return cw.GetStats()
})
}),
// getOrdersForPageAsync(page: number, perPage: number, snapshotID?: string): Promise<GetOrdersResponse>
"getOrdersForPageAsync": js.FuncOf(func(this js.Value, args []js.Value) interface{} {
return wrapInPromise(func() (interface{}, error) {
// snapshotID is optional in the JavaScript function. Check if it is
// null or undefined.
snapshotID := ""
if !isNullOrUndefined(args[2]) {
snapshotID = args[2].String()
}
return cw.GetOrders(args[0].Int(), args[1].Int(), snapshotID)
})
}),
// addOrdersAsync(orders: Array<SignedOrder>): Promise<ValidationResults>
"addOrdersAsync": js.FuncOf(func(this js.Value, args []js.Value) interface{} {
return wrapInPromise(func() (interface{}, error) {
Expand Down
2 changes: 1 addition & 1 deletion browser/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@0x/mesh-browser",
"version": "8.1.2",
"version": "8.2.0",
"description": "TypeScript and JavaScript bindings for running Mesh directly in the browser.",
"main": "./lib/index.js",
"license": "Apache-2.0",
Expand Down
166 changes: 166 additions & 0 deletions browser/ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,69 @@ export interface ContractAddresses {
zrxToken?: string;
}

export interface LatestBlock {
number: number;
hash: string;
}

interface WrapperStats {
version: string;
pubSubTopic: string;
rendezvous: string;
peerID: string;
ethereumChainID: number;
latestBlock: LatestBlock;
numPeers: number;
numOrders: number;
numOrdersIncludingRemoved: number;
numPinnedOrders: number;
maxExpirationTime: string; // string instead of BigNumber
startOfCurrentUTCDay: string; // string instead of Date
ethRPCRequestsSentInCurrentUTCDay: number;
ethRPCRateLimitExpiredRequests: number;
}

export interface Stats {
version: string;
pubSubTopic: string;
rendezvous: string;
peerID: string;
ethereumChainID: number;
latestBlock: LatestBlock;
numPeers: number;
numOrders: number;
numOrdersIncludingRemoved: number;
numPinnedOrders: number;
maxExpirationTime: BigNumber;
startOfCurrentUTCDay: Date;
ethRPCRequestsSentInCurrentUTCDay: number;
ethRPCRateLimitExpiredRequests: number;
}

interface WrapperOrderInfo {
orderHash: string;
signedOrder: WrapperSignedOrder;
fillableTakerAssetAmount: string;
}

export interface OrderInfo {
orderHash: string;
signedOrder: SignedOrder;
fillableTakerAssetAmount: BigNumber;
}

interface WrapperGetOrdersResponse {
snapshotID: string;
snapshotTimestamp: number;
ordersInfos: WrapperOrderInfo[];
}

export interface GetOrdersResponse {
snapshotID: string;
snapshotTimestamp: number;
ordersInfos: OrderInfo[];
}

export enum Verbosity {
Panic = 0,
Fatal = 1,
Expand All @@ -162,6 +225,8 @@ interface MeshWrapper {
startAsync(): Promise<void>;
onError(handler: (err: Error) => void): void;
onOrderEvents(handler: (events: WrapperOrderEvent[]) => void): void;
getStatsAsync(): Promise<WrapperStats>;
getOrdersForPageAsync(page: number, perPage: number, snapshotID?: string): Promise<WrapperGetOrdersResponse>;
addOrdersAsync(orders: WrapperSignedOrder[], pinned: boolean): Promise<WrapperValidationResults>;
}

Expand Down Expand Up @@ -631,6 +696,82 @@ export class Mesh {
return this._wrapper.startAsync();
}

/**
* Returns various stats about Mesh, including the total number of orders
* and the number of peers Mesh is connected to.
*/
public async getStatsAsync(): Promise<Stats> {
await waitForLoadAsync();
if (this._wrapper === undefined) {
// If this is called after startAsync, this._wrapper is always
// defined. This check is here just in case and satisfies the
// compiler.
return Promise.reject(new Error('Mesh is still loading. Try again soon.'));
}
const wrapperStats = await this._wrapper.getStatsAsync();
return wrapperStatsToStats(wrapperStats);
}

/**
* Get all 0x signed orders currently stored in the Mesh node
* @param perPage number of signedOrders to fetch per paginated request
* @returns the snapshotID, snapshotTimestamp and all orders, their hashes and fillableTakerAssetAmounts
*/
public async getOrdersAsync(perPage: number = 200): Promise<GetOrdersResponse> {
await waitForLoadAsync();
if (this._wrapper === undefined) {
// If this is called after startAsync, this._wrapper is always
// defined. This check is here just in case and satisfies the
// compiler.
return Promise.reject(new Error('Mesh is still loading. Try again soon.'));
}

let snapshotID = ''; // New snapshot

// TODO(albrow): De-dupe this code with the method by the same name
// in the TypeScript RPC client.
let page = 0;
let getOrdersResponse = await this.getOrdersForPageAsync(page, perPage, snapshotID);
snapshotID = getOrdersResponse.snapshotID;
let ordersInfos = getOrdersResponse.ordersInfos;

let allOrderInfos: OrderInfo[] = [];

do {
allOrderInfos = [...allOrderInfos, ...ordersInfos];
page++;
getOrdersResponse = await this.getOrdersForPageAsync(page, perPage, snapshotID);
ordersInfos = getOrdersResponse.ordersInfos;
} while (ordersInfos.length > 0);

getOrdersResponse = {
snapshotID,
snapshotTimestamp: getOrdersResponse.snapshotTimestamp,
ordersInfos: allOrderInfos,
};
return getOrdersResponse;
}

/**
* Get page of 0x signed orders stored on the Mesh node at the specified snapshot
* @param page Page index at which to retrieve orders
* @param perPage Number of signedOrders to fetch per paginated request
* @param snapshotID The DB snapshot at which to fetch orders. If omitted, a new snapshot is created
* @returns the snapshotID, snapshotTimestamp and all orders, their hashes and fillableTakerAssetAmounts
*/
public async getOrdersForPageAsync(page: number, perPage: number, snapshotID?: string): Promise<GetOrdersResponse> {
await waitForLoadAsync();
if (this._wrapper === undefined) {
// If this is called after startAsync, this._wrapper is always
// defined. This check is here just in case and satisfies the
// compiler.
return Promise.reject(new Error('Mesh is still loading. Try again soon.'));
}

const wrapperOrderResponse = await this._wrapper.getOrdersForPageAsync(page, perPage, snapshotID);
return wrapperGetOrdersResponseToGetOrdersResponse(wrapperOrderResponse);
}

/**
* Validates and adds the given orders to Mesh. If an order is successfully
* added, Mesh will share it with any peers in the network and start
Expand Down Expand Up @@ -863,6 +1004,31 @@ function orderEventsHandlerToWrapperOrderEventsHandler(
};
}

function wrapperStatsToStats(wrapperStats: WrapperStats): Stats {
return {
...wrapperStats,
startOfCurrentUTCDay: new Date(wrapperStats.startOfCurrentUTCDay),
maxExpirationTime: new BigNumber(wrapperStats.maxExpirationTime),
};
}

function wrapperGetOrdersResponseToGetOrdersResponse(
wrapperGetOrdersResponse: WrapperGetOrdersResponse,
): GetOrdersResponse {
return {
...wrapperGetOrdersResponse,
ordersInfos: wrapperGetOrdersResponse.ordersInfos.map(wrapperOrderInfoToOrderInfo),
};
}

function wrapperOrderInfoToOrderInfo(wrapperOrderInfo: WrapperOrderInfo): OrderInfo {
return {
...wrapperOrderInfo,
fillableTakerAssetAmount: new BigNumber(wrapperOrderInfo.fillableTakerAssetAmount),
signedOrder: wrapperSignedOrderToSignedOrder(wrapperOrderInfo.signedOrder),
};
}

function wrapperValidationResultsToValidationResults(
wrapperValidationResults: WrapperValidationResults,
): ValidationResults {
Expand Down
7 changes: 4 additions & 3 deletions cmd/mesh/rpc_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"strings"
"time"

"github.com/0xProject/0x-mesh/common/types"
"github.com/0xProject/0x-mesh/constants"
"github.com/0xProject/0x-mesh/core"
"github.com/0xProject/0x-mesh/rpc"
Expand Down Expand Up @@ -60,7 +61,7 @@ func listenRPC(ctx context.Context, app *core.App, config standaloneConfig) erro
}

// GetOrders is called when an RPC client calls GetOrders.
func (handler *rpcHandler) GetOrders(page, perPage int, snapshotID string) (result *rpc.GetOrdersResponse, err error) {
func (handler *rpcHandler) GetOrders(page, perPage int, snapshotID string) (result *types.GetOrdersResponse, err error) {
log.WithFields(map[string]interface{}{
"page": page,
"perPage": perPage,
Expand Down Expand Up @@ -98,7 +99,7 @@ func (handler *rpcHandler) GetOrders(page, perPage int, snapshotID string) (resu
}

// AddOrders is called when an RPC client calls AddOrders.
func (handler *rpcHandler) AddOrders(signedOrdersRaw []*json.RawMessage, opts rpc.AddOrdersOpts) (results *ordervalidator.ValidationResults, err error) {
func (handler *rpcHandler) AddOrders(signedOrdersRaw []*json.RawMessage, opts types.AddOrdersOpts) (results *ordervalidator.ValidationResults, err error) {
log.WithFields(log.Fields{
"count": len(signedOrdersRaw),
"pinned": opts.Pinned,
Expand Down Expand Up @@ -155,7 +156,7 @@ func (handler *rpcHandler) AddPeer(peerInfo peerstore.PeerInfo) (err error) {
}

// GetStats is called when an RPC client calls GetStats,
func (handler *rpcHandler) GetStats() (result *rpc.GetStatsResponse, err error) {
func (handler *rpcHandler) GetStats() (result *types.Stats, err error) {
log.Debug("received GetStats request via RPC")
// Catch panics, log stack trace and return RPC error message
defer func() {
Expand Down
Loading

0 comments on commit 0ca1efd

Please sign in to comment.