refactor: splitting factories to node/web versions

This commit is contained in:
ppedziwiatr
2021-08-25 13:45:37 +02:00
parent 671a97b7ca
commit c1bfc38cf2
8 changed files with 131 additions and 37 deletions

View File

@@ -1,5 +1,5 @@
/* eslint-disable */
import { LoggerFactory, SmartWeaveFactory } from '@smartweave';
import { LoggerFactory, SmartWeaveNodeFactory } from '@smartweave';
import Arweave from 'arweave';
import fs from 'fs';
import path from 'path';
@@ -14,7 +14,7 @@ async function main() {
});
const logger = LoggerFactory.INST.create(__filename);
LoggerFactory.INST.logLevel('silly', 'benchmark');
const swcClient = SmartWeaveFactory.fileCacheClient(arweave);
const swcClient = SmartWeaveNodeFactory.fileCacheClient(arweave);
const contractTxId = 'OrO8n453N6bx921wtsEs-0OCImBLCItNU5oSbFKlFuU';
// Kyve:

View File

@@ -1,6 +1,7 @@
/* eslint-disable */
import Arweave from 'arweave';
import { SmartWeaveFactory, LoggerFactory } from '@smartweave';
import { SmartWeaveNodeFactory, LoggerFactory } from '@smartweave';
import fs from 'fs';
const contracts = [
'gepLlre8wG8K3C15rNjpdKZZv_9pWsurRoEB6ir_EC4',
@@ -23,14 +24,39 @@ async function main() {
logging: false // Enable network request logging
});
const smartWeave = SmartWeaveFactory.memCached(arweave);
const contract1 = smartWeave.contract('W_njBtwDRyltjVU1RizJtZfF0S_4X3aSrrrA0HUEhUs');
const contract2 = smartWeave.contract('TMkCZKYO3GwcTLEKGgWSJegIlYCHi_UArtG0unCi2xA');
LoggerFactory.INST.logLevel('debug');
const smartWeave = SmartWeaveNodeFactory.memCached(arweave);
const contract1 = smartWeave.contract('W_njBtwDRyltjVU1RizJtZfF0S_4X3aSrrrA0HUEhUs');
const contract2 = smartWeave.contract('TMkCZKYO3GwcTLEKGgWSJegIlYCHi_UArtG0unCi2xA');
await contract1.readState();
await contract2.readState();
const jwk = readJSON('../../redstone-node/.secrets/redstone-dev-jwk.json');
contract1.connect(jwk);
type Contract1Input = {
function: string;
};
type Contract1View = {
foo: string;
bar: number;
};
const { type, result } = await contract1.viewState<Contract1Input, Contract1View>({
function: 'currentManifest'
});
if (type === 'ok') {
console.log((result as Contract1View).foo);
}
}
function readJSON(path) {
const content = fs.readFileSync(path, 'utf-8');
try {
return JSON.parse(content);
} catch (e) {
throw new Error(`File "${path}" does not contain a valid JSON`);
}
}
main();

View File

