Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
322 changes: 322 additions & 0 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@ edition = "2024"

[dependencies]
rsa = "0.10.0-rc.11"
sha2 = "0.11.0-rc.3"
rand = "0.10.0-rc.6"
sha2 = "0.10.9"
socket2 = "0.5"
rkyv = "0.8.13"
rand = "0.10.0-rc.6"
11 changes: 11 additions & 0 deletions src/block/block.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use crate::block::transaction::Transaction;

pub struct BlockHeader {
prev_hash: [u8; 32],
nonce: u64,
merkle_root: [u8; 32]
}
pub struct Block{
block_header: BlockHeader,
txs: Vec<Transaction>
}
6 changes: 6 additions & 0 deletions src/block/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub mod block;
pub mod transaction{
pub struct Transaction{

}
}
File renamed without changes.
Empty file removed src/network.rs
Empty file.
78 changes: 78 additions & 0 deletions src/network/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use socket2::{Domain, Protocol, Socket, Type};
use std::io::Result;
use std::net::{SocketAddr, SocketAddrV4, UdpSocket};

mod protocol;

pub const PORT: u16 = 1200;

pub struct UdpBroadcast {
socket: UdpSocket,
target: SocketAddr,
}

impl UdpBroadcast {
pub fn new() -> Result<Self> {
Self::with_port(PORT, PORT)
}

pub fn with_port(send: u16, receive: u16) -> Result<Self> {
let socket = Socket::new(Domain::IPV4, Type::DGRAM, Some(Protocol::UDP))?;
socket.set_broadcast(true)?;
socket.set_reuse_address(true)?;

let addr: SocketAddr = ([0, 0, 0, 0], receive).into(); // 0.0.0.0 != 192.168.x.x.. 미래의 나, 해결해라!
socket.bind(&addr.into())?;

let socket: UdpSocket = socket.into();

Ok(Self {
socket,
target: ([255, 255, 255, 255], send).into(), // 브로드캐스트 주소 바꿀 것
})
}

pub fn send(&self, data: &[u8]) -> Result<usize> {
self.socket.send_to(data, self.target)
}

pub fn recv(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)> {
self.socket.recv_from(buf)
}

pub fn is_self(&self, addr: SocketAddr) -> bool {
addr == self.target
}
}

#[cfg(test)]
mod tests {
use std::thread;
use std::time::Duration;
use crate::network::UdpBroadcast;

#[test]
fn test_broadcast() {
let node1 = UdpBroadcast::new().unwrap();
let node2 = UdpBroadcast::new().unwrap();
let data: [u8; 4] = [0x43, 0x55, 0x54, 0x45];
let mut receive_buffer = [0u8; 4];

let receiver = thread::scope(|scope| {
let result = scope.spawn(|| {
thread::sleep(Duration::from_secs(1));
node2.recv(&mut receive_buffer).unwrap()
});
scope.spawn(|| {
node1.send(&data).unwrap();
});
result.join().unwrap()
});
let (receive_count, sender_address) = receiver;

assert_eq!(receive_count, data.len());
assert_eq!(receive_buffer, data);

}

}
87 changes: 87 additions & 0 deletions src/network/protocol.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@

use rkyv::{Archive, Deserialize, Serialize};
use std::net::Ipv4Addr;

#[derive(Archive, Deserialize, Serialize, Debug, PartialEq, Clone)]
#[rkyv(
compare(PartialEq),
derive(Debug),
)]
pub struct Packet {
pub sender_ip: [u8; 4],
}

impl Packet {
pub fn new(sender: Ipv4Addr) -> Self {
Self {
sender_ip: sender.octets(),
}
}

pub fn sender(&self) -> Ipv4Addr {
Ipv4Addr::from(self.sender_ip)
}
}

impl ArchivedPacket {
pub fn sender(&self) -> Ipv4Addr {
Ipv4Addr::new(
self.sender_ip[0],
self.sender_ip[1],
self.sender_ip[2],
self.sender_ip[3],
)
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::network::UdpBroadcast;
use std::net::Ipv4Addr;
use std::thread;
use std::time::Duration;

#[test]
fn test_packet_broadcast() {
let node1 = UdpBroadcast::with_port(1201, 1201).unwrap();
let node2 = UdpBroadcast::with_port(1201, 1201).unwrap();

// 보낼 패킷
let packet = Packet::new(Ipv4Addr::new(192, 168, 0, 100));

let serialized = rkyv::to_bytes::<rkyv::rancor::Error>(&packet).unwrap();

let mut receive_buffer = [0u8; 1024]; // 1KB 버퍼 재사용

let receiver = thread::scope(|scope| {
let result = scope.spawn(|| {
thread::sleep(Duration::from_millis(100));
let (size, addr) = node2.recv(&mut receive_buffer).unwrap();
(size, addr)
});

scope.spawn(|| {
thread::sleep(Duration::from_millis(50));
node1.send(&serialized).unwrap();
});

result.join().unwrap()
});

let (received_size, _sender_addr) = receiver;


let valid_data = &receive_buffer[..received_size];


let archived = rkyv::access::<ArchivedPacket, rkyv::rancor::Error>(valid_data).unwrap();

assert_eq!(archived.sender(), packet.sender());
assert_eq!(archived.sender(), Ipv4Addr::new(192, 168, 0, 100));

// 역직렬화
let deserialized: Packet = rkyv::deserialize::<Packet, rkyv::rancor::Error>(archived).unwrap();
assert_eq!(deserialized, packet);
}
}