fcoin/migrate/chaindb0to1.js
2017-07-31 18:21:02 -07:00

114 lines
2.1 KiB
JavaScript

'use strict';
const bcoin = require('../');
const assert = require('assert');
const BufferWriter = require('../lib/utils/writer');
let file = process.argv[2];
assert(typeof file === 'string', 'Please pass in a database path.');
file = file.replace(/\.ldb\/?$/, '');
const db = bcoin.ldb({
location: file,
db: 'leveldb',
compression: true,
cacheSize: 32 << 20,
createIfMissing: false,
bufferKeys: true
});
function makeKey(data) {
const height = data.readUInt32LE(1, true);
const key = Buffer.allocUnsafe(5);
key[0] = 0x48;
key.writeUInt32BE(height, 1, true);
return key;
}
async function checkVersion() {
console.log('Checking version.');
const data = await db.get('V');
if (!data)
return;
const ver = data.readUInt32LE(0, true);
if (ver !== 0)
throw Error(`DB is version ${ver}.`);
}
async function updateState() {
console.log('Updating chain state.');
const data = await db.get('R');
if (!data || data.length < 32)
throw new Error('No chain state.');
const hash = data.slice(0, 32);
let p = new BufferWriter();
p.writeHash(hash);
p.writeU64(0);
p.writeU64(0);
p.writeU64(0);
p = p.render();
const batch = db.batch();
batch.put('R', p);
const ver = Buffer.allocUnsafe(4);
ver.writeUInt32LE(1, 0, true);
batch.put('V', ver);
await batch.write();
console.log('Updated chain state.');
}
async function updateEndian() {
const batch = db.batch();
let total = 0;
console.log('Updating endianness.');
console.log('Iterating...');
const iter = db.iterator({
gte: Buffer.from('4800000000', 'hex'),
lte: Buffer.from('48ffffffff', 'hex'),
values: true
});
for (;;) {
const item = await iter.next();
if (!item)
break;
batch.del(item.key);
batch.put(makeKey(item.key), item.value);
total++;
}
console.log('Migrating %d items.', total);
await batch.write();
console.log('Migrated endianness.');
}
(async () => {
await db.open();
console.log('Opened %s.', file);
await checkVersion();
await updateState();
await updateEndian();
})().then(() => {
console.log('Migration complete.');
process.exit(0);
});