@@ -3,7 +3,7 @@ import Arweave from 'arweave';
import * as fs from 'fs';
import path from 'path';
import Transaction from 'arweave/node/lib/transaction';
import { GQLEdgeInterface, GQLResultInterface, LoggerFactory, SmartWeaveFactory } from '@smartweave';
import { GQLEdgeInterface, GQLResultInterface, LoggerFactory, SmartWeaveNodeFactory } from '@smartweave';
import { readContract } from 'smartweave';
const diffStateToVerify = [
@@ -51,7 +51,7 @@ async function main() {
const errorContractTxIds = [];
const swcClient = SmartWeaveFactory.fileCacheClient(arweave, 'cache');
const swcClient = SmartWeaveNodeFactory.fileCacheClient(arweave, 'cache');
const contractsBlacklist = [
'jFInOjLc_FFt802OmUObIIOlY1xNKvomzUTkoUpyP9U', // readContract very long evaluation

View File

@@ -20,7 +20,7 @@ export interface Contract<State = unknown> {
* Returns the view of the state, computed by the SWC.
* Similar to the {@link interactRead} from the current SDK version.
*/
viewState<Input, View>(
viewState<Input = unknown, View = unknown>(
input: Input,
blockHeight?: number,
evaluationOptions?: EvaluationOptions
@@ -33,7 +33,7 @@ export interface Contract<State = unknown> {
* note: calling "interactRead" from withing contract's source code was not previously possible -
* this is a new feature.
*/
viewStateForTx<Input, View>(
viewStateForTx<Input = unknown, View = unknown>(
input: Input,
transaction: InteractionTx,
evaluationOptions?: EvaluationOptions
@@ -42,5 +42,5 @@ export interface Contract<State = unknown> {
/**
* Writes a new "interaction" transaction - ie. such transaction that stores input for the contract.
*/
writeInteraction<Input>(input: Input);
writeInteraction<Input = unknown>(input: Input);
}

View File

@@ -1,5 +1,6 @@
export * from './Contract';
export * from './HandlerBasedContract';
export * from './SmartWeaveFactory';
export * from './web/SmartWeaveWebFactory';
export * from './node/SmartWeaveNodeFactory';
export * from './SmartWeave';
export * from './SmartWeaveBuilder';

View File

@@ -1,36 +1,29 @@
import { Contract, HandlerBasedContract, SmartWeave, SmartWeaveWebFactory } from '@smartweave/contract';
import Arweave from 'arweave';
import { HandlerBasedContract, Contract, SmartWeave } from './index';
import {
ContractDefinitionLoader,
ContractInteractionsLoader,
EvalStateResult,
HandlerExecutorFactory,
LexicographicalInteractionsSorter
} from '@smartweave/core';
import {
CacheableContractInteractionsLoader,
CacheableExecutorFactory,
CacheableStateEvaluator,
Evolve
} from '@smartweave/plugins';
import {
ContractDefinitionLoader,
ContractInteractionsLoader,
DefaultStateEvaluator,
EvalStateResult,
HandlerApi,
HandlerExecutorFactory,
LexicographicalInteractionsSorter
} from '@smartweave/core';
import { BsonFileBlockHeightSwCache, MemBlockHeightSwCache, MemCache } from '@smartweave/cache';
/**
* A factory that simplifies the process of creating different versions of {@link Contract}.
* All versions have the {@link Evolve} plugin...erm, plugged in ;-).
*
* TODO: add builders (or BUIDLers ;-)) that would simplify the process of customizing SwcClient behaviour
* TODO: consider introducing some IoC container (like `inversify`),
* but without forcing to use it (as some developers may be allergic to IoC/DI concepts ;-))
* - this would probably require some consultations within the community.
* A {@link SmartWeave} factory that can be safely used only in Node.js env.
*/
export class SmartWeaveFactory {
export class SmartWeaveNodeFactory extends SmartWeaveWebFactory {
/**
* Returns a {@link Contract} that is using mem cache for all layers.
* Returns a {@link SmartWeave} that is using file-based cache for {@link StateEvaluator} layer
* and mem cache for the rest.
*/
static memCached(arweave: Arweave): SmartWeave {
static fileCacheClient(arweave: Arweave, cacheBasePath?: string): SmartWeave {
const definitionLoader = new ContractDefinitionLoader(arweave, new MemCache());
const interactionsLoader = new CacheableContractInteractionsLoader(
@@ -40,7 +33,7 @@ export class SmartWeaveFactory {
const executorFactory = new CacheableExecutorFactory(arweave, new HandlerExecutorFactory(arweave), new MemCache());
const stateEvaluator = new CacheableStateEvaluator(arweave, new MemBlockHeightSwCache<EvalStateResult<unknown>>(), [
const stateEvaluator = new CacheableStateEvaluator(arweave, new BsonFileBlockHeightSwCache(cacheBasePath), [
new Evolve(definitionLoader, executorFactory)
]);

View File

@@ -0,0 +1,72 @@
import Arweave from 'arweave';
import { HandlerBasedContract, Contract, SmartWeave } from '@smartweave/contract';
import {
CacheableContractInteractionsLoader,
CacheableExecutorFactory,
CacheableStateEvaluator,
Evolve
} from '@smartweave/plugins';
import {
ContractDefinitionLoader,
ContractInteractionsLoader,
DefaultStateEvaluator,
EvalStateResult,
HandlerApi,
HandlerExecutorFactory,
LexicographicalInteractionsSorter
} from '@smartweave/core';
import { BsonFileBlockHeightSwCache, MemBlockHeightSwCache, MemCache } from '@smartweave/cache';
/**
* A factory that simplifies the process of creating different versions of {@link SmartWeave}.
* All versions use the {@link Evolve} plugin.
*/
export class SmartWeaveWebFactory {
/**
* Returns a {@link SmartWeave} that is using mem cache for all layers.
*/
static memCached(arweave: Arweave): SmartWeave {
const definitionLoader = new ContractDefinitionLoader(arweave, new MemCache());
const interactionsLoader = new CacheableContractInteractionsLoader(
new ContractInteractionsLoader(arweave),
new MemBlockHeightSwCache()
);
const executorFactory = new CacheableExecutorFactory(arweave, new HandlerExecutorFactory(arweave), new MemCache());
const stateEvaluator = new CacheableStateEvaluator(arweave, new MemBlockHeightSwCache<EvalStateResult<unknown>>(), [
new Evolve(definitionLoader, executorFactory)
]);
const interactionsSorter = new LexicographicalInteractionsSorter(arweave);
return SmartWeave.builder(arweave)
.setDefinitionLoader(definitionLoader)
.setInteractionsLoader(interactionsLoader)
.setInteractionsSorter(interactionsSorter)
.setExecutorFactory(executorFactory)
.setStateEvaluator(stateEvaluator)
.build();
}
/**
* Returns a {@link SmartWeave} that (yup, you've guessed it!) does not use any caches.
* This one is gonna be slooow...
*/
static noCacheClient(arweave: Arweave): SmartWeave {
const definitionLoader = new ContractDefinitionLoader(arweave);
const interactionsLoader = new ContractInteractionsLoader(arweave);
const executorFactory = new HandlerExecutorFactory(arweave);
const stateEvaluator = new DefaultStateEvaluator(arweave, [new Evolve(definitionLoader, executorFactory)]);
const interactionsSorter = new LexicographicalInteractionsSorter(arweave);
return SmartWeave.builder(arweave)
.setDefinitionLoader(definitionLoader)
.setInteractionsLoader(interactionsLoader)
.setInteractionsSorter(interactionsSorter)
.setExecutorFactory(executorFactory)
.setStateEvaluator(stateEvaluator)
.build();
}
}

View File

@@ -100,12 +100,14 @@ export class HandlerExecutorFactory implements ExecutorFactory<HandlerApi<unknow
) {
swGlobal.contracts.viewContractState = async <View>(contractTxId: string, input: any) => {
throw new Error('TODO implement');
/*logger.debug('swGlobal.viewContractState call: %o', {
logger.debug('swGlobal.viewContractState call: %o', {
from: contractDefinition.txId,
to: contractTxId,
input
});
return await executionContext.contract.viewStateForTx(contractTxId, input, swGlobal._activeTx);*/
const childContract = executionContext.smartweave.contract(contractTxId);
return await childContract.viewStateForTx(input, swGlobal._activeTx);
};
}
@@ -175,7 +177,7 @@ export type HandlerFunction<State, Input, Result> = (
// TODO: change to XOR between result and state?
export type HandlerResult<State, Result> = {
result: string | Result;
result: string | Result; // this really sucks, but has to be declared this way to be backwards compatbile
state: State;
};