Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

OnChain invalid timestamp block propagation fail

オープン
#808 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
35/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
停滞
技術スタック
rust

調査の方向性

core/verification/queue/mod.rs と、issue に示されている verify() 関数から始めます。status、header response、body response メッセージを使って block1/block2 のタイムスタンプシナリオを再現し、その後 ready_signal と対象ノードの status response を追跡します。無効なブロックが拒否され、有効な先行ブロックが処理され、logging 文に依存せずに期待される status メッセージが送信されれば完了です。

索引モデルが issue の本文から書いたものです。

説明

bug test

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.
  3. Send a status message with block2's hash as the bestHash.
  4. Send a header response message which is [genesisHeader, block1Header, block2Header].
  5. Send a body response message == [[], []], which is correspond to block1's body and block2's body.
  6. 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.

    fn verify(
        verification: Arc<Verification<K>>,
        engine: Arc<CodeChainEngine>,
        ready_signal: Arc<QueueSignal>,
        empty: Arc<SCondvar>,
        more_to_verify: Arc<SCondvar>,
        _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();
            }
        }
    }
主要言語
Rust
スター
256
フォーク
50
PR マージ指標
30日以内にマージされた PR はありません

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

CodeChain-io/codechain のほかの issue

CodeChain-io/codechain の issue をすべて見る

似ている issue

Rust の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。