feat: internal writes for Rust
This commit is contained in:
@@ -111,6 +111,7 @@ export class ContractHandlerApi<State> implements HandlerApi<State> {
|
|||||||
input
|
input
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// The contract that we want to call and modify its state
|
||||||
const calleeContract = executionContext.smartweave.contract(
|
const calleeContract = executionContext.smartweave.contract(
|
||||||
contractTxId,
|
contractTxId,
|
||||||
executionContext.contract,
|
executionContext.contract,
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ export abstract class DefaultStateEvaluator implements StateEvaluator {
|
|||||||
executionContext: ExecutionContext<State, HandlerApi<State>>,
|
executionContext: ExecutionContext<State, HandlerApi<State>>,
|
||||||
currentTx: CurrentTx[]
|
currentTx: CurrentTx[]
|
||||||
): Promise<EvalStateResult<State>> {
|
): Promise<EvalStateResult<State>> {
|
||||||
const stateEvaluationBenchmark = Benchmark.measure();
|
|
||||||
const { ignoreExceptions, stackTrace, internalWrites } = executionContext.evaluationOptions;
|
const { ignoreExceptions, stackTrace, internalWrites } = executionContext.evaluationOptions;
|
||||||
const { contract, contractDefinition, sortedInteractions } = executionContext;
|
const { contract, contractDefinition, sortedInteractions } = executionContext;
|
||||||
|
|
||||||
@@ -129,6 +128,8 @@ export abstract class DefaultStateEvaluator implements StateEvaluator {
|
|||||||
|
|
||||||
if (newState !== null) {
|
if (newState !== null) {
|
||||||
currentState = newState.cachedValue.state;
|
currentState = newState.cachedValue.state;
|
||||||
|
// we need to update the state in the wasm module
|
||||||
|
executionContext?.handler.initState(currentState);
|
||||||
validity[interactionTx.id] = newState.cachedValue.validity[interactionTx.id];
|
validity[interactionTx.id] = newState.cachedValue.validity[interactionTx.id];
|
||||||
|
|
||||||
const toCache = new EvalStateResult(currentState, validity);
|
const toCache = new EvalStateResult(currentState, validity);
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ export class WasmContractHandlerApi<State> implements HandlerApi<State> {
|
|||||||
this.swGlobal.gasUsed = 0;
|
this.swGlobal.gasUsed = 0;
|
||||||
|
|
||||||
this.assignReadContractState<Input>(executionContext, currentTx, currentResult, interactionTx);
|
this.assignReadContractState<Input>(executionContext, currentTx, currentResult, interactionTx);
|
||||||
|
this.assignWrite(executionContext, currentTx);
|
||||||
|
|
||||||
const handlerResult = await this.doHandle(interaction);
|
const handlerResult = await this.doHandle(interaction);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -210,4 +212,47 @@ export class WasmContractHandlerApi<State> implements HandlerApi<State> {
|
|||||||
return returnValidity ? deepCopy(stateWithValidity) : deepCopy(stateWithValidity.state);
|
return returnValidity ? deepCopy(stateWithValidity) : deepCopy(stateWithValidity.state);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private assignWrite(executionContext: ExecutionContext<State>, currentTx: CurrentTx[]) {
|
||||||
|
this.swGlobal.contracts.write = async <Input = unknown>(
|
||||||
|
contractTxId: string,
|
||||||
|
input: Input
|
||||||
|
): Promise<InteractionResult<unknown, unknown>> => {
|
||||||
|
if (!executionContext.evaluationOptions.internalWrites) {
|
||||||
|
throw new Error("Internal writes feature switched off. Change EvaluationOptions.internalWrites flag to 'true'");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.debug('swGlobal.write call:', {
|
||||||
|
from: this.contractDefinition.txId,
|
||||||
|
to: contractTxId,
|
||||||
|
input
|
||||||
|
});
|
||||||
|
|
||||||
|
const calleeContract = executionContext.smartweave.contract(
|
||||||
|
contractTxId,
|
||||||
|
executionContext.contract,
|
||||||
|
this.swGlobal._activeTx
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await calleeContract.dryWriteFromTx<Input>(input, this.swGlobal._activeTx, [
|
||||||
|
...(currentTx || []),
|
||||||
|
{
|
||||||
|
contractTxId: this.contractDefinition.txId,
|
||||||
|
interactionTxId: this.swGlobal.transaction.id
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
this.logger.debug('Cache result?:', !this.swGlobal._activeTx.dry);
|
||||||
|
await executionContext.smartweave.stateEvaluator.onInternalWriteStateUpdate(
|
||||||
|
this.swGlobal._activeTx,
|
||||||
|
contractTxId,
|
||||||
|
{
|
||||||
|
state: result.state as State,
|
||||||
|
validity: {}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,8 +50,11 @@ export const rustWasmImports = (swGlobal, wbindgenImports, wasmInstance, dtorVal
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
SmartWeave: {
|
SmartWeave: {
|
||||||
readContractState: async function (contractTxId) {
|
readContractState: async function (contractTxId): Promise<any> {
|
||||||
return await swGlobal.contracts.readContractState(contractTxId);
|
return await swGlobal.contracts.readContractState(contractTxId);
|
||||||
|
},
|
||||||
|
write: async function(contractId: string, input: any) {
|
||||||
|
return await swGlobal.contracts.write(contractId, input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -98,8 +101,9 @@ export const rustWasmImports = (swGlobal, wbindgenImports, wasmInstance, dtorVal
|
|||||||
__wbg_viewContractState: function (arg0, arg1) {
|
__wbg_viewContractState: function (arg0, arg1) {
|
||||||
// TODO
|
// TODO
|
||||||
},
|
},
|
||||||
__wbg_write: function (arg0, arg1) {
|
__wbg_write: function(arg0, arg1, arg2) {
|
||||||
// TODO
|
var ret = rawImports.SmartWeave.write(getStringFromWasm0(arg0, arg1), takeObject(arg2));
|
||||||
|
return addHeapObject(ret);
|
||||||
},
|
},
|
||||||
__wbg_refreshState: function (arg0, arg1) {
|
__wbg_refreshState: function (arg0, arg1) {
|
||||||
// TODO
|
// TODO
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { TsLogFactory } from '../src/logging/node/TsLogFactory';
|
|||||||
const logger = LoggerFactory.INST.create('Contract');
|
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('error', 'RedstoneGatewayInteractionsLoader');
|
LoggerFactory.INST.logLevel('error', 'RedstoneGatewayInteractionsLoader');
|
||||||
LoggerFactory.INST.logLevel('error', 'DefaultStateEvaluator');
|
LoggerFactory.INST.logLevel('error', 'DefaultStateEvaluator');
|
||||||
@@ -40,9 +40,8 @@ async function main() {
|
|||||||
const jwk = readJSON('../redstone-node/.secrets/redstone-jwk.json');
|
const jwk = readJSON('../redstone-node/.secrets/redstone-jwk.json');
|
||||||
// connecting to a given contract
|
// connecting to a given contract
|
||||||
const token = smartweave
|
const token = smartweave
|
||||||
.contract("-8A6RexFkpfWwuyVO98wzSFZh0d6VJuI-buTJvlwOJQ")
|
.contract("_IHQHkZrZfB3lN69Hw3xTRcHv2cBiNgh1HG1WENydP4")
|
||||||
.setEvaluationOptions({
|
.setEvaluationOptions({
|
||||||
useVM2: true,
|
|
||||||
sequencerAddress: "https://gateway.redstone.finance/"
|
sequencerAddress: "https://gateway.redstone.finance/"
|
||||||
})
|
})
|
||||||
// connecting wallet to a contract. It is required before performing any "writeInteraction"
|
// connecting wallet to a contract. It is required before performing any "writeInteraction"
|
||||||
@@ -51,16 +50,23 @@ async function main() {
|
|||||||
|
|
||||||
const result1 = await token.readState();
|
const result1 = await token.readState();
|
||||||
|
|
||||||
|
console.log(result1.state);
|
||||||
console.log(token.lastReadStateStats());
|
console.log(token.lastReadStateStats());
|
||||||
|
|
||||||
//logger.info("Amount of computed interactions before 'bundleInteraction':", Object.keys(result1.validity).length);
|
//logger.info("Amount of computed interactions before 'bundleInteraction':", Object.keys(result1.validity).length);
|
||||||
|
|
||||||
/*for (let i = 0 ; i < 100 ; i++) {
|
/*for (let i = 0 ; i < 1100 ; i++) {
|
||||||
console.log(`mint ${i + 1}`);
|
console.log(`mint ${i + 1}`);
|
||||||
const result = await token.bundleInteraction<any>({
|
try {
|
||||||
function: "mint"
|
const result = await token.bundleInteraction<any>({
|
||||||
});
|
function: "transfer",
|
||||||
await sleep(1000);
|
target: "33F0QHcb22W7LwWR1iRC8Az1ntZG09XQ03YWuw2ABqA",
|
||||||
|
qty: 10
|
||||||
|
});
|
||||||
|
} catch(e:any) {
|
||||||
|
|
||||||
|
}
|
||||||
|
//await sleep(1);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user