refactor: final touches for the new client api

This commit is contained in:
ppedziwiatr
2021-08-26 21:11:07 +02:00
parent 354bc2e7db
commit f966e89616
8 changed files with 40 additions and 18 deletions

View File

@@ -47,7 +47,7 @@ async function main() {
const txs = loadTxFromFile();
const resumeFromContractTxId = 'YLVpmhSq5JmLltfg6R-5fL04rIRPrlSU22f6RQ6VyYE';
let resumeFrom = true;
let resumeFrom = false;
logger.info(`Checking ${txs.length} contracts`);

View File

@@ -1,6 +1,6 @@
{
"name": "redstone-smartweave",
"version": "0.1.0-alpha.1",
"version": "0.2.0-alpha.1",
"description": "An implementation of the SmartWeave SDK.",
"main": "lib/index.js",
"types": "lib/index.d.ts",
@@ -15,6 +15,7 @@
"preversion": "yarn lint && yarn build",
"version": "yarn format && git add -A src",
"postversion": "git push && git push --tags",
"yalc:publish": "yarn build && yalc publish --push",
"test": "jest"
},
"license": "MIT",

View File

@@ -80,17 +80,21 @@ export class HandlerBasedContract<State> implements Contract<State> {
const evalStateResult = await stateEvaluator.eval(executionContext, []);
logger.debug('Creating new intraction for view state');
const interaction: ContractInteraction<Input> = {
input,
caller: executionContext.caller
};
logger.trace('interaction', interaction);
const handler = (await this.smartweave.executorFactory.create(
executionContext.contractDefinition
)) as HandlerApi<State>;
// TODO: what is the best way to create a transaction in this case?
return await handler.handle<Input, View>(
const handleResult = await handler.handle<Input, View>(
executionContext,
evalStateResult.state,
interaction,
@@ -107,6 +111,15 @@ export class HandlerBasedContract<State> implements Contract<State> {
},
[]
);
if (handleResult.type !== 'ok') {
logger.fatal('Error while interacting with contract', {
type: handleResult.type,
error: handleResult.errorMessage
});
}
return handleResult;
}
async viewStateForTx<Input, View>(

View File

@@ -23,7 +23,7 @@ export class SmartWeaveNodeFactory extends SmartWeaveWebFactory {
* Returns a {@link SmartWeave} that is using file-based cache for {@link StateEvaluator} layer
* and mem cache for the rest.
*/
static fileCacheClient(arweave: Arweave, cacheBasePath?: string): SmartWeave {
static fileCached(arweave: Arweave, cacheBasePath?: string): SmartWeave {
const definitionLoader = new ContractDefinitionLoader(arweave, new MemCache());
const interactionsLoader = new CacheableContractInteractionsLoader(

View File

@@ -20,6 +20,7 @@ import { BsonFileBlockHeightSwCache, MemBlockHeightSwCache, MemCache } from '@sm
/**
* A factory that simplifies the process of creating different versions of {@link SmartWeave}.
* All versions use the {@link Evolve} plugin.
* SmartWeave instances created by this factory can be safely used in a web environment.
*/
export class SmartWeaveWebFactory {
/**
@@ -52,9 +53,9 @@ export class SmartWeaveWebFactory {
/**
* Returns a {@link SmartWeave} that (yup, you've guessed it!) does not use any caches.
* This one is gonna be slooow...
* This one is gonna be slooow!
*/
static noCacheClient(arweave: Arweave): SmartWeave {
static nonCached(arweave: Arweave): SmartWeave {
const definitionLoader = new ContractDefinitionLoader(arweave);
const interactionsLoader = new ContractInteractionsLoader(arweave);
const executorFactory = new HandlerExecutorFactory(arweave);

View File

@@ -59,14 +59,14 @@ export class DefaultStateEvaluator implements StateEvaluator {
executionContext.contractDefinition
)) as HandlerApi<State>;
logger.debug(
logger.trace(
'missingInteractions',
missingInteractions.map((int) => {
return int.node.id;
})
);
logger.debug('Init state', JSON.stringify(baseState.state));
logger.trace('Init state', JSON.stringify(baseState.state));
for (const missingInteraction of missingInteractions) {
logger.debug(
@@ -125,11 +125,11 @@ export class DefaultStateEvaluator implements StateEvaluator {
private logResult<State>(result: InteractionResult<State, unknown>, currentTx: GQLNodeInterface) {
if (result.type === 'exception') {
logger.error(`${result.result}`);
logger.error(`${result.errorMessage}`);
logger.error(`Executing of interaction: ${currentTx.id} threw exception.`);
}
if (result.type === 'error') {
logger.error(`${result.result}`);
logger.error(`${result.errorMessage}`);
logger.error(`Executing of interaction: ${currentTx.id} returned error.`);
}
}

View File

@@ -58,7 +58,7 @@ export class HandlerExecutorFactory implements ExecutorFactory<HandlerApi<unknow
const handler = contractFunction(swGlobal, BigNumber, clarity) as HandlerFunction<State, Input, Result>;
const stateCopy = JSON.parse(JSON.stringify(state));
swGlobal._activeTx = interactionTx;
logger.debug(`SmartWeave.contract.id: ${swGlobal.contract.id}`, swGlobal.contract.id);
logger.debug(`SmartWeave.contract.id:`, swGlobal.contract.id);
self.assignReadContractState<Input, State>(swGlobal, contractDefinition, executionContext, currentTx);
self.assignViewContractState<Input, State>(swGlobal, contractDefinition, executionContext);
@@ -80,14 +80,20 @@ export class HandlerExecutorFactory implements ExecutorFactory<HandlerApi<unknow
case 'ContractError':
return {
type: 'error',
result: err.message,
state
errorMessage: err.message,
state,
// note: previous version was writing error message to a "result" field,
// which fucks-up the HandlerResult type definition -
// HandlerResult.result had to be declared as 'Result | string' - and that led to a poor dev exp.
// TODO: this might be breaking change!
result: null
};
default:
return {
type: 'exception',
result: `${(err && err.stack) || (err && err.message)}`,
state
errorMessage: `${(err && err.stack) || (err && err.message)}`,
state,
result: null
};
}
}
@@ -180,12 +186,13 @@ export type HandlerFunction<State, Input, Result> = (
// TODO: change to XOR between result and state?
export type HandlerResult<State, Result> = {
result: string | Result; // this really sucks, but has to be declared this way to be backwards compatbile
result: Result;
state: State;
};
export type InteractionResult<State, Result> = HandlerResult<State, Result> & {
type: 'ok' | 'error' | 'exception';
errorMessage?: string;
};
export type ContractInteraction<Input> = {

View File

@@ -4,8 +4,8 @@ import { LogLevel, RedStoneLogger } from '../RedStoneLogger';
export const defaultLoggerOptions: ISettingsParam = {
displayFunctionName: false,
displayFilePath: 'hideNodeModulesOnly',
displayLoggerName: false,
displayFilePath: 'hidden',
displayLoggerName: true,
dateTimeTimezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
minLevel: 'debug'
};