From 88c21dcfc05f3470be77f7074e8ce5e79fd94ed7 Mon Sep 17 00:00:00 2001 From: Tadeuchi Date: Wed, 18 Oct 2023 14:25:31 +0200 Subject: [PATCH] fix: kvStorage does not return properly falsy values --- .../integration/basic/pst-kv.test.ts | 31 +++++++++++++++++++ src/__tests__/integration/data/kv-storage.js | 18 +++++++++++ src/cache/impl/LevelDbCache.ts | 2 +- src/legacy/smartweave-global.ts | 2 +- 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/__tests__/integration/basic/pst-kv.test.ts b/src/__tests__/integration/basic/pst-kv.test.ts index 54a63410..a9100ea1 100644 --- a/src/__tests__/integration/basic/pst-kv.test.ts +++ b/src/__tests__/integration/basic/pst-kv.test.ts @@ -144,4 +144,35 @@ describe('Testing the Profit Sharing Token', () => { ).toEqual(23111222); expect((await pst.getStorageValues(['foo'])).cachedValue.get('foo')).toBeNull(); }); + + it('should properly store false and falsy values in kv', async () => { + const falsyEntries = { + 'false': false, + 'emptyString': '', + 'zero': 0, + 'emptyArray': [], + 'nan': NaN, + 'null': null, + 'undefined': undefined, + } as const; + + await pst.writeInteraction({ + function: 'kvPut', + kvPut: falsyEntries + }); + await mineBlock(warp); + + const { kvGet } = + (await pst.viewState({ + function: 'kvGet', + kvGet: Object.keys(falsyEntries) })).result; + + expect(kvGet.emptyArray).toEqual([]); + expect(kvGet.emptyString).toEqual(''); + expect(kvGet.zero).toEqual(0); + expect(kvGet.false).toEqual(false); + expect(kvGet.nan).toBeNull(); + expect(kvGet.null).toBeNull(); + expect(kvGet.undefined).toBeNull(); + }); }); diff --git a/src/__tests__/integration/data/kv-storage.js b/src/__tests__/integration/data/kv-storage.js index 38962196..cb72639b 100644 --- a/src/__tests__/integration/data/kv-storage.js +++ b/src/__tests__/integration/data/kv-storage.js @@ -67,5 +67,23 @@ export async function handle(state, action) { return {result: {target, ticker, balance: result ? result : 0}}; } + if (input.function === 'kvPut') { + for (const [key, value] of Object.entries(input.kvPut)) { + await SmartWeave.kv.put(key, value); + } + + return {state}; + } + + if (input.function === 'kvGet') { + const kvGet = {}; + + for (const key of input.kvGet) { + kvGet[key] = await SmartWeave.kv.get(key); + } + + return {result: {kvGet}}; + } + throw new ContractError(`No function supplied or function not recognised: "${input.function}"`); } diff --git a/src/cache/impl/LevelDbCache.ts b/src/cache/impl/LevelDbCache.ts index 191c5998..dc847a1e 100644 --- a/src/cache/impl/LevelDbCache.ts +++ b/src/cache/impl/LevelDbCache.ts @@ -107,7 +107,7 @@ export class LevelDbCache implements SortKeyCache { const keys = await contractCache.keys({ reverse: true, lte: sortKey, limit: 1 }).all(); if (keys.length) { const subLevelValue = await this.getValueFromLevel(keys[0], contractCache); - if (subLevelValue) { + if (subLevelValue != null) { return new SortKeyCacheResult(keys[0], subLevelValue); } } diff --git a/src/legacy/smartweave-global.ts b/src/legacy/smartweave-global.ts index a9203064..725af939 100644 --- a/src/legacy/smartweave-global.ts +++ b/src/legacy/smartweave-global.ts @@ -293,7 +293,7 @@ export class KV { } const result = await this._storage.getLessOrEqual(key, this._transaction.sortKey); - return result?.cachedValue || null; + return result?.cachedValue ?? null; } async del(key: string): Promise {