Skip to content

Commit

Permalink
ALL-1512 Archive Non archive calls
Browse files Browse the repository at this point in the history
  • Loading branch information
Hathoriel committed Jul 11, 2023
1 parent 77e0cf5 commit 4359b34
Show file tree
Hide file tree
Showing 21 changed files with 242 additions and 101 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## [1.5.8] - 2023.07.10
### Changed
- Selected Archive/Non-Archive node for Ethereum RPC calls based on method

## [1.5.7] - 2023.07.10
### Changed
- Extended JSON stringify to see error message in case of error to Loadbalancer
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tatumcom/js",
"version": "1.5.7",
"version": "1.5.8",
"description": "Tatum JS SDK",
"author": "Tatum",
"repository": "https://github.com/tatumio/tatum-js",
Expand Down
49 changes: 19 additions & 30 deletions src/dto/Network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,52 +190,41 @@ export const EVM_LOAD_BALANCER_NETWORKS = [
Network.HAQQ_TESTNET,
Network.ETHEREUM,
Network.ETHEREUM_SEPOLIA,
Network.POLYGON,
Network.POLYGON_MUMBAI,
]

export const LOAD_BALANCER_NETWORKS = [
...UTXO_LOAD_BALANCER_NETWORKS,
...EVM_LOAD_BALANCER_NETWORKS,
]

export const EVM_ARCHIVE_NON_ARCHIVE_LOAD_BALANCER_NETWORKS = [
Network.ETHEREUM,
Network.ETHEREUM_SEPOLIA,
]

export const SOLANA_NETWORKS = [Network.SOLANA, Network.SOLANA_DEVNET]
export const TRON_NETWORKS = [Network.TRON, Network.TRON_SHASTA]

export const isEvmBasedNetwork = (network: Network) => {
return EVM_BASED_NETWORKS.includes(network)
}
export const isEvmBasedNetwork = (network: Network) => EVM_BASED_NETWORKS.includes(network)

export const isUtxoBasedNetwork = (network: Network) => {
return UTXO_BASED_NETWORKS.includes(network)
}
export const isUtxoBasedNetwork = (network: Network) => UTXO_BASED_NETWORKS.includes(network)

export const isXrpNetwork = (network: Network) => {
return [Network.XRP, Network.XRP_TESTNET].includes(network)
}
export const isXrpNetwork = (network: Network) => [Network.XRP, Network.XRP_TESTNET].includes(network)

export const isDataApiEvmEnabledNetwork = (network: Network) => {
return DATA_API_EVM_NETWORKS.includes(network)
}
export const isDataApiEvmEnabledNetwork = (network: Network) => DATA_API_EVM_NETWORKS.includes(network)

export const isDataApiUtxoEnabledNetwork = (network: Network) => {
return DATA_API_UTXO_NETWORKS.includes(network)
}
export const isDataApiUtxoEnabledNetwork = (network: Network) => DATA_API_UTXO_NETWORKS.includes(network)

export const isSolanaEnabledNetwork = (network: Network) => {
return SOLANA_NETWORKS.includes(network)
}
export const isSolanaEnabledNetwork = (network: Network) => SOLANA_NETWORKS.includes(network)

export const isTronNetwork = (network: Network) => {
return TRON_NETWORKS.includes(network)
}
export const isTronNetwork = (network: Network) => TRON_NETWORKS.includes(network)

export const isLoadBalancerNetwork = (network: Network) => {
return LOAD_BALANCER_NETWORKS.includes(network)
}
export const isLoadBalancerNetwork = (network: Network) => LOAD_BALANCER_NETWORKS.includes(network)

export const isUtxoLoadBalancerNetwork = (network: Network) => {
return UTXO_LOAD_BALANCER_NETWORKS.includes(network)
}
export const isUtxoLoadBalancerNetwork = (network: Network) => UTXO_LOAD_BALANCER_NETWORKS.includes(network)

export const isEvmLoadBalancerNetwork = (network: Network) => {
return EVM_LOAD_BALANCER_NETWORKS.includes(network)
}
export const isEvmLoadBalancerNetwork = (network: Network) => EVM_LOAD_BALANCER_NETWORKS.includes(network)

