fix: viewState interaction transaction does not take 'evolve' into account #14
This commit is contained in:
committed by
Piotr Pędziwiatr
parent
717c325a36
commit
ce5a589b10
13
.github/workflows/tests.yml
vendored
Normal file
13
.github/workflows/tests.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
name: CI
|
||||||
|
on: push
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Install modules
|
||||||
|
run: yarn
|
||||||
|
- name: Run unit tests
|
||||||
|
run: yarn test:unit
|
||||||
|
- name: Run integration tests
|
||||||
|
run: yarn test:integration
|
||||||
@@ -18,6 +18,7 @@ module.exports = {
|
|||||||
|
|
||||||
testPathIgnorePatterns: [
|
testPathIgnorePatterns: [
|
||||||
"/.yalc/",
|
"/.yalc/",
|
||||||
|
"/data/"
|
||||||
],
|
],
|
||||||
|
|
||||||
testEnvironment: 'node',
|
testEnvironment: 'node',
|
||||||
|
|||||||
@@ -24,7 +24,10 @@
|
|||||||
"version": "yarn format && git add -A src",
|
"version": "yarn format && git add -A src",
|
||||||
"postversion": "git push && git push --tags",
|
"postversion": "git push && git push --tags",
|
||||||
"yalc:publish": "yarn build && yalc publish --push",
|
"yalc:publish": "yarn build && yalc publish --push",
|
||||||
"test": "jest"
|
"test": "jest",
|
||||||
|
"test:unit": "jest ./src/__tests__/unit",
|
||||||
|
"test:integration": "jest ./src/__tests__/integration",
|
||||||
|
"test:regression": "jest ./src/__tests__/regression"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": "Redstone Team <dev@redstone.finance>",
|
"author": "Redstone Team <dev@redstone.finance>",
|
||||||
|
|||||||
66
src/__tests__/integration/data/token-evolve.js
Normal file
66
src/__tests__/integration/data/token-evolve.js
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
export function handle(state, action) {
|
||||||
|
const balances = state.balances;
|
||||||
|
const canEvolve = state.canEvolve;
|
||||||
|
const input = action.input;
|
||||||
|
const caller = action.caller;
|
||||||
|
|
||||||
|
if (input.function === 'transfer') {
|
||||||
|
const target = input.target;
|
||||||
|
const qty = input.qty;
|
||||||
|
|
||||||
|
if (!Number.isInteger(qty)) {
|
||||||
|
throw new ContractError('Invalid value for "qty". Must be an integer');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!target) {
|
||||||
|
throw new ContractError('No target specified');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qty <= 0 || caller === target) {
|
||||||
|
throw new ContractError('Invalid token transfer');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (balances[caller] < qty) {
|
||||||
|
throw new ContractError(`Caller balance not high enough to send ${qty} token(s)!`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lower the token balance of the caller
|
||||||
|
balances[caller] -= qty;
|
||||||
|
if (target in balances) {
|
||||||
|
// Wallet already exists in state, add new tokens
|
||||||
|
balances[target] += qty;
|
||||||
|
} else {
|
||||||
|
// Wallet is new, set starting balance
|
||||||
|
balances[target] = qty;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { state };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.function === 'balance') {
|
||||||
|
const target = input.target;
|
||||||
|
const ticker = state.ticker;
|
||||||
|
|
||||||
|
if (typeof target !== 'string') {
|
||||||
|
throw new ContractError('Must specify target to get balance for');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof balances[target] !== 'number') {
|
||||||
|
throw new ContractError('Cannot get balance, target does not exist');
|
||||||
|
}
|
||||||
|
|
||||||
|
return { result: { target, ticker, balance: balances[target] + 555 } };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.function === 'evolve' && canEvolve) {
|
||||||
|
if (state.owner !== caller) {
|
||||||
|
throw new ContractError('Only the owner can evolve a contract.');
|
||||||
|
}
|
||||||
|
|
||||||
|
state.evolve = input.value;
|
||||||
|
|
||||||
|
return { state };
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ContractError(`No function supplied or function not recognised: "${input.function}"`);
|
||||||
|
}
|
||||||
@@ -1,67 +1,66 @@
|
|||||||
|
export function handle(state, action) {
|
||||||
export function handle (state, action) {
|
const balances = state.balances;
|
||||||
const balances = state.balances
|
const canEvolve = state.canEvolve;
|
||||||
const canEvolve = state.canEvolve
|
const input = action.input;
|
||||||
const input = action.input
|
const caller = action.caller;
|
||||||
const caller = action.caller
|
|
||||||
|
|
||||||
if (input.function === 'transfer') {
|
if (input.function === 'transfer') {
|
||||||
const target = input.target
|
const target = input.target;
|
||||||
const qty = input.qty
|
const qty = input.qty;
|
||||||
|
|
||||||
if (!Number.isInteger(qty)) {
|
if (!Number.isInteger(qty)) {
|
||||||
throw new ContractError('Invalid value for "qty". Must be an integer')
|
throw new ContractError('Invalid value for "qty". Must be an integer');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!target) {
|
if (!target) {
|
||||||
throw new ContractError('No target specified')
|
throw new ContractError('No target specified');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qty <= 0 || caller === target) {
|
if (qty <= 0 || caller === target) {
|
||||||
throw new ContractError('Invalid token transfer')
|
throw new ContractError('Invalid token transfer');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (balances[caller] < qty) {
|
if (balances[caller] < qty) {
|
||||||
throw new ContractError(`Caller balance not high enough to send ${qty} token(s)!`)
|
throw new ContractError(`Caller balance not high enough to send ${qty} token(s)!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lower the token balance of the caller
|
// Lower the token balance of the caller
|
||||||
balances[caller] -= qty
|
balances[caller] -= qty;
|
||||||
if (target in balances) {
|
if (target in balances) {
|
||||||
// Wallet already exists in state, add new tokens
|
// Wallet already exists in state, add new tokens
|
||||||
balances[target] += qty
|
balances[target] += qty;
|
||||||
} else {
|
} else {
|
||||||
// Wallet is new, set starting balance
|
// Wallet is new, set starting balance
|
||||||
balances[target] = qty
|
balances[target] = qty;
|
||||||
}
|
}
|
||||||
|
|
||||||
return { state }
|
return { state };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.function === 'balance') {
|
if (input.function === 'balance') {
|
||||||
const target = input.target
|
const target = input.target;
|
||||||
const ticker = state.ticker
|
const ticker = state.ticker;
|
||||||
|
|
||||||
if (typeof target !== 'string') {
|
if (typeof target !== 'string') {
|
||||||
throw new ContractError('Must specify target to get balance for')
|
throw new ContractError('Must specify target to get balance for');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof balances[target] !== 'number') {
|
if (typeof balances[target] !== 'number') {
|
||||||
throw new ContractError('Cannot get balance, target does not exist')
|
throw new ContractError('Cannot get balance, target does not exist');
|
||||||
}
|
}
|
||||||
|
|
||||||
return { result: { target, ticker, balance: balances[target] } }
|
return { result: { target, ticker, balance: balances[target] } };
|
||||||
}
|
}
|
||||||
|
|
||||||
if(input.function === 'evolve' && canEvolve) {
|
if (input.function === 'evolve' && canEvolve) {
|
||||||
if(state.owner !== caller) {
|
if (state.owner !== caller) {
|
||||||
throw new ContractError('Only the owner can evolve a contract.');
|
throw new ContractError('Only the owner can evolve a contract.');
|
||||||
}
|
}
|
||||||
|
|
||||||
state.evolve = input.value
|
state.evolve = input.value;
|
||||||
|
|
||||||
return { state }
|
return { state };
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new ContractError(`No function supplied or function not recognised: "${input.function}"`)
|
throw new ContractError(`No function supplied or function not recognised: "${input.function}"`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ describe('Testing the SmartWeave client', () => {
|
|||||||
let walletAddress: string;
|
let walletAddress: string;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
|
// note: each tests suit (i.e. file with tests that Jest is running concurrently
|
||||||
|
// with another files has to have ArLocal set to a different port!)
|
||||||
arlocal = new ArLocal(1985, false);
|
arlocal = new ArLocal(1985, false);
|
||||||
await arlocal.start();
|
await arlocal.start();
|
||||||
|
|
||||||
@@ -58,7 +60,7 @@ describe('Testing the SmartWeave client', () => {
|
|||||||
src: contractSrc
|
src: contractSrc
|
||||||
});
|
});
|
||||||
|
|
||||||
contract = smartweave.contract(contractTxId) as HandlerBasedContract<ExampleContractState>;
|
contract = smartweave.contract(contractTxId);
|
||||||
contract.connect(wallet);
|
contract.connect(wallet);
|
||||||
|
|
||||||
await mine();
|
await mine();
|
||||||
|
|||||||
@@ -20,12 +20,14 @@ describe('Testing the Profit Sharing Token', () => {
|
|||||||
let initialState: PstState;
|
let initialState: PstState;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
arlocal = new ArLocal(1985, false);
|
// note: each tests suit (i.e. file with tests that Jest is running concurrently
|
||||||
|
// with another files has to have ArLocal set to a different port!)
|
||||||
|
arlocal = new ArLocal(1986, false);
|
||||||
await arlocal.start();
|
await arlocal.start();
|
||||||
|
|
||||||
arweave = Arweave.init({
|
arweave = Arweave.init({
|
||||||
host: 'localhost',
|
host: 'localhost',
|
||||||
port: 1985,
|
port: 1986,
|
||||||
protocol: 'http'
|
protocol: 'http'
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -42,6 +44,7 @@ describe('Testing the Profit Sharing Token', () => {
|
|||||||
initialState = {
|
initialState = {
|
||||||
...stateFromFile,
|
...stateFromFile,
|
||||||
...{
|
...{
|
||||||
|
owner: walletAddress,
|
||||||
balances: {
|
balances: {
|
||||||
...stateFromFile.balances,
|
...stateFromFile.balances,
|
||||||
[walletAddress]: 555669
|
[walletAddress]: 555669
|
||||||
@@ -95,6 +98,21 @@ describe('Testing the Profit Sharing Token', () => {
|
|||||||
expect(result.ticker).toEqual('EXAMPLE_PST_TOKEN');
|
expect(result.ticker).toEqual('EXAMPLE_PST_TOKEN');
|
||||||
expect(result.target).toEqual('uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M');
|
expect(result.target).toEqual('uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should properly evolve contract's source code", async () => {
|
||||||
|
expect((await pst.currentState()).balances[walletAddress]).toEqual(555114);
|
||||||
|
|
||||||
|
const newSource = fs.readFileSync(path.join(__dirname, 'data/token-evolve.js'), 'utf8');
|
||||||
|
|
||||||
|
const newSrcTxId = await pst.saveNewSource(newSource);
|
||||||
|
await mine();
|
||||||
|
|
||||||
|
await pst.evolve(newSrcTxId);
|
||||||
|
await mine();
|
||||||
|
|
||||||
|
// note: the evolved balance always adds 555 to the result
|
||||||
|
expect((await pst.currentBalance(walletAddress)).balance).toEqual(555114 + 555);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
async function mine() {
|
async function mine() {
|
||||||
|
|||||||
@@ -61,6 +61,9 @@ export interface Contract<State = unknown> {
|
|||||||
*
|
*
|
||||||
* note: calling "interactRead" from withing contract's source code was not previously possible -
|
* note: calling "interactRead" from withing contract's source code was not previously possible -
|
||||||
* this is a new feature.
|
* this is a new feature.
|
||||||
|
*
|
||||||
|
* TODO: this should not be exposed in a public API - as it is supposed
|
||||||
|
* to be used only by Handler code.
|
||||||
*/
|
*/
|
||||||
viewStateForTx<Input = unknown, View = unknown>(
|
viewStateForTx<Input = unknown, View = unknown>(
|
||||||
input: Input,
|
input: Input,
|
||||||
|
|||||||
@@ -30,13 +30,13 @@ import { NetworkInfoInterface } from 'arweave/node/network';
|
|||||||
export class HandlerBasedContract<State> implements Contract<State> {
|
export class HandlerBasedContract<State> implements Contract<State> {
|
||||||
private readonly logger = LoggerFactory.INST.create('HandlerBasedContract');
|
private readonly logger = LoggerFactory.INST.create('HandlerBasedContract');
|
||||||
|
|
||||||
private wallet?: ArWallet;
|
protected wallet?: ArWallet;
|
||||||
private evaluationOptions: EvaluationOptions = new DefaultEvaluationOptions();
|
private evaluationOptions: EvaluationOptions = new DefaultEvaluationOptions();
|
||||||
public networkInfo?: NetworkInfoInterface = null;
|
public networkInfo?: NetworkInfoInterface = null;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly contractTxId: string,
|
readonly contractTxId: string,
|
||||||
private readonly smartweave: SmartWeave,
|
protected readonly smartweave: SmartWeave,
|
||||||
// note: this will be probably used for creating contract's
|
// note: this will be probably used for creating contract's
|
||||||
// call hierarchy and generating some sort of "stack trace"
|
// call hierarchy and generating some sort of "stack trace"
|
||||||
private readonly callingContract: Contract = null
|
private readonly callingContract: Contract = null
|
||||||
|
|||||||
@@ -1,20 +1,49 @@
|
|||||||
import { Contract, InteractionResult } from '@smartweave';
|
import { Contract } from '@smartweave';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The result from the "balance" view method on the PST Contract.
|
||||||
|
*/
|
||||||
export interface BalanceResult {
|
export interface BalanceResult {
|
||||||
target: string;
|
target: string;
|
||||||
ticker: string;
|
ticker: string;
|
||||||
balance: number;
|
balance: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PstState {
|
/**
|
||||||
|
* Interface for all contracts the implement the {@link Evolve} feature
|
||||||
|
*/
|
||||||
|
export interface EvolvingContract {
|
||||||
|
saveNewSource(newContractSource: string): Promise<string | null>;
|
||||||
|
|
||||||
|
evolve(newSrcTxId: string): Promise<string | null>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface describing state for all Evolve-compatible contracts.
|
||||||
|
* Evolve is a feature that allows to change contract's source
|
||||||
|
* code, without deploying a new contract.
|
||||||
|
* See ({@link Evolve})
|
||||||
|
*/
|
||||||
|
export interface EvolveState {
|
||||||
|
settings: any[] | {} | null;
|
||||||
|
canEvolve: boolean; // whether contract is allowed to evolve. seems to default to true..
|
||||||
|
evolve: string; // the transaction id of the Arweave transaction with the updated source code. odd naming convention..
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface describing state for all PST contracts.
|
||||||
|
*/
|
||||||
|
export interface PstState extends EvolveState {
|
||||||
ticker: string;
|
ticker: string;
|
||||||
owner: string;
|
owner: string;
|
||||||
canEvolve: boolean;
|
|
||||||
balances: {
|
balances: {
|
||||||
[key: string]: number;
|
[key: string]: number;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface describing data required for making a transfer
|
||||||
|
*/
|
||||||
export interface TransferInput {
|
export interface TransferInput {
|
||||||
target: string;
|
target: string;
|
||||||
qty: number;
|
qty: number;
|
||||||
@@ -24,7 +53,7 @@ export interface TransferInput {
|
|||||||
* A type of {@link Contract} designed specifically for the interaction with
|
* A type of {@link Contract} designed specifically for the interaction with
|
||||||
* Profit Sharing Tokens.
|
* Profit Sharing Tokens.
|
||||||
*/
|
*/
|
||||||
export interface PstContract extends Contract {
|
export interface PstContract extends Contract, EvolvingContract {
|
||||||
currentBalance(target: string): Promise<BalanceResult>;
|
currentBalance(target: string): Promise<BalanceResult>;
|
||||||
|
|
||||||
currentState(): Promise<PstState>;
|
currentState(): Promise<PstState>;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { SmartWeaveTags } from '@smartweave';
|
||||||
import { BalanceResult, HandlerBasedContract, PstContract, PstState, TransferInput } from '@smartweave/contract';
|
import { BalanceResult, HandlerBasedContract, PstContract, PstState, TransferInput } from '@smartweave/contract';
|
||||||
|
|
||||||
interface BalanceInput {
|
interface BalanceInput {
|
||||||
@@ -7,7 +8,7 @@ interface BalanceInput {
|
|||||||
|
|
||||||
export class PstContractImpl extends HandlerBasedContract<PstState> implements PstContract {
|
export class PstContractImpl extends HandlerBasedContract<PstState> implements PstContract {
|
||||||
async currentBalance(target: string): Promise<BalanceResult> {
|
async currentBalance(target: string): Promise<BalanceResult> {
|
||||||
const interactionResult = await super.viewState<BalanceInput, BalanceResult>({ function: 'balance', target });
|
const interactionResult = await this.viewState<BalanceInput, BalanceResult>({ function: 'balance', target });
|
||||||
if (interactionResult.type !== 'ok') {
|
if (interactionResult.type !== 'ok') {
|
||||||
throw Error(interactionResult.errorMessage);
|
throw Error(interactionResult.errorMessage);
|
||||||
}
|
}
|
||||||
@@ -19,6 +20,27 @@ export class PstContractImpl extends HandlerBasedContract<PstState> implements P
|
|||||||
}
|
}
|
||||||
|
|
||||||
async transfer(transfer: TransferInput): Promise<string | null> {
|
async transfer(transfer: TransferInput): Promise<string | null> {
|
||||||
return await super.writeInteraction<any>({ function: 'transfer', ...transfer });
|
return await this.writeInteraction<any>({ function: 'transfer', ...transfer });
|
||||||
|
}
|
||||||
|
|
||||||
|
async evolve(newSrcTxId: string): Promise<string | null> {
|
||||||
|
return await this.writeInteraction<any>({ function: 'evolve', value: newSrcTxId });
|
||||||
|
}
|
||||||
|
|
||||||
|
async saveNewSource(newContractSource: string): Promise<string | null> {
|
||||||
|
if (!this.wallet) {
|
||||||
|
throw new Error("Wallet not connected. Use 'connect' method first.");
|
||||||
|
}
|
||||||
|
const { arweave } = this.smartweave;
|
||||||
|
|
||||||
|
const tx = await arweave.createTransaction({ data: newContractSource }, this.wallet);
|
||||||
|
tx.addTag(SmartWeaveTags.APP_NAME, 'SmartWeaveContractSource');
|
||||||
|
tx.addTag(SmartWeaveTags.APP_VERSION, '0.3.0');
|
||||||
|
tx.addTag('Content-Type', 'application/javascript');
|
||||||
|
|
||||||
|
await arweave.transactions.sign(tx, this.wallet);
|
||||||
|
await arweave.transactions.post(tx);
|
||||||
|
|
||||||
|
return tx.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export class CacheableStateEvaluator extends DefaultStateEvaluator {
|
|||||||
executionContext.contractDefinition.txId,
|
executionContext.contractDefinition.txId,
|
||||||
requestedBlockHeight
|
requestedBlockHeight
|
||||||
)) as BlockHeightCacheResult<EvalStateResult<State>>;
|
)) as BlockHeightCacheResult<EvalStateResult<State>>;
|
||||||
logger.trace('Retrieving value from cache', benchmark.elapsed());
|
this.cLogger.trace('Retrieving value from cache', benchmark.elapsed());
|
||||||
|
|
||||||
if (cachedState != null) {
|
if (cachedState != null) {
|
||||||
this.cLogger.debug(`Cached state for ${executionContext.contractDefinition.txId}`, {
|
this.cLogger.debug(`Cached state for ${executionContext.contractDefinition.txId}`, {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
DefinitionLoader,
|
DefinitionLoader,
|
||||||
|
EvolveState,
|
||||||
ExecutionContext,
|
ExecutionContext,
|
||||||
ExecutionContextModifier,
|
ExecutionContextModifier,
|
||||||
ExecutorFactory,
|
ExecutorFactory,
|
||||||
@@ -9,12 +10,6 @@ import {
|
|||||||
SmartWeaveErrorType
|
SmartWeaveErrorType
|
||||||
} from '@smartweave';
|
} from '@smartweave';
|
||||||
|
|
||||||
export interface EvolveCompatibleState {
|
|
||||||
settings: any[]; // some..erm..settings?
|
|
||||||
canEvolve: boolean; // whether contract is allowed to evolve. seems to default to true..
|
|
||||||
evolve: string; // the transaction id of the Arweave transaction with the updated source code. odd naming convention..
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
...I'm still not fully convinced to the whole "evolve" idea.
|
...I'm still not fully convinced to the whole "evolve" idea.
|
||||||
|
|
||||||
@@ -33,7 +28,7 @@ without the need of hard-coding contract's txId in the client's source code.
|
|||||||
This also makes it easier to audit given contract - as you keep all its versions in one place.
|
This also makes it easier to audit given contract - as you keep all its versions in one place.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function isEvolveCompatible(state: any): state is EvolveCompatibleState {
|
function isEvolveCompatible(state: any): state is EvolveState {
|
||||||
if (!state) {
|
if (!state) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -90,17 +85,18 @@ export class Evolve implements ExecutionContextModifier {
|
|||||||
const newContractDefinition = await this.definitionLoader.load<State>(contractTxId, evolve);
|
const newContractDefinition = await this.definitionLoader.load<State>(contractTxId, evolve);
|
||||||
const newHandler = (await this.executorFactory.create<State>(newContractDefinition)) as HandlerApi<State>;
|
const newHandler = (await this.executorFactory.create<State>(newContractDefinition)) as HandlerApi<State>;
|
||||||
|
|
||||||
const modifiedContext = {
|
//FIXME: side-effect...
|
||||||
...executionContext,
|
executionContext.contractDefinition = newContractDefinition;
|
||||||
contractDefinition: newContractDefinition,
|
executionContext.handler = newHandler;
|
||||||
handler: newHandler
|
|
||||||
};
|
|
||||||
this.logger.debug('evolved to:', {
|
this.logger.debug('evolved to:', {
|
||||||
txId: modifiedContext.contractDefinition.txId,
|
evolve: evolve,
|
||||||
srcTxId: modifiedContext.contractDefinition.srcTxId
|
newSrcTxId: executionContext.contractDefinition.srcTxId,
|
||||||
|
current: currentSrcTxId,
|
||||||
|
txId: executionContext.contractDefinition.txId,
|
||||||
});
|
});
|
||||||
|
|
||||||
return modifiedContext;
|
return executionContext;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new SmartWeaveError(SmartWeaveErrorType.CONTRACT_NOT_FOUND, {
|
throw new SmartWeaveError(SmartWeaveErrorType.CONTRACT_NOT_FOUND, {
|
||||||
message: `Contract having txId: ${contractTxId} not found`,
|
message: `Contract having txId: ${contractTxId} not found`,
|
||||||
|
|||||||
Reference in New Issue
Block a user