Skip to content

Commit

Permalink
Merge pull request #49 from firstbatchxyz/erhant/regex-check
Browse files Browse the repository at this point in the history
Null value fix
  • Loading branch information
fco-fbatch authored Aug 14, 2023
2 parents 6a6cf9c + 78d6441 commit 1823b82
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 4 deletions.
1 change: 1 addition & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const config: Config = {
verbose: true,
// Warp & Arlocal takes some time to close, so make this 5 secs
openHandlesTimeout: 5000,
forceExit: true,
};

export default config;
1 change: 1 addition & 0 deletions src/contracts/errors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ export const UnknownProtocolError = new ContractError('Unknown protocol.');
export const NotWhitelistedError = new ContractError('Not whitelisted.');
export const InvalidProofError = new ContractError('Invalid proof.');
export const ExpectedProofError = new ContractError('Expected a proof.');
export const NullValueError = new ContractError('Value cant be null, use remove instead.');
export const NotOwnerError = new ContractError('Not contract owner.');
export const InvalidFunctionError = new ContractError('Invalid function.');
8 changes: 7 additions & 1 deletion src/contracts/functions/crud.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {ContractState, GetInput, PutInput, RemoveInput, UpdateInput} from '../types';
import {KeyExistsError} from '../errors';
import {KeyExistsError, NullValueError} from '../errors';
import {assertWhitelist, safeGet, verifyAuthProof} from '../utils';

/** Gets a value at the specified key. */
Expand All @@ -22,6 +22,9 @@ export async function put<State extends ContractState<{whitelists: ['put']; circ
) {
assertWhitelist(state, caller, 'put');

if (value === null) {
throw NullValueError;
}
if ((await SmartWeave.kv.get(key)) !== null) {
throw KeyExistsError;
}
Expand Down Expand Up @@ -67,6 +70,9 @@ export async function update<State extends ContractState<{whitelists: ['update']
) {
assertWhitelist(state, caller, 'update');

if (value === null) {
throw NullValueError;
}
const dbValue = await safeGet(key);
await verifyAuthProof(state, proof, dbValue, value, key);
await SmartWeave.kv.put(key, value);
Expand Down
9 changes: 8 additions & 1 deletion src/contracts/functions/htx.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {ContractState} from '../types';
import {KeyExistsError} from '../errors';
import {KeyExistsError, NullValueError} from '../errors';
import {assertWhitelist, safeGet, verifyAuthProofImmediate} from '../utils';
import {HTXValueType, PutHTXInput, RemoveHTXInput, UpdateHTXInput} from '../types/htx';

Expand All @@ -10,9 +10,13 @@ export async function putHTX<State extends ContractState<{whitelists: ['put']; c
) {
assertWhitelist(state, caller, 'put');

if (value === null) {
throw NullValueError;
}
if ((await SmartWeave.kv.get(key)) !== null) {
throw KeyExistsError;
}

await SmartWeave.kv.put(key, value);

return {state};
Expand Down Expand Up @@ -41,6 +45,9 @@ export async function updateHTX<State extends ContractState<{whitelists: ['updat
) {
assertWhitelist(state, caller, 'update');

if (value === null) {
throw NullValueError;
}
const dbValue = await safeGet<string>(key);
const [oldHash] = dbValue.split('.');
const [newHash] = value.split('.');
Expand Down
3 changes: 1 addition & 2 deletions tests/htx.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@ describe('hash.txid value tests', () => {
});

describe('disabling proofs', () => {
const {VALUE, NEXT_VALUE} = createValues<ValueType>();
const KEY = 'some-non-bigint-friendly-key';
const {VALUE, NEXT_VALUE, KEY} = createValues<ValueType>();

beforeAll(async () => {
const {cachedValue} = await owner.readState();
Expand Down
66 changes: 66 additions & 0 deletions tests/null.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import fs from 'fs';
import {Prover} from 'hollowdb-prover';
import constants from './constants';
import {createValues, deployContract} from './utils';
import {setupWarp} from './hooks';
import {Admin} from '../src/hollowdb';

// adding `null` to type for testing purposes
// it is not allowed normally
type ValueType = {val: string} | null;

describe('null value tests with proofs', () => {
const warpHook = setupWarp();
const protocol = 'groth16';
let prover: Prover;
let owner: Admin<ValueType>;

const {KEY, KEY_PREIMAGE, VALUE, NEXT_VALUE} = createValues<ValueType>();

beforeAll(async () => {
const hook = warpHook();
const [ownerWallet] = hook.wallets;
const contractTxId = await deployContract(hook.warp, ownerWallet.jwk);

prover = new Prover(
constants.PROVERS[protocol].HOLLOWDB.WASM_PATH,
constants.PROVERS[protocol].HOLLOWDB.PROVERKEY_PATH,
protocol
);

owner = new Admin(ownerWallet.jwk, contractTxId, hook.warp);
});

it('should set verification key', async () => {
const verificationKey = JSON.parse(
fs.readFileSync(constants.PROVERS[protocol].HOLLOWDB.VERIFICATIONKEY_PATH, 'utf8')
);
await owner.updateVerificationKey('auth', verificationKey);
const {cachedValue} = await owner.readState();
expect(cachedValue.state.verificationKeys.auth).toEqual(verificationKey);
});

it('should NOT allow putting a null value', async () => {
await expect(owner.put(KEY, null)).rejects.toThrow('Contract Error [put]: Value cant be null, use remove instead.');
});

it('should allow putting without a proof', async () => {
await owner.put(KEY, VALUE);
});

it('should NOT allow updating to null with a proof', async () => {
const {proof} = await prover.prove(KEY_PREIMAGE, VALUE, null);
await expect(owner.update(KEY, null, proof)).rejects.toThrow(
'Contract Error [update]: Value cant be null, use remove instead.'
);
});

it('should allow removing with a proof', async () => {
const {proof} = await prover.prove(KEY_PREIMAGE, VALUE, null);
await owner.remove(KEY, proof);
});

it('should allow putting again to a removed key without a proof', async () => {
await owner.put(KEY, NEXT_VALUE);
});
});

0 comments on commit 1823b82

Please sign in to comment.