Skip to content

Commit

Permalink
feat: [FEATURE] Safe Block Fetch #464
Browse files Browse the repository at this point in the history
  • Loading branch information
ppedziwiatr authored and Tadeuchi committed Oct 25, 2023
1 parent 249e370 commit 98e3df4
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 3 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "warp-contracts",
"version": "1.4.21",
"version": "1.4.22-beta.1",
"description": "An implementation of the SmartWeave smart contract protocol.",
"types": "./lib/types/index.d.ts",
"main": "./lib/cjs/index.js",
Expand Down
35 changes: 34 additions & 1 deletion src/__tests__/integration/basic/pst.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { LoggerFactory } from '../../../logging/LoggerFactory';
import { DeployPlugin } from 'warp-contracts-plugin-deploy';
import { VM2Plugin } from 'warp-contracts-plugin-vm2';
import { InteractionCompleteEvent } from '../../../core/modules/StateEvaluator';
import { NetworkCommunicationError } from '../../../utils/utils';

describe('Testing the Profit Sharing Token', () => {
let contractSrc: string;
Expand Down Expand Up @@ -117,7 +118,7 @@ describe('Testing the Profit Sharing Token', () => {
expect(resultVM.target).toEqual('uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M');
});

it('should properly dispatch en event', async () => {
it('should properly dispatch an event', async () => {
let handlerCalled = false;
const interactionResult = await pst.writeInteraction({
function: 'dispatchEvent'
Expand Down Expand Up @@ -208,4 +209,36 @@ describe('Testing the Profit Sharing Token', () => {
expect((await pst.currentBalance(walletAddress)).balance).toEqual(startBalance - 100);
});
});

describe("when loading data from Arweave", () => {
it('should allow to safe fetch from external api', async () => {
const blockData = await arweave.blocks.getCurrent();

await pst.writeInteraction({
function: 'loadBlockData',
height: blockData.height
});

await mineBlock(warp);

const result = await pst.readState();

expect((result.cachedValue.state as any).blocks['' + blockData.height]).toEqual(blockData.indep_hash);
});

// note: this has to be the last test.
it('should stop evaluation on safe fetch error', async () => {
const blockData = await arweave.blocks.getCurrent();

await pst.writeInteraction({
function: 'loadBlockData',
height: blockData.height,
throwError: true
});

await mineBlock(warp);

await expect(pst.readState()).rejects.toThrowError(NetworkCommunicationError);
});
});
});
20 changes: 19 additions & 1 deletion src/__tests__/integration/data/token-evolve.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export function handle(state, action) {
export async function handle(state, action) {
const balances = state.balances;
const canEvolve = state.canEvolve;
const input = action.input;
Expand Down Expand Up @@ -37,6 +37,24 @@ export function handle(state, action) {
return { state };
}

if (input.function === 'loadBlockData') {
const height = input.height;
const throwError = input.throwError;

const blockData = await SmartWeave.safeArweaveGet(
throwError
? `/blockkkk/height/${height}`
: `/block/height/${height}`
);

if (!state.blocks) {
state.blocks = {};
}

state.blocks["" + height] = blockData.indep_hash;
return { state };
}

if (input.function === 'balance') {
const target = input.target;
const ticker = state.ticker;
Expand Down
18 changes: 18 additions & 0 deletions src/__tests__/integration/data/token-pst.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,24 @@ export async function handle(state, action) {
return {state};
}

if (input.function === 'loadBlockData') {
const height = input.height;
const throwError = input.throwError;

const blockData = await SmartWeave.safeArweaveGet(
throwError
? `/blockkkk/height/${height}`
: `/block/height/${height}`
);

if (!state.blocks) {
state.blocks = {};
}

state.blocks["" + height] = blockData.indep_hash;
return { state };
}

if (input.function === 'dispatchEvent') {
return {
state,
Expand Down
7 changes: 7 additions & 0 deletions src/legacy/smartweave-global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { GQLNodeInterface, GQLTagInterface, VrfData } from './gqlResult';
import { CacheKey, SortKeyCache } from '../cache/SortKeyCache';
import { SortKeyCacheRangeOptions } from '../cache/SortKeyCacheRangeOptions';
import { InteractionState } from '../contract/states/InteractionState';
import { safeGet } from '../utils/utils';

/**
*
Expand Down Expand Up @@ -47,6 +48,8 @@ export class SmartWeaveGlobal {
owner: string;
};
unsafeClient: Arweave;
baseArweaveUrl: string;
safeArweaveGet: (input: RequestInfo | URL, init?: RequestInit) => Promise<unknown>;

contracts: {
readContractState: (contractId: string) => Promise<any>;
Expand Down Expand Up @@ -79,6 +82,10 @@ export class SmartWeaveGlobal {
wallets: arweave.wallets,
crypto: arweave.crypto
};
this.baseArweaveUrl = `${arweave.api.config.protocol}://${arweave.api.config.host}:${arweave.api.config.port}`;
this.safeArweaveGet = async function(query: string) {
return safeGet(`${this.baseArweaveUrl}${query}`);
};

this.evaluationOptions = evaluationOptions;

Expand Down
4 changes: 4 additions & 0 deletions src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,7 @@ export async function getJsonResponse<T>(response: Promise<Response>): Promise<T
throw new NetworkCommunicationError(`Error while parsing json response: ${JSON.stringify(e)}`);
}
}

export async function safeGet<T>(input: RequestInfo | URL, init?: RequestInit): Promise<T> {
return getJsonResponse(fetch(input, init));
}

0 comments on commit 98e3df4

Please sign in to comment.