fix: force leveldb open

This commit is contained in:
ppe
2022-10-31 16:53:19 +01:00
committed by just_ppe
parent de490bfd0e
commit 4deee6f3bd
19 changed files with 284 additions and 128 deletions

View File

@@ -25,16 +25,15 @@ const runBuild = async () => {
...buildConfig, ...buildConfig,
minify: true, minify: true,
outfile: './bundles/web.bundle.min.js', outfile: './bundles/web.bundle.min.js',
metafile: true
}).catch((e) => { }).catch((e) => {
console.log(e); console.log(e);
process.exit(1); process.exit(1);
}); });
fs.writeFileSync('metadata.json', JSON.stringify({ /*fs.writeFileSync('metadata.json', JSON.stringify({
inputs: result.metafile.inputs, inputs: result.metafile.inputs,
outputs: result.metafile.outputs outputs: result.metafile.outputs
})); }));*/
console.log('Building web bundle iife.'); console.log('Building web bundle iife.');
await build({ await build({

View File

@@ -66,16 +66,15 @@
"arweave": "1.11.6", "arweave": "1.11.6",
"elliptic": "^6.5.4", "elliptic": "^6.5.4",
"events": "3.3.0", "events": "3.3.0",
"fast-copy": "^2.1.1", "fast-copy": "^3.0.0",
"knex": "^0.95.14",
"level": "^8.0.0", "level": "^8.0.0",
"memory-level": "^1.0.0", "memory-level": "^1.0.0",
"redstone-isomorphic": "1.1.8", "redstone-isomorphic": "1.1.8",
"redstone-wasm-metering": "1.0.3", "redstone-wasm-metering": "1.0.3",
"safe-stable-stringify": "2.3.1", "safe-stable-stringify": "2.4.1",
"stream-buffers": "^3.0.2", "stream-buffers": "^3.0.2",
"unzipit": "^1.4.0", "unzipit": "^1.4.0",
"vm2": "3.9.9" "vm2": "3.9.11"
}, },
"devDependencies": { "devDependencies": {
"@types/cheerio": "^0.22.30", "@types/cheerio": "^0.22.30",
@@ -100,7 +99,8 @@
"sqlite3": "^5.0.2", "sqlite3": "^5.0.2",
"ts-jest": "^28.0.7", "ts-jest": "^28.0.7",
"ts-node": "^10.2.1", "ts-node": "^10.2.1",
"typescript": "^4.7.4" "typescript": "^4.7.4",
"warp-contracts-lmdb": "^1.0.4"
}, },
"browser": { "browser": {
"fs": false, "fs": false,

View File

@@ -39,9 +39,14 @@ export interface SortKeyCache<V> {
/** /**
* Return all cached contracts. * Return all cached contracts.
* Slow, as LevelDB in general kinda sucks in case of iterating all keys/values.
*/ */
allContracts(): Promise<string[]>; allContracts(): Promise<string[]>;
/**
* returns underlying storage (LevelDB, LMDB, sqlite...)
* - useful for performing low-level operations
*/
storage<S>(): S;
} }
export class CacheKey { export class CacheKey {

View File

@@ -39,7 +39,8 @@ export class LevelDbCache<V = any> implements SortKeyCache<V> {
async get(contractTxId: string, sortKey: string, returnDeepCopy?: boolean): Promise<SortKeyCacheResult<V> | null> { async get(contractTxId: string, sortKey: string, returnDeepCopy?: boolean): Promise<SortKeyCacheResult<V> | null> {
const contractCache = this.db.sublevel<string, any>(contractTxId, { valueEncoding: 'json' }); const contractCache = this.db.sublevel<string, any>(contractTxId, { valueEncoding: 'json' });
// manually opening to fix https://github.com/Level/level/issues/221
await contractCache.open();
try { try {
const result = await contractCache.get(sortKey); const result = await contractCache.get(sortKey);
@@ -58,6 +59,8 @@ export class LevelDbCache<V = any> implements SortKeyCache<V> {
async getLast(contractTxId: string): Promise<SortKeyCacheResult<V> | null> { async getLast(contractTxId: string): Promise<SortKeyCacheResult<V> | null> {
const contractCache = this.db.sublevel<string, any>(contractTxId, { valueEncoding: 'json' }); const contractCache = this.db.sublevel<string, any>(contractTxId, { valueEncoding: 'json' });
// manually opening to fix https://github.com/Level/level/issues/221
await contractCache.open();
const keys = await contractCache.keys({ reverse: true, limit: 1 }).all(); const keys = await contractCache.keys({ reverse: true, limit: 1 }).all();
if (keys.length) { if (keys.length) {
return { return {
@@ -71,6 +74,8 @@ export class LevelDbCache<V = any> implements SortKeyCache<V> {
async getLessOrEqual(contractTxId: string, sortKey: string): Promise<SortKeyCacheResult<V> | null> { async getLessOrEqual(contractTxId: string, sortKey: string): Promise<SortKeyCacheResult<V> | null> {
const contractCache = this.db.sublevel<string, any>(contractTxId, { valueEncoding: 'json' }); const contractCache = this.db.sublevel<string, any>(contractTxId, { valueEncoding: 'json' });
// manually opening to fix https://github.com/Level/level/issues/221
await contractCache.open();
const keys = await contractCache.keys({ reverse: true, lte: sortKey, limit: 1 }).all(); const keys = await contractCache.keys({ reverse: true, lte: sortKey, limit: 1 }).all();
if (keys.length) { if (keys.length) {
return { return {
@@ -102,6 +107,7 @@ export class LevelDbCache<V = any> implements SortKeyCache<V> {
// the lastSortKey should be probably memoized during "put" // the lastSortKey should be probably memoized during "put"
async getLastSortKey(): Promise<string | null> { async getLastSortKey(): Promise<string | null> {
let lastSortKey = ''; let lastSortKey = '';
await this.db.open();
const keys = await this.db.keys().all(); const keys = await this.db.keys().all();
for (const key of keys) { for (const key of keys) {
@@ -117,6 +123,7 @@ export class LevelDbCache<V = any> implements SortKeyCache<V> {
} }
async allContracts(): Promise<string[]> { async allContracts(): Promise<string[]> {
await this.db.open();
const keys = await this.db.keys().all(); const keys = await this.db.keys().all();
const result = new Set<string>(); const result = new Set<string>();
@@ -124,4 +131,8 @@ export class LevelDbCache<V = any> implements SortKeyCache<V> {
return Array.from(result); return Array.from(result);
} }
storage<S>(): S {
return this.db as S;
}
} }

View File

@@ -1,63 +0,0 @@
import Arweave from 'arweave';
import { LexicographicalInteractionsSorter } from '../../core/modules/impl/LexicographicalInteractionsSorter';
import { EvalStateResult } from '../../core/modules/StateEvaluator';
import knex from 'knex';
import { LoggerFactory } from '../../logging/LoggerFactory';
import { LevelDbCache } from '../../cache/impl/LevelDbCache';
export type MigrationResult = Array<{ contractTxId: string; height: number; sortKey: string }>;
export class MigrationTool {
private readonly logger = LoggerFactory.INST.create('MigrationTool');
private readonly sorter: LexicographicalInteractionsSorter;
constructor(private readonly arweave: Arweave, private readonly levelDb: LevelDbCache<EvalStateResult<unknown>>) {
this.sorter = new LexicographicalInteractionsSorter(arweave);
}
async migrateSqlite(sqlitePath: string): Promise<MigrationResult> {
this.logger.info(`Migrating from sqlite ${sqlitePath} to leveldb.`);
const knexDb = knex({
client: 'sqlite3',
connection: {
filename: sqlitePath
},
useNullAsDefault: true
});
const cache = await knexDb
.select(['contract_id', 'height', 'state'])
.from('states')
.max('height')
.groupBy(['contract_id']);
this.logger.info(`Migrating ${cache?.length} contracts' state`);
const result = [];
for (const entry of cache) {
const contractTxId = entry['contract_id'];
const height = entry['height'];
const state = JSON.parse(entry['state']);
const sortKey = this.sorter.generateLastSortKey(parseInt(height));
this.logger.debug(`Migrating ${contractTxId} at height ${height}: ${sortKey}`);
await this.levelDb.put(
{
contractTxId,
sortKey
},
new EvalStateResult(state.state, state.validity, {})
);
result.push({ contractTxId, height, sortKey });
}
this.logger.info(`Migration done.`);
return result;
}
}

View File

@@ -1,12 +1,10 @@
import Arweave from 'arweave'; import Arweave from 'arweave';
import { LevelDbCache } from '../cache/impl/LevelDbCache';
import { Contract, InnerCallData } from '../contract/Contract'; import { Contract, InnerCallData } from '../contract/Contract';
import { CreateContract } from '../contract/deploy/CreateContract'; import { CreateContract } from '../contract/deploy/CreateContract';
import { DefaultCreateContract } from '../contract/deploy/impl/DefaultCreateContract'; import { DefaultCreateContract } from '../contract/deploy/impl/DefaultCreateContract';
import { HandlerBasedContract } from '../contract/HandlerBasedContract'; import { HandlerBasedContract } from '../contract/HandlerBasedContract';
import { PstContract } from '../contract/PstContract'; import { PstContract } from '../contract/PstContract';
import { PstContractImpl } from '../contract/PstContractImpl'; import { PstContractImpl } from '../contract/PstContractImpl';
import { MigrationTool } from '../contract/migration/MigrationTool';
import { Testing, Wallet } from '../contract/testing/Testing'; import { Testing, Wallet } from '../contract/testing/Testing';
import { DefinitionLoader } from './modules/DefinitionLoader'; import { DefinitionLoader } from './modules/DefinitionLoader';
import { ExecutorFactory } from './modules/ExecutorFactory'; import { ExecutorFactory } from './modules/ExecutorFactory';
@@ -15,6 +13,8 @@ import { InteractionsLoader } from './modules/InteractionsLoader';
import { EvalStateResult, StateEvaluator } from './modules/StateEvaluator'; import { EvalStateResult, StateEvaluator } from './modules/StateEvaluator';
import { WarpBuilder } from './WarpBuilder'; import { WarpBuilder } from './WarpBuilder';
import { WarpPluginType, WarpPlugin, knownWarpPlugins } from './WarpPlugin'; import { WarpPluginType, WarpPlugin, knownWarpPlugins } from './WarpPlugin';
import { SortKeyCache } from '../cache/SortKeyCache';
import { ContractDefinition } from './ContractDefinition';
export type WarpEnvironment = 'local' | 'testnet' | 'mainnet' | 'custom'; export type WarpEnvironment = 'local' | 'testnet' | 'mainnet' | 'custom';
@@ -28,14 +28,12 @@ export type WarpEnvironment = 'local' | 'testnet' | 'mainnet' | 'custom';
*/ */
export class Warp { export class Warp {
readonly createContract: CreateContract; readonly createContract: CreateContract;
readonly migrationTool: MigrationTool;
readonly testing: Testing; readonly testing: Testing;
private readonly plugins: Map<WarpPluginType, WarpPlugin<unknown, unknown>> = new Map(); private readonly plugins: Map<WarpPluginType, WarpPlugin<unknown, unknown>> = new Map();
constructor( constructor(
readonly arweave: Arweave, readonly arweave: Arweave,
readonly levelDb: LevelDbCache<EvalStateResult<unknown>>,
readonly definitionLoader: DefinitionLoader, readonly definitionLoader: DefinitionLoader,
readonly interactionsLoader: InteractionsLoader, readonly interactionsLoader: InteractionsLoader,
readonly executorFactory: ExecutorFactory<HandlerApi<unknown>>, readonly executorFactory: ExecutorFactory<HandlerApi<unknown>>,
@@ -43,16 +41,15 @@ export class Warp {
readonly environment: WarpEnvironment = 'custom' readonly environment: WarpEnvironment = 'custom'
) { ) {
this.createContract = new DefaultCreateContract(arweave, this); this.createContract = new DefaultCreateContract(arweave, this);
this.migrationTool = new MigrationTool(arweave, levelDb);
this.testing = new Testing(arweave); this.testing = new Testing(arweave);
} }
static builder( static builder(
arweave: Arweave, arweave: Arweave,
cache: LevelDbCache<EvalStateResult<unknown>>, stateCache: SortKeyCache<EvalStateResult<unknown>>,
environment: WarpEnvironment environment: WarpEnvironment
): WarpBuilder { ): WarpBuilder {
return new WarpBuilder(arweave, cache, environment); return new WarpBuilder(arweave, stateCache, environment);
} }
/** /**
@@ -72,6 +69,16 @@ export class Warp {
return new PstContractImpl(contractTxId, this); return new PstContractImpl(contractTxId, this);
} }
useStateCache(stateCache: SortKeyCache<EvalStateResult<unknown>>): Warp {
this.stateEvaluator.setCache(stateCache);
return this;
}
useContractCache(contractsCache: SortKeyCache<ContractDefinition<any>>): Warp {
this.definitionLoader.setCache(contractsCache);
return this;
}
use(plugin: WarpPlugin<unknown, unknown>): Warp { use(plugin: WarpPlugin<unknown, unknown>): Warp {
const pluginType = plugin.type(); const pluginType = plugin.type();
if (!knownWarpPlugins.some((p) => p == pluginType)) { if (!knownWarpPlugins.some((p) => p == pluginType)) {

View File

@@ -1,6 +1,4 @@
import Arweave from 'arweave'; import Arweave from 'arweave';
import { MemCache } from '../cache/impl/MemCache';
import { LevelDbCache } from '../cache/impl/LevelDbCache';
import { DebuggableExecutorFactory } from '../plugins/DebuggableExecutorFactor'; import { DebuggableExecutorFactory } from '../plugins/DebuggableExecutorFactor';
import { DefinitionLoader } from './modules/DefinitionLoader'; import { DefinitionLoader } from './modules/DefinitionLoader';
import { ExecutorFactory } from './modules/ExecutorFactory'; import { ExecutorFactory } from './modules/ExecutorFactory';
@@ -14,6 +12,8 @@ import { InteractionsLoader } from './modules/InteractionsLoader';
import { StateEvaluator, EvalStateResult } from './modules/StateEvaluator'; import { StateEvaluator, EvalStateResult } from './modules/StateEvaluator';
import { WarpEnvironment, Warp } from './Warp'; import { WarpEnvironment, Warp } from './Warp';
import { CacheOptions, GatewayOptions } from './WarpFactory'; import { CacheOptions, GatewayOptions } from './WarpFactory';
import { SortKeyCache } from '../cache/SortKeyCache';
import { LevelDbCache } from '../cache/impl/LevelDbCache';
export class WarpBuilder { export class WarpBuilder {
private _definitionLoader?: DefinitionLoader; private _definitionLoader?: DefinitionLoader;
@@ -23,7 +23,7 @@ export class WarpBuilder {
constructor( constructor(
private readonly _arweave: Arweave, private readonly _arweave: Arweave,
private readonly _cache: LevelDbCache<EvalStateResult<unknown>>, private readonly _stateCache: SortKeyCache<EvalStateResult<unknown>>,
private readonly _environment: WarpEnvironment = 'custom' private readonly _environment: WarpEnvironment = 'custom'
) {} ) {}
@@ -63,10 +63,16 @@ export class WarpBuilder {
gatewayOptions.source gatewayOptions.source
) )
); );
const contractsCache = new LevelDbCache({
...cacheOptions,
dbLocation: `${cacheOptions.dbLocation}/contracts`
});
this._definitionLoader = new WarpGatewayContractDefinitionLoader( this._definitionLoader = new WarpGatewayContractDefinitionLoader(
gatewayOptions.address, gatewayOptions.address,
this._arweave, this._arweave,
cacheOptions, contractsCache,
this._environment this._environment
); );
return this; return this;
@@ -83,7 +89,6 @@ export class WarpBuilder {
build(): Warp { build(): Warp {
return new Warp( return new Warp(
this._arweave, this._arweave,
this._cache,
this._definitionLoader, this._definitionLoader,
this._interactionsLoader, this._interactionsLoader,
this._executorFactory, this._executorFactory,

View File

@@ -9,6 +9,7 @@ import { ConfirmationStatus, SourceType } from './modules/impl/WarpGatewayIntera
import { EvalStateResult } from './modules/StateEvaluator'; import { EvalStateResult } from './modules/StateEvaluator';
import { WarpEnvironment, Warp } from './Warp'; import { WarpEnvironment, Warp } from './Warp';
import { WarpBuilder } from './WarpBuilder'; import { WarpBuilder } from './WarpBuilder';
import { SortKeyCache } from '../cache/SortKeyCache';
export type GatewayOptions = { export type GatewayOptions = {
confirmationStatus: ConfirmationStatus; confirmationStatus: ConfirmationStatus;
@@ -41,6 +42,8 @@ export const defaultCacheOptions: CacheOptions = {
* All versions use the {@link Evolve} plugin. * All versions use the {@link Evolve} plugin.
*/ */
export class WarpFactory { export class WarpFactory {
private stateCache: SortKeyCache<EvalStateResult<unknown>>;
/** /**
* creates a Warp instance suitable for testing in a local environment * creates a Warp instance suitable for testing in a local environment
* (e.g. usually using ArLocal) * (e.g. usually using ArLocal)
@@ -115,16 +118,16 @@ export class WarpFactory {
* @param arweave * @param arweave
* @param cacheOptions * @param cacheOptions
*/ */
static custom(arweave: Arweave, cacheOptions: CacheOptions, environment: WarpEnvironment): WarpBuilder { static custom(arweave: Arweave, cacheOptions: CacheOptions, environment: WarpEnvironment, ): WarpBuilder {
const cache = new LevelDbCache<EvalStateResult<unknown>>({ const stateCache = new LevelDbCache<EvalStateResult<unknown>>({
...cacheOptions, ...cacheOptions,
dbLocation: `${cacheOptions.dbLocation}/state` dbLocation: `${cacheOptions.dbLocation}/state`
}); });
const executorFactory = new CacheableExecutorFactory(arweave, new HandlerExecutorFactory(arweave), new MemCache()); const executorFactory = new CacheableExecutorFactory(arweave, new HandlerExecutorFactory(arweave), new MemCache());
const stateEvaluator = new CacheableStateEvaluator(arweave, cache, [new Evolve()]); const stateEvaluator = new CacheableStateEvaluator(arweave, stateCache, [new Evolve()]);
return Warp.builder(arweave, cache, environment) return Warp.builder(arweave, stateCache, environment)
.setExecutorFactory(executorFactory) .setExecutorFactory(executorFactory)
.setStateEvaluator(stateEvaluator); .setStateEvaluator(stateEvaluator);
} }

View File

@@ -1,5 +1,6 @@
import { ContractDefinition, ContractSource } from '../../core/ContractDefinition'; import { ContractDefinition, ContractSource } from '../../core/ContractDefinition';
import { GwTypeAware } from './InteractionsLoader'; import { GwTypeAware } from './InteractionsLoader';
import { SortKeyCache } from '../../cache/SortKeyCache';
/** /**
* Implementors of this interface are responsible for loading contract's definitions - * Implementors of this interface are responsible for loading contract's definitions -
@@ -8,5 +9,10 @@ import { GwTypeAware } from './InteractionsLoader';
*/ */
export interface DefinitionLoader extends GwTypeAware { export interface DefinitionLoader extends GwTypeAware {
load<State>(contractTxId: string, evolvedSrcTxId?: string): Promise<ContractDefinition<State>>; load<State>(contractTxId: string, evolvedSrcTxId?: string): Promise<ContractDefinition<State>>;
loadContractSource(srcTxId: string): Promise<ContractSource>; loadContractSource(srcTxId: string): Promise<ContractSource>;
setCache(cache: SortKeyCache<ContractDefinition<any>>): void;
getCache(): SortKeyCache<ContractDefinition<any>>;
} }

View File

@@ -1,4 +1,4 @@
import { SortKeyCacheResult } from '../../cache/SortKeyCache'; import { SortKeyCache, SortKeyCacheResult } from '../../cache/SortKeyCache';
import { CurrentTx } from '../../contract/Contract'; import { CurrentTx } from '../../contract/Contract';
import { ExecutionContext } from '../../core/ExecutionContext'; import { ExecutionContext } from '../../core/ExecutionContext';
import { GQLNodeInterface } from '../../legacy/gqlResult'; import { GQLNodeInterface } from '../../legacy/gqlResult';
@@ -85,6 +85,10 @@ export interface StateEvaluator {
lastCachedSortKey(): Promise<string | null>; lastCachedSortKey(): Promise<string | null>;
allCachedContracts(): Promise<string[]>; allCachedContracts(): Promise<string[]>;
setCache(cache: SortKeyCache<EvalStateResult<unknown>>): void;
getCache(): SortKeyCache<EvalStateResult<unknown>>;
} }
export class EvalStateResult<State> { export class EvalStateResult<State> {

View File

@@ -24,7 +24,7 @@ export class CacheableStateEvaluator extends DefaultStateEvaluator {
constructor( constructor(
arweave: Arweave, arweave: Arweave,
private readonly cache: SortKeyCache<EvalStateResult<unknown>>, private cache: SortKeyCache<EvalStateResult<unknown>>,
executionContextModifiers: ExecutionContextModifier[] = [] executionContextModifiers: ExecutionContextModifier[] = []
) { ) {
super(arweave, executionContextModifiers); super(arweave, executionContextModifiers);
@@ -205,9 +205,7 @@ export class CacheableStateEvaluator extends DefaultStateEvaluator {
contractTxId, contractTxId,
transaction: transaction.id, transaction: transaction.id,
sortKey: transaction.sortKey, sortKey: transaction.sortKey,
dry: transaction.dry, dry: transaction.dry
state: stateToCache.state,
validity: stateToCache.validity
}); });
await this.cache.put(new CacheKey(contractTxId, transaction.sortKey), stateToCache); await this.cache.put(new CacheKey(contractTxId, transaction.sortKey), stateToCache);
@@ -240,4 +238,12 @@ export class CacheableStateEvaluator extends DefaultStateEvaluator {
async allCachedContracts(): Promise<string[]> { async allCachedContracts(): Promise<string[]> {
return await this.cache.allContracts(); return await this.cache.allContracts();
} }
setCache(cache: SortKeyCache<EvalStateResult<unknown>>): void {
this.cache = cache;
}
getCache(): SortKeyCache<EvalStateResult<unknown>> {
return this.cache;
}
} }

View File

@@ -11,6 +11,7 @@ import { GW_TYPE } from '../InteractionsLoader';
import { TagsParser } from './TagsParser'; import { TagsParser } from './TagsParser';
import { WasmSrc } from './wasm/WasmSrc'; import { WasmSrc } from './wasm/WasmSrc';
import { WarpEnvironment } from '../../Warp'; import { WarpEnvironment } from '../../Warp';
import { SortKeyCache } from 'cache/SortKeyCache';
const supportedSrcContentTypes = ['application/javascript', 'application/wasm']; const supportedSrcContentTypes = ['application/javascript', 'application/wasm'];
@@ -134,4 +135,11 @@ export class ContractDefinitionLoader implements DefinitionLoader {
type(): GW_TYPE { type(): GW_TYPE {
return 'arweave'; return 'arweave';
} }
setCache(cache: SortKeyCache<ContractDefinition<any>>): void {
throw new Error('No cache implemented for this loader');
}
getCache(): SortKeyCache<ContractDefinition<any>> {
throw new Error('No cache implemented for this loader');
}
} }

View File

@@ -2,7 +2,7 @@ import Arweave from 'arweave';
import { ProofHoHash } from '@idena/vrf-js'; import { ProofHoHash } from '@idena/vrf-js';
import elliptic from 'elliptic'; import elliptic from 'elliptic';
import { SortKeyCacheResult } from '../../../cache/SortKeyCache'; import { SortKeyCache, SortKeyCacheResult } from '../../../cache/SortKeyCache';
import { CurrentTx } from '../../../contract/Contract'; import { CurrentTx } from '../../../contract/Contract';
import { InteractionCall } from '../../ContractCallRecord'; import { InteractionCall } from '../../ContractCallRecord';
import { ExecutionContext } from '../../../core/ExecutionContext'; import { ExecutionContext } from '../../../core/ExecutionContext';
@@ -359,4 +359,8 @@ export abstract class DefaultStateEvaluator implements StateEvaluator {
abstract lastCachedSortKey(): Promise<string | null>; abstract lastCachedSortKey(): Promise<string | null>;
abstract allCachedContracts(): Promise<string[]>; abstract allCachedContracts(): Promise<string[]>;
abstract setCache(cache: SortKeyCache<EvalStateResult<unknown>>): void;
abstract getCache(): SortKeyCache<EvalStateResult<unknown>>;
} }

View File

@@ -14,6 +14,7 @@ export const sortingFirst = ''.padEnd(64, '0');
export const sortingLast = ''.padEnd(64, 'z'); export const sortingLast = ''.padEnd(64, 'z');
export const genesisSortKey = `${''.padStart(12, '0')},${firstSortKeyMs},${sortingFirst}`; export const genesisSortKey = `${''.padStart(12, '0')},${firstSortKeyMs},${sortingFirst}`;
export const lastPossibleKey = `${''.padStart(12, '9')},${lastSortKeyMs},${sortingLast}`;
/** /**
* implementation that is based on current's SDK sorting alg. * implementation that is based on current's SDK sorting alg.

View File

@@ -16,6 +16,7 @@ import { MemoryLevel } from 'memory-level';
import { Level } from 'level'; import { Level } from 'level';
import { WarpEnvironment } from '../../Warp'; import { WarpEnvironment } from '../../Warp';
import { TagsParser } from './TagsParser'; import { TagsParser } from './TagsParser';
import { SortKeyCache } from '../../../cache/SortKeyCache';
/** /**
* An extension to {@link ContractDefinitionLoader} that makes use of * An extension to {@link ContractDefinitionLoader} that makes use of
@@ -29,29 +30,18 @@ export class WarpGatewayContractDefinitionLoader implements DefinitionLoader {
private readonly rLogger = LoggerFactory.INST.create('WarpGatewayContractDefinitionLoader'); private readonly rLogger = LoggerFactory.INST.create('WarpGatewayContractDefinitionLoader');
private contractDefinitionLoader: ContractDefinitionLoader; private contractDefinitionLoader: ContractDefinitionLoader;
private arweaveWrapper: ArweaveWrapper; private arweaveWrapper: ArweaveWrapper;
private readonly db: MemoryLevel<string, ContractDefinition<unknown>>;
private readonly tagsParser: TagsParser; private readonly tagsParser: TagsParser;
constructor( constructor(
private readonly baseUrl: string, private readonly baseUrl: string,
arweave: Arweave, arweave: Arweave,
cacheOptions: CacheOptions, private cache: SortKeyCache<ContractDefinition<any>>,
private readonly env: WarpEnvironment private readonly env: WarpEnvironment
) { ) {
this.baseUrl = stripTrailingSlash(baseUrl); this.baseUrl = stripTrailingSlash(baseUrl);
this.contractDefinitionLoader = new ContractDefinitionLoader(arweave, env); this.contractDefinitionLoader = new ContractDefinitionLoader(arweave, env);
this.arweaveWrapper = new ArweaveWrapper(arweave); this.arweaveWrapper = new ArweaveWrapper(arweave);
this.tagsParser = new TagsParser(); this.tagsParser = new TagsParser();
if (cacheOptions.inMemory) {
this.db = new MemoryLevel<string, ContractDefinition<unknown>>({ valueEncoding: 'json' });
} else {
if (!cacheOptions.dbLocation) {
throw new Error('LevelDb cache configuration error - no db location specified');
}
const dbLocation = cacheOptions.dbLocation;
this.db = new Level<string, ContractDefinition<unknown>>(`${dbLocation}/contracts`, { valueEncoding: 'json' });
}
} }
async load<State>(contractTxId: string, evolvedSrcTxId?: string): Promise<ContractDefinition<State>> { async load<State>(contractTxId: string, evolvedSrcTxId?: string): Promise<ContractDefinition<State>> {
@@ -60,29 +50,22 @@ export class WarpGatewayContractDefinitionLoader implements DefinitionLoader {
cacheKey += `_${evolvedSrcTxId}`; cacheKey += `_${evolvedSrcTxId}`;
} }
let cacheResult = null; const cacheResult = await this.cache.get(cacheKey, 'cd');
try {
cacheResult = await this.db.get(cacheKey);
} catch (e: any) {
if (e.code == 'LEVEL_NOT_FOUND') {
cacheResult = null;
} else {
throw e;
}
}
if (cacheResult) { if (cacheResult) {
this.rLogger.debug('WarpGatewayContractDefinitionLoader: Hit from cache!'); this.rLogger.debug('WarpGatewayContractDefinitionLoader: Hit from cache!');
if (cacheResult.contractType == 'wasm') { const result = cacheResult.cachedValue;
cacheResult.srcBinary = Buffer.from(cacheResult.srcBinary.data); // LevelDB serializes Buffer to an object with 'type' and 'data' fields
if (result.contractType == 'wasm' && (result.srcBinary as any).data) {
result.srcBinary = Buffer.from((result.srcBinary as any).data);
} }
this.verifyEnv(cacheResult); this.verifyEnv(result);
return cacheResult; return result;
} }
const benchmark = Benchmark.measure(); const benchmark = Benchmark.measure();
const contract = await this.doLoad<State>(contractTxId, evolvedSrcTxId); const contract = await this.doLoad<State>(contractTxId, evolvedSrcTxId);
this.rLogger.info(`Contract definition loaded in: ${benchmark.elapsed()}`); this.rLogger.info(`Contract definition loaded in: ${benchmark.elapsed()}`);
this.verifyEnv(contract); this.verifyEnv(contract);
await this.db.put(cacheKey, contract); await this.cache.put({ contractTxId: cacheKey, sortKey: 'cd' }, contract);
return contract; return contract;
} }
@@ -134,6 +117,14 @@ export class WarpGatewayContractDefinitionLoader implements DefinitionLoader {
return 'warp'; return 'warp';
} }
setCache(cache: SortKeyCache<ContractDefinition<any>>): void {
this.cache = cache;
}
getCache(): SortKeyCache<ContractDefinition<any>> {
return this.cache;
}
private verifyEnv(def: ContractDefinition<unknown>): void { private verifyEnv(def: ContractDefinition<unknown>): void {
if (def.testnet && this.env !== 'testnet') { if (def.testnet && this.env !== 'testnet') {
throw new Error('Trying to use testnet contract in a non-testnet env. Use the "forTestnet" factory method.'); throw new Error('Trying to use testnet contract in a non-testnet env. Use the "forTestnet" factory method.');

View File

@@ -5,6 +5,8 @@ export * from './logging/LoggerFactory';
export * from './logging/LoggerSettings'; export * from './logging/LoggerSettings';
export * from './logging/Benchmark'; export * from './logging/Benchmark';
export * from './cache/SortKeyCache';
export * from './core/modules/DefinitionLoader'; export * from './core/modules/DefinitionLoader';
export * from './core/modules/ExecutorFactory'; export * from './core/modules/ExecutorFactory';
export * from './core/modules/InteractionsLoader'; export * from './core/modules/InteractionsLoader';

View File

@@ -62,7 +62,7 @@ export class Evolve implements ExecutionContextModifier {
return executionContext; return executionContext;
} catch (e) { } catch (e) {
throw new SmartWeaveError(SmartWeaveErrorType.CONTRACT_NOT_FOUND, { throw new SmartWeaveError(SmartWeaveErrorType.CONTRACT_NOT_FOUND, {
message: `Contract having txId: ${contractTxId} not found`, message: `Error while evolving ${contractTxId} from ${currentSrcTxId} to ${evolvedSrcTxId}: ${e}`,
requestedTxId: contractTxId requestedTxId: contractTxId
}); });
} }

View File

@@ -17,7 +17,9 @@ async function main() {
}); });
try { try {
const warp = WarpFactory.forMainnet({...defaultCacheOptions, inMemory: true}); const warp = WarpFactory
.forMainnet({...defaultCacheOptions, inMemory: true})
.useStateCache(new LmdbCache());
/*const warp = WarpFactory /*const warp = WarpFactory
.custom(arweave, { .custom(arweave, {
...defaultCacheOptions, ...defaultCacheOptions,

173
yarn.lock
View File

@@ -1118,6 +1118,36 @@
dependencies: dependencies:
vary "^1.1.2" vary "^1.1.2"
"@lmdb/lmdb-darwin-arm64@2.6.9":
version "2.6.9"
resolved "https://registry.yarnpkg.com/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.6.9.tgz#4b84bb0ad71e78472332920c9cf8603ea3dad0bc"
integrity sha512-QxyheKfTP9k5ZVAiddCqGUtp2AD3/BMgYfski96iIbFH0skPFO+MYARMGZuemTgyM9uieT+5oKj4FjigWplpWg==
"@lmdb/lmdb-darwin-x64@2.6.9":
version "2.6.9"
resolved "https://registry.yarnpkg.com/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.6.9.tgz#28b191a9f7a1f30462d8d179cd05598fa66ebbfc"
integrity sha512-zJ1oUepZMaqiujvWeWJRG5VHXBS3opJnjAzbd4vTVsQFT0t5rbPhHgAJ2ruR9rVrb2V1BINJZuwpjhIOg9fLCQ==
"@lmdb/lmdb-linux-arm64@2.6.9":
version "2.6.9"
resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.6.9.tgz#274dfe11209a70c059cb55c72026c24903dde3e1"
integrity sha512-KZRet8POwKowbYZqrRqdYJ+B6l+7cWG18vMCe2sgOSuE41sEMpfRQ1mKcolt3fsr0KVbuP63aPG+dwi0wGpX9w==
"@lmdb/lmdb-linux-arm@2.6.9":
version "2.6.9"
resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.6.9.tgz#7bacd104067e7dbb1bb67c907c1bc642e2d2ac96"
integrity sha512-Umw+ikxbsYZHHqr8eMycmApj6IIZCK4k1rp5/pqqx9FvAaPv4/Y63owiMLoKfipjel0YPaNyvSeXAJK3l/8Pbw==
"@lmdb/lmdb-linux-x64@2.6.9":
version "2.6.9"
resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.6.9.tgz#d37b25c9b553c5d5e66055a64d118e3fd42557d9"
integrity sha512-11xFQ4kCIPGnYULcfkW4SIMIY1sukA4DHez62DKvYn+tLr4AB1o9jm1Jk6bisKFh5Cql+JUr7klHxeIuxvGZdg==
"@lmdb/lmdb-win32-x64@2.6.9":
version "2.6.9"
resolved "https://registry.yarnpkg.com/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.6.9.tgz#bf8e647dabd8b672744315f5df3e363b5987a463"
integrity sha512-qECZ+1j3PSarYeCmJlYlrxq3TB7S020ICrYmpxyQyphbRiMI9I1Bw4t+vPrMAEKsTqB8UaOzBp21YWUpsiCBfA==
"@mapbox/node-pre-gyp@^1.0.0": "@mapbox/node-pre-gyp@^1.0.0":
version "1.0.10" version "1.0.10"
resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz#8e6735ccebbb1581e5a7e652244cadc8a844d03c" resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz#8e6735ccebbb1581e5a7e652244cadc8a844d03c"
@@ -1133,6 +1163,36 @@
semver "^7.3.5" semver "^7.3.5"
tar "^6.1.11" tar "^6.1.11"
"@msgpackr-extract/msgpackr-extract-darwin-arm64@2.1.2":
version "2.1.2"
resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-2.1.2.tgz#9571b87be3a3f2c46de05585470bc4f3af2f6f00"
integrity sha512-TyVLn3S/+ikMDsh0gbKv2YydKClN8HaJDDpONlaZR+LVJmsxLFUgA+O7zu59h9+f9gX1aj/ahw9wqa6rosmrYQ==
"@msgpackr-extract/msgpackr-extract-darwin-x64@2.1.2":
version "2.1.2"
resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-2.1.2.tgz#bfbc6936ede2955218f5621a675679a5fe8e6f4c"
integrity sha512-YPXtcVkhmVNoMGlqp81ZHW4dMxK09msWgnxtsDpSiZwTzUBG2N+No2bsr7WMtBKCVJMSD6mbAl7YhKUqkp/Few==
"@msgpackr-extract/msgpackr-extract-linux-arm64@2.1.2":
version "2.1.2"
resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-2.1.2.tgz#22555e28382af2922e7450634c8a2f240bb9eb82"
integrity sha512-vHZ2JiOWF2+DN9lzltGbhtQNzDo8fKFGrf37UJrgqxU0yvtERrzUugnfnX1wmVfFhSsF8OxrfqiNOUc5hko1Zg==
"@msgpackr-extract/msgpackr-extract-linux-arm@2.1.2":
version "2.1.2"
resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-2.1.2.tgz#ffb6ae1beea7ac572b6be6bf2a8e8162ebdd8be7"
integrity sha512-42R4MAFeIeNn+L98qwxAt360bwzX2Kf0ZQkBBucJ2Ircza3asoY4CDbgiu9VWklq8gWJVSJSJBwDI+c/THiWkA==
"@msgpackr-extract/msgpackr-extract-linux-x64@2.1.2":
version "2.1.2"
resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-2.1.2.tgz#7caf62eebbfb1345de40f75e89666b3d4194755f"
integrity sha512-RjRoRxg7Q3kPAdUSC5EUUPlwfMkIVhmaRTIe+cqHbKrGZ4M6TyCA/b5qMaukQ/1CHWrqYY2FbKOAU8Hg0pQFzg==
"@msgpackr-extract/msgpackr-extract-win32-x64@2.1.2":
version "2.1.2"
resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-2.1.2.tgz#f2d8b9ddd8d191205ed26ce54aba3dfc5ae3e7c9"
integrity sha512-rIZVR48zA8hGkHIK7ED6+ZiXsjRCcAVBJbm8o89OKAMTmEAQ2QvoOxoiu3w2isAaWwzgtQIOFIqHwvZDyLKCvw==
"@noble/ed25519@^1.6.1": "@noble/ed25519@^1.6.1":
version "1.7.0" version "1.7.0"
resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.0.tgz#583ac38340a479314b9e348d4572101ed9492f9d" resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.0.tgz#583ac38340a479314b9e348d4572101ed9492f9d"
@@ -3586,9 +3646,14 @@ external-editor@^3.0.3:
tmp "^0.0.33" tmp "^0.0.33"
fast-copy@^2.1.1: fast-copy@^2.1.1:
version "2.1.3" version "2.1.7"
resolved "https://registry.yarnpkg.com/fast-copy/-/fast-copy-2.1.3.tgz#bf6e05ac3cb7a9d66fbf12c51dd4440e9ddd4afb" resolved "https://registry.yarnpkg.com/fast-copy/-/fast-copy-2.1.7.tgz#affc9475cb4b555fb488572b2a44231d0c9fa39e"
integrity sha512-LDzYKNTHhD+XOp8wGMuCkY4eTxFZOOycmpwLBiuF3r3OjOmZnURRD8t2dUAbmKuXGbo/MGggwbSjcBdp8QT0+g== integrity sha512-ozrGwyuCTAy7YgFCua8rmqmytECYk/JYAMXcswOcm0qvGoE3tPb7ivBeIHTOK2DiapBhDZgacIhzhQIKU5TCfA==
fast-copy@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/fast-copy/-/fast-copy-3.0.0.tgz#875ebf33b13948ae012b6e51d33da5e6e7571ab8"
integrity sha512-4HzS+9pQ5Yxtv13Lhs1Z1unMXamBdn5nA4bEi1abYpDNSpSp7ODYQ1KPMF6nTatfEzgH6/zPvXKU1zvHiUjWlA==
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3" version "3.1.3"
@@ -5100,6 +5165,24 @@ lines-and-columns@^1.1.6:
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
lmdb@^2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/lmdb/-/lmdb-2.6.9.tgz#aa782ec873bcf70333b251eede9e711819ef5765"
integrity sha512-rVA3OchNoKxoD2rYhtc9nooqbJmId+vvfPzTWhanRPhdVr0hbgnF9uB9ZEHFU2lEeYVdh83Pt2H6DudeWuz+JA==
dependencies:
msgpackr "1.7.2"
node-addon-api "^4.3.0"
node-gyp-build-optional-packages "5.0.3"
ordered-binary "^1.4.0"
weak-lru-cache "^1.2.2"
optionalDependencies:
"@lmdb/lmdb-darwin-arm64" "2.6.9"
"@lmdb/lmdb-darwin-x64" "2.6.9"
"@lmdb/lmdb-linux-arm" "2.6.9"
"@lmdb/lmdb-linux-arm64" "2.6.9"
"@lmdb/lmdb-linux-x64" "2.6.9"
"@lmdb/lmdb-win32-x64" "2.6.9"
locate-path@^5.0.0: locate-path@^5.0.0:
version "5.0.0" version "5.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
@@ -5477,6 +5560,27 @@ ms@2.1.3, ms@^2.0.0:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
msgpackr-extract@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/msgpackr-extract/-/msgpackr-extract-2.1.2.tgz#56272030f3e163e1b51964ef8b1cd5e7240c03ed"
integrity sha512-cmrmERQFb19NX2JABOGtrKdHMyI6RUyceaPBQ2iRz9GnDkjBWFjNJC0jyyoOfZl2U/LZE3tQCCQc4dlRyA8mcA==
dependencies:
node-gyp-build-optional-packages "5.0.3"
optionalDependencies:
"@msgpackr-extract/msgpackr-extract-darwin-arm64" "2.1.2"
"@msgpackr-extract/msgpackr-extract-darwin-x64" "2.1.2"
"@msgpackr-extract/msgpackr-extract-linux-arm" "2.1.2"
"@msgpackr-extract/msgpackr-extract-linux-arm64" "2.1.2"
"@msgpackr-extract/msgpackr-extract-linux-x64" "2.1.2"
"@msgpackr-extract/msgpackr-extract-win32-x64" "2.1.2"
msgpackr@1.7.2:
version "1.7.2"
resolved "https://registry.yarnpkg.com/msgpackr/-/msgpackr-1.7.2.tgz#68d6debf5999d6b61abb6e7046a689991ebf7261"
integrity sha512-mWScyHTtG6TjivXX9vfIy2nBtRupaiAj0HQ2mtmpmYujAmqZmaaEVPaSZ1NKLMvicaMLFzEaMk0ManxMRg8rMQ==
optionalDependencies:
msgpackr-extract "^2.1.2"
multistream@^4.1.0: multistream@^4.1.0:
version "4.1.0" version "4.1.0"
resolved "https://registry.yarnpkg.com/multistream/-/multistream-4.1.0.tgz#7bf00dfd119556fbc153cff3de4c6d477909f5a8" resolved "https://registry.yarnpkg.com/multistream/-/multistream-4.1.0.tgz#7bf00dfd119556fbc153cff3de4c6d477909f5a8"
@@ -5534,7 +5638,7 @@ node-addon-api@^2.0.0:
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32"
integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==
node-addon-api@^4.2.0: node-addon-api@^4.2.0, node-addon-api@^4.3.0:
version "4.3.0" version "4.3.0"
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f"
integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==
@@ -5551,6 +5655,11 @@ node-fetch@^2.6.7:
dependencies: dependencies:
whatwg-url "^5.0.0" whatwg-url "^5.0.0"
node-gyp-build-optional-packages@5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz#92a89d400352c44ad3975010368072b41ad66c17"
integrity sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA==
node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: node-gyp-build@^4.2.0, node-gyp-build@^4.3.0:
version "4.5.0" version "4.5.0"
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.5.0.tgz#7a64eefa0b21112f89f58379da128ac177f20e40" resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.5.0.tgz#7a64eefa0b21112f89f58379da128ac177f20e40"
@@ -5706,6 +5815,11 @@ ora@^5.4.1:
strip-ansi "^6.0.0" strip-ansi "^6.0.0"
wcwidth "^1.0.1" wcwidth "^1.0.1"
ordered-binary@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/ordered-binary/-/ordered-binary-1.4.0.tgz#6bb53d44925f3b8afc33d1eed0fa15693b211389"
integrity sha512-EHQ/jk4/a9hLupIKxTfUsQRej1Yd/0QLQs3vGvIqg5ZtCYSzNhkzHoZc7Zf4e4kUlDaC3Uw8Q/1opOLNN2OKRQ==
os-tmpdir@~1.0.2: os-tmpdir@~1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
@@ -6194,6 +6308,11 @@ safe-stable-stringify@2.3.1:
resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.3.1.tgz#ab67cbe1fe7d40603ca641c5e765cb942d04fc73" resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.3.1.tgz#ab67cbe1fe7d40603ca641c5e765cb942d04fc73"
integrity sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg== integrity sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg==
safe-stable-stringify@2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.1.tgz#34694bd8a30575b7f94792aa51527551bd733d61"
integrity sha512-dVHE6bMtS/bnL2mwualjc6IxEv1F+OCUpA46pKUj6F8uDbUM0jCCulPqRNPSnWwGNKx5etqMjZYdXtrm5KJZGA==
"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.1.0: "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.1.0:
version "2.1.2" version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
@@ -6989,6 +7108,14 @@ vlq@^2.0.4:
resolved "https://registry.yarnpkg.com/vlq/-/vlq-2.0.4.tgz#6057b85729245b9829e3cc7755f95b228d4fe041" resolved "https://registry.yarnpkg.com/vlq/-/vlq-2.0.4.tgz#6057b85729245b9829e3cc7755f95b228d4fe041"
integrity sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA== integrity sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA==
vm2@3.9.11:
version "3.9.11"
resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.11.tgz#a880f510a606481719ec3f9803b940c5805a06fe"
integrity sha512-PFG8iJRSjvvBdisowQ7iVF580DXb1uCIiGaXgm7tynMR1uTBlv7UJlB1zdv5KJ+Tmq1f0Upnj3fayoEOPpCBKg==
dependencies:
acorn "^8.7.0"
acorn-walk "^8.2.0"
vm2@3.9.9: vm2@3.9.9:
version "3.9.9" version "3.9.9"
resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.9.tgz#c0507bc5fbb99388fad837d228badaaeb499ddc5" resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.9.tgz#c0507bc5fbb99388fad837d228badaaeb499ddc5"
@@ -7004,6 +7131,39 @@ walker@^1.0.8:
dependencies: dependencies:
makeerror "1.0.12" makeerror "1.0.12"
warp-contracts-lmdb@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/warp-contracts-lmdb/-/warp-contracts-lmdb-1.0.4.tgz#49350b5e11e5b49564a839529365149b3c0c01e5"
integrity sha512-8olZXkOJpE2+In2Td0SAoMjbB8PZqk7FE6jGHaoRh1yVACo6nYdfSGMFEU5ZAX0ZnfKeroCiou85TRPF6Zs59A==
dependencies:
lmdb "^2.6.9"
warp-contracts "1.2.14-lambda.6"
warp-contracts@1.2.14-lambda.6:
version "1.2.14-lambda.6"
resolved "https://registry.yarnpkg.com/warp-contracts/-/warp-contracts-1.2.14-lambda.6.tgz#5f709b537e6dd27401c38a981dd11fd34b73ab82"
integrity sha512-DnwKhorbJGKGwqunCleVJoPLhYwsopK3QtqjwT6bXGpNo2jxEOWaMrYzAoihFnkWKfNRpADnrlJVcCb0ExP0gA==
dependencies:
"@assemblyscript/loader" "^0.19.23"
"@idena/vrf-js" "^1.0.1"
archiver "^5.3.0"
arweave "1.11.6"
bignumber.js "^9.0.1"
elliptic "^6.5.4"
events "3.3.0"
fast-copy "^2.1.1"
knex "^0.95.14"
level "^8.0.0"
lmdb "^2.6.9"
lodash "^4.17.21"
memory-level "^1.0.0"
redstone-isomorphic "1.1.8"
redstone-wasm-metering "1.0.3"
safe-stable-stringify "2.3.1"
stream-buffers "^3.0.2"
unzipit "^1.4.0"
vm2 "3.9.9"
wcwidth@^1.0.1: wcwidth@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8"
@@ -7011,6 +7171,11 @@ wcwidth@^1.0.1:
dependencies: dependencies:
defaults "^1.0.3" defaults "^1.0.3"
weak-lru-cache@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz#fdbb6741f36bae9540d12f480ce8254060dccd19"
integrity sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==
webidl-conversions@^3.0.0: webidl-conversions@^3.0.0:
version "3.0.1" version "3.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"