/*! * layout.js - blockchain data layout for bcoin * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License). * https://github.com/bcoin-org/bcoin */ 'use strict'; const assert = require('assert'); /* * Database Layout: * R -> tip hash * O -> chain options * e[hash] -> entry * h[hash] -> height * H[height] -> hash * n[hash] -> next hash * p[hash] -> tip index * b[hash] -> block * t[hash] -> extended tx * c[hash] -> coins * u[hash] -> undo coins * v -> versionbits deployments * v[bit][hash] -> versionbits state * T[addr-hash][hash] -> dummy (tx by address) * C[addr-hash][hash][index] -> dummy (coin by address) * W+T[witaddr-hash][hash] -> dummy (tx by address) * W+C[witaddr-hash][hash][index] -> dummy (coin by address) */ const layout = { binary: true, R: Buffer.from([0x52]), O: Buffer.from([0x4f]), V: Buffer.from([0x76]), e: function e(hash) { return pair(0x65, hash); }, h: function h(hash) { return pair(0x68, hash); }, H: function H(height) { return ipair(0x48, height); }, n: function n(hash) { return pair(0x6e, hash); }, p: function p(hash) { return pair(0x70, hash); }, b: function b(hash) { return pair(0x62, hash); }, t: function t(hash) { return pair(0x74, hash); }, c: function c(hash, index) { return bpair(0x63, hash, index); }, u: function u(hash) { return pair(0x75, hash); }, v: function v(bit, hash) { const key = Buffer.allocUnsafe(1 + 1 + 32); assert(typeof bit === 'number'); key[0] = 0x76; key[1] = bit; write(key, hash, 2); return key; }, vv: function vv(key) { assert(Buffer.isBuffer(key)); assert(key.length === 34); return [key[1], key.toString('hex', 2, 34)]; }, T: function T(addr, hash) { let len = addr.length; if (typeof addr === 'string') len /= 2; let key; if (len === 32) { key = Buffer.allocUnsafe(65); key[0] = 0xab; // W + T write(key, addr, 1); write(key, hash, 33); } else if (len === 20) { key = Buffer.allocUnsafe(53); key[0] = 0x54; // T write(key, addr, 1); write(key, hash, 21); } else { assert(false); } return key; }, C: function C(addr, hash, index) { let len = addr.length; assert(typeof index === 'number'); if (typeof addr === 'string') len /= 2; let key; if (len === 32) { key = Buffer.allocUnsafe(69); key[0] = 0x9a; // W + C write(key, addr, 1); write(key, hash, 33); key.writeUInt32BE(index, 65, true); } else if (len === 20) { key = Buffer.allocUnsafe(57); key[0] = 0x43; // C write(key, addr, 1); write(key, hash, 21); key.writeUInt32BE(index, 53, true); } else { assert(false); } return key; }, pp: function pp(key) { assert(Buffer.isBuffer(key)); assert(key.length === 33); return key.toString('hex', 1, 33); }, Cc: function Cc(key) { assert(Buffer.isBuffer(key)); let hash, index; if (key.length === 69) { hash = key.toString('hex', 33, 65); index = key.readUInt32BE(65, 0); } else if (key.length === 57) { hash = key.toString('hex', 21, 53); index = key.readUInt32BE(53, 0); } else { assert(false); } return [hash, index]; }, Tt: function Tt(key) { assert(Buffer.isBuffer(key)); if (key.length === 65) return key.toString('hex', 33, 65); assert(key.length === 53); return key.toString('hex', 21, 53); } }; /* * Helpers */ function write(data, str, off) { if (Buffer.isBuffer(str)) return str.copy(data, off); assert(typeof str === 'string'); return data.write(str, off, 'hex'); } function pair(prefix, hash) { const key = Buffer.allocUnsafe(33); key[0] = prefix; write(key, hash, 1); return key; } function ipair(prefix, num) { const key = Buffer.allocUnsafe(5); assert(typeof num === 'number'); key[0] = prefix; key.writeUInt32BE(num, 1, true); return key; } function bpair(prefix, hash, index) { const key = Buffer.allocUnsafe(37); assert(typeof index === 'number'); key[0] = prefix; write(key, hash, 1); key.writeUInt32BE(index, 33, true); return key; } /* * Expose */ module.exports = layout;