123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- "use strict";
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- var desc = Object.getOwnPropertyDescriptor(m, k);
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
- desc = { enumerable: true, get: function() { return m[k]; } };
- }
- Object.defineProperty(o, k2, desc);
- }) : (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- o[k2] = m[k];
- }));
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
- Object.defineProperty(o, "default", { enumerable: true, value: v });
- }) : function(o, v) {
- o["default"] = v;
- });
- var __importStar = (this && this.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
- __setModuleDefault(result, mod);
- return result;
- };
- var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
- };
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.hashStateTree = exports.hashTxTree = exports.hashLedgerHeader = exports.hashSignedTx = void 0;
- const bignumber_js_1 = __importDefault(require("bignumber.js"));
- const ripple_binary_codec_1 = require("ripple-binary-codec");
- const errors_1 = require("../../errors");
- const HashPrefix_1 = __importDefault(require("./HashPrefix"));
- const sha512Half_1 = __importDefault(require("./sha512Half"));
- const SHAMap_1 = __importStar(require("./SHAMap"));
- const HEX = 16;
- function intToHex(integer, byteLength) {
- const foo = Number(integer)
- .toString(HEX)
- .padStart(byteLength * 2, '0');
- return foo;
- }
- function bytesToHex(bytes) {
- return Buffer.from(bytes).toString('hex');
- }
- function bigintToHex(integerString, byteLength) {
- const hex = new bignumber_js_1.default(integerString).toString(HEX);
- return hex.padStart(byteLength * 2, '0');
- }
- function addLengthPrefix(hex) {
- const length = hex.length / 2;
- if (length <= 192) {
- return bytesToHex([length]) + hex;
- }
- if (length <= 12480) {
- const prefix = length - 193;
- return bytesToHex([193 + (prefix >>> 8), prefix & 0xff]) + hex;
- }
- if (length <= 918744) {
- const prefix = length - 12481;
- return (bytesToHex([
- 241 + (prefix >>> 16),
- (prefix >>> 8) & 0xff,
- prefix & 0xff,
- ]) + hex);
- }
- throw new errors_1.XrplError('Variable integer overflow.');
- }
- function hashSignedTx(tx) {
- let txBlob;
- let txObject;
- if (typeof tx === 'string') {
- txBlob = tx;
- txObject = (0, ripple_binary_codec_1.decode)(tx);
- }
- else {
- txBlob = (0, ripple_binary_codec_1.encode)(tx);
- txObject = tx;
- }
- if (txObject.TxnSignature === undefined && txObject.Signers === undefined) {
- throw new errors_1.ValidationError('The transaction must be signed to hash it.');
- }
- const prefix = HashPrefix_1.default.TRANSACTION_ID.toString(16).toUpperCase();
- return (0, sha512Half_1.default)(prefix.concat(txBlob));
- }
- exports.hashSignedTx = hashSignedTx;
- function hashLedgerHeader(ledgerHeader) {
- const prefix = HashPrefix_1.default.LEDGER.toString(HEX).toUpperCase();
- const ledger = prefix +
- intToHex(Number(ledgerHeader.ledger_index), 4) +
- bigintToHex(ledgerHeader.total_coins, 8) +
- ledgerHeader.parent_hash +
- ledgerHeader.transaction_hash +
- ledgerHeader.account_hash +
- intToHex(ledgerHeader.parent_close_time, 4) +
- intToHex(ledgerHeader.close_time, 4) +
- intToHex(ledgerHeader.close_time_resolution, 1) +
- intToHex(ledgerHeader.close_flags, 1);
- return (0, sha512Half_1.default)(ledger);
- }
- exports.hashLedgerHeader = hashLedgerHeader;
- function hashTxTree(transactions) {
- var _a;
- const shamap = new SHAMap_1.default();
- for (const txJSON of transactions) {
- const txBlobHex = (0, ripple_binary_codec_1.encode)(txJSON);
- const metaHex = (0, ripple_binary_codec_1.encode)((_a = txJSON.metaData) !== null && _a !== void 0 ? _a : {});
- const txHash = hashSignedTx(txBlobHex);
- const data = addLengthPrefix(txBlobHex) + addLengthPrefix(metaHex);
- shamap.addItem(txHash, data, SHAMap_1.NodeType.TRANSACTION_METADATA);
- }
- return shamap.hash;
- }
- exports.hashTxTree = hashTxTree;
- function hashStateTree(entries) {
- const shamap = new SHAMap_1.default();
- entries.forEach((ledgerEntry) => {
- const data = (0, ripple_binary_codec_1.encode)(ledgerEntry);
- shamap.addItem(ledgerEntry.index, data, SHAMap_1.NodeType.ACCOUNT_STATE);
- });
- return shamap.hash;
- }
- exports.hashStateTree = hashStateTree;
- function computeTransactionHash(ledger, options) {
- const { transaction_hash } = ledger;
- if (!options.computeTreeHashes) {
- return transaction_hash;
- }
- if (ledger.transactions == null) {
- throw new errors_1.ValidationError('transactions is missing from the ledger');
- }
- const transactionHash = hashTxTree(ledger.transactions);
- if (transaction_hash !== transactionHash) {
- throw new errors_1.ValidationError('transactionHash in header' +
- ' does not match computed hash of transactions', {
- transactionHashInHeader: transaction_hash,
- computedHashOfTransactions: transactionHash,
- });
- }
- return transactionHash;
- }
- function computeStateHash(ledger, options) {
- const { account_hash } = ledger;
- if (!options.computeTreeHashes) {
- return account_hash;
- }
- if (ledger.accountState == null) {
- throw new errors_1.ValidationError('accountState is missing from the ledger');
- }
- const stateHash = hashStateTree(ledger.accountState);
- if (account_hash !== stateHash) {
- throw new errors_1.ValidationError('stateHash in header does not match computed hash of state');
- }
- return stateHash;
- }
- function hashLedger(ledger, options = {}) {
- const subhashes = {
- transaction_hash: computeTransactionHash(ledger, options),
- account_hash: computeStateHash(ledger, options),
- };
- return hashLedgerHeader(Object.assign(Object.assign({}, ledger), subhashes));
- }
- exports.default = hashLedger;
- //# sourceMappingURL=hashLedger.js.map
|