@lodestar/beacon-node
Version:
A Typescript implementation of the beacon chain
112 lines • 4.08 kB
JavaScript
import { bigIntToBytes, bytesToBigInt, fromHex, toHex } from "@lodestar/utils";
import { ErrorParseJson } from "./jsonRpcHttpClient.js";
export const rootHexRegex = /^0x[a-fA-F0-9]{64}$/;
export function numberToHex(n) {
return "0x" + n.toString(16);
}
export function isJsonRpcTruncatedError(error) {
return (
// Truncated responses usually get as 200 but since it's truncated the JSON will be invalid
error instanceof ErrorParseJson ||
// Otherwise guess Infura error message of too many events
(error instanceof Error && error.message.includes("query returned more than 10000 results")) ||
// Nethermind enforces limits on JSON RPC batch calls
(error instanceof Error && error.message.toLowerCase().includes("batch size limit exceeded")));
}
export function bytesToHex(bytes) {
// Handle special case in Ethereum hex formating where hex values may include a single letter
// 0x0, 0x1 are valid values
if (bytes.length === 1 && bytes[0] <= 0xf) {
return "0x" + bytes[0].toString(16);
}
return toHex(bytes);
}
/**
* QUANTITY as defined in ethereum execution layer JSON RPC https://eth.wiki/json-rpc/API
*
* When encoding QUANTITIES (integers, numbers): encode as hex, prefix with “0x”, the most compact representation (slight exception: zero should be represented as “0x0”). Examples:
* - 0x41 (65 in decimal)
* - 0x400 (1024 in decimal)
* - WRONG: 0x (should always have at least one digit - zero is “0x0”)
* - WRONG: 0x0400 (no leading zeroes allowed)
* - WRONG: ff (must be prefixed 0x)
*/
export function numToQuantity(num) {
return "0x" + num.toString(16);
}
/**
* QUANTITY as defined in ethereum execution layer JSON RPC https://eth.wiki/json-rpc/API
*/
export function quantityToNum(hex, id = "") {
const num = parseInt(hex, 16);
if (Number.isNaN(num) || num < 0)
throw Error(`Invalid hex decimal ${id} '${hex}'`);
return num;
}
/**
* QUANTITY as defined in ethereum execution layer JSON RPC https://eth.wiki/json-rpc/API.
* Typesafe fn to convert hex string to bigint. The BigInt constructor param is any
*/
export function quantityToBigint(hex, id = "") {
try {
return BigInt(hex);
}
catch (e) {
throw Error(`Invalid hex bigint ${id} '${hex}': ${e.message}`);
}
}
/**
* QUANTITY as defined in ethereum execution layer JSON RPC https://eth.wiki/json-rpc/API.
*/
export function quantityToBytes(hex) {
const bn = quantityToBigint(hex);
return bigIntToBytes(bn, 32, "le");
}
/**
* QUANTITY as defined in ethereum execution layer JSON RPC https://eth.wiki/json-rpc/API.
* Compress a 32 ByteVector into a QUANTITY
*/
export function bytesToQuantity(bytes) {
const bn = bytesToBigInt(bytes, "le");
return numToQuantity(bn);
}
/**
* DATA as defined in ethereum execution layer JSON RPC https://eth.wiki/json-rpc/API
*
* When encoding UNFORMATTED DATA (byte arrays, account addresses, hashes, bytecode arrays): encode as hex, prefix with
* “0x”, two hex digits per byte. Examples:
*
* - 0x41 (size 1, “A”)
* - 0x004200 (size 3, “\0B\0”)
* - 0x (size 0, “”)
* - WRONG: 0xf0f0f (must be even number of digits)
* - WRONG: 004200 (must be prefixed 0x)
*/
export function bytesToData(bytes) {
return toHex(bytes);
}
/**
* DATA as defined in ethereum execution layer JSON RPC https://eth.wiki/json-rpc/API
*/
export function dataToBytes(hex, fixedLength) {
try {
const bytes = fromHex(hex);
if (fixedLength != null && bytes.length !== fixedLength) {
throw Error(`Wrong data length ${bytes.length} expected ${fixedLength}`);
}
return bytes;
}
catch (e) {
e.message = `Invalid hex string: ${e.message}`;
throw e;
}
}
/**
* DATA as defined in ethereum execution layer JSON RPC https://eth.wiki/json-rpc/API
*/
export function dataToRootHex(hex, id = "") {
if (!rootHexRegex.test(hex))
throw Error(`Invalid hex root ${id} '${hex}'`);
return hex;
}
//# sourceMappingURL=utils.js.map