diff --git a/packages/chain/package.json b/packages/chain/package.json index 42e9640..a6f9a09 100644 --- a/packages/chain/package.json +++ b/packages/chain/package.json @@ -1,5 +1,5 @@ { - "name": "@deth/chain", + "name": "@ethereum-ts/chain", "description": "Local ethereum chain with sane api.", "version": "0.1.0", "license": "MIT", @@ -7,8 +7,7 @@ "module": "./dist/esm/index.js", "types": "./dist/esm/index.d.ts", "engines": { - "node": "^11.15.0", - "yarn": ">=1.15.2" + "node": ">=8.0.0" }, "scripts": { "lint": "eslint --ext .ts src test", diff --git a/packages/chain/src/Chain.ts b/packages/chain/src/Chain.ts index 787e78a..29acd9e 100644 --- a/packages/chain/src/Chain.ts +++ b/packages/chain/src/Chain.ts @@ -169,7 +169,7 @@ export class Chain { ): Promise async getBlock (blockTagOrHash: Quantity | Tag | Hash, includeTransactions?: boolean) { - if (blockTagOrHash === 'pending') { + if (blockTagOrHash === 'pending' || blockTagOrHash === 'earliest') { throw unsupportedBlockTag('call', blockTagOrHash) } diff --git a/packages/chain/src/model/FilterRequest.ts b/packages/chain/src/model/FilterRequest.ts index 5fd7fb5..6c1c00a 100644 --- a/packages/chain/src/model/FilterRequest.ts +++ b/packages/chain/src/model/FilterRequest.ts @@ -10,12 +10,16 @@ export interface FilterByRangeRequest { fromBlock?: Quantity | Tag, toBlock?: Quantity | Tag, address?: Address, - topics?: unknown, + topics?: Hash[], } // https://github.com/ethers-io/ethers.js/blob/4ac08432b8e2c7c374dc4a0e141a39a369e2d430/src.ts/providers/base-provider.ts#L370 export interface FilterByBlockRequest { blockHash?: Hash, address?: Address, - topics?: unknown, + topics?: Hash[], +} + +export function isByBlockRequest (filter: FilterRequest): filter is FilterByBlockRequest { + return (filter as any).blockHash } diff --git a/packages/chain/src/model/primitives/Hash.ts b/packages/chain/src/model/primitives/Hash.ts index 4670515..2e599b7 100644 --- a/packages/chain/src/model/primitives/Hash.ts +++ b/packages/chain/src/model/primitives/Hash.ts @@ -1,6 +1,7 @@ import { Opaque } from 'ts-essentials' import { HEX_REGEX } from './common' import { bufferToHex, toBuffer } from 'ethereumjs-util' +import { isString } from 'lodash' /** * A hexadecimal string representing a hash. @@ -21,3 +22,7 @@ export function bufferToHash (buffer: Buffer): Hash { export function hashToBuffer (hash: Hash): Buffer { return toBuffer(hash) } + +export function isHash (value: any): value is Hash { + return isString(value) && value.length === 66 +} diff --git a/packages/chain/src/vm/SaneVM.ts b/packages/chain/src/vm/SaneVM.ts index fb9106c..4c12eb8 100644 --- a/packages/chain/src/vm/SaneVM.ts +++ b/packages/chain/src/vm/SaneVM.ts @@ -1,12 +1,9 @@ import VM from 'ethereumts-vm' -import Block from 'ethereumjs-block' -import { BN, toBuffer } from 'ethereumjs-util' import { Transaction } from 'ethereumjs-tx' -import { RpcTransactionReceipt, RpcTransactionResponse, RpcBlockResponse, toBlockResponse } from '../model' +import { RpcBlockResponse, toBlockResponse } from '../model' import { ChainOptions } from '../ChainOptions' import { Hash, Address, bufferToHash, Quantity, bufferToQuantity, HexData, bufferToHexData } from '../model' import { initializeVM } from './initializeVM' -import { getLatestBlock } from './getLatestBlock' import { putBlock } from './putBlock' import { runIsolatedTransaction } from './runIsolatedTransaction' import { DethStateManger } from './storage/DethStateManger' @@ -18,6 +15,7 @@ import { InterpreterStep } from 'ethereumts-vm/dist/evm/interpreter' import { BlockchainAdapter } from './storage/BlockchainAdapter' import { StateManagerAdapter } from './storage/StateManagerAdapter' import { Snapshot } from '../utils/Snapshot' +import { assert } from 'ts-essentials' interface VMSnapshot { blockchain: DethBlockchain, @@ -32,18 +30,19 @@ export class SaneVM { vm!: VM state: Snapshot<{ stateManger: DethStateManger, blockchain: DethBlockchain }> pendingTransactions: Transaction[] = [] - transactions: Map = new Map() - receipts: Map = new Map() snapshots: VMSnapshot[] = [] constructor (private options: ChainOptions) { - this.state = new Snapshot({ - stateManger: new DethStateManger(), - blockchain: new DethBlockchain(), - }, (t) => ({ - blockchain: t.blockchain.copy(), - stateManger: t.stateManger.copy(), - })) + this.state = new Snapshot( + { + stateManger: new DethStateManger(), + blockchain: new DethBlockchain(), + }, + t => ({ + blockchain: t.blockchain.copy(), + stateManger: t.stateManger.copy(), + }), + ) } async init () { @@ -73,13 +72,17 @@ export class SaneVM { ;(this.vm as any).pStateManager = new PStateManager(stateManagerAdapter as any) } - async getBlockNumber (): Promise { - const block = await getLatestBlock(this.vm) + getBlockNumber (): Quantity { + const block = this.state.value.blockchain.getLatestBlock() + assert(block, 'Blockchain is empty (no genesis block was generated)') + return bufferToQuantity(block.header.number) } - async getLatestBlock (): Promise { - const block = await getLatestBlock(this.vm) + getLatestBlock (): RpcBlockResponse { + const block = this.state.value.blockchain.getLatestBlock() + assert(block, 'Blockchain is empty (no genesis block was generated)') + return toBlockResponse(block) } @@ -93,22 +96,15 @@ export class SaneVM { const transactions = this.pendingTransactions this.pendingTransactions = [] - const { receipts, responses } = await putBlock(this.vm, transactions, this.options, clockSkew) - - for (const receipt of receipts) { - this.receipts.set(receipt.transactionHash, receipt) - } - for (const response of responses) { - this.transactions.set(response.hash, response) - } + await putBlock(this.vm, this.state.value.blockchain, transactions, this.options, clockSkew) } getTransaction (hash: Hash) { - return this.transactions.get(hash) + return this.state.value.blockchain.getTransaction(hash) } getTransactionReceipt (hash: Hash) { - return this.receipts.get(hash) + return this.state.value.blockchain.getTransactionReceipt(hash) } async getNonce (address: Address) { @@ -131,14 +127,10 @@ export class SaneVM { } async runIsolatedTransaction (transaction: Transaction, clockSkew: number) { - return runIsolatedTransaction(this.vm, transaction, this.options, clockSkew) + return runIsolatedTransaction(this.vm, this.state.value.blockchain, transaction, this.options, clockSkew) } - async getBlock (hashOrNumber: string): Promise { - const query = hashOrNumber.length === 66 ? toBuffer(hashOrNumber) : new BN(hashOrNumber.substr(2), 'hex') - const block = await new Promise((resolve, reject) => { - this.vm.blockchain.getBlock(query, (err: unknown, block: Block) => (err != null ? reject(err) : resolve(block))) - }) - return toBlockResponse(block) + async getBlock (hashOrNumber: Quantity | Hash): Promise { + return toBlockResponse(this.state.value.blockchain.getBlock(hashOrNumber)) } } diff --git a/packages/chain/src/vm/getLatestBlock.ts b/packages/chain/src/vm/getLatestBlock.ts deleted file mode 100644 index eb15775..0000000 --- a/packages/chain/src/vm/getLatestBlock.ts +++ /dev/null @@ -1,11 +0,0 @@ -import VM from 'ethereumts-vm' -import Block from 'ethereumjs-block' - -export function getLatestBlock (vm: VM): Promise { - return new Promise((resolve, reject) => { - vm.blockchain.getLatestBlock((err: unknown, block: Block) => { - if (err) reject(err) - resolve(block) - }) - }) -} diff --git a/packages/chain/src/vm/getNextBlock.ts b/packages/chain/src/vm/getNextBlock.ts index 1529a80..e85175d 100644 --- a/packages/chain/src/vm/getNextBlock.ts +++ b/packages/chain/src/vm/getNextBlock.ts @@ -4,21 +4,24 @@ import { Transaction } from 'ethereumjs-tx' import BN from 'bn.js' import { toBuffer } from 'ethereumjs-util' import { ChainOptions } from '../ChainOptions' -import { getLatestBlock } from './getLatestBlock' +import { assert } from 'ts-essentials' +import { DethBlockchain } from './storage/DethBlockchain' export async function getNextBlock ( vm: VM, + blockchain: DethBlockchain, transactions: Transaction[], options: ChainOptions, clockSkew: number, ): Promise { - const block = await getEmptyNextBlock(vm, options, clockSkew) + const block = await getEmptyNextBlock(vm, blockchain, options, clockSkew) await addTransactionsToBlock(block, transactions) return block } -async function getEmptyNextBlock (vm: VM, options: ChainOptions, clockSkew: number) { - const latestBlock = await getLatestBlock(vm) +async function getEmptyNextBlock (vm: VM, blockchain: DethBlockchain, options: ChainOptions, clockSkew: number) { + const latestBlock = blockchain.getLatestBlock() + assert(latestBlock, 'Blockchain is empty (no genesis block was generated)') const header: BlockHeaderData = { gasLimit: options.blockGasLimit, @@ -29,7 +32,7 @@ async function getEmptyNextBlock (vm: VM, options: ChainOptions, clockSkew: numb coinbase: options.coinbaseAddress, } const block = new Block({ header }, { common: vm._common }) - block.validate = (blockchain, cb) => cb(null) + block.validate = (_blockchain, cb) => cb(null) block.header.difficulty = toBuffer(block.header.canonicalDifficulty(latestBlock)) return block @@ -38,7 +41,7 @@ async function getEmptyNextBlock (vm: VM, options: ChainOptions, clockSkew: numb async function addTransactionsToBlock (block: Block, transactions: Transaction[]) { block.transactions.push(...transactions) await new Promise((resolve, reject) => { - block.genTxTrie(err => err != null ? reject(err) : resolve()) + block.genTxTrie(err => (err != null ? reject(err) : resolve())) }) block.header.transactionsTrie = block.txTrie.root } diff --git a/packages/chain/src/vm/putBlock.ts b/packages/chain/src/vm/putBlock.ts index bb39317..10e0743 100644 --- a/packages/chain/src/vm/putBlock.ts +++ b/packages/chain/src/vm/putBlock.ts @@ -4,9 +4,16 @@ import { Transaction } from 'ethereumjs-tx' import { ChainOptions } from '../ChainOptions' import { getNextBlock } from './getNextBlock' import { getReceiptsAndResponses } from './getReceiptsAndResponses' +import { DethBlockchain } from './storage/DethBlockchain' -export async function putBlock (vm: VM, transactions: Transaction[], options: ChainOptions, clockSkew: number) { - const block = await getNextBlock(vm, transactions, options, clockSkew) +export async function putBlock ( + vm: VM, + blockchain: DethBlockchain, + transactions: Transaction[], + options: ChainOptions, + clockSkew: number, +) { + const block = await getNextBlock(vm, blockchain, transactions, options, clockSkew) const { results } = await vm.runBlock({ block, @@ -16,10 +23,13 @@ export async function putBlock (vm: VM, transactions: Transaction[], options: Ch skipBalance: options.skipBalanceCheck, }) await new Promise((resolve, reject) => { - vm.blockchain.putBlock(block, (err: unknown, block: Block) => - err != null ? reject(err) : resolve(block), - ) + vm.blockchain.putBlock(block, (err: unknown, block: Block) => (err != null ? reject(err) : resolve(block))) }) - return getReceiptsAndResponses(block, transactions, results) + const { receipts, responses } = getReceiptsAndResponses(block, transactions, results) + + blockchain.addReceipts(receipts) + blockchain.addTransactions(responses) + + return { receipts, responses } } diff --git a/packages/chain/src/vm/runIsolatedTransaction.ts b/packages/chain/src/vm/runIsolatedTransaction.ts index 3a0ad43..e29ab33 100644 --- a/packages/chain/src/vm/runIsolatedTransaction.ts +++ b/packages/chain/src/vm/runIsolatedTransaction.ts @@ -4,9 +4,11 @@ import { Transaction } from 'ethereumjs-tx' import { RunTxResult } from 'ethereumts-vm/dist/runTx' import { getNextBlock } from './getNextBlock' import { ChainOptions } from '../ChainOptions' +import { DethBlockchain } from './storage/DethBlockchain' export async function runIsolatedTransaction ( vm: VM, + blockchain: DethBlockchain, transaction: Transaction, options: ChainOptions, clockSkew: number, @@ -15,7 +17,7 @@ export async function runIsolatedTransaction ( const initialStateRoot = await psm.getStateRoot() try { - const block = await getNextBlock(vm, [transaction], options, clockSkew) + const block = await getNextBlock(vm, blockchain, [transaction], options, clockSkew) const result = await vm.runTx({ block, tx: transaction, diff --git a/packages/chain/src/vm/storage/BlockchainRepository.ts b/packages/chain/src/vm/storage/BlockchainRepository.ts new file mode 100644 index 0000000..dea1a73 --- /dev/null +++ b/packages/chain/src/vm/storage/BlockchainRepository.ts @@ -0,0 +1,57 @@ +import { range, flatten } from 'lodash' + +import { Snapshot } from '../../utils/Snapshot' +import { DethStateManger } from './DethStateManger' +import { DethBlockchain } from './DethBlockchain' +import { RpcBlockResponse, numberToQuantity, toBlockResponse, RpcTransactionReceipt } from '../../model' +import { isByBlockRequest, FilterRequest, RpcLogObject } from '../..' + +export class BlockchainRepository { + constructor (private readonly state: Snapshot<{ stateManger: DethStateManger, blockchain: DethBlockchain }>) {} + + // @todo: super slow impl + getAllReceipts (blocks: RpcBlockResponse[]): RpcTransactionReceipt[] { + const validBlockHashes = blocks.map(b => b.hash) + + const receipts: RpcTransactionReceipt[] = [] + for (const receipt of this.state.value.blockchain.receipts.values()) { + if (validBlockHashes.includes(receipt.blockHash)) { + receipts.push(receipt) + } + } + + return receipts + } + + getLogs (filter: FilterRequest): RpcLogObject[] { + const blocks: RpcBlockResponse[] = [] + if (isByBlockRequest(filter)) { + blocks.push(toBlockResponse(this.state.value.blockchain.getBlockByHash(filter.blockHash!))) + } else { + // TODO: fix handling for tags! + blocks.push(...this.getBlockByRange(filter.fromBlock as any, (filter.toBlock as any)!)) + } + + const receipts = this.getAllReceipts(blocks) + let logs = flatten(receipts.map(r => r.logs)) + + if (filter.address) { + logs = logs.filter(r => r.address === filter.address) + } + + if (filter.topics) { + // @todo implement + throw new Error('unimplemented') + // logs = logs.filter(r => r.topics) + } + + return logs + } + + getBlockByRange (start: number, _last?: number): RpcBlockResponse[] { + const last = _last ?? this.state.value.blockchain.getBlockNumber() + return range(start, last) + .map(n => this.state.value.blockchain.getBlockByNumber(numberToQuantity(n))) + .map(toBlockResponse) + } +} diff --git a/packages/chain/src/vm/storage/DethBlockchain.ts b/packages/chain/src/vm/storage/DethBlockchain.ts index 415afef..46d484a 100644 --- a/packages/chain/src/vm/storage/DethBlockchain.ts +++ b/packages/chain/src/vm/storage/DethBlockchain.ts @@ -1,11 +1,43 @@ import Block from 'ethereumjs-block' -import { Quantity, Hash, bufferToHash, quantityToNumber } from '../../model' +import { + Quantity, + Hash, + bufferToHash, + quantityToNumber, + RpcTransactionResponse, + RpcTransactionReceipt, + isHash, +} from '../../model' /** * Simple, in memory, copyable blockchain */ export class DethBlockchain { - constructor (private blocks: Block[] = []) {} + constructor ( + public readonly blocks: Block[] = [], + public readonly transactions: Map = new Map(), + public readonly receipts: Map = new Map(), + ) {} + + addReceipts (receipts: RpcTransactionReceipt[]): void { + for (const receipt of receipts) { + this.receipts.set(receipt.transactionHash, receipt) + } + } + + addTransactions (txs: RpcTransactionResponse[]): void { + for (const tx of txs) { + this.transactions.set(tx.hash, tx) + } + } + + getBlock (hashOrQuantity: Quantity | Hash): Block { + if (isHash(hashOrQuantity)) { + return this.getBlockByHash(hashOrQuantity) + } else { + return this.getBlockByNumber(hashOrQuantity) + } + } getBlockByNumber (blockNumber: Quantity) { return this.blocks[quantityToNumber(blockNumber)] @@ -37,7 +69,22 @@ export class DethBlockchain { return this.blocks[this.blocks.length - 1] } + getBlockNumber (): number { + return this.blocks.length + } + + getTransaction (hash: Hash) { + return this.transactions.get(hash) + } + + getTransactionReceipt (hash: Hash) { + return this.receipts.get(hash) + } + copy () { - return new DethBlockchain([...this.blocks]) + return new DethBlockchain([...this.blocks], new Map(this.transactions), new Map(this.receipts)) } } + +// extract BlockchainRepository with all methods using OUR interface already +// it should have reference to blockchain? diff --git a/packages/node/package.json b/packages/node/package.json index 68ebcab..6aa268a 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -36,7 +36,7 @@ "test:fix": "yarn lint:fix && yarn test && yarn typecheck" }, "dependencies": { - "@deth/chain": "^0.1.0", + "@ethereum-ts/chain": "^0.1.0", "@types/classnames": "^2.2.9", "@types/debug": "^4.1.5", "@types/express": "^4.17.2", diff --git a/packages/node/src/config/config.ts b/packages/node/src/config/config.ts index a88adf8..37d8480 100644 --- a/packages/node/src/config/config.ts +++ b/packages/node/src/config/config.ts @@ -1,4 +1,4 @@ -import { ChainOptions, DEFAULT_CHAIN_OPTIONS } from '@deth/chain' +import { ChainOptions, DEFAULT_CHAIN_OPTIONS } from '@ethereum-ts/chain' import { Path, makePath } from '../services/fs/Path' import { DeepPartial } from 'ts-essentials' import { merge } from 'lodash' diff --git a/packages/node/src/rpc/codecs.ts b/packages/node/src/rpc/codecs.ts index 7372134..7d755c9 100644 --- a/packages/node/src/rpc/codecs.ts +++ b/packages/node/src/rpc/codecs.ts @@ -1,6 +1,7 @@ import * as t from 'io-ts' import { Either, map } from 'fp-ts/lib/Either' -import { makeQuantity, makeHexData, makeHash, makeAddress } from '@deth/chain' +import { flow } from 'lodash' +import { makeQuantity, makeHexData, makeHash, makeAddress } from '@ethereum-ts/chain' const mapCodec = ( type: t.Type, @@ -15,18 +16,28 @@ const mapCodec = ( ) as any // @TODO: without any I can't get compiler to accept this type... export const quantity = codecFromMake(makeQuantity) -export const hexData = codecFromMake(makeHexData) +export const hexData = codecFromMake(flow(normalize0xPrefix, makeHexData)) export const hash = codecFromMake(makeHash) export const address = codecFromMake(makeAddress) +function normalize0xPrefix (data: string): string { + if (!data.startsWith('0x')) { + return '0x' + data + } + return data +} + const toNull = (x: A | undefined): A | null => x ?? null const toUndefined = (x: A | null | undefined): A | undefined => x ?? undefined +const toDefaultValue = (defaultValue: A) => (x: A | null | undefined): A | undefined => x ?? defaultValue // automatically deals with null/undefined conversions across the RPC <-> our code boundary // decodes: null and undefined to undefined // encodes undefined to nulls export const undefinable = (type: t.Type) => mapCodec(t.union([type, t.null, t.undefined]), map(toUndefined), toNull) +export const undefinableOr = (type: t.Type, defaultInputValue: A) => + mapCodec(t.union([type, t.null, t.undefined]), map(toDefaultValue(defaultInputValue)), toNull) function codecFromMake (make: (value: string) => T) { return new t.Type('RPC_QUANTITY', checkFromMake(make), validateFromMake(make), make) @@ -53,7 +64,7 @@ function validateFromMake (make: (value: string) => T) { try { return t.success(make(value)) } catch (e) { - return t.failure(`Can't parse "${value}"`, c) + return t.failure(`Can't parse value. Reason: ${e.message ?? 'unknown'}. Original value: "${value}"`, c) } } } diff --git a/packages/node/src/rpc/middlewares.ts b/packages/node/src/rpc/middlewares.ts index 3ace63b..461bd1a 100644 --- a/packages/node/src/rpc/middlewares.ts +++ b/packages/node/src/rpc/middlewares.ts @@ -66,6 +66,7 @@ export function sanitizeRPC ( return res.right } + d(`Error during decoding calldata. Method: ${method}, calldata: ${JSON.stringify(params)}`) throw new IOTSError(res) } diff --git a/packages/node/src/rpc/schema.ts b/packages/node/src/rpc/schema.ts index 32a0112..9fb6f02 100644 --- a/packages/node/src/rpc/schema.ts +++ b/packages/node/src/rpc/schema.ts @@ -1,6 +1,6 @@ import * as t from 'io-ts' import { AsyncOrSync } from 'ts-essentials' -import { quantity, hash, hexData, address, undefinable } from './codecs' +import { quantity, hash, hexData, address, undefinable, undefinableOr } from './codecs' export const tag = t.union([t.literal('earliest'), t.literal('latest'), t.literal('pending')]) @@ -36,12 +36,21 @@ const log = t.type({ blockNumber: quantity, data: hexData, logIndex: quantity, - removed: t.literal(false), + removed: t.boolean, topics: t.array(hash), transactionHash: hash, transactionIndex: quantity, }) +// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getlogs +const logFilter = t.type({ + fromBlock: undefinableOr(quantityOrTag, 'latest'), + toBlock: undefinableOr(quantityOrTag, 'latest'), + address: undefinable(address), + topics: undefinable(t.array(hash)), + blockHash: undefinable(hash), +}) + // https://github.com/ethereum/wiki/wiki/JSON-RPC#returns-31 const txReceipt = t.type({ transactionHash: hash, @@ -160,6 +169,11 @@ export const rpcCommandsDescription = { // note: currently supports only block filters returns: t.boolean, }, + eth_getLogs: { + parameters: t.tuple([logFilter]), + // note: currently supports only block filters + returns: t.array(log), + }, // ganache compatibility // docs: https://github.com/trufflesuite/ganache-cli#custom-methods diff --git a/packages/node/src/services/Explorer.ts b/packages/node/src/services/Explorer.ts index b3bdbd3..f064aa6 100644 --- a/packages/node/src/services/Explorer.ts +++ b/packages/node/src/services/Explorer.ts @@ -6,7 +6,7 @@ import { Hash, Address, RpcTransactionResponse, -} from '@deth/chain' +} from '@ethereum-ts/chain' import { utils } from 'ethers' export interface BlockListItem { diff --git a/packages/node/src/services/WalletManager.ts b/packages/node/src/services/WalletManager.ts index 7d28f42..f2798c9 100644 --- a/packages/node/src/services/WalletManager.ts +++ b/packages/node/src/services/WalletManager.ts @@ -1,5 +1,5 @@ import { Wallet, providers } from 'ethers' -import { Address, makeAddress } from '@deth/chain' +import { Address, makeAddress } from '@ethereum-ts/chain' import debug from 'debug' const d = debug('deth:WalletManager') diff --git a/packages/node/src/services/chain.ts b/packages/node/src/services/chain.ts index ef38398..d6bbaf9 100644 --- a/packages/node/src/services/chain.ts +++ b/packages/node/src/services/chain.ts @@ -1,6 +1,6 @@ import { DethLogger } from './logger/DethLogger' import { eventLogger, revertLogger } from './logger/stepsLoggers' -import { ChainOptions, Chain } from '@deth/chain' +import { ChainOptions, Chain } from '@ethereum-ts/chain' export function createChain (logger: DethLogger, options: ChainOptions) { const chain = new Chain(options) diff --git a/packages/node/src/services/fakeHistory.ts b/packages/node/src/services/fakeHistory.ts index 91d3791..14c3b3d 100644 --- a/packages/node/src/services/fakeHistory.ts +++ b/packages/node/src/services/fakeHistory.ts @@ -1,4 +1,4 @@ -import { Chain, makeHexData } from '@deth/chain' +import { Chain, makeHexData } from '@ethereum-ts/chain' import { WalletManager } from './WalletManager' import { utils } from 'ethers' diff --git a/packages/node/src/services/logger/CliLogger.ts b/packages/node/src/services/logger/CliLogger.ts index 465e795..272d8e2 100644 --- a/packages/node/src/services/logger/CliLogger.ts +++ b/packages/node/src/services/logger/CliLogger.ts @@ -1,6 +1,6 @@ import { gray, yellow, red, blue, green } from 'chalk' -import { HexData, Address, makeAddress } from '@deth/chain' +import { HexData, Address, makeAddress } from '@ethereum-ts/chain' import { AbiDecoder } from '../AbiDecoder' import { DethLogger } from './DethLogger' import { WalletManager } from '../WalletManager' diff --git a/packages/node/src/services/logger/DethLogger.ts b/packages/node/src/services/logger/DethLogger.ts index 44ded24..bdaa316 100644 --- a/packages/node/src/services/logger/DethLogger.ts +++ b/packages/node/src/services/logger/DethLogger.ts @@ -1,4 +1,4 @@ -import { Address, HexData } from '@deth/chain' +import { Address, HexData } from '@ethereum-ts/chain' import { WalletManager } from '../WalletManager' export interface DethLogger { diff --git a/packages/node/src/services/logger/stepsLoggers.ts b/packages/node/src/services/logger/stepsLoggers.ts index 18314e4..2134070 100644 --- a/packages/node/src/services/logger/stepsLoggers.ts +++ b/packages/node/src/services/logger/stepsLoggers.ts @@ -1,6 +1,6 @@ // eslint-disable-next-line import { InterpreterStep } from 'ethereumts-vm/dist/evm/interpreter' -import { bufferToAddress, bufferToHexData } from '@deth/chain' +import { bufferToAddress, bufferToHexData } from '@ethereum-ts/chain' import { DethLogger } from './DethLogger' export const eventLogger = (logger: DethLogger) => (runState: InterpreterStep) => { diff --git a/packages/node/src/services/rpcExecutor.ts b/packages/node/src/services/rpcExecutor.ts index e3ea3f7..eda41dd 100644 --- a/packages/node/src/services/rpcExecutor.ts +++ b/packages/node/src/services/rpcExecutor.ts @@ -8,7 +8,7 @@ import { makeAddress, ChainOptions, Chain, -} from '@deth/chain' +} from '@ethereum-ts/chain' import { BadRequestHttpError } from '../middleware/errorHandler' import { WalletManager } from './WalletManager' @@ -76,6 +76,9 @@ export const createRpcExecutor = ( eth_uninstallFilter: ([filterId]) => { return chain.uninstallFilter(filterId) }, + eth_getLogs: ([filter]) => { + return chain.getLogs(filter) + }, // ganache compatibility evm_increaseTime: ([n]) => { diff --git a/packages/node/src/views/AddressDisplay.tsx b/packages/node/src/views/AddressDisplay.tsx index b9a5c03..2a7b434 100644 --- a/packages/node/src/views/AddressDisplay.tsx +++ b/packages/node/src/views/AddressDisplay.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { Address } from '@deth/chain' +import { Address } from '@ethereum-ts/chain' export interface AddressDisplayProps { address: Address diff --git a/packages/node/src/views/HashDisplay.tsx b/packages/node/src/views/HashDisplay.tsx index e562e96..4e625f4 100644 --- a/packages/node/src/views/HashDisplay.tsx +++ b/packages/node/src/views/HashDisplay.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { Hash } from '@deth/chain' +import { Hash } from '@ethereum-ts/chain' export interface HashDisplayProps { hash: Hash diff --git a/packages/node/test/middleware/rpc/call.test.ts b/packages/node/test/middleware/rpc/call.test.ts index 1e24fbd..b956ee5 100644 --- a/packages/node/test/middleware/rpc/call.test.ts +++ b/packages/node/test/middleware/rpc/call.test.ts @@ -4,7 +4,7 @@ import { ContractFactory, Contract } from 'ethers' import { COUNTER_ABI, COUNTER_BYTECODE } from '../../contracts/Counter' import { makeRpcCall } from './common' import { buildTestApp } from '../../buildTestApp' -import { numberToQuantity } from '@deth/chain' +import { numberToQuantity } from '@ethereum-ts/chain' describe('rpc -> call', () => { xit('supports eth_call calling smartcontracts') diff --git a/packages/node/test/middleware/rpc/codecs.test.ts b/packages/node/test/middleware/rpc/codecs.test.ts new file mode 100644 index 0000000..779765a --- /dev/null +++ b/packages/node/test/middleware/rpc/codecs.test.ts @@ -0,0 +1,23 @@ +import { hexData } from '../../../src/rpc/codecs' +import { expect } from 'chai' +import { isRight, Either, Right } from 'fp-ts/lib/Either' + +function takeRightOrThrow (value: Either): R { + expect(isRight(value), 'expected value to be right but got left').to.be.true + + return ((value as any) as Right).right +} + +describe('codecs > hexData', () => { + it('works with 0x prefixed values', () => { + const input = '0x1234' + + expect(takeRightOrThrow(hexData.decode(input))).to.be.eq('0x1234') + }) + + it('works without 0x prefix values', () => { + const input = '1234' + + expect(takeRightOrThrow(hexData.decode(input))).to.be.eq('0x1234') + }) +}) diff --git a/packages/node/test/middleware/rpc/common.ts b/packages/node/test/middleware/rpc/common.ts index c20ce38..f01769a 100644 --- a/packages/node/test/middleware/rpc/common.ts +++ b/packages/node/test/middleware/rpc/common.ts @@ -1,7 +1,7 @@ import { request, expect } from 'chai' import { COUNTER_ABI, COUNTER_BYTECODE } from '../../contracts/Counter' import { ContractFactory, Wallet, Contract } from 'ethers' -import { numberToQuantity } from '@deth/chain' +import { numberToQuantity } from '@ethereum-ts/chain' import { Application } from 'express' export function makeRpcCall ( diff --git a/packages/node/test/middleware/rpc/getBalance.test.ts b/packages/node/test/middleware/rpc/getBalance.test.ts index 61a6ea8..303f792 100644 --- a/packages/node/test/middleware/rpc/getBalance.test.ts +++ b/packages/node/test/middleware/rpc/getBalance.test.ts @@ -3,7 +3,7 @@ import { utils } from 'ethers' import { makeRpcCall } from './common' import { buildTestApp } from '../../buildTestApp' -import { numberToQuantity } from '@deth/chain' +import { numberToQuantity } from '@ethereum-ts/chain' describe('rpc -> getBalance', () => { it('supports eth_getBalance call for account with non-zero balance', async () => { diff --git a/packages/node/test/middleware/rpc/getStorageAt.test.ts b/packages/node/test/middleware/rpc/getStorageAt.test.ts index 8ac934f..0e4fa88 100644 --- a/packages/node/test/middleware/rpc/getStorageAt.test.ts +++ b/packages/node/test/middleware/rpc/getStorageAt.test.ts @@ -2,7 +2,7 @@ import { expect } from 'chai' import { makeRpcCall, unwrapRpcResponse } from './common' import { buildTestApp } from '../../buildTestApp' -import { numberToQuantity } from '@deth/chain' +import { numberToQuantity } from '@ethereum-ts/chain' describe('rpc -> getStorageAt', () => { it('works with not-existing data', async () => { diff --git a/packages/node/test/middleware/rpc/getTransactionReceipt.test.ts b/packages/node/test/middleware/rpc/getTransactionReceipt.test.ts index 65b298a..ceb357d 100644 --- a/packages/node/test/middleware/rpc/getTransactionReceipt.test.ts +++ b/packages/node/test/middleware/rpc/getTransactionReceipt.test.ts @@ -2,7 +2,7 @@ import { expect } from 'chai' import { makeRpcCall, unwrapRpcResponse, deployCounterContract } from './common' import { buildTestApp } from '../../buildTestApp' -import { numberToQuantity } from '@deth/chain' +import { numberToQuantity } from '@ethereum-ts/chain' describe('rpc -> getTransactionReceipt', () => { it('supports eth_getTransactionReceipt for not existing txs', async () => { diff --git a/packages/node/test/middleware/rpc/miningControl.test.ts b/packages/node/test/middleware/rpc/miningControl.test.ts index 6063bea..362a4b2 100644 --- a/packages/node/test/middleware/rpc/miningControl.test.ts +++ b/packages/node/test/middleware/rpc/miningControl.test.ts @@ -2,7 +2,7 @@ import { expect } from 'chai' import { makeRpcCall, unwrapRpcResponse } from './common' import { buildTestApp } from '../../buildTestApp' -import { numberToQuantity } from '@deth/chain' +import { numberToQuantity } from '@ethereum-ts/chain' describe('rpc -> miningControl', () => { it('stops mining', async () => { diff --git a/packages/node/test/middleware/rpc/sendRawTransaction.test.ts b/packages/node/test/middleware/rpc/sendRawTransaction.test.ts index 6abc85d..e941ab5 100644 --- a/packages/node/test/middleware/rpc/sendRawTransaction.test.ts +++ b/packages/node/test/middleware/rpc/sendRawTransaction.test.ts @@ -4,7 +4,7 @@ import { ContractFactory } from 'ethers' import { COUNTER_ABI, COUNTER_BYTECODE } from '../../contracts/Counter' import { makeRpcCall, unwrapRpcResponse } from './common' import { buildTestApp } from '../../buildTestApp' -import { numberToQuantity } from '@deth/chain' +import { numberToQuantity } from '@ethereum-ts/chain' describe('rpc -> sendRawTransaction', () => { it('supports contract deploys via eth_sendRawTransaction', async () => { diff --git a/packages/node/test/middleware/rpc/sendTransaction.test.ts b/packages/node/test/middleware/rpc/sendTransaction.test.ts index 3defec0..5bf9e8a 100644 --- a/packages/node/test/middleware/rpc/sendTransaction.test.ts +++ b/packages/node/test/middleware/rpc/sendTransaction.test.ts @@ -2,7 +2,7 @@ import { expect } from 'chai' import { makeRpcCall } from './common' import { buildTestApp } from '../../buildTestApp' -import { numberToQuantity } from '@deth/chain' +import { numberToQuantity } from '@ethereum-ts/chain' describe('rpc -> sendTransaction', () => { it('supports eth_sendTransaction', async () => { diff --git a/packages/node/test/middleware/rpc/snapshot.test.ts b/packages/node/test/middleware/rpc/snapshot.test.ts index f44e8ca..7408cb6 100644 --- a/packages/node/test/middleware/rpc/snapshot.test.ts +++ b/packages/node/test/middleware/rpc/snapshot.test.ts @@ -2,7 +2,7 @@ import { expect } from 'chai' import { makeRpcCall, unwrapRpcResponse, deployCounterContract } from './common' import { buildTestApp } from '../../buildTestApp' -import { numberToQuantity } from '@deth/chain' +import { numberToQuantity } from '@ethereum-ts/chain' describe('rpc -> snapshot', () => { it('support evm_snapshots', async () => { diff --git a/packages/node/test/middleware/rpc/timeControl.test.ts b/packages/node/test/middleware/rpc/timeControl.test.ts index 0b384ee..c0f6e5d 100644 --- a/packages/node/test/middleware/rpc/timeControl.test.ts +++ b/packages/node/test/middleware/rpc/timeControl.test.ts @@ -2,7 +2,7 @@ import { expect } from 'chai' import { makeRpcCall, unwrapRpcResponse } from './common' import { buildTestApp } from '../../buildTestApp' -import { numberToQuantity, quantityToNumber } from '@deth/chain' +import { numberToQuantity, quantityToNumber } from '@ethereum-ts/chain' import sinon from 'sinon' describe('rpc -> time control', () => { diff --git a/packages/node/test/services/WalletManager/getWalletForAddress.test.ts b/packages/node/test/services/WalletManager/getWalletForAddress.test.ts index 2b0a5ea..e453311 100644 --- a/packages/node/test/services/WalletManager/getWalletForAddress.test.ts +++ b/packages/node/test/services/WalletManager/getWalletForAddress.test.ts @@ -1,6 +1,6 @@ import { WalletManager } from '../../../src/services/WalletManager' import { expect } from 'chai' -import { makeAddress } from '@deth/chain' +import { makeAddress } from '@ethereum-ts/chain' describe('WalletManager.getWalletForAddress', () => { it('gets wallet if exist', () => {