chore: split functions

This commit is contained in:
fryorcraken.eth 2023-03-03 14:17:26 +11:00
parent 22ffcf571a
commit af5c5733a5
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4

View File

@ -18,42 +18,67 @@ export class EnrDecoder {
static fromRLP(encoded: Uint8Array): Promise<ENR> { static fromRLP(encoded: Uint8Array): Promise<ENR> {
const decoded = RLP.decode(encoded).map(hexToBytes); const decoded = RLP.decode(encoded).map(hexToBytes);
return EnrDecoder.fromValues(decoded); return fromValues(decoded);
} }
}
private static async fromValues(decoded: Uint8Array[]): Promise<ENR> {
if (!Array.isArray(decoded)) { async function fromValues(values: Uint8Array[]): Promise<ENR> {
throw new Error("Decoded ENR must be an array"); const { signature, seq, kvs } = checkValues(values);
}
if (decoded.length % 2 !== 0) { const obj: Record<ENRKey, ENRValue> = {};
throw new Error("Decoded ENR must have an even number of elements"); for (let i = 0; i < kvs.length; i += 2) {
} try {
const [signature, seq, ...kvs] = decoded; obj[bytesToUtf8(kvs[i])] = kvs[i + 1];
if (!signature || Array.isArray(signature)) { } catch (e) {
throw new Error("Decoded ENR invalid signature: must be a byte array"); log("Failed to decode ENR key to UTF-8, skipping it", kvs[i], e);
} }
if (!seq || Array.isArray(seq)) { }
throw new Error( const _seq = decodeSeq(seq);
"Decoded ENR invalid sequence number: must be a byte array"
); const enr = await ENR.create(obj, _seq, signature);
} checkSignature(seq, kvs, enr, signature);
const obj: Record<ENRKey, ENRValue> = {}; return enr;
for (let i = 0; i < kvs.length; i += 2) { }
try {
obj[bytesToUtf8(kvs[i])] = kvs[i + 1]; function decodeSeq(seq: Uint8Array): bigint {
} catch (e) { // If seq is an empty array, translate as value 0
log("Failed to decode ENR key to UTF-8, skipping it", kvs[i], e); if (!seq.length) return BigInt(0);
}
} return BigInt("0x" + bytesToHex(seq));
// If seq is an empty array, translate as value 0 }
const hexSeq = "0x" + (seq.length ? bytesToHex(seq) : "00");
function checkValues(values: Uint8Array[]): {
const enr = await ENR.create(obj, BigInt(hexSeq), signature); signature: Uint8Array;
seq: Uint8Array;
const rlpEncodedBytes = hexToBytes(RLP.encode([seq, ...kvs])); kvs: Uint8Array[];
if (!enr.verify(rlpEncodedBytes, signature)) { } {
throw new Error("Unable to verify ENR signature"); if (!Array.isArray(values)) {
} throw new Error("Decoded ENR must be an array");
return enr; }
if (values.length % 2 !== 0) {
throw new Error("Decoded ENR must have an even number of elements");
}
const [signature, seq, ...kvs] = values;
if (!signature || Array.isArray(signature)) {
throw new Error("Decoded ENR invalid signature: must be a byte array");
}
if (!seq || Array.isArray(seq)) {
throw new Error(
"Decoded ENR invalid sequence number: must be a byte array"
);
}
return { signature, seq, kvs };
}
function checkSignature(
seq: Uint8Array,
kvs: Uint8Array[],
enr: ENR,
signature: Uint8Array
): void {
const rlpEncodedBytes = hexToBytes(RLP.encode([seq, ...kvs]));
if (!enr.verify(rlpEncodedBytes, signature)) {
throw new Error("Unable to verify ENR signature");
} }
} }