perf: add option to use fast-copy library for deep copying object #114

This commit is contained in:
ppedziwiatr
2022-03-08 17:23:20 +01:00
committed by Piotr Pędziwiatr
parent 39af94599f
commit 04a4683357
7 changed files with 29 additions and 71 deletions

View File

@@ -57,6 +57,7 @@
"arweave-multihost": "^0.1.0",
"axios": "^0.21.4",
"bignumber.js": "^9.0.1",
"fast-copy": "^2.1.1",
"json-beautify": "^1.1.1",
"knex": "^0.95.14",
"lodash": "^4.17.21",
@@ -69,7 +70,7 @@
"devDependencies": {
"@types/cheerio": "^0.22.30",
"@types/jest": "^27.0.1",
"@types/node": "^16.7.1",
"@types/node": "^17.0.21",
"@typescript-eslint/eslint-plugin": "^4.29.2",
"@typescript-eslint/parser": "^4.29.2",
"arlocal": "1.1.22",

View File

@@ -96,6 +96,8 @@ export class DefaultEvaluationOptions implements EvaluationOptions {
sequencerAddress = 'https://gateway.redstone.finance/';
gasLimit = Number.MAX_SAFE_INTEGER;
useFastCopy = false;
}
// an interface for the contract EvaluationOptions - can be used to change the behaviour of some of the features.
@@ -143,4 +145,10 @@ export interface EvaluationOptions {
sequencerAddress: string;
gasLimit: number;
// Whether fast-copy library should be used during the state evaluation
// https://github.com/planttheidea/fast-copy#isstrict
// it's much faster (e.g. almost twice for the SJ3l7474UHh3Dw6dWVT1bzsJ-8JvOewtGoDdOecWIZo contract)
// but not yet fully tested - so exposing it as an option (with default to false)
useFastCopy: boolean;
}

View File

@@ -49,7 +49,7 @@ export class ContractHandlerApi<State> implements HandlerApi<State> {
try {
const { interaction, interactionTx, currentTx } = interactionData;
const stateCopy = deepCopy(currentResult.state);
const stateCopy = deepCopy(currentResult.state, executionContext.evaluationOptions.useFastCopy);
this.swGlobal._activeTx = interactionTx;
const handler = this.contractFunction(this.swGlobal, BigNumber, clarity, contractLogger) as HandlerFunction<

View File

@@ -68,8 +68,6 @@ export abstract class DefaultStateEvaluator implements StateEvaluator {
`Evaluating state for ${contractDefinition.txId} [${missingInteractions.length} non-cached of ${sortedInteractions.length} all]`
);
this.logger.trace('Base state:', baseState.state);
let errorMessage = null;
let lastConfirmedTxState: { tx: GQLNodeInterface; state: EvalStateResult<State> } = null;

View File

@@ -1,12 +1,13 @@
/* eslint-disable */
import cloneDeep from 'lodash/cloneDeep';
import copy from "fast-copy";
export const sleep = (ms: number): Promise<void> => {
return new Promise((resolve) => setTimeout(resolve, ms));
};
export const deepCopy = (input: unknown): any => {
return cloneDeep(input);
export const deepCopy = (input: unknown, useFastCopy = false): any => {
return useFastCopy ? copy(input) : cloneDeep(input);
};
export const mapReplacer = (key: unknown, value: unknown) => {

View File

@@ -20,9 +20,9 @@ const logger = LoggerFactory.INST.create('Contract');
//LoggerFactory.use(new TsLogFactory());
LoggerFactory.INST.logLevel('error');
//LoggerFactory.INST.logLevel('info', 'Contract');
LoggerFactory.INST.logLevel('info', 'Contract');
//LoggerFactory.INST.logLevel('debug', 'DefaultStateEvaluator');
//LoggerFactory.INST.logLevel('error', 'CacheableStateEvaluator');
//LoggerFactory.INST.logLevel('debug', 'CacheableStateEvaluator');
async function main() {
printTestInfo();
@@ -52,71 +52,18 @@ async function main() {
const koi_source = fs.readFileSync(path.join(__dirname, 'data', 'koi-source.js'), "utf-8");
const smartweave = SmartWeaveNodeFactory.memCachedBased(arweave)
const smartweave = SmartWeaveNodeFactory.fileCachedBased(arweave, 'data')
.setInteractionsLoader(
new RedstoneGatewayInteractionsLoader('https://gateway.redstone.finance')
)
.overwriteSource({
["egfnrQFu-xDNgl1x04HlH6-wGKcHVKMF7U5Nsc-1USA"]: "export async function handle (state, action) {\n" +
" const puzzles = state.puzzles\n" +
" const input = action.input\n" +
" const caller = action.caller\n" +
"\n" +
" if (input.function === 'create') {\n" +
" const solution_hash = input.solution_hash\n" +
" const file_id = input.file_id\n" +
"\n" +
" if (!solution_hash) {\n" +
" throw new ContractError('No solution hash provided')\n" +
" }\n" +
"\n" +
" if (!file_id) {\n" +
" throw new ContractError('No file id specified')\n" +
" }\n" +
"\n" +
" if (solution_hash in puzzles) {\n" +
" throw new ContractError('Puzzle already exists')\n" +
" } else {\n" +
" puzzles[solution_hash] = {\n" +
" \"file_id\": file_id,\n" +
" \"creator\": caller,\n" +
" \"winner\": null\n" +
" }\n" +
" }\n" +
"\n" +
" return { state }\n" +
" }\n" +
"\n" +
" if (input.function === 'solve') {\n" +
" const solution = input.solution\n" +
" const solution_hash = input.solution_hash\n" +
"\n" +
" if (solution_hash in puzzles) {\n" +
" const solution_buffer = SmartWeave.arweave.utils.stringToBuffer(solution)\n" +
" const calculated_hash =\n" +
" SmartWeave.arweave.utils.bufferTob64Url(\n" +
" await SmartWeave.arweave.utils.crypto.hash(solution_buffer)\n" +
" )\n" +
" if (calculated_hash === solution_hash){\n" +
" puzzles[solution_hash].winner = caller\n" +
" }\n" +
" } else {\n" +
" throw new ContractError('Puzzle not found')\n" +
" }\n" +
"\n" +
" return { state }\n" +
" }\n" +
"\n" +
" throw new ContractError(`No function supplied or function not recognised: \"${input.function}\"`)\n" +
"}\n",
});
.build();
const jwk = readJSON('../redstone-node/.secrets/redstone-jwk.json');
const contract = smartweave
.contract("egfnrQFu-xDNgl1x04HlH6-wGKcHVKMF7U5Nsc-1USA")
.contract(PIANITY_CONTRACT)
.setEvaluationOptions({
sequencerAddress: 'http://localhost:5666/',
updateCacheForEachInteraction: false
useFastCopy: true
})
.connect(jwk);
/* const bundledInteraction = await contract.bundleInteraction({
@@ -133,8 +80,6 @@ async function main() {
fs.writeFileSync(path.join(__dirname, 'data', 'koi-proper-state_2.json'), stringify(state));
logger.info("State", state);
const heapUsedAfter = Math.round((process.memoryUsage().heapUsed / 1024 / 1024) * 100) / 100;
const rssUsedAfter = Math.round((process.memoryUsage().rss / 1024 / 1024) * 100) / 100;
logger.warn('Heap used in MB', {

View File

@@ -1425,10 +1425,10 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.46.tgz#7e49dee4c54fd19584e6a9e0da5f3dc2e9136bc7"
integrity sha512-cPjLXj8d6anFPzFvOPxS3fvly3Shm5nTfl6g8X5smexixbuGUf7hfr21J5tX9JW+UPStp/5P5R8qrKL5IyVJ+A==
"@types/node@^16.7.1":
version "16.11.25"
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.25.tgz#bb812b58bacbd060ce85921250d8b4ca553cd4a2"
integrity sha512-NrTwfD7L1RTc2qrHQD4RTTy4p0CO2LatKBEKEds3CaVuhoM/+DJzmWZl5f+ikR8cm8F5mfJxK+9rQq07gRiSjQ==
"@types/node@^17.0.21":
version "17.0.21"
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.21.tgz#864b987c0c68d07b4345845c3e63b75edd143644"
integrity sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==
"@types/prettier@^2.1.5":
version "2.4.4"
@@ -3495,6 +3495,11 @@ eyes@^0.1.8:
resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0"
integrity sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=
fast-copy@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/fast-copy/-/fast-copy-2.1.1.tgz#f5cbcf2df64215e59b8e43f0b2caabc19848083a"
integrity sha512-Qod3DdRgFZ8GUIM6ygeoZYpQ0QLW9cf/FS9KhhjlYggcSZXWAemAw8BOCO5LuYCrR3Uj3qXDVTUzOUwG8C7beQ==
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"