Skip to content

Commit a5b5560

Browse files
authored
Merge pull request #64 from Terran-One/fix/do-db-read-null
Fix `do_db_read`: wrong value when key not found
2 parents 15423ef + bdb01b1 commit a5b5560

File tree

1 file changed

+90
-60
lines changed

1 file changed

+90
-60
lines changed

src/instance.ts

Lines changed: 90 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ export class VMInstance {
2020
public bech32: BechLib;
2121
public debugMsgs: string[] = [];
2222

23-
constructor(public backend: IBackend, public readonly gasLimit?: number | undefined) {
23+
constructor(
24+
public backend: IBackend,
25+
public readonly gasLimit?: number | undefined
26+
) {
2427
this.bech32 = bech32;
2528
}
2629

@@ -60,13 +63,13 @@ export class VMInstance {
6063
}
6164

6265
public allocate(size: number): Region {
63-
let {allocate, memory} = this.exports;
66+
let { allocate, memory } = this.exports;
6467
let regPtr = allocate(size);
6568
return new Region(memory, regPtr);
6669
}
6770

6871
public deallocate(region: Region): void {
69-
let {deallocate} = this.exports;
72+
let { deallocate } = this.exports;
7073
deallocate(region.ptr);
7174
}
7275

@@ -93,41 +96,36 @@ export class VMInstance {
9396
return region;
9497
}
9598

96-
public allocate_none(): Region {
97-
const none = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0]);
98-
return this.allocate_bytes(none);
99-
}
100-
10199
public instantiate(env: Env, info: MessageInfo, msg: object): Region {
102-
let {instantiate} = this.exports;
100+
let { instantiate } = this.exports;
103101
let args = [env, info, msg].map((x) => this.allocate_json(x).ptr);
104102
let result = instantiate(...args);
105103
return this.region(result);
106104
}
107105

108106
public execute(env: Env, info: MessageInfo, msg: object): Region {
109-
let {execute} = this.exports;
107+
let { execute } = this.exports;
110108
let args = [env, info, msg].map((x) => this.allocate_json(x).ptr);
111109
let result = execute(...args);
112110
return this.region(result);
113111
}
114112

115113
public query(env: Env, msg: object): Region {
116-
let {query} = this.exports;
114+
let { query } = this.exports;
117115
let args = [env, msg].map((x) => this.allocate_json(x).ptr);
118116
let result = query(...args);
119117
return this.region(result);
120118
}
121119

122120
public migrate(env: Env, msg: object): Region {
123-
let {migrate} = this.exports;
121+
let { migrate } = this.exports;
124122
let args = [env, msg].map((x) => this.allocate_json(x).ptr);
125123
let result = migrate(...args);
126124
return this.region(result);
127125
}
128126

