CodeChain-io / CodeChain-io/codechain

OnChain invalid timestamp block propagation fail

未關閉
#808 1 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視
bug test
主要語言
Rust
星號
256
分支
50
PR 合併指標
30 天內沒有已合併 PR

描述

There are some issues in sending invalid timestamp onChain blocks.
---
Below is a test scenario.
1. Make block1 and block2.
2. The timestamp in Block2's header should be invalid. Simply make it smaller than block1.
2. Send a `status message` with block2's hash as the bestHash.
3. Send a `header response message` which is [genesisHeader, block1Header, block2Header].
4. Send a `body response message` == [[], []], which is correspond to block1's body and block2's body.
5. Block is accepted from the target node only for block1. So the target node should send a status message with block1's hash as bestHash.(This is normal behaviour but it didn't)
---
And here are problems
1. The target node does not send `status message` if in the above situation. However, if I inserted `info!("55");` then the `status message` come properly.
2. In below `verify()` function in `/core/verification/queue/mod.rs`, `Ok(verified)` is returned twice although the block2 is invalid.
```rust

fn verify(
verification: Arc>,
engine: Arc,
ready_signal: Arc,
empty: Arc,
more_to_verify: Arc,
_id: usize,
) {
loop {
// wait for work if empty.
{
let mut more_to_verify_mutex = verification.more_to_verify_mutex.lock().unwrap();

if verification.unverified.lock().is_empty() && verification.verifying.lock().is_empty() {
empty.notify_all();
}

while verification.unverified.lock().is_empty() {
more_to_verify_mutex = more_to_verify.wait(more_to_verify_mutex).unwrap();
}
}

// do work.
let item = {
// acquire these locks before getting the item to verify.
let mut unverified = verification.unverified.lock();
let mut verifying = verification.verifying.lock();

let item = match unverified.pop_front() {
Some(item) => item,
None => continue,
};

verification.sizes.unverified.fetch_sub(item.heap_size_of_children(), AtomicOrdering::SeqCst);
verifying.push_back(Verifying {
hash: item.hash(),
output: None,
});
item
};

let hash = item.hash();
let is_ready = match K::verify(item, &*engine, verification.check_seal) {
Ok(verified) => {
let mut verifying = verification.verifying.lock();
let mut idx = None;
for (i, e) in verifying.iter_mut().enumerate() {
if e.hash == hash {
idx = Some(i);

verification
.sizes
.verifying
.fetch_add(verified.heap_size_of_children(), AtomicOrdering::SeqCst);
e.output = Some(verified);
break
}
}

if idx == Some(0) {
// we're next!
let mut verified = verification.verified.lock();
let mut bad = verification.bad.lock();
VerificationQueue::drain_verifying(
&mut verifying,
&mut verified,
&mut bad,
&verification.sizes,
);
info!("111");
true
} else {
info!("222");
false
}
}
Err(_) => {
let mut verifying = verification.verifying.lock();
let mut verified = verification.verified.lock();
let mut bad = verification.bad.lock();

bad.insert(hash.clone());
verifying.retain(|e| e.hash != hash);

if verifying.front().map_or(false, |x| x.output.is_some()) {
VerificationQueue::drain_verifying(
&mut verifying,
&mut verified,
&mut bad,
&verification.sizes,
);
info!("33");
true
} else {
info!("44");
false
}
}
};
if is_ready {
info!("55");
// Import the block immediately
ready_signal.set_sync();
}
}
}
```

貢獻指南

開啟貢獻指南

研究方向

從 core/verification/queue/mod.rs 和 issue 中顯示的 verify() 函式開始。使用 status、header response 和 body response 訊息重現 block1/block2 的時間戳情境,然後追蹤 ready_signal 和目標節點的 status response。完成的標準是:無效區塊被拒絕,有效前置區塊被處理,並且在不依賴 logging 陳述式的情況下傳送預期的 status 訊息。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
rust
領域
blockchain, networking
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
停滯
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。