Master Fixes
This commit is contained in:
@@ -10,13 +10,34 @@ const { encodeEvent, entriesToBootstrapEvents } = require('./consensus-events');
|
||||
const { listAllEntries, waitForAutobaseIdle } = require('./dns-pass-queue');
|
||||
|
||||
let consensusBase = null;
|
||||
let consensusStore = null;
|
||||
let bootstrapComplete = false;
|
||||
let initPromise = null;
|
||||
|
||||
const CONSENSUS_INIT_TIMEOUT_MS = parseInt(process.env.CONSENSUS_INIT_TIMEOUT_MS || '30000', 10);
|
||||
const CONSENSUS_STORE_NAMESPACE = 'p2ns-consensus';
|
||||
|
||||
function getConsensusBase() {
|
||||
return consensusBase;
|
||||
}
|
||||
|
||||
function getConsensusStore(store) {
|
||||
if (!store) return null;
|
||||
if (typeof store.namespace === 'function') {
|
||||
return store.namespace(CONSENSUS_STORE_NAMESPACE);
|
||||
}
|
||||
return store;
|
||||
}
|
||||
|
||||
function withTimeout(promise, ms, label) {
|
||||
return Promise.race([
|
||||
promise,
|
||||
sleep(ms).then(() => {
|
||||
throw new Error(`${label} timed out after ${ms}ms`);
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
function isBootstrapComplete() {
|
||||
return bootstrapComplete;
|
||||
}
|
||||
@@ -39,7 +60,8 @@ function createConsensusAutobase(store, bootstrapKey) {
|
||||
|
||||
async function appendConsensusEvent(event) {
|
||||
if (!consensusBase || consensusBase.closed) {
|
||||
throw new Error('consensus autobase not open');
|
||||
logDebug('ConsensusAutobase', 'Skipping event append — sidecar not ready');
|
||||
return;
|
||||
}
|
||||
await waitForAutobaseIdle({ base: consensusBase });
|
||||
await consensusBase.append(encodeEvent(event));
|
||||
@@ -52,11 +74,15 @@ async function appendConsensusEvents(events) {
|
||||
}
|
||||
}
|
||||
|
||||
async function ensureLocalWriter() {
|
||||
async function ensureLocalWriter(isNewBase) {
|
||||
if (!consensusBase || consensusBase.closed) return;
|
||||
await consensusBase.ready();
|
||||
await consensusBase.update();
|
||||
if (consensusBase.writable) return;
|
||||
if (isNewBase) {
|
||||
logDebug('ConsensusAutobase', 'New sidecar not writable yet; skipping add_writer during init');
|
||||
return;
|
||||
}
|
||||
|
||||
const localKey = consensusBase.local?.key;
|
||||
if (!localKey) return;
|
||||
@@ -103,7 +129,14 @@ async function bootstrapFromDnsPass(pass, options = {}) {
|
||||
return;
|
||||
}
|
||||
|
||||
const entries = await listAllEntries(pass);
|
||||
let entries;
|
||||
try {
|
||||
entries = await listAllEntries(pass);
|
||||
} catch (err) {
|
||||
logWarn('ConsensusAutobase', `Bootstrap entry scan failed: ${err.message}`);
|
||||
bootstrapComplete = true;
|
||||
return;
|
||||
}
|
||||
const events = entriesToBootstrapEvents(entries);
|
||||
if (events.length === 0) {
|
||||
bootstrapComplete = true;
|
||||
@@ -129,7 +162,8 @@ function sleep(ms) {
|
||||
* @param {boolean} options.isGenesis
|
||||
*/
|
||||
async function initializeConsensusAutobase({ store, bootstrapKey, dnsPass, isGenesis }) {
|
||||
if (!store || typeof store.get !== 'function') {
|
||||
const namespacedStore = getConsensusStore(store);
|
||||
if (!namespacedStore || typeof namespacedStore.get !== 'function') {
|
||||
logWarn('ConsensusAutobase', 'Valid corestore required — skipping consensus sidecar init');
|
||||
return null;
|
||||
}
|
||||
@@ -142,18 +176,21 @@ async function initializeConsensusAutobase({ store, bootstrapKey, dnsPass, isGen
|
||||
}
|
||||
|
||||
try {
|
||||
consensusBase = createConsensusAutobase(store, bootstrapKey || null);
|
||||
consensusStore = namespacedStore;
|
||||
await namespacedStore.ready();
|
||||
const isNewBase = !bootstrapKey;
|
||||
consensusBase = createConsensusAutobase(namespacedStore, bootstrapKey || null);
|
||||
state.consensusAutobase = consensusBase;
|
||||
|
||||
await consensusBase.ready();
|
||||
await consensusBase.update();
|
||||
await withTimeout(consensusBase.ready(), CONSENSUS_INIT_TIMEOUT_MS, 'consensus autobase ready');
|
||||
await withTimeout(consensusBase.update(), CONSENSUS_INIT_TIMEOUT_MS, 'consensus autobase update');
|
||||
|
||||
if (!bootstrapKey && isGenesis) {
|
||||
if (isNewBase) {
|
||||
const keyHex = consensusBase.key.toString('hex');
|
||||
logInfo('ConsensusAutobase', `Genesis consensus autobase created: ${keyHex.slice(0, 16)}...`);
|
||||
logInfo('ConsensusAutobase', `Consensus autobase created: ${keyHex.slice(0, 16)}...`);
|
||||
}
|
||||
|
||||
await ensureLocalWriter();
|
||||
await ensureLocalWriter(isNewBase);
|
||||
await bootstrapFromDnsPass(dnsPass, {
|
||||
allowLocalBootstrap: !bootstrapKey || isGenesis,
|
||||
syncWaitMs: bootstrapKey ? 3000 : 0
|
||||
@@ -214,9 +251,22 @@ async function closeConsensusAutobase() {
|
||||
} finally {
|
||||
consensusBase = null;
|
||||
state.consensusAutobase = null;
|
||||
consensusStore = null;
|
||||
}
|
||||
}
|
||||
|
||||
function startConsensusForNetwork(options) {
|
||||
initConsensusForNetwork(options)
|
||||
.then((base) => {
|
||||
if (base) {
|
||||
logInfo('ConsensusAutobase', 'Consensus sidecar ready (background init)');
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
logError('ConsensusAutobase', `Background consensus init failed: ${err.message}`);
|
||||
});
|
||||
}
|
||||
|
||||
function getConsensusStatus() {
|
||||
const base = consensusBase;
|
||||
const view = base && !base.closed ? base.view : null;
|
||||
@@ -261,6 +311,7 @@ module.exports = {
|
||||
isBootstrapComplete,
|
||||
initializeConsensusAutobase,
|
||||
initConsensusForNetwork,
|
||||
startConsensusForNetwork,
|
||||
appendConsensusEvent,
|
||||
appendConsensusEvents,
|
||||
replicateConsensus,
|
||||
|
||||
@@ -107,27 +107,20 @@ function createCoreSwarmHandlers(ctx) {
|
||||
|
||||
setupListeners();
|
||||
|
||||
try {
|
||||
const { initConsensusForNetwork } = require('./consensus-autobase');
|
||||
const networkManifest = require('../infrastructure/network-manifest');
|
||||
const manifestPath = networkManifest.getManifestPath(process.env.NETWORK_MANIFEST_FILE);
|
||||
let manifest = state.networkManifest;
|
||||
if (!manifest) {
|
||||
manifest = await networkManifest.readManifest(manifestPath);
|
||||
if (manifest) state.networkManifest = manifest;
|
||||
}
|
||||
const base = await initConsensusForNetwork({
|
||||
store,
|
||||
dnsPass: newPass,
|
||||
networkManifest: manifest,
|
||||
manifestPath
|
||||
});
|
||||
if (base) {
|
||||
logInfo('Swarm', 'Consensus sidecar initialized after pairing');
|
||||
}
|
||||
} catch (err) {
|
||||
logError('Swarm', `Failed to initialize consensus sidecar: ${err.message}`);
|
||||
const { startConsensusForNetwork } = require('./consensus-autobase');
|
||||
const networkManifest = require('../infrastructure/network-manifest');
|
||||
const manifestPath = networkManifest.getManifestPath(process.env.NETWORK_MANIFEST_FILE);
|
||||
let manifest = state.networkManifest;
|
||||
if (!manifest) {
|
||||
manifest = await networkManifest.readManifest(manifestPath);
|
||||
if (manifest) state.networkManifest = manifest;
|
||||
}
|
||||
startConsensusForNetwork({
|
||||
store,
|
||||
dnsPass: newPass,
|
||||
networkManifest: manifest,
|
||||
manifestPath
|
||||
});
|
||||
|
||||
if (isMaster) {
|
||||
state.masterPendingPass = false;
|
||||
|
||||
@@ -1563,20 +1563,13 @@ async function main() {
|
||||
}
|
||||
setupListeners();
|
||||
|
||||
try {
|
||||
const { initConsensusForNetwork } = require('./includes/core/consensus-autobase');
|
||||
const base = await initConsensusForNetwork({
|
||||
store,
|
||||
dnsPass: newPass,
|
||||
networkManifest: state.networkManifest,
|
||||
manifestPath
|
||||
});
|
||||
if (base) {
|
||||
logInfo('Main', 'Consensus sidecar initialized');
|
||||
}
|
||||
} catch (err) {
|
||||
logError('Main', `Failed to initialize consensus sidecar: ${err.message}`);
|
||||
}
|
||||
const { startConsensusForNetwork } = require('./includes/core/consensus-autobase');
|
||||
startConsensusForNetwork({
|
||||
store,
|
||||
dnsPass: newPass,
|
||||
networkManifest: state.networkManifest,
|
||||
manifestPath
|
||||
});
|
||||
}
|
||||
|
||||
if (isMaster) {
|
||||
|
||||
Reference in New Issue
Block a user