129127
public reply(env: Env, msg: object): Region {
130-
let {reply} = this.exports;
128+
let { reply } = this.exports;
131129
let args = [env, msg].map((x) => this.allocate_json(x).ptr);
132130
let result = reply(...args);
133131
return this.region(result);
@@ -178,9 +176,9 @@ export class VMInstance {
178176
}
179177

180178
secp256k1_verify(
181-
hash_ptr: number,
182-
signature_ptr: number,
183-
pubkey_ptr: number
179+
hash_ptr: number,
180+
signature_ptr: number,
181+
pubkey_ptr: number
184182
): number {
185183
let hash = this.region(hash_ptr);
186184
let signature = this.region(signature_ptr);
@@ -189,19 +187,21 @@ export class VMInstance {
189187
}
190188

191189
secp256k1_recover_pubkey(
192-
hash_ptr: number,
193-
signature_ptr: number,
194-
recover_param: number
190+
hash_ptr: number,
191+
signature_ptr: number,
192+
recover_param: number
195193
): bigint {
196194
let hash = this.region(hash_ptr);
197195
let signature = this.region(signature_ptr);
198-
return BigInt(this.do_secp256k1_recover_pubkey(hash, signature, recover_param).ptr);
196+
return BigInt(
197+
this.do_secp256k1_recover_pubkey(hash, signature, recover_param).ptr
198+
);
199199
}
200200

201201
ed25519_verify(
202-
message_ptr: number,
203-
signature_ptr: number,
204-
pubkey_ptr: number
202+
message_ptr: number,
203+
signature_ptr: number,
204+
pubkey_ptr: number
205205
): number {
206206
let message = this.region(message_ptr);
207207
let signature = this.region(signature_ptr);
@@ -210,9 +210,9 @@ export class VMInstance {
210210
}
211211

212212
ed25519_batch_verify(
213-
messages_ptr: number,
214-
signatures_ptr: number,
215-
public_keys_ptr: number
213+
messages_ptr: number,
214+
signatures_ptr: number,
215+
public_keys_ptr: number
216216
): number {
217217
let messages = this.region(messages_ptr);
218218
let signatures = this.region(signatures_ptr);
@@ -243,12 +243,14 @@ export class VMInstance {
243243
let value: Uint8Array | null = this.backend.storage.get(key.data);
244244

245245
if (key.str.length > MAX_LENGTH_DB_KEY) {
246-
throw new Error(`Key length ${key.str.length} exceeds maximum length ${MAX_LENGTH_DB_KEY}`);
246+
throw new Error(
247+
`Key length ${key.str.length} exceeds maximum length ${MAX_LENGTH_DB_KEY}`
248+
);
247249
}
248250

249251
if (value === null) {
250252
console.warn(`db_read: key not found: ${key.str}`);
251-
return this.allocate_none();
253+
return this.region(0);
252254
}
253255

254256
return this.allocate_bytes(value);
@@ -272,7 +274,11 @@ export class VMInstance {
272274
}
273275

274276
do_db_scan(start: Region, end: Region, order: number): Region {
275-
const iteratorId: Uint8Array = this.backend.storage.scan(start.data, end.data, order);
277+
const iteratorId: Uint8Array = this.backend.storage.scan(
278+
start.data,
279+
end.data,
280+
order
281+
);
276282

277283
let region = this.allocate(iteratorId.length);
278284
region.write(iteratorId);
@@ -284,16 +290,17 @@ export class VMInstance {
284290
const record: Record | null = this.backend.storage.next(iterator_id.data);
285291

286292
if (record === null) {
287-
return this.allocate_none();
293+
return this.allocate_bytes(Uint8Array.from([0, 0, 0, 0, 0, 0, 0, 0]));
288294
}
289295

290-
return this.allocate_bytes(new Uint8Array(
291-
[
292-
...record.key,
293-
...toByteArray(record.key.length, 4),
294-
...record.value,
295-
...toByteArray(record.value.length, 4)
296-
]));
296+
return this.allocate_bytes(
297+
new Uint8Array([
298+
...record.key,
299+
...toByteArray(record.key.length, 4),
300+
...record.value,
301+
...toByteArray(record.value.length, 4),
302+
])
303+
);
297304
}
298305

299306
do_addr_humanize(source: Region, destination: Region): Region {
@@ -333,16 +340,16 @@ export class VMInstance {
333340
}
334341

335342
const canonical = this.bech32.fromWords(
336-
this.bech32.decode(source.str).words
343+
this.bech32.decode(source.str).words
337344
);
338345

339346
if (canonical.length === 0) {
340347
throw new Error('Invalid address.');
341348
}
342349

343350
const human = this.bech32.encode(
344-
this.backend.backend_api.bech32_prefix,
345-
this.bech32.toWords(canonical)
351+
this.backend.backend_api.bech32_prefix,
352+
this.bech32.toWords(canonical)
346353
);
347354
if (human !== source.str) {
348355
throw new Error('Invalid address.');
@@ -354,9 +361,9 @@ export class VMInstance {
354361
// Returns 0 on verification success, 1 on verification failure
355362
do_secp256k1_verify(hash: Region, signature: Region, pubkey: Region): number {
356363
const isValidSignature = ecdsaVerify(
357-
signature.data,
358-
hash.data,
359-
pubkey.data
364+
signature.data,
365+
hash.data,
366+
pubkey.data
360367
);
361368

362369
if (isValidSignature) {
@@ -367,20 +374,25 @@ export class VMInstance {
367374
}
368375

369376
do_secp256k1_recover_pubkey(
370-
msgHash: Region,
371-
signature: Region,
372-
recover_param: number
377+
msgHash: Region,
378+
signature: Region,
379+
recover_param: number
373380
): Region {
374-
const pub = ecdsaRecover(signature.data, recover_param, msgHash.data, false);
381+
const pub = ecdsaRecover(
382+
signature.data,
383+
recover_param,
384+
msgHash.data,
385+
false
386+
);
375387
return this.allocate_bytes(pub);
376388
}
377389

378390
// Verifies a message against a signature with a public key, using the ed25519 EdDSA scheme.
379391
// Returns 0 on verification success, 1 on verification failure
380392
do_ed25519_verify(
381-
message: Region,
382-
signature: Region,
383-
pubkey: Region
393+
message: Region,
394+
signature: Region,
395+
pubkey: Region
384396
): number {
385397
if (message.length > MAX_LENGTH_ED25519_MESSAGE) return 1;
386398
if (signature.length > MAX_LENGTH_ED25519_SIGNATURE) return 1;
@@ -405,34 +417,50 @@ export class VMInstance {
405417
// using the ed25519 EdDSA scheme.
406418
// Returns 0 on verification success (all batches verify correctly), 1 on verification failure
407419
do_ed25519_batch_verify(
408-
messages_ptr: Region,
409-
signatures_ptr: Region,
410-
public_keys_ptr: Region
420+
messages_ptr: Region,
421+
signatures_ptr: Region,
422+
public_keys_ptr: Region
411423
): number {
412424
let messages = decodeSections(messages_ptr.data);
413425
let signatures = decodeSections(signatures_ptr.data);
414426
let publicKeys = decodeSections(public_keys_ptr.data);
415427

416-
if (messages.length === signatures.length && messages.length === publicKeys.length) {
428+
if (
429+
messages.length === signatures.length &&
430+
messages.length === publicKeys.length
431+
) {
417432
// Do nothing, we're good to go
418-
} else if (messages.length === 1 && signatures.length == publicKeys.length) {
433+
} else if (
434+
messages.length === 1 &&
435+
signatures.length == publicKeys.length
436+
) {
419437
const repeated = [];
420438
for (let i = 0; i < signatures.length; i++) {
421439
repeated.push(...messages);
422440
}
423441
messages = repeated;
424-
} else if (publicKeys.length === 1 && messages.length == signatures.length) {
442+
} else if (
443+
publicKeys.length === 1 &&
444+
messages.length == signatures.length
445+
) {
425446
const repeated = [];
426447
for (let i = 0; i < messages.length; i++) {
427448
repeated.push(...publicKeys);
428449
}
429450
publicKeys = repeated;
430451
} else {
431-
throw new Error('Lengths of messages, signatures and public keys do not match.');
452+
throw new Error(
453+
'Lengths of messages, signatures and public keys do not match.'
454+
);
432455
}
433456

434-
if (messages.length !== signatures.length || messages.length !== publicKeys.length) {
435-
throw new Error('Lengths of messages, signatures and public keys do not match.');
457+
if (
458+
messages.length !== signatures.length ||
459+
messages.length !== publicKeys.length
460+
) {
461+
throw new Error(
462+
'Lengths of messages, signatures and public keys do not match.'
463+
);
436464
}
437465

438466
for (let i = 0; i < messages.length; i++) {
@@ -476,7 +504,9 @@ export class VMInstance {
476504
}
477505
}
478506

479-
function decodeSections(data: Uint8Array | number[]): (number[] | Uint8Array)[] {
507+
function decodeSections(
508+
data: Uint8Array | number[]
509+
): (number[] | Uint8Array)[] {
480510
let result: (number[] | Uint8Array)[] = [];
481511
let remainingLen = data.length;
482512

0 commit comments

Comments
 (0)