Skip to content

Commit

Permalink
fix: always consider genesis blocks to be caught-up
Browse files Browse the repository at this point in the history
  • Loading branch information
bitjson committed Nov 5, 2021
1 parent 4be41b8 commit 37e226b
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 29 deletions.
59 changes: 32 additions & 27 deletions src/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,9 @@ export class Agent {
* Buffer the genesis block for this node (as if it were received over
* the P2P interface).
*/
this.bufferParsedBlock(expectedGenesisBlock, new Date());
this.bufferParsedBlock(expectedGenesisBlock, new Date(), [
node.name,
]);
} else if (genesisBlockHeaderFromDb !== expectedGenesisBlock.hash) {
logger.fatal(
`Fatal error: attempted to restore chain for node ${node.name}, but the genesis block hash in the database differs from the one provided by the agent. This is likely a configuration error – shutting down to avoid corrupting the database. Block 0 hash expected: ${expectedGenesisBlock.hash} – from database: ${genesisBlockHeaderFromDb}`
Expand Down Expand Up @@ -749,8 +751,10 @@ export class Agent {
this.completedInitialSync = true;
logger.info(`Agent: initial sync is complete.`);
optionallyEnableSynchronousCommit()
.then(() => {
logger.debug('Re-enabled synchronous_commit.');
.then((disabled) => {
if (disabled) {
logger.debug('Re-enabled synchronous_commit.');
}
})
.catch((err) => {
logger.error(err);
Expand Down Expand Up @@ -1217,10 +1221,14 @@ export class Agent {
});
}

bufferParsedBlock(block: ChaingraphBlock, receivedTime: Date) {
bufferParsedBlock(
block: ChaingraphBlock,
receivedTime: Date,
acceptedBy?: string[]
) {
logger.trace(`bufferParsedBlock: ${block.hash}`);
this.blockBuffer.addBlock(block);
this.saveBlock(block, receivedTime)
this.saveBlock(block, receivedTime, acceptedBy)
.then(() => {
this.scheduleBlockBufferFill();
})
Expand All @@ -1240,14 +1248,18 @@ export class Agent {
* `node_transaction` table).
*
* @param block - the block to save to the database
* @param nodeAcceptances - a list of nodes which have accepted this block
* @param firstAcceptedAt - the Date at which the block was first announced by
* a trusted node (it may have been heard from multiple other nodes before the
* block contents finished downloading to the agent)
* @param acceptedBy - (only for genesis blocks) the node for which this
* genesis block is being saved
*/
async saveBlock(block: ChaingraphBlock, firstAcceptedAt: Date) {
async saveBlock(
block: ChaingraphBlock,
firstAcceptedAt: Date,
acceptedBy = this.blockTree.getNodesWithBlock(block.hash, block.height)
) {
logger.trace(`saveBlock: ${block.hash}`);
const acceptedBy = this.blockTree.getNodesWithBlock(
block.hash,
block.height
);

const blockTime = blockTimestampToDate(block.timestamp);
/**
Expand All @@ -1265,25 +1277,18 @@ export class Agent {
* ~12 block window, `accepted_at` times are expected to be accurate.
*/
const acceptedAt = blockTime > twoHoursAgo() ? firstAcceptedAt : null;
const nodeAcceptances = acceptedBy
.map((nodeName) => ({
acceptedAt,
nodeInternalId: this.nodes[nodeName].internalId,
nodeName,
}))
/**
* When saving genesis blocks, `internalId` may be `undefined` for other
* nodes.
*/
.filter(
(
acceptance
): acceptance is {
const nodeAcceptances = acceptedBy.map(
(nodeName) =>
({
acceptedAt,
nodeInternalId: this.nodes[nodeName].internalId,
nodeName,
} as {
acceptedAt: Date | null;
nodeInternalId: number;
nodeName: string;
} => acceptance.nodeInternalId !== undefined
);
})
);

const startTime = Date.now();
const { attemptedSavedTransactions, transactionCacheMisses } =
Expand Down
6 changes: 4 additions & 2 deletions src/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -571,19 +571,21 @@ export const optionallyDisableSynchronousCommit = async () => {
};

/**
* Re-enable `synchronous_commit` for the database.
* Re-enable `synchronous_commit` for the database. (Returns false if
* synchronous_commit was not disabled.)
*
* See `disableSynchronousCommit` for details.
*/
export const optionallyEnableSynchronousCommit = async () => {
if (postgresSynchronousCommit) {
return;
return false;
}
const client = await pool.connect();
await client.query(
`DO $$ BEGIN execute 'ALTER DATABASE ' || current_database() || ' SET synchronous_commit TO ON'; END $$;`
);
client.release();
return true;
};

/**
Expand Down
2 changes: 2 additions & 0 deletions src/e2e/e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,8 @@ test.serial('[e2e] syncs remaining blocks one-by-one', async (t) => {
t.pass();
});

test.todo('[e2e] simulates syncing against a mid-IBD node');

/**
* These tests run concurrently after all serial tests have completed. They can
* also be run independently via `yarn test:e2e:postgres`.
Expand Down

0 comments on commit 37e226b

Please sign in to comment.