From 46f800768426d32852f4470226af3dc9a2b78d2f Mon Sep 17 00:00:00 2001 From: takkyhuang Date: Wed, 7 Aug 2024 11:42:17 +0800 Subject: [PATCH] =?UTF-8?q?task7=20=E9=99=90=E6=B5=81=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- members/mosida/task7/index.ts | 79 +++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 members/mosida/task7/index.ts diff --git a/members/mosida/task7/index.ts b/members/mosida/task7/index.ts new file mode 100644 index 000000000..55a620e1d --- /dev/null +++ b/members/mosida/task7/index.ts @@ -0,0 +1,79 @@ +import { + allocate, + entryPoint, + execute, + IPreContractCallJP, + PreContractCallInput, + sys, + uint8ArrayToHex, + UintData, +} from "@artela/aspect-libs"; +import {Protobuf} from "as-proto/assembly"; + +/** + + */ +class Aspect implements IPreContractCallJP { + /** + * + * @param input + */ + preContractCall(input: PreContractCallInput): void { + // read the throttle config from the properties and decode + const interval = sys.aspect.property.get("interval"); + const limit = sys.aspect.property.get("limit"); + + // get the contract address, from address and build the storage prefix + const contractAddress = uint8ArrayToHex(input.call!.to); + const from = uint8ArrayToHex(input.call!.from); + const storagePrefix = `${contractAddress}:${from}`; + + // load the current block timestamp + const blockTimeBytes = sys.hostApi.runtimeContext.get('block.header.timestamp'); + const blockTime = Protobuf.decode(blockTimeBytes, UintData.decode).data; + + // load last execution timestamp + const lastExecState = sys.aspect.mutableState.get( + storagePrefix + 'lastExecAt' + ); + const lastExec = lastExecState.unwrap(); + + // check if the throttle interval has passed, revert if not + if(lastExec > 0 && (blockTime - lastExec) < interval){ + sys.revert('throttled'); + } + + // check if the throttle limit has been reached, revert if so + const execTimeState = sys.aspect.mutableState.get( + storagePrefix + 'execTimees' + ); + const execTimes = execTimeState.unwrap(); + if(limit && execTimes >= limit){ + sys.revert('execution time exceeded'); + } + + // update the throttle state + execTimeState.set(execTimes + 1); + lastExecState.set(blockTime); + } + + /** + * isOwner is the governance account implemented by the Aspect, when any of the governance operation + * (including upgrade, config, destroy) is made, isOwner method will be invoked to check + * against the initiator's account to make sure it has the permission. + * + * @param sender address of the transaction + * @return true if check success, false if check fail + */ + isOwner(sender: Uint8Array): bool { + return false; + } +} + +// 2.register aspect Instance +const aspect = new Aspect() +entryPoint.setAspect(aspect) + +// 3.must export it +export { execute, allocate } +