From 046a771b7842dac74d5cb82a56b28fbbbbe1a33a Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E5=BF=97=E5=AE=87?= Date: Tue, 13 Jan 2026 14:02:00 +0800 Subject: [PATCH] fix(core): `push` now errors on `prev_blockhash` mismatch --- crates/core/src/checkpoint.rs | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/crates/core/src/checkpoint.rs b/crates/core/src/checkpoint.rs index bff83362..16892217 100644 --- a/crates/core/src/checkpoint.rs +++ b/crates/core/src/checkpoint.rs @@ -349,21 +349,30 @@ where /// Puts another checkpoint onto the linked list representing the blockchain. /// - /// Returns an `Err(self)` if the block you are pushing on is not at a greater height that the - /// one you are pushing on to. + /// Returns an `Err(self)` if: + /// * The block you are pushing on is not at a greater height that the one you are pushing on to. + /// * The `prev_blockhash` does not match. pub fn push(self, height: u32, data: D) -> Result { - if self.height() < height { - Ok(Self(Arc::new(CPInner { - block_id: BlockId { - height, - hash: data.to_blockhash(), - }, - data, - prev: Some(self.0), - }))) - } else { - Err(self) + // Reject if trying to push at or below current height - chain must grow forward. + if height <= self.height() { + return Err(self); } + + // For contiguous height, ensure prev_blockhash does not conflict. + if let Some(prev_blockhash) = data.prev_blockhash() { + if self.height() + 1 == height && self.hash() != prev_blockhash { + return Err(self); + } + } + + Ok(Self(Arc::new(CPInner { + block_id: BlockId { + height, + hash: data.to_blockhash(), + }, + data, + prev: Some(self.0), + }))) } } -- 2.49.0