rust 网络行为不满足特征界限

gijlo24d  于 2023-01-26  发布在  其他
关注(0)|答案(1)|浏览(141)

我是Rust的初学者,我一直在学习这个教程,学习如何使用Rust创建一个简单的区块链。
chain.rs

use byteorder::{BigEndian, ReadBytesExt};
use chrono::offset::Utc;
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use std::io::Cursor;

//  Represents the entire chain in the network
pub struct Chain {
    //  Actual chain
    pub blocks: Vec<Block>,
}

//  Represents a single block in the blockchain
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Block {
    pub id: u64,

    //  Hash representing block
    pub hash: String,

    //  Hash of the previous block
    pub previous_hash: String,

    //  Time of creation in UTC
    pub timestamp: i64,

    //  Data contained in the block
    pub data: String,

    //  Value for hashing the block(PoW)
    pub nonce: u64,
}

p2p.rs

use std::collections::HashSet;

use super::chain::{Block, Chain};
use libp2p::{
    floodsub::{Floodsub, FloodsubEvent, Topic},
    identity::Keypair,
    mdns::{Mdns, MdnsEvent},
    swarm::{NetworkBehaviourEventProcess, Swarm},
    NetworkBehaviour, PeerId,
};
use log::{error, info};
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use serde_json;
use tokio::sync::mpsc;

//  Topics for pub/sub protocol
//  Impairements: Broadcasts on each request thus extremely inefficient
pub static BLOCK_TOPIC: Lazy<Topic> = Lazy::new(|| Topic::new("blocks"));
pub static CHAIN_TOPIC: Lazy<Topic> = Lazy::new(|| Topic::new("chains"));

//  Key Pair for peer identification on network
pub static KEYS: Lazy<Keypair> = Lazy::new(Keypair::generate_ed25519);

//  Peer id for peer identification on network
pub static PEER_ID: Lazy<PeerId> = Lazy::new(|| PeerId::from(KEYS.public()));

 ...
//  Defines overall NetworkBehaviour for the chain
#[derive(NetworkBehaviour)]
pub struct ChainBehaviour {
    //  Chain
    #[behaviour(ignore)]
    pub chain: Chain,

    //  Handles FloodSub protocol
    pub floodsub: Floodsub,

    //  Sends response to the UnboundedReceiver
    #[behaviour(ignore)]
    pub init_sender: mpsc::UnboundedSender<bool>,

    //  Handles automatic discovery of peers on the local network
    //  and adds them to the topology
    pub mdns: Mdns,

