perf: add option to use fast-copy library for deep copying object #114
This commit is contained in:
committed by
Piotr Pędziwiatr
parent
39af94599f
commit
04a4683357
@@ -57,6 +57,7 @@
|
|||||||
"arweave-multihost": "^0.1.0",
|
"arweave-multihost": "^0.1.0",
|
||||||
"axios": "^0.21.4",
|
"axios": "^0.21.4",
|
||||||
"bignumber.js": "^9.0.1",
|
"bignumber.js": "^9.0.1",
|
||||||
|
"fast-copy": "^2.1.1",
|
||||||
"json-beautify": "^1.1.1",
|
"json-beautify": "^1.1.1",
|
||||||
"knex": "^0.95.14",
|
"knex": "^0.95.14",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
@@ -69,7 +70,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/cheerio": "^0.22.30",
|
"@types/cheerio": "^0.22.30",
|
||||||
"@types/jest": "^27.0.1",
|
"@types/jest": "^27.0.1",
|
||||||
"@types/node": "^16.7.1",
|
"@types/node": "^17.0.21",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.29.2",
|
"@typescript-eslint/eslint-plugin": "^4.29.2",
|
||||||
"@typescript-eslint/parser": "^4.29.2",
|
"@typescript-eslint/parser": "^4.29.2",
|
||||||
"arlocal": "1.1.22",
|
"arlocal": "1.1.22",
|
||||||
|
|||||||
@@ -96,6 +96,8 @@ export class DefaultEvaluationOptions implements EvaluationOptions {
|
|||||||
sequencerAddress = 'https://gateway.redstone.finance/';
|
sequencerAddress = 'https://gateway.redstone.finance/';
|
||||||
|
|
||||||
gasLimit = Number.MAX_SAFE_INTEGER;
|
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.
|
// 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;
|
sequencerAddress: string;
|
||||||
|
|
||||||
gasLimit: number;
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export class ContractHandlerApi<State> implements HandlerApi<State> {
|
|||||||
try {
|
try {
|
||||||
const { interaction, interactionTx, currentTx } = interactionData;
|
const { interaction, interactionTx, currentTx } = interactionData;
|
||||||
|
|
||||||
const stateCopy = deepCopy(currentResult.state);
|
const stateCopy = deepCopy(currentResult.state, executionContext.evaluationOptions.useFastCopy);
|
||||||
this.swGlobal._activeTx = interactionTx;
|
this.swGlobal._activeTx = interactionTx;
|
||||||
|
|
||||||
const handler = this.contractFunction(this.swGlobal, BigNumber, clarity, contractLogger) as HandlerFunction<
|
const handler = this.contractFunction(this.swGlobal, BigNumber, clarity, contractLogger) as HandlerFunction<
|
||||||
|
|||||||
@@ -68,8 +68,6 @@ export abstract class DefaultStateEvaluator implements StateEvaluator {
|
|||||||
`Evaluating state for ${contractDefinition.txId} [${missingInteractions.length} non-cached of ${sortedInteractions.length} all]`
|
`Evaluating state for ${contractDefinition.txId} [${missingInteractions.length} non-cached of ${sortedInteractions.length} all]`
|
||||||
);
|
);
|
||||||
|
|
||||||
this.logger.trace('Base state:', baseState.state);
|
|
||||||
|
|
||||||
let errorMessage = null;
|
let errorMessage = null;
|
||||||
let lastConfirmedTxState: { tx: GQLNodeInterface; state: EvalStateResult<State> } = null;
|
let lastConfirmedTxState: { tx: GQLNodeInterface; state: EvalStateResult<State> } = null;
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import cloneDeep from 'lodash/cloneDeep';
|
import cloneDeep from 'lodash/cloneDeep';
|
||||||
|
import copy from "fast-copy";
|
||||||
|
|
||||||
export const sleep = (ms: number): Promise<void> => {
|
export const sleep = (ms: number): Promise<void> => {
|
||||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const deepCopy = (input: unknown): any => {
|
export const deepCopy = (input: unknown, useFastCopy = false): any => {
|
||||||
return cloneDeep(input);
|
return useFastCopy ? copy(input) : cloneDeep(input);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const mapReplacer = (key: unknown, value: unknown) => {
|
export const mapReplacer = (key: unknown, value: unknown) => {
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ const logger = LoggerFactory.INST.create('Contract');
|
|||||||
|
|
||||||
//LoggerFactory.use(new TsLogFactory());
|
//LoggerFactory.use(new TsLogFactory());
|
||||||
LoggerFactory.INST.logLevel('error');
|
LoggerFactory.INST.logLevel('error');
|
||||||
//LoggerFactory.INST.logLevel('info', 'Contract');
|
LoggerFactory.INST.logLevel('info', 'Contract');
|
||||||
//LoggerFactory.INST.logLevel('debug', 'DefaultStateEvaluator');
|
//LoggerFactory.INST.logLevel('debug', 'DefaultStateEvaluator');
|
||||||
//LoggerFactory.INST.logLevel('error', 'CacheableStateEvaluator');
|
//LoggerFactory.INST.logLevel('debug', 'CacheableStateEvaluator');
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
printTestInfo();
|
printTestInfo();
|
||||||
@@ -52,71 +52,18 @@ async function main() {
|
|||||||
|
|
||||||
const koi_source = fs.readFileSync(path.join(__dirname, 'data', 'koi-source.js'), "utf-8");
|
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(
|
.setInteractionsLoader(
|
||||||
new RedstoneGatewayInteractionsLoader('https://gateway.redstone.finance')
|
new RedstoneGatewayInteractionsLoader('https://gateway.redstone.finance')
|
||||||
)
|
)
|
||||||
.overwriteSource({
|
.build();
|
||||||
["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",
|
|
||||||
});
|
|
||||||
|
|
||||||
const jwk = readJSON('../redstone-node/.secrets/redstone-jwk.json');
|
const jwk = readJSON('../redstone-node/.secrets/redstone-jwk.json');
|
||||||
const contract = smartweave
|
const contract = smartweave
|
||||||
.contract("egfnrQFu-xDNgl1x04HlH6-wGKcHVKMF7U5Nsc-1USA")
|
.contract(PIANITY_CONTRACT)
|
||||||
.setEvaluationOptions({
|
.setEvaluationOptions({
|
||||||
sequencerAddress: 'http://localhost:5666/',
|
sequencerAddress: 'http://localhost:5666/',
|
||||||
updateCacheForEachInteraction: false
|
useFastCopy: true
|
||||||
})
|
})
|
||||||
.connect(jwk);
|
.connect(jwk);
|
||||||
/* const bundledInteraction = await contract.bundleInteraction({
|
/* 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));
|
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 heapUsedAfter = Math.round((process.memoryUsage().heapUsed / 1024 / 1024) * 100) / 100;
|
||||||
const rssUsedAfter = Math.round((process.memoryUsage().rss / 1024 / 1024) * 100) / 100;
|
const rssUsedAfter = Math.round((process.memoryUsage().rss / 1024 / 1024) * 100) / 100;
|
||||||
logger.warn('Heap used in MB', {
|
logger.warn('Heap used in MB', {
|
||||||
|
|||||||
13
yarn.lock
13
yarn.lock
@@ -1425,10 +1425,10 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.46.tgz#7e49dee4c54fd19584e6a9e0da5f3dc2e9136bc7"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.46.tgz#7e49dee4c54fd19584e6a9e0da5f3dc2e9136bc7"
|
||||||
integrity sha512-cPjLXj8d6anFPzFvOPxS3fvly3Shm5nTfl6g8X5smexixbuGUf7hfr21J5tX9JW+UPStp/5P5R8qrKL5IyVJ+A==
|
integrity sha512-cPjLXj8d6anFPzFvOPxS3fvly3Shm5nTfl6g8X5smexixbuGUf7hfr21J5tX9JW+UPStp/5P5R8qrKL5IyVJ+A==
|
||||||
|
|
||||||
"@types/node@^16.7.1":
|
"@types/node@^17.0.21":
|
||||||
version "16.11.25"
|
version "17.0.21"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.25.tgz#bb812b58bacbd060ce85921250d8b4ca553cd4a2"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.21.tgz#864b987c0c68d07b4345845c3e63b75edd143644"
|
||||||
integrity sha512-NrTwfD7L1RTc2qrHQD4RTTy4p0CO2LatKBEKEds3CaVuhoM/+DJzmWZl5f+ikR8cm8F5mfJxK+9rQq07gRiSjQ==
|
integrity sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==
|
||||||
|
|
||||||
"@types/prettier@^2.1.5":
|
"@types/prettier@^2.1.5":
|
||||||
version "2.4.4"
|
version "2.4.4"
|
||||||
@@ -3495,6 +3495,11 @@ eyes@^0.1.8:
|
|||||||
resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0"
|
resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0"
|
||||||
integrity sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=
|
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:
|
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
||||||
version "3.1.3"
|
version "3.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||||
|
|||||||
Reference in New Issue
Block a user