export const isEvmArchiveNonArchiveLoadBalancerNetwork = (network: Network) => EVM_ARCHIVE_NON_ARCHIVE_LOAD_BALANCER_NETWORKS.includes(network)
20 changes: 15 additions & 5 deletions src/e2e/rpc/evm.e2e.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { RpcE2eUtils } from './rpc.e2e.utils'
export const EvmE2eUtils = {
initTatum: async (network: Network) => TatumSDK.init<BaseEvmClass>(RpcE2eUtils.initConfig(network)),
e2e: ({ network, chainId }: { network: Network; chainId: number }) => {
it('chain info', async () => {
it('eth_blockNumber', async () => {
const tatum = await EvmE2eUtils.initTatum(network)
const { data, status } = await tatum.rpc.blockNumber()

Expand All @@ -15,7 +15,7 @@ export const EvmE2eUtils = {
tatum.rpc.destroy()
})

it('chain id', async () => {
it('eth_chainId', async () => {
const tatum = await EvmE2eUtils.initTatum(network)
const { data, status } = await tatum.rpc.chainId()

Expand All @@ -24,7 +24,7 @@ export const EvmE2eUtils = {
tatum.rpc.destroy()
})

it('estimate gas', async () => {
it('eth_estimateGas', async () => {
const tatum = await EvmE2eUtils.initTatum(network)
const { data, status } = await tatum.rpc.estimateGas({
from: '0xb4c9E4617a16Be36B92689b9e07e9F64757c1792',
Expand All @@ -37,7 +37,7 @@ export const EvmE2eUtils = {
tatum.rpc.destroy()
})

it('gas price', async () => {
it('eth_gasPrice', async () => {
const tatum = await EvmE2eUtils.initTatum(network)
const { data, status } = await tatum.rpc.gasPrice()

Expand All @@ -46,13 +46,23 @@ export const EvmE2eUtils = {
tatum.rpc.destroy()
})

it('client version', async () => {
it('web3_clientVersion', async () => {
const tatum = await EvmE2eUtils.initTatum(network)
const { data, status } = await tatum.rpc.clientVersion()

expect(status).toBe(Status.SUCCESS)
expect(data).toBeTruthy()
tatum.rpc.destroy()
})

it('eth_getBlockByNumber', async () => {
const tatum = await EvmE2eUtils.initTatum(network)
const { data: blockNum } = await tatum.rpc.blockNumber()
const { data, status } = await tatum.rpc.getBlockByNumber(blockNum.toNumber())
expect(status).toBe(Status.SUCCESS)
expect(data.timestamp).toBeDefined()
expect(data.size).toBeDefined()
tatum.rpc.destroy()
})
},
}
3 changes: 3 additions & 0 deletions src/e2e/rpc/rpc.e2e.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@ export const RpcE2eUtils = {
network,
retryCount: 1,
retryDelay: 2000,
apiKey: {
v2: 't-647835e1930be3001cb53f81-647835e2930be3001cb53f87'
}
}),
}
2 changes: 1 addition & 1 deletion src/e2e/rpc/tatum.rpc.flare.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Network } from '../../service'
import { EvmE2eUtils } from './evm.e2e.utils'

//temporarily skipping Flare as RPC's are not available
describe.skip('Flare', () => {
describe('Flare', () => {
describe('mainnet', () => {
EvmE2eUtils.e2e({ network: Network.FLARE, chainId: 14 })
})
Expand Down
2 changes: 1 addition & 1 deletion src/e2e/rpc/tatum.rpc.polygon.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ describe('Polygon', () => {
EvmE2eUtils.e2e({ network: Network.POLYGON, chainId: 137 })
})

describe('mumbai', () => {
describe.skip('mumbai', () => {
EvmE2eUtils.e2e({ network: Network.POLYGON_MUMBAI, chainId: 80001 })
})
})
4 changes: 2 additions & 2 deletions src/service/address/address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
isEvmBasedNetwork,
} from '../../dto'
import { CONFIG, Constant, ErrorUtils, ResponseDto, Utils } from '../../util'
import { EvmBasedRpc, GenericRpc } from '../rpc'
import { EvmRpc, GenericRpc } from '../rpc'
import { Network, TatumConfig } from '../tatum'
import { AddressBalance, AddressTransaction, GetAddressTransactionsQuery } from './address.dto'

Expand Down Expand Up @@ -235,7 +235,7 @@ export class Address {
private async getNativeBalance(addresses: string[]): Promise<string[]> {
const network = this.config.network
if (isEvmBasedNetwork(network)) {
const rpc = Utils.getRpc<EvmBasedRpc>(this.id, network)
const rpc = Utils.getRpc<EvmRpc>(this.id, network)
const result = await Promise.all(addresses.map((a, i) => rpc.rawRpcCall(Utils.prepareRpcCall('eth_getBalance', [a, 'pending'], i))))
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
import { ErrorUtils, ResponseDto, ResponseUtils, Status } from '../../../util'

@Service()
export abstract class AbstractEvmBasedRpc implements EvmBasedRpcInterface {
export abstract class AbstractEvmRpc implements EvmBasedRpcInterface {
protected abstract rpcCall<T>(method: string, params?: unknown[]): Promise<T>

async blockNumber(): Promise<ResponseDto<BigNumber>> {
Expand Down
95 changes: 95 additions & 0 deletions src/service/rpc/evm/EvmArchiveLoadBalancerRpc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { Container, Service } from 'typedi'
import { EvmBasedRpcSuite, JsonRpcCall, JsonRpcResponse } from '../../../dto'
import { LoadBalancerRpc } from '../generic/LoadBalancerRpc'
import { Utils } from '../../../util'
import { AbstractEvmRpc } from './AbstractEvmRpc'

const ARCHIVE_METHODS = [
// Archival information
'debug_getBadBlocks',
'debug_storageRangeAt',
'debug_traceCall',
'debug_traceTransaction',
'debug_traceBlockByHash',
'debug_traceBlockByNumber',
'trace_block',
'trace_call',
'trace_callMany',
'trace_rawTransaction',
'trace_replayBlockTransactions',
// Network state
'eth_getBlockByHash',
'eth_getTransactionByHash',
'eth_getTransactionReceipt',
'eth_getUncleCountByBlockHash',
'eth_getUncleCountByBlockNumber',
'eth_getBlockByNumber',
'eth_getBlockTransactionCountByHash',
'eth_getBlockTransactionCountByNumber',
'eth_getTransactionByBlockHashAndIndex',
'eth_getTransactionByBlockNumberAndIndex',
'eth_getTransactionCount',
'eth_getProof',
]

const POSSIBLE_ARCHIVE_METHODS = [
// Network state
{ method: 'eth_getStorageAt', index: 2 }, // second param block
{ method: 'eth_call', index: 1 }, // second param block
{ method: 'eth_getBalance', index: 1 }, // second param block
{ method: 'eth_getCode', index: 1 }, // second param block
]

@Service({
factory: (data: { id: string }) => {
return new EvmArchiveLoadBalancerRpc(data.id)
},
transient: true,
})
export class EvmArchiveLoadBalancerRpc extends AbstractEvmRpc implements EvmBasedRpcSuite {
protected readonly loadBalancerRpc: LoadBalancerRpc

constructor(id: string) {
super()
this.loadBalancerRpc = Container.of(id).get(LoadBalancerRpc)
}

private isArchiveMethod(rpc: JsonRpcCall): boolean {
const isArchiveMethod = ARCHIVE_METHODS.includes(rpc.method)
if (isArchiveMethod) {
return true
}

const possibleArchiveMethod = POSSIBLE_ARCHIVE_METHODS.find((possibleArchiveMethod) => possibleArchiveMethod.method === rpc.method)
if (possibleArchiveMethod) {
const param = rpc?.params?.[possibleArchiveMethod.index]
return !!param
}

if (rpc.method === 'eth_getLogs') {
const param = rpc?.params?.[1]
return !!param?.fromBlock || !!param?.toBlock
}

return false
}

protected async rpcCall<T>(method: string, params?: unknown[]): Promise<T> {
const preparedCall = Utils.prepareRpcCall(method, params)
const isArchive = this.isArchiveMethod(preparedCall)
return (await this.loadBalancerRpc.rawRpcCall(preparedCall, isArchive)) as T
}

async rawRpcCall(body: JsonRpcCall): Promise<JsonRpcResponse> {
const isArchive = this.isArchiveMethod(body)
return this.loadBalancerRpc.rawRpcCall(body, isArchive)
}

rawBatchRpcCall(body: JsonRpcCall[]): Promise<JsonRpcResponse[]> {
return this.loadBalancerRpc.rawBatchRpcCall(body)
}

public destroy() {
this.loadBalancerRpc.destroy()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import { Container, Service } from 'typedi'
import { EvmBasedRpcSuite, JsonRpcCall, JsonRpcResponse } from '../../../dto'
import { LoadBalancerRpc } from '../generic/LoadBalancerRpc'
import { Utils } from '../../../util'
import { AbstractEvmBasedRpc } from './AbstractEvmBasedRpc'
import { AbstractEvmRpc } from './AbstractEvmRpc'

@Service({
factory: (data: { id: string }) => {
return new EvmBasedLoadBalancerRpc(data.id)
return new EvmLoadBalancerRpc(data.id)
},
transient: true,
})
export class EvmBasedLoadBalancerRpc extends AbstractEvmBasedRpc implements EvmBasedRpcSuite {
export class EvmLoadBalancerRpc extends AbstractEvmRpc implements EvmBasedRpcSuite {
protected readonly loadBalancerRpc: LoadBalancerRpc

constructor(id: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import {
} from '../../../dto'
import { GenericRpc } from '../generic/GenericRpc'
import { Utils } from '../../../util'
import { AbstractEvmBasedRpc } from './AbstractEvmBasedRpc'
import { AbstractEvmRpc } from './AbstractEvmRpc'

@Service({
factory: (data: { id: string }) => {
return new EvmBasedRpc(data.id)
return new EvmRpc(data.id)
},
transient: true,
})
export class EvmBasedRpc extends AbstractEvmBasedRpc {
export class EvmRpc extends AbstractEvmRpc {
public readonly genericRpc: GenericRpc

constructor(id: string) {
Expand Down
4 changes: 2 additions & 2 deletions src/service/rpc/evm/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from './EvmBasedRpc'
export * from './EvmBasedLoadBalancerRpc'
export * from './EvmRpc'
export * from './EvmLoadBalancerRpc'
Loading

0 comments on commit 4359b34

Please sign in to comment.