fix: extract VRF to a plugin #248
This commit is contained in:
4
.github/workflows/tests.yml
vendored
4
.github/workflows/tests.yml
vendored
@@ -23,10 +23,10 @@ jobs:
|
||||
run: yarn test:integration:internal-writes
|
||||
- name: Run integration tests [wasm]
|
||||
run: yarn test:integration:wasm
|
||||
- name: Run regression tests
|
||||
run: yarn test:regression
|
||||
- name: Test example rust contracts
|
||||
run: yarn build:test:wasm
|
||||
- name: Run regression tests
|
||||
run: yarn test:regression
|
||||
- name: Trigger integration tests
|
||||
if: github.ref_name == 'main'
|
||||
run: >
|
||||
|
||||
@@ -21,6 +21,7 @@ import path from 'path';
|
||||
import { PstContract } from '../contract/definition/bindings/ts/PstContract';
|
||||
import { State } from '../contract/definition/bindings/ts/ContractState';
|
||||
import { TheAnswerExtension } from './the-answer-plugin';
|
||||
import { VRFPlugin } from 'warp-contracts-plugin-vrf';
|
||||
|
||||
jest.setTimeout(30000);
|
||||
|
||||
@@ -60,7 +61,7 @@ describe('Testing the Rust WASM Profit Sharing Token', () => {
|
||||
LoggerFactory.INST.logLevel('debug', 'WASM:Rust');
|
||||
//LoggerFactory.INST.logLevel('debug', 'WasmContractHandlerApi');
|
||||
|
||||
warp = WarpFactory.forLocal(1820).use(new DeployPlugin()).use(new TheAnswerExtension());
|
||||
warp = WarpFactory.forLocal(1820).use(new DeployPlugin()).use(new TheAnswerExtension()).use(new VRFPlugin());
|
||||
({ arweave } = warp);
|
||||
arweaveWrapper = new ArweaveWrapper(warp);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "warp-contracts",
|
||||
"version": "1.4.2",
|
||||
"version": "1.4.3-beta.0",
|
||||
"description": "An implementation of the SmartWeave smart contract protocol.",
|
||||
"types": "./lib/types/index.d.ts",
|
||||
"main": "./lib/cjs/index.js",
|
||||
@@ -78,12 +78,10 @@
|
||||
},
|
||||
"homepage": "https://github.com/warp-contracts/warp#readme",
|
||||
"dependencies": {
|
||||
"@idena/vrf-js": "^1.0.1",
|
||||
"archiver": "^5.3.0",
|
||||
"arweave": "^1.12.4",
|
||||
"async-mutex": "^0.4.0",
|
||||
"bignumber.js": "9.1.1",
|
||||
"elliptic": "^6.5.4",
|
||||
"events": "3.3.0",
|
||||
"fast-copy": "^3.0.0",
|
||||
"level": "^8.0.0",
|
||||
@@ -95,6 +93,7 @@
|
||||
"warp-wasm-metering": "1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@idena/vrf-js": "^1.0.1",
|
||||
"@types/cheerio": "^0.22.30",
|
||||
"@types/jest": "^28.1.6",
|
||||
"@types/node": "^18.0.6",
|
||||
@@ -103,6 +102,7 @@
|
||||
"arlocal": "1.1.42",
|
||||
"cheerio": "^1.0.0-rc.10",
|
||||
"colors": "^1.4.0",
|
||||
"elliptic": "^6.5.4",
|
||||
"esbuild": "0.17.5",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
@@ -119,6 +119,7 @@
|
||||
"typescript": "^4.9.5",
|
||||
"warp-contracts-plugin-deploy": "^1.0.3",
|
||||
"warp-contracts-plugin-vm2": "1.0.0",
|
||||
"warp-contracts-plugin-vrf": "^1.0.3",
|
||||
"ws": "^8.11.0"
|
||||
},
|
||||
"resolutions": {
|
||||
|
||||
@@ -17,6 +17,7 @@ import { LoggerFactory } from '../../../logging/LoggerFactory';
|
||||
import { ArweaveGatewayInteractionsLoader } from '../../../core/modules/impl/ArweaveGatewayInteractionsLoader';
|
||||
import { LexicographicalInteractionsSorter } from '../../../core/modules/impl/LexicographicalInteractionsSorter';
|
||||
import { DeployPlugin } from 'warp-contracts-plugin-deploy';
|
||||
import { VRFPlugin } from "warp-contracts-plugin-vrf";
|
||||
|
||||
const EC = new elliptic.ec('secp256k1');
|
||||
const key = EC.genKeyPair();
|
||||
@@ -65,7 +66,8 @@ describe('Testing the Profit Sharing Token', () => {
|
||||
.useArweaveGateway()
|
||||
.setInteractionsLoader(loader)
|
||||
.build()
|
||||
.use(new DeployPlugin());
|
||||
.use(new DeployPlugin())
|
||||
.use(new VRFPlugin());
|
||||
|
||||
({ jwk: wallet, address: walletAddress } = await warp.generateWallet());
|
||||
walletAddress = await arweave.wallets.jwkToAddress(wallet);
|
||||
@@ -142,7 +144,9 @@ describe('Testing the Profit Sharing Token', () => {
|
||||
});
|
||||
|
||||
it('should allow to test VRF on a standard forLocal Warp instance', async () => {
|
||||
const localWarp = WarpFactory.forLocal(1823).use(new DeployPlugin());
|
||||
const localWarp = WarpFactory.forLocal(1823)
|
||||
.use(new DeployPlugin())
|
||||
.use(new VRFPlugin());
|
||||
|
||||
const { contractTxId: vrfContractTxId } = await localWarp.deploy({
|
||||
wallet,
|
||||
@@ -174,7 +178,9 @@ describe('Testing the Profit Sharing Token', () => {
|
||||
});
|
||||
|
||||
it('should allow to test VRF on a standard forLocal Warp instance in strict mode', async () => {
|
||||
const localWarp = WarpFactory.forLocal(1823).use(new DeployPlugin());
|
||||
const localWarp = WarpFactory.forLocal(1823)
|
||||
.use(new DeployPlugin())
|
||||
.use(new VRFPlugin());
|
||||
|
||||
const { contractTxId: vrfContractTxId } = await localWarp.deploy({
|
||||
wallet,
|
||||
@@ -206,7 +212,9 @@ describe('Testing the Profit Sharing Token', () => {
|
||||
});
|
||||
|
||||
it('should allow to test VRF on a standard forLocal Warp instance with internal writes', async () => {
|
||||
const localWarp = WarpFactory.forLocal(1823).use(new DeployPlugin());
|
||||
const localWarp = WarpFactory.forLocal(1823)
|
||||
.use(new DeployPlugin())
|
||||
.use(new VRFPlugin());
|
||||
|
||||
const { contractTxId: vrfContractTxId } = await localWarp.deploy({
|
||||
wallet,
|
||||
|
||||
@@ -31,7 +31,6 @@ import {
|
||||
} from './Contract';
|
||||
import { ArTransfer, ArWallet, emptyTransfer, Tags } from './deploy/CreateContract';
|
||||
import { InnerWritesEvaluator } from './InnerWritesEvaluator';
|
||||
import { generateMockVrf } from '../utils/vrf';
|
||||
import { CustomSignature, Signature } from './Signature';
|
||||
import { EvaluationOptionsEvaluator } from './EvaluationOptionsEvaluator';
|
||||
import { WarpFetchWrapper } from '../core/WarpFetchWrapper';
|
||||
@@ -40,6 +39,7 @@ import { TransactionStatusResponse } from '../utils/types/arweave-types';
|
||||
import { InteractionState } from './states/InteractionState';
|
||||
import { ContractInteractionState } from './states/ContractInteractionState';
|
||||
import { Crypto } from 'warp-isomorphic';
|
||||
import { VrfPluginFunctions } from '../core/WarpPlugin';
|
||||
|
||||
/**
|
||||
* An implementation of {@link Contract} that is backwards compatible with current style
|
||||
@@ -688,7 +688,12 @@ export class HandlerBasedContract<State> implements Contract<State> {
|
||||
dummyTx.sortKey = await this._sorter.createSortKey(dummyTx.block.id, dummyTx.id, dummyTx.block.height, true);
|
||||
dummyTx.strict = strict;
|
||||
if (vrf) {
|
||||
dummyTx.vrf = generateMockVrf(dummyTx.sortKey, arweave);
|
||||
const vrfPlugin = this.warp.maybeLoadPlugin<void, VrfPluginFunctions>('vrf');
|
||||
if (vrfPlugin) {
|
||||
dummyTx.vrf = vrfPlugin.process().generateMockVrf(dummyTx.sortKey);
|
||||
} else {
|
||||
this.logger.warn('Cannot generate mock vrf for interaction - no "warp-contracts-plugin-vrf" attached!');
|
||||
}
|
||||
}
|
||||
|
||||
const handleResult = await this.evalInteraction<Input, View>(
|
||||
|
||||
@@ -174,6 +174,14 @@ export class Warp {
|
||||
return this.plugins.get(type) as WarpPlugin<P, Q>;
|
||||
}
|
||||
|
||||
maybeLoadPlugin<P, Q>(type: WarpPluginType): WarpPlugin<P, Q> | null {
|
||||
if (!this.hasPlugin(type)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.plugins.get(type) as WarpPlugin<P, Q>;
|
||||
}
|
||||
|
||||
// Close cache connection
|
||||
async close(): Promise<void> {
|
||||
return Promise.all([
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import Arweave from 'arweave';
|
||||
import { VrfData } from '../legacy/gqlResult';
|
||||
|
||||
export const knownWarpPluginsPartial = [`^smartweave-extension-`] as const;
|
||||
export const knownWarpPlugins = [
|
||||
'evm-signature-verification',
|
||||
@@ -7,7 +10,8 @@ export const knownWarpPlugins = [
|
||||
'fetch-options',
|
||||
'deploy',
|
||||
'contract-blacklist',
|
||||
'vm2'
|
||||
'vm2',
|
||||
'vrf'
|
||||
] as const;
|
||||
type WarpPluginPartialType = `smartweave-extension-${string}`;
|
||||
export type WarpKnownPluginType = (typeof knownWarpPlugins)[number];
|
||||
@@ -18,3 +22,8 @@ export interface WarpPlugin<T, R> {
|
||||
|
||||
process(input: T): R;
|
||||
}
|
||||
|
||||
export type VrfPluginFunctions = {
|
||||
generateMockVrf(sortKey: string): VrfData;
|
||||
verify(vrf: VrfData, sortKey: string): boolean;
|
||||
};
|
||||
|
||||
@@ -9,15 +9,16 @@ import { InteractionsSorter } from '../InteractionsSorter';
|
||||
import { EvaluationOptions } from '../StateEvaluator';
|
||||
import { LexicographicalInteractionsSorter } from './LexicographicalInteractionsSorter';
|
||||
import { Warp, WarpEnvironment } from '../../Warp';
|
||||
import { generateMockVrf } from '../../../utils/vrf';
|
||||
import { Tag } from 'utils/types/arweave-types';
|
||||
import { ArweaveGQLTxsFetcher } from './ArweaveGQLTxsFetcher';
|
||||
import { WarpTags, WARP_TAGS } from '../../KnownTags';
|
||||
import { safeParseInt } from '../../../utils/utils';
|
||||
import { VrfPluginFunctions, WarpPlugin } from '../../WarpPlugin';
|
||||
import { TagsParser } from './TagsParser';
|
||||
|
||||
const MAX_REQUEST = 100;
|
||||
// SortKey.blockHeight is blockheight
|
||||
// at which interaction was send to bundler
|
||||
// SortKey.blockHeight is block height
|
||||
// at which interaction was sent to bundler
|
||||
// it can be actually finalized in later block
|
||||
// we assume that this maximal "delay"
|
||||
const EMPIRIC_BUNDLR_FINALITY_TIME = 100;
|
||||
@@ -44,7 +45,9 @@ export class ArweaveGatewayBundledInteractionLoader implements InteractionsLoade
|
||||
|
||||
private arweaveFetcher: ArweaveGQLTxsFetcher;
|
||||
private arweaveWrapper: ArweaveWrapper;
|
||||
private _warp: Warp;
|
||||
private readonly sorter: InteractionsSorter;
|
||||
private readonly tagsParser = new TagsParser();
|
||||
|
||||
constructor(protected readonly arweave: Arweave, private readonly environment: WarpEnvironment) {
|
||||
this.sorter = new LexicographicalInteractionsSorter(arweave);
|
||||
@@ -108,12 +111,13 @@ export class ArweaveGatewayBundledInteractionLoader implements InteractionsLoade
|
||||
|
||||
const sortedInteractions = await this.sorter.sort(interactions);
|
||||
const isLocalOrTestnetEnv = this.environment === 'local' || this.environment === 'testnet';
|
||||
const vrfPlugin = this._warp.maybeLoadPlugin<void, VrfPluginFunctions>('vrf');
|
||||
|
||||
return sortedInteractions
|
||||
.filter((interaction) => this.isNewerThenSortKeyBlockHeight(interaction))
|
||||
.filter((interaction) => this.isSortKeyInBounds(fromSortKey, toSortKey, interaction))
|
||||
.map((interaction) => this.attachSequencerDataToInteraction(interaction))
|
||||
.map((interaction) => this.maybeAddMockVrf(isLocalOrTestnetEnv, interaction))
|
||||
.map((interaction) => this.maybeAddMockVrf(isLocalOrTestnetEnv, interaction, vrfPlugin))
|
||||
.map((interaction, index, allInteractions) => this.verifySortKeyIntegrity(interaction, index, allInteractions))
|
||||
.map(({ node: interaction }) => interaction);
|
||||
}
|
||||
@@ -218,14 +222,18 @@ export class ArweaveGatewayBundledInteractionLoader implements InteractionsLoade
|
||||
return interactions;
|
||||
}
|
||||
|
||||
private maybeAddMockVrf(isLocalOrTestnetEnv: boolean, interaction: GQLEdgeInterface): GQLEdgeInterface {
|
||||
private maybeAddMockVrf(
|
||||
isLocalOrTestnetEnv: boolean,
|
||||
interaction: GQLEdgeInterface,
|
||||
vrfPlugin?: WarpPlugin<void, VrfPluginFunctions>
|
||||
): GQLEdgeInterface {
|
||||
if (isLocalOrTestnetEnv) {
|
||||
if (
|
||||
interaction.node.tags.some((t) => {
|
||||
return t.name == WARP_TAGS.REQUEST_VRF && t.value === 'true';
|
||||
})
|
||||
) {
|
||||
interaction.node.vrf = generateMockVrf(interaction.node.sortKey, this.arweave);
|
||||
if (this.tagsParser.hasVrfTag(interaction.node)) {
|
||||
if (vrfPlugin) {
|
||||
interaction.node.vrf = vrfPlugin.process().generateMockVrf(interaction.node.sortKey);
|
||||
} else {
|
||||
this.logger.warn('Cannot generate mock vrf for interaction - no "warp-contracts-plugin-vrf" attached!');
|
||||
}
|
||||
}
|
||||
}
|
||||
return interaction;
|
||||
@@ -238,11 +246,7 @@ export class ArweaveGatewayBundledInteractionLoader implements InteractionsLoade
|
||||
const sendToBundlerBlockHeight = Number.parseInt(blockHeightSortKey);
|
||||
const finalizedBlockHeight = Number(interaction.node.block.height);
|
||||
const blockHeightDiff = finalizedBlockHeight - sendToBundlerBlockHeight;
|
||||
if (blockHeightDiff < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return blockHeightDiff >= 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -263,5 +267,6 @@ export class ArweaveGatewayBundledInteractionLoader implements InteractionsLoade
|
||||
set warp(warp: Warp) {
|
||||
this.arweaveWrapper = new ArweaveWrapper(warp);
|
||||
this.arweaveFetcher = new ArweaveGQLTxsFetcher(warp);
|
||||
this._warp = warp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,9 @@ import { InteractionsSorter } from '../InteractionsSorter';
|
||||
import { EvaluationOptions } from '../StateEvaluator';
|
||||
import { LexicographicalInteractionsSorter } from './LexicographicalInteractionsSorter';
|
||||
import { Warp, WarpEnvironment } from '../../Warp';
|
||||
import { generateMockVrf } from '../../../utils/vrf';
|
||||
import { ArweaveGQLTxsFetcher, ArweaveTransactionQuery } from './ArweaveGQLTxsFetcher';
|
||||
import { VrfPluginFunctions } from '../../WarpPlugin';
|
||||
import { TagsParser } from './TagsParser';
|
||||
|
||||
const MAX_REQUEST = 100;
|
||||
|
||||
@@ -22,6 +23,8 @@ export class ArweaveGatewayInteractionsLoader implements InteractionsLoader {
|
||||
|
||||
private readonly sorter: InteractionsSorter;
|
||||
private arweaveTransactionQuery: ArweaveGQLTxsFetcher;
|
||||
private _warp: Warp;
|
||||
private readonly tagsParser = new TagsParser();
|
||||
|
||||
constructor(protected readonly arweave: Arweave, private readonly environment: WarpEnvironment) {
|
||||
this.sorter = new LexicographicalInteractionsSorter(arweave);
|
||||
@@ -76,9 +79,9 @@ export class ArweaveGatewayInteractionsLoader implements InteractionsLoader {
|
||||
},
|
||||
first: MAX_REQUEST
|
||||
};
|
||||
const innerWritesInteractions = await (
|
||||
await this.arweaveTransactionQuery.transactions(innerWritesVariables)
|
||||
).filter(bundledTxsFilter);
|
||||
const innerWritesInteractions = (await this.arweaveTransactionQuery.transactions(innerWritesVariables)).filter(
|
||||
bundledTxsFilter
|
||||
);
|
||||
|
||||
this.logger.debug('Inner writes interactions length:', innerWritesInteractions.length);
|
||||
interactions = interactions.concat(innerWritesInteractions);
|
||||
@@ -116,15 +119,17 @@ export class ArweaveGatewayInteractionsLoader implements InteractionsLoader {
|
||||
});
|
||||
|
||||
const isLocalOrTestnetEnv = this.environment === 'local' || this.environment === 'testnet';
|
||||
const vrfPlugin = this._warp.maybeLoadPlugin<void, VrfPluginFunctions>('vrf');
|
||||
|
||||
return sortedInteractions.map((i) => {
|
||||
const interaction = i.node;
|
||||
if (isLocalOrTestnetEnv) {
|
||||
if (
|
||||
interaction.tags.some((t) => {
|
||||
return t.name == WARP_TAGS.REQUEST_VRF && t.value === 'true';
|
||||
})
|
||||
) {
|
||||
interaction.vrf = generateMockVrf(interaction.sortKey, this.arweave);
|
||||
if (this.tagsParser.hasVrfTag(interaction)) {
|
||||
if (vrfPlugin) {
|
||||
interaction.vrf = vrfPlugin.process().generateMockVrf(interaction.sortKey);
|
||||
} else {
|
||||
this.logger.warn('Cannot generate mock vrf for interaction - no "warp-contracts-plugin-vrf" attached!');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,5 +147,6 @@ export class ArweaveGatewayInteractionsLoader implements InteractionsLoader {
|
||||
|
||||
set warp(warp: Warp) {
|
||||
this.arweaveTransactionQuery = new ArweaveGQLTxsFetcher(warp);
|
||||
this._warp = warp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
import Arweave from 'arweave';
|
||||
|
||||
import { ProofHoHash } from '@idena/vrf-js';
|
||||
import elliptic from 'elliptic';
|
||||
import { SortKeyCache, SortKeyCacheResult } from '../../../cache/SortKeyCache';
|
||||
import { InteractionCall } from '../../ContractCallRecord';
|
||||
import { ExecutionContext } from '../../../core/ExecutionContext';
|
||||
import { ExecutionContextModifier } from '../../../core/ExecutionContextModifier';
|
||||
import { GQLNodeInterface, GQLTagInterface, VrfData } from '../../../legacy/gqlResult';
|
||||
import { GQLNodeInterface, GQLTagInterface } from '../../../legacy/gqlResult';
|
||||
import { Benchmark } from '../../../logging/Benchmark';
|
||||
import { LoggerFactory } from '../../../logging/LoggerFactory';
|
||||
import { indent } from '../../../utils/utils';
|
||||
import { EvalStateResult, StateEvaluator } from '../StateEvaluator';
|
||||
import { ContractInteraction, HandlerApi, InteractionResult } from './HandlerExecutorFactory';
|
||||
import { TagsParser } from './TagsParser';
|
||||
import { VrfPluginFunctions } from '../../WarpPlugin';
|
||||
|
||||
const EC = new elliptic.ec('secp256k1');
|
||||
type EvaluationProgressInput = {
|
||||
contractTxId: string;
|
||||
currentInteraction: number;
|
||||
allInteractions: number;
|
||||
lastInteractionProcessingTime: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class contains the base functionality of evaluating the contracts state - according
|
||||
@@ -71,21 +75,11 @@ export abstract class DefaultStateEvaluator implements StateEvaluator {
|
||||
|
||||
const missingInteractionsLength = missingInteractions.length;
|
||||
|
||||
const evmSignatureVerificationPlugin = warp.hasPlugin('evm-signature-verification')
|
||||
? warp.loadPlugin<GQLNodeInterface, Promise<boolean>>('evm-signature-verification')
|
||||
: null;
|
||||
|
||||
const progressPlugin = warp.hasPlugin('evaluation-progress')
|
||||
? warp.loadPlugin<
|
||||
{
|
||||
contractTxId: string;
|
||||
currentInteraction: number;
|
||||
allInteractions: number;
|
||||
lastInteractionProcessingTime: string;
|
||||
},
|
||||
void
|
||||
>('evaluation-progress')
|
||||
: null;
|
||||
const evmSignatureVerificationPlugin = warp.maybeLoadPlugin<GQLNodeInterface, Promise<boolean>>(
|
||||
'evm-signature-verification'
|
||||
);
|
||||
const progressPlugin = warp.maybeLoadPlugin<EvaluationProgressInput, void>('evaluation-progress');
|
||||
const vrfPlugin = warp.maybeLoadPlugin<void, VrfPluginFunctions>('vrf');
|
||||
|
||||
let shouldBreakAfterEvolve = false;
|
||||
|
||||
@@ -103,8 +97,12 @@ export abstract class DefaultStateEvaluator implements StateEvaluator {
|
||||
currentSortKey = missingInteraction.sortKey;
|
||||
|
||||
if (missingInteraction.vrf) {
|
||||
if (!this.verifyVrf(missingInteraction.vrf, missingInteraction.sortKey, this.arweave)) {
|
||||
throw new Error('Vrf verification failed.');
|
||||
if (!vrfPlugin) {
|
||||
this.logger.warn('Cannot verify vrf for interaction - no "warp-contracts-plugin-vrf" attached!');
|
||||
} else {
|
||||
if (!vrfPlugin.process().verify(missingInteraction.vrf, missingInteraction.sortKey)) {
|
||||
throw new Error('Vrf verification failed.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,25 +313,6 @@ export abstract class DefaultStateEvaluator implements StateEvaluator {
|
||||
return new SortKeyCacheResult(currentSortKey, evalStateResult);
|
||||
}
|
||||
|
||||
private verifyVrf(vrf: VrfData, sortKey: string, arweave: Arweave): boolean {
|
||||
const keys = EC.keyFromPublic(vrf.pubkey, 'hex');
|
||||
|
||||
let hash;
|
||||
try {
|
||||
// ProofHoHash throws its own 'invalid vrf' exception
|
||||
hash = ProofHoHash(
|
||||
keys.getPublic(),
|
||||
arweave.utils.stringToBuffer(sortKey),
|
||||
arweave.utils.b64UrlToBuffer(vrf.proof)
|
||||
);
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (e: any) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return arweave.utils.bufferTob64Url(hash) == vrf.index;
|
||||
}
|
||||
|
||||
private logResult<State>(
|
||||
result: InteractionResult<State, unknown>,
|
||||
currentTx: GQLNodeInterface,
|
||||
|
||||
@@ -112,4 +112,10 @@ export class TagsParser {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
hasVrfTag(interaction: GQLNodeInterface) {
|
||||
return interaction.tags.some((t) => {
|
||||
return t.name == WARP_TAGS.REQUEST_VRF && t.value === 'true';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import elliptic from 'elliptic';
|
||||
import Arweave from 'arweave';
|
||||
import { Evaluate } from '@idena/vrf-js';
|
||||
import { bufToBn } from './utils';
|
||||
import { VrfData } from '../legacy/gqlResult';
|
||||
|
||||
const EC = new elliptic.ec('secp256k1');
|
||||
const key = EC.genKeyPair();
|
||||
const pubKeyS = key.getPublic(true, 'hex');
|
||||
|
||||
export function generateMockVrf(sortKey: string, arweave: Arweave): VrfData {
|
||||
const data = arweave.utils.stringToBuffer(sortKey);
|
||||
const [index, proof] = Evaluate(key.getPrivate().toArray(), data);
|
||||
return {
|
||||
index: arweave.utils.bufferTob64Url(index),
|
||||
proof: arweave.utils.bufferTob64Url(proof),
|
||||
bigint: bufToBn(index).toString(),
|
||||
pubkey: pubKeyS
|
||||
};
|
||||
}
|
||||
20
yarn.lock
20
yarn.lock
@@ -2365,7 +2365,17 @@ arweave-stream-tx@^1.1.0:
|
||||
dependencies:
|
||||
exponential-backoff "^3.1.0"
|
||||
|
||||
arweave@^1.10.13, arweave@^1.10.23, arweave@^1.10.5, arweave@^1.11.4, arweave@^1.12.4:
|
||||
arweave@1.13.7:
|
||||
version "1.13.7"
|
||||
resolved "https://registry.yarnpkg.com/arweave/-/arweave-1.13.7.tgz#cda8534c833baec372a7052c61f53b4e39a886d7"
|
||||
integrity sha512-Hv+x2bSI6UyBHpuVbUDMMpMje1ETfpJWj52kKfz44O0IqDRi/LukOkkDUptup1p6OT6KP1/DdpnUnsNHoskFeA==
|
||||
dependencies:
|
||||
arconnect "^0.4.2"
|
||||
asn1.js "^5.4.1"
|
||||
base64-js "^1.5.1"
|
||||
bignumber.js "^9.0.2"
|
||||
|
||||
arweave@^1.10.13, arweave@^1.10.23, arweave@^1.10.5, arweave@^1.11.4:
|
||||
version "1.13.0"
|
||||
resolved "https://registry.yarnpkg.com/arweave/-/arweave-1.13.0.tgz#046d1b74efe5b157ad85279473f3729e8c7a47a9"
|
||||
integrity sha512-pir1s0Lg7MzAxmFsPqht1SGOq8Hoj1fhf44/8PVjBd6T8l6JRrFN23UvKp7N+MXBYM5SqrLYB8KrgvxAaczGFg==
|
||||
@@ -7479,6 +7489,14 @@ warp-contracts-plugin-vm2@1.0.0:
|
||||
bignumber.js "^9.1.1"
|
||||
vm2 "^3.9.16"
|
||||
|
||||
warp-contracts-plugin-vrf@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/warp-contracts-plugin-vrf/-/warp-contracts-plugin-vrf-1.0.3.tgz#84077e00b02778fe181c50ed4c2bf987d72c6ffe"
|
||||
integrity sha512-QIrlN/HQ4FfaqiPl38auHtJYnvC15ID3GWzsEIukzHHdcKgskuzskc0q0fCCI63q74so++9EKbQ+0k4s1+XXtw==
|
||||
dependencies:
|
||||
"@idena/vrf-js" "^1.0.1"
|
||||
elliptic "^6.5.4"
|
||||
|
||||
warp-isomorphic@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/warp-isomorphic/-/warp-isomorphic-1.0.0.tgz#dccccfc046bc6ac77919f8be1024ced1385c70ea"
|
||||
|
||||
Reference in New Issue
Block a user