Skip to content

Commit f3da16c

Browse files
authored
Merge pull request #2 from coding-1ab/master
Recent master commit PR
2 parents e0aacce + e5d0572 commit f3da16c

8 files changed

Lines changed: 508 additions & 2 deletions

File tree

Cargo.lock

Lines changed: 322 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,7 @@ edition = "2024"
55

66
[dependencies]
77
rsa = "0.10.0-rc.11"
8-
sha2 = "0.11.0-rc.3"
9-
rand = "0.10.0-rc.6"
8+
sha2 = "0.10.9"
9+
socket2 = "0.5"
10+
rkyv = "0.8.13"
11+
rand = "0.10.0-rc.6"

src/block/block.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use crate::block::transaction::Transaction;
2+
3+
pub struct BlockHeader {
4+
prev_hash: [u8; 32],
5+
nonce: u64,
6+
merkle_root: [u8; 32]
7+
}
8+
pub struct Block{
9+
block_header: BlockHeader,
10+
txs: Vec<Transaction>
11+
}

src/block/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pub mod block;
2+
pub mod transaction{
3+
pub struct Transaction{
4+
5+
}
6+
}
File renamed without changes.

src/network.rs

Whitespace-only changes.

src/network/mod.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
use socket2::{Domain, Protocol, Socket, Type};
2+
use std::io::Result;
3+
use std::net::{SocketAddr, SocketAddrV4, UdpSocket};
4+
5+
mod protocol;
6+
7+
pub const PORT: u16 = 1200;
8+
9+
pub struct UdpBroadcast {
10+
socket: UdpSocket,
11+
target: SocketAddr,
12+
}
13+
14+
impl UdpBroadcast {
15+
pub fn new() -> Result<Self> {
16+
Self::with_port(PORT, PORT)
17+
}
18+
19+
pub fn with_port(send: u16, receive: u16) -> Result<Self> {
20+
let socket = Socket::new(Domain::IPV4, Type::DGRAM, Some(Protocol::UDP))?;
21+
socket.set_broadcast(true)?;
22+
socket.set_reuse_address(true)?;
23+
24+
let addr: SocketAddr = ([0, 0, 0, 0], receive).into(); // 0.0.0.0 != 192.168.x.x.. 미래의 나, 해결해라!
25+
socket.bind(&addr.into())?;
26+
27+
let socket: UdpSocket = socket.into();
28+
29+
Ok(Self {
30+
socket,
31+
target: ([255, 255, 255, 255], send).into(), // 브로드캐스트 주소 바꿀 것
32+
})
33+
}
34+
35+
pub fn send(&self, data: &[u8]) -> Result<usize> {
36+
self.socket.send_to(data, self.target)
37+
}
38+
39+
pub fn recv(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)> {
40+
self.socket.recv_from(buf)
41+
}
42+
43+
pub fn is_self(&self, addr: SocketAddr) -> bool {
44+
addr == self.target
45+
}
46+
}
47+
48+
#[cfg(test)]
49+
mod tests {
50+
use std::thread;
51+
use std::time::Duration;
52+
use crate::network::UdpBroadcast;
53+
54+
#[test]
55+
fn test_broadcast() {
56+
let node1 = UdpBroadcast::new().unwrap();
57+
let node2 = UdpBroadcast::new().unwrap();
58+
let data: [u8; 4] = [0x43, 0x55, 0x54, 0x45];
59+
let mut receive_buffer = [0u8; 4];
60+
61+
let receiver = thread::scope(|scope| {
62+
let result = scope.spawn(|| {
63+
thread::sleep(Duration::from_secs(1));
64+
node2.recv(&mut receive_buffer).unwrap()
65+
});
66+
scope.spawn(|| {
67+
node1.send(&data).unwrap();
68+
});
69+
result.join().unwrap()
70+
});
71+
let (receive_count, sender_address) = receiver;
72+
73+
assert_eq!(receive_count, data.len());
74+
assert_eq!(receive_buffer, data);
75+
76+
}
77+
78+
}

src/network/protocol.rs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
2+
use rkyv::{Archive, Deserialize, Serialize};
3+
use std::net::Ipv4Addr;
4+
5+
#[derive(Archive, Deserialize, Serialize, Debug, PartialEq, Clone)]
6+
#[rkyv(
7+
compare(PartialEq),
8+
derive(Debug),
9+
)]
10+
pub struct Packet {
11+
pub sender_ip: [u8; 4],
12+
}
13+
14+
impl Packet {
15+
pub fn new(sender: Ipv4Addr) -> Self {
16+
Self {
17+
sender_ip: sender.octets(),
18+
}
19+
}
20+
21+
pub fn sender(&self) -> Ipv4Addr {
22+
Ipv4Addr::from(self.sender_ip)
23+
}
24+
}
25+
26+
impl ArchivedPacket {
27+
pub fn sender(&self) -> Ipv4Addr {
28+
Ipv4Addr::new(
29+
self.sender_ip[0],
30+
self.sender_ip[1],
31+
self.sender_ip[2],
32+
self.sender_ip[3],
33+
)
34+
}
35+
}
36+
37+
#[cfg(test)]
38+
mod tests {
39+
use super::*;
40+
use crate::network::UdpBroadcast;
41+
use std::net::Ipv4Addr;
42+
use std::thread;
43+
use std::time::Duration;
44+
45+
#[test]
46+
fn test_packet_broadcast() {
47+
let node1 = UdpBroadcast::with_port(1201, 1201).unwrap();
48+
let node2 = UdpBroadcast::with_port(1201, 1201).unwrap();
49+
50+
// 보낼 패킷
51+
let packet = Packet::new(Ipv4Addr::new(192, 168, 0, 100));
52+
53+
let serialized = rkyv::to_bytes::<rkyv::rancor::Error>(&packet).unwrap();
54+
55+
let mut receive_buffer = [0u8; 1024]; // 1KB 버퍼 재사용
56+
57+
let receiver = thread::scope(|scope| {
58+
let result = scope.spawn(|| {
59+
thread::sleep(Duration::from_millis(100));
60+
let (size, addr) = node2.recv(&mut receive_buffer).unwrap();
61+
(size, addr)
62+
});
63+
64+
scope.spawn(|| {
65+
thread::sleep(Duration::from_millis(50));
66+
node1.send(&serialized).unwrap();
67+
});
68+
69+
result.join().unwrap()
70+
});
71+
72+
let (received_size, _sender_addr) = receiver;
73+
74+
75+
let valid_data = &receive_buffer[..received_size];
76+
77+
78+
let archived = rkyv::access::<ArchivedPacket, rkyv::rancor::Error>(valid_data).unwrap();
79+
80+
assert_eq!(archived.sender(), packet.sender());
81+
assert_eq!(archived.sender(), Ipv4Addr::new(192, 168, 0, 100));
82+
83+
// 역직렬화
84+
let deserialized: Packet = rkyv::deserialize::<Packet, rkyv::rancor::Error>(archived).unwrap();
85+
assert_eq!(deserialized, packet);
86+
}
87+
}

0 commit comments

Comments
 (0)