Skip to content

Commit b2c0175

Browse files
MaxGraeys1na
authored andcommitted
Minor improvments for util & rlp (#57)
* minor improvments * fixes & format * refactor * more * cleanups * update & fixes * more refactoring * use copy instead loop for u8ArrToUintArr * simplify hash
1 parent 005b684 commit b2c0175

File tree

3 files changed

+73
-83
lines changed

3 files changed

+73
-83
lines changed

assembly/rlp.ts

+40-33
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ export function decodeAccount(buf: Uint8Array): Array<Uint8Array> {
2929
} else if (nonceLen <= 0x7f) {
3030
nonce = buf.subarray(2, 3)
3131
} else {
32-
nonce = buf.subarray(3, 3 + nonceLen - 0x80)
3332
offset = 3 + nonceLen - 0x80
33+
nonce = buf.subarray(3, offset)
3434
}
3535

3636
let balance: Uint8Array
@@ -39,12 +39,14 @@ export function decodeAccount(buf: Uint8Array): Array<Uint8Array> {
3939
balance = new Uint8Array(0)
4040
offset++
4141
} else if (balanceFirstByte <= 0x7f) {
42-
balance = buf.subarray(offset, offset + 1)
43-
offset++
42+
let end = offset + 1
43+
balance = buf.subarray(offset, end)
44+
offset = end
4445
} else {
4546
offset++
46-
balance = buf.subarray(offset, offset + balanceFirstByte - 0x80)
47-
offset = offset + balanceFirstByte - 0x80
47+
let end = offset + balanceFirstByte - 0x80
48+
balance = buf.subarray(offset, end)
49+
offset = end
4850
}
4951

5052
// stateRoot and codeHash are 32 byte hashes
@@ -194,7 +196,7 @@ export function hashBranch(children: Array<Uint8Array | null>): Uint8Array {
194196
}
195197

196198
// How many bytes do we need to encode length?
197-
let lenOfLen = dataLen > 255 ? 2 : 1
199+
let lenOfLen = 1 + i32(dataLen > 255)
198200
let totalLen = 1 + lenOfLen + dataLen
199201
let buf = new Uint8Array(totalLen)
200202
let offset = 0
@@ -265,13 +267,14 @@ export function hashBranchNode(branchNodeChildren: Array<usize>): usize {
265267
// bytes for hashes = len(0xa0 + hash) = 33*branch_num_children
266268
// bytes for empty nodes (0x80) = (17 - branch_num_children)
267269

268-
let child_indexes = Array.create<u8>(17)
269-
let child_hash_ptrs = Array.create<usize>(17)
270+
let child_indexes = new Array<u8>()
271+
let child_hash_ptrs = new Array<usize>()
270272
for (let i = 0; i < 17; i++) {
271273
// read child index
272-
if (branchNodeChildren[i] > 0) {
274+
let branchNodeChild = branchNodeChildren[i]
275+
if (branchNodeChild > 0) {
273276
child_indexes.push(i as u8)
274-
child_hash_ptrs.push(branchNodeChildren[i])
277+
child_hash_ptrs.push(branchNodeChild)
275278
}
276279
}
277280

@@ -396,10 +399,11 @@ export class Decoded {
396399
* @param base The base to parse the integer into
397400
*/
398401
function safeParseInt(v: string, base: u32): u32 {
399-
if (v.slice(0, 2) == '00') {
402+
// v.slice(0, 2) == '00'
403+
if (v.charCodeAt(0) == 0x30 && v.charCodeAt(1) == 0x30) {
400404
throw new Error('invalid RLP: extra zeros')
401405
}
402-
return I32.parseInt(v, base) as u32
406+
return <u32>I32.parseInt(v, base)
403407
}
404408

405409
/** Transform an integer into its hexadecimal value */
@@ -412,16 +416,16 @@ function intToHex(integer: u32): string {
412416
res.push(hexAlphabet[r])
413417
} while (integer)
414418
let hex = res.reverse().join('')
415-
return hex.length % 2 ? '0' + hex : hex
419+
return hex.length & 1 ? '0' + hex : hex
416420
}
417421

418422
function bytesToHex(bytes: Uint8Array): string {
419423
let len = bytes.length
420424
let res = new Uint8Array(len * 2)
421425
for (let i = 0; i < len; i++) {
422426
let hex = intToHex(bytes[i])
423-
res[i * 2 + 0] = hex.charCodeAt(0)
424-
res[i * 2 + 1] = hex.charCodeAt(1)
427+
unchecked((res[i * 2 + 0] = hex.charCodeAt(0)))
428+
unchecked((res[i * 2 + 1] = hex.charCodeAt(1)))
425429
}
426430
return String.UTF8.decodeUnsafe(res.dataStart as usize, res.byteLength)
427431
}
@@ -434,16 +438,18 @@ function hexToBytes(hex: string): Uint8Array {
434438
let byteLength = hex.length / 2
435439
let res = new Uint8Array(byteLength)
436440
for (let i = 0; i < byteLength; i++) {
437-
res[i] = I32.parseInt(hex.substring(i * 2, 2), 16) as u8
441+
res[i] = U8.parseInt(hex.substring(i * 2, 2), 16)
438442
}
439443
return res
440444
}
441445

442446
function concatUint8Array(arr1: Uint8Array, arr2: Uint8Array): Uint8Array {
443-
let len = arr1.byteLength + arr2.byteLength
444-
let res = new Uint8Array(len)
445-
memory.copy(res.dataStart as usize, arr1.dataStart as usize, arr1.byteLength)
446-
memory.copy((res.dataStart as usize) + arr1.byteLength, arr2.dataStart as usize, arr2.byteLength)
447+
let len1 = arr1.byteLength
448+
let len2 = arr2.byteLength
449+
let res = new Uint8Array(len1 + len2)
450+
let dst = res.dataStart as usize
451+
memory.copy(dst, arr1.dataStart as usize, len1)
452+
memory.copy(dst + len1, arr2.dataStart as usize, len2)
447453
return res
448454
}
449455

@@ -468,11 +474,11 @@ function concatUint8Arrays(arrays: Array<Uint8Array>): Uint8Array {
468474
**/
469475
export function encode(input: RLPData): Uint8Array {
470476
let children = input.children
471-
if (children.length) {
472-
let output = new Array<Uint8Array>()
473-
output.push(new Uint8Array(0))
477+
let len = children.length
478+
if (len) {
479+
let output = [new Uint8Array(0)]
474480
let totalLen = 0
475-
for (let i = 0, len = children.length; i < len; i++) {
481+
for (let i = 0; i < len; i++) {
476482
let e = encode(children[i])
477483
output.push(e)
478484
totalLen += output[i + 1].byteLength
@@ -482,12 +488,13 @@ export function encode(input: RLPData): Uint8Array {
482488
} else {
483489
//debug_mem((input.buffer.buffer as usize) + input.buffer.byteOffset, input.buffer.byteLength);
484490
let inputBuffer = input.buffer
485-
if (inputBuffer.length == 1 && inputBuffer[0] < 128) {
491+
len = inputBuffer.length
492+
if (len == 1 && inputBuffer[0] < 128) {
486493
return inputBuffer
487494
}
488-
let len_encoded = encodeLength(inputBuffer.length, 128)
489-
//debug_mem(len_encoded.dataStart, len_encoded.byteLength);
490-
return concatUint8Array(len_encoded, inputBuffer)
495+
let encodedLen = encodeLength(len, 128)
496+
//debug_mem(len_encoded.dataStart, encodedLen.byteLength);
497+
return concatUint8Array(encodedLen, inputBuffer)
491498
}
492499
}
493500

@@ -505,12 +512,12 @@ function encodeLength(len: u32, offset: u32): Uint8Array {
505512
let int_as_bytes = new Uint8Array(2)
506513
//let int_view = DataView.wrap(int_as_bytes.buffer, 0, 2);
507514
let int_view = new DataView(int_as_bytes.buffer, 0, 2)
508-
int_view.setUint16(0, int as u16, false)
515+
int_view.setUint16(0, int as u16)
509516
return int_as_bytes
510517
}
511518
throw new Error('longer lengths unsupported')
512-
//return hexToBytes(intToHex(len + offset));
513-
return hexToBytes(intToHex(len + offset))
519+
// return hexToBytes(intToHex(len + offset));
520+
// return hexToBytes(intToHex(len + offset))
514521
} else {
515522
/*
516523
let hexLength = intToHex(len);
@@ -529,7 +536,7 @@ function encodeLength(len: u32, offset: u32): Uint8Array {
529536
lLength = 2
530537
len_as_bytes = new Uint8Array(2)
531538
let len_view = new DataView(len_as_bytes.buffer, 0, 2)
532-
len_view.setUint16(0, len as u16, false)
539+
len_view.setUint16(0, len as u16)
533540
} else {
534541
throw new Error('longer lengths unsupported')
535542
}
@@ -545,7 +552,7 @@ function encodeLength(len: u32, offset: u32): Uint8Array {
545552
firstByte_as_bytes = new Uint8Array(2)
546553
//let int_view = DataView.wrap(int_as_bytes.buffer, 0, 2);
547554
let int_view = new DataView(firstByte_as_bytes.buffer, 0, 2)
548-
int_view.setUint16(0, firstByte as u16, false)
555+
int_view.setUint16(0, firstByte as u16)
549556
//return int_as_bytes;
550557
} else {
551558
throw new Error('longer lengths unsupported')

assembly/token.ts

+12-14
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ function verifyMultiproofAndUpdate(
337337
}
338338

339339
// Verify given keys match computed paths
340-
for (let i = 0; i < paths.length; i++) {
340+
for (let i = 0, len = paths.length; i < len; i++) {
341341
let path = nibbleArrToUintArr(paths[i])
342342
if (cmpBuf(path, keys[i]) != 0) {
343343
throw new Error('invalid key')
@@ -369,9 +369,7 @@ function insertNewLeafNewBranch(
369369
// current_node.bodyrlp
370370

371371
// pathStack could be smaller than 40
372-
let pathStack = Array.create<usize>(40)
373-
pathStack.push(prestate_root_hash_ptr)
374-
372+
let pathStack = [prestate_root_hash_ptr]
375373
for (let k_i = 0; k_i < 40; k_i++) {
376374
let branch_index_i = new_leaf_key_nibbles[k_i]
377375

@@ -386,7 +384,7 @@ function insertNewLeafNewBranch(
386384
return
387385
} else if (currentNode.type == NodeType.Branch) {
388386
if (currentNode.branchBody.dirty == null) {
389-
currentNode.branchBody.dirty = Array.create<u8>(16)
387+
currentNode.branchBody.dirty = new Array<u8>()
390388

391389
// setting the dirty flag to an empty array indicates that no children are dity but the branch node itself needs to be rehashed
392390
// explanation:
@@ -460,10 +458,10 @@ function createNewBranchWhereLeafExists(
460458
addHexPrefix(new_key_for_existing_leaf_nibbles, true),
461459
)
462460

463-
let new_node_for_existing_leaf_rlp_children = Array.create<RLPData>(2)
464-
465-
new_node_for_existing_leaf_rlp_children.push(new RLPData(null, Array.create<RLPData>(0)))
466-
new_node_for_existing_leaf_rlp_children.push(new RLPData(null, Array.create<RLPData>(0)))
461+
let new_node_for_existing_leaf_rlp_children = [
462+
new RLPData(null, new Array<RLPData>()),
463+
new RLPData(null, new Array<RLPData>()),
464+
]
467465
new_node_for_existing_leaf_rlp_children[0].buffer = new_key_for_existing_leaf
468466
new_node_for_existing_leaf_rlp_children[1].buffer = existing_leaf_value
469467
let new_node_for_existing_leaf_rlp = new RLPData(null, new_node_for_existing_leaf_rlp_children)
@@ -487,10 +485,10 @@ function createNewBranchWhereLeafExists(
487485
let branch_index_for_new_leaf = new_key_nibbles[k_i]
488486
let key_for_new_leaf = nibbleArrToUintArr(addHexPrefix(new_key_nibbles.slice(k_i + 1), true))
489487

490-
let node_for_new_leaf_rlp_children = Array.create<RLPData>(2)
491-
492-
node_for_new_leaf_rlp_children.push(new RLPData(null, Array.create<RLPData>(0)))
493-
node_for_new_leaf_rlp_children.push(new RLPData(null, Array.create<RLPData>(0)))
488+
let node_for_new_leaf_rlp_children = [
489+
new RLPData(null, new Array<RLPData>()),
490+
new RLPData(null, new Array<RLPData>()),
491+
]
494492
node_for_new_leaf_rlp_children[0].buffer = key_for_new_leaf
495493
node_for_new_leaf_rlp_children[1].buffer = new_leaf_account_rlp
496494
let node_for_new_leaf_rlp = new RLPData(null, node_for_new_leaf_rlp_children)
@@ -554,7 +552,7 @@ function rehashNode(staleHashPtr: usize): usize {
554552
throw new Error('ERROR: called rehash on a branch node that has no dirty flag')
555553
}
556554

557-
for (let i = 0; i < dirty_indexes.length; i++) {
555+
for (let i = 0, len = dirty_indexes.length; i < len; i++) {
558556
let dirty_i = dirty_indexes[i]
559557
let stale_hash_for_dirty_child_ptr = node_with_stale_hash.branchBody.children[dirty_i]
560558
let new_hash_for_dirty_child_ptr = rehashNode(stale_hash_for_dirty_child_ptr)

assembly/util.ts

+21-36
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@ export function parseU8(buf: Uint8Array): u8 {
99
export function bufEq(buf: Uint8Array, other: Uint8Array): boolean {
1010
let bufLen = buf.length
1111
if (bufLen != other.length) return false
12-
for (let i = 0; i < bufLen; i++) {
13-
if (unchecked(buf[i]) != unchecked(other[i])) return false
14-
}
15-
return true
12+
return memory.compare(buf.dataStart as usize, other.dataStart as usize, bufLen) == 0
1613
}
1714

1815
export function padBuf(buf: Uint8Array, length: usize): Uint8Array {
@@ -45,7 +42,7 @@ export function cmpBuf(buf: Uint8Array, other: Uint8Array): i32 {
4542

4643
export function stripBuf(buf: Uint8Array): Uint8Array {
4744
let start = buf.length
48-
for (let i = 0, len = buf.length; i < len; i++) {
45+
for (let i = 0, len = start; i < len; i++) {
4946
if (unchecked(buf[i]) != 0) {
5047
start = i
5148
break
@@ -56,19 +53,16 @@ export function stripBuf(buf: Uint8Array): Uint8Array {
5653

5754
@inline
5855
export function hash(buf: Uint8Array): Uint8Array {
59-
let hashBuf = new ArrayBuffer(32)
56+
let res = new Uint8Array(32)
6057
// @ts-ignore
61-
ethash_keccak256(hashBuf as usize, buf.dataStart as usize, buf.byteLength)
62-
return Uint8Array.wrap(hashBuf)
58+
ethash_keccak256(res.dataStart as usize, buf.dataStart as usize, buf.byteLength)
59+
return res
6360
}
6461

62+
@inline
6563
export function removeHexPrefix(nib_arr: Array<u8>): Array<u8> {
6664
// the hex prefix is merkle-patricia-trie encoding, not RLP
67-
if (nib_arr[0] & 1) {
68-
return nib_arr.slice(1)
69-
} else {
70-
return nib_arr.slice(2)
71-
}
65+
return nib_arr.slice(1 + i32((nib_arr[0] & 1) == 0))
7266
}
7367

7468
export function addHexPrefix(key_nib_arr: Array<u8>, terminator: bool): Array<u8> {
@@ -82,7 +76,7 @@ export function addHexPrefix(key_nib_arr: Array<u8>, terminator: bool): Array<u8
8276
}
8377

8478
if (terminator) {
85-
key_nib_arr[0] = key_nib_arr[0] + 2
79+
key_nib_arr[0] += 2
8680
}
8781

8882
return key_nib_arr
@@ -93,47 +87,38 @@ export function u8ArrToNibbleArr(u8_arr: Array<u8>): Array<u8> {
9387

9488
let nib_arr = new Array<u8>(len * 2) // length is num of hex chars for address_hash
9589
// TODO: we might not need to convert the whole thing to nibbles, just enough chars to follow the path to the proof
96-
97-
let q = 0
9890
for (let i = 0; i < len; i++) {
99-
q = i * 2
100-
nib_arr[q] = u8_arr[i] >> 4
101-
q = q + 1
102-
nib_arr[q] = u8_arr[i] & 15
91+
let byte = u8_arr[i]
92+
nib_arr[(i << 1) + 0] = byte >> 4
93+
nib_arr[(i << 1) + 1] = byte & 15
10394
}
104-
10595
return nib_arr
10696
}
10797

10898
export function uintArrToNibbleArr(uint_arr: Uint8Array): Array<u8> {
10999
let len = uint_arr.length
110100
let nib_arr = new Array<u8>(len * 2) // length is num of hex chars for address_hash
111101
// TODO: we might not need to convert the whole thing to nibbles, just enough chars to follow the path to the proof
112-
113-
let q = 0
114102
for (let i = 0; i < len; i++) {
115-
q = i << 1
116-
nib_arr[q] = uint_arr[i] >> 4
117-
q = q + 1
118-
nib_arr[q] = uint_arr[i] & 15
103+
let byte = uint_arr[i]
104+
nib_arr[(i << 1) + 0] = byte >> 4
105+
nib_arr[(i << 1) + 1] = byte & 15
119106
}
120-
121107
return nib_arr
122108
}
123109

124110
export function nibbleArrToUintArr(arr: Array<u8>): Uint8Array {
125-
let buf = new Uint8Array(arr.length / 2)
126-
for (let i = 0, len = buf.length; i < len; i++) {
127-
let q = i << 1
128-
unchecked((buf[i] = (arr[q] << 4) + arr[++q]))
111+
let len = arr.length / 2
112+
let buf = new Uint8Array(len)
113+
for (let i = 0; i < len; i++) {
114+
unchecked((buf[i] = (arr[i << 1] << 4) + arr[(i << 1) + 1]))
129115
}
130116
return buf
131117
}
132118

133119
export function u8ArrToUintArr(arr: Array<u8>): Uint8Array {
134-
let buf = new Uint8Array(arr.length)
135-
for (let i = 0, len = arr.length; i < len; i++) {
136-
unchecked((buf[i] = arr[i]))
137-
}
120+
let len = arr.length
121+
let buf = new Uint8Array(len)
122+
memory.copy(buf.dataStart as usize, arr.dataStart as usize, len)
138123
return buf
139124
}

0 commit comments

Comments
 (0)