    //  Sends response to the UnboundedReceiver
    #[behaviour(ignore)]
    pub response_sender: mpsc::UnboundedSender<ChainResponse>,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct ChainResponse {
    pub blocks: Vec<Block>,
    pub receiver: String,
}

//  Triggers chain communication for requested ID
#[derive(Debug, Deserialize, Serialize)]
pub struct LocalChainRequest {
    pub from_peer_id: String,
}

//  Keep states for handling incoming messages, lazy init
//  and keyboard input by the client's user
pub enum EventType {
    LocalChainRequest(ChainResponse),
    Input(String),
    Init,
}

//  Implemnt FloodsubEvent for ChainBehaviour
impl NetworkBehaviourEventProcess<FloodsubEvent> for ChainBehaviour {
    fn inject_event(&mut self, event: FloodsubEvent) {
        if let FloodsubEvent::Message(msg) = event {
            //  If message is of type ChainResponse and that the message is ours,
            //  we execute our consensus.
            if let Ok(response) = serde_json::from_slice::<ChainResponse>(&msg.data) {
                if response.receiver == PEER_ID.to_string() {
                    info!("Response from {}:", msg.source);
                    response.blocks.iter().for_each(|r| info!("{:?}", r));

                    self.chain.blocks = self
                        .chain
                        .choose(self.chain.blocks.clone(), response.blocks);
                }
            } else if let Ok(response) = serde_json::from_slice::<LocalChainRequest>(&msg.data) {
                //  If of type LocalChainRequest, we send ChainResponse to
                //  initiator
                info!("sending local chain to {}", msg.source.to_string());
                let peer_id = response.from_peer_id;

                if PEER_ID.to_string() == peer_id {
                    if let Err(e) = self.response_sender.send(ChainResponse {
                        blocks: self.chain.blocks.clone(),
                        receiver: msg.source.to_string(),
                    }) {
                        error!("error sending response via channel, {}", e);
                    };
                }
            } else if let Ok(block) = serde_json::from_slice::<Block>(&msg.data) {
                //  If of type Block, we try adding the block if valid
                info!("received new block from {}", msg.source.to_string());
                self.chain.try_add_block(block);
            }
        }
    }
}

//  Implement MdnsEvents for ChainBehaviour
impl NetworkBehaviourEventProcess<MdnsEvent> for ChainBehaviour {
    fn inject_event(&mut self, event: MdnsEvent) {
        match event {
            //  Add node to list of nodes when discovered
            MdnsEvent::Discovered(nodes) => {
                for (peer, _) in nodes {
                    self.floodsub.add_node_to_partial_view(peer)
                }
            }
            //  Remove node from list of nodes when TTL expires and
            //  address hasn't been refreshed
            MdnsEvent::Expired(nodes) => {
                for (peer, _) in nodes {
                    if !self.mdns.has_node(&peer) {
                        self.floodsub.remove_node_from_partial_view(&peer);
                    }
                }
            }
        }
    }
}

这是我的货

byteorder = "1"
chrono = "0.4.19"
getrandom = "0.2.3"
hex = "0.4.3"
libp2p = {version = "0.41.0", features = ['tcp-tokio', "mdns"]}
log = "0.4.14"
once_cell = "1.9.0"
oorandom = "11.1.3"
pretty_env_logger = "0.4.0"
serde = {version = "1.0.133", features = ["derive"]}
serde_json = "1.0.74"
sha2 = "0.10.0"
tokio = { version = "1.15.0", features = ["io-util", "io-std", "macros", "rt", "rt-multi-thread", "sync", "time"] }

我一直在这个结构体上得到以下错误:

error[E0277]: the trait bound `(): From<MdnsEvent>` is not satisfied
  --> src/p2p.rs:30:10
   |
30 | #[derive(NetworkBehaviour)]
   |          ^^^^^^^^^^^^^^^^ the trait `From<MdnsEvent>` is not implemented for `()`
   |
   = help: see issue #48214
   = note: this error originates in the derive macro `NetworkBehaviour` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `(): From<FloodsubEvent>` is not satisfied
  --> src/p2p.rs:30:10
   |
30 | #[derive(NetworkBehaviour)]
   |          ^^^^^^^^^^^^^^^^ the trait `From<FloodsubEvent>` is not implemented for `()`
   |
   = help: see issue #48214
   = note: this error originates in the derive macro `NetworkBehaviour` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0277`.

我尝试按照this论坛的建议,并得到以下错误:

error[E0599]: no method named `into_inner` found for struct `OneShotHandler` in the current scope
  --> src/p2p.rs:30:10
   |
30 | #[derive(NetworkBehaviour)]
   |          ^^^^^^^^^^^^^^^^ method not found in `OneShotHandler<FloodsubProtocol, FloodsubRpc, floodsub::layer::InnerMessage>`
   |
   = note: this error originates in the derive macro `NetworkBehaviour` (in Nightly builds, run with -Z macro-backtrace for more info)

我在#[derive(NetworkBehaviour)]上也一直收到一个add reference here错误。什么可能导致这个错误?我该怎么修复它?我用的是rust-analyzer。
Link到教程的github存储库。
Link到我的github repo。整个代码相当大,但应该只有前面提到的错误。

mnemlml8

mnemlml81#

这个问题已经存在将近一年了,但也许将来还会遇到这个问题。
我在学习同一个教程时遇到了同样的问题,有趣的是,新版本的libp2p似乎要求您做两件本教程所用版本似乎没有要求的事情:

  • AppBehaviour结构指定#[behaviour(out_event="Event")]
  • 在文档中提到这是可选的,但是如果你不指定它,那么宏将使用StructName<Event>
  • AppBehaviour的结构成员发出的所有事件实现枚举Event的trait From<>,因为结构成员发出的事件 Package 在event枚举中。

我为此添加了两个新的枚举值,如libp2p文档中所示:

use crate::net::{ChainResponse};

use libp2p::{floodsub::FloodsubEvent, mdns::MdnsEvent};

pub enum Event {
    ChainResponse(ChainResponse),
    Floodsub(FloodsubEvent),
    Mdns(MdnsEvent),
    Input(String),
    Init,
}

impl From<FloodsubEvent> for Event {
    fn from(event: FloodsubEvent) -> Self {
        Self::Floodsub(event)
    }
}

impl From<MdnsEvent> for Event {
    fn from(event: MdnsEvent) -> Self {
        Self::Mdns(event)
    }
}

相关问题