Shred作为 solana 网络中数据传播的最小单元,以最快的速度在网络中以 udp 的形式传播。通过拼装解析 Shred 数据流可以使得交易者抢占先机。本文教你如何开启基于 Jito 的 ShredStream,更详细的教程请参与Jito 文档
在此处填写 jito 提供的表单注册授权 pubkey,此账户中不应有任何的资金,提交时只需要提交 pubkey 即可。
此处放行了 jito 所有区域的 ip,可以在此处查看。
ufw allow from 74.118.140.240
ufw allow from 202.8.8.174
ufw allow from 145.40.93.84
ufw allow from 145.40.93.41
ufw allow from 141.98.216.96
ufw allow from 64.130.48.56
ufw allow from 64.130.53.8
ufw allow from 64.130.53.57
ufw allow from 202.8.9.160
ufw allow from 202.8.9.19
查询自己的 tvu 端口
bash -c "$(curl -fsSL https://raw.githubusercontent.com/jito-labs/shredstream-proxy/master/scripts/get_tvu_port.sh)"
开启 jito-shredstream 数据流服务,默认接收到的 shreds 数据在本地 udp 20000 端口
git clone https://github.com/jito-labs/shredstream-proxy.git --recurse-submodules
RUST_LOG=info cargo run --release --bin jito-shredstream-proxy -- shredstream \
--block-engine-url https://frankfurt.mainnet.block-engine.jito.wtf \
--auth-keypair /root/xyz4g33hXuR84saNFe3tRgcu9NbB8AeqX5YMcLetMek.json \
--desired-regions amsterdam,frankfurt \
--dest-ip-ports 127.0.0.1:8001
use pcap::{Capture, Device};
use solana_ledger::shred::Shred;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
// 获取网络设备列表
let devices = Device::list()?;
// 打印可用设备列表
// println!("可用网络设备:");
for (i, device) in devices.iter().enumerate() {
println!("{}. {}", i, device.name);
}
// 选择要监听的设备(这里假设使用第一个设备,你可以根据需要修改)
let device = &devices[0];
// 创建捕获器
let mut cap = Capture::from_device(device.name.as_str())?
.promisc(true)
.snaplen(65535)
.open()?;
// 设置过滤器只捕获UDP 20000端口的数据包
cap.filter("udp port 20000", true)?;
println!("开始监听 {} 上的UDP 20000端口...", device.name);
while let Ok(packet) = cap.next_packet() {
// UDP头部长度为8字节,我们需要跳过它
let payload = &packet.data[42..]; // 跳过以太网头(14字节) + IP头(20字节) + UDP头(8字节)
match Shred::new_from_serialized_shred(payload.to_vec()) {
Ok(shred) => {
println!("接收到Shred");
println!("ID: {:?}", shred.id());
println!("Slot: {}", shred.slot());
println!("Index: {}", shred.index());
println!("数据完整: {}", shred.data_complete());
if shred.is_data() {
println!("类型: 数据Shred");
let payload = shred.payload();
println!("payload长度: {}", payload.len());
} else {
println!("类型: 编码Shred");
}
println!("------------------------");
},
Err(e) => println!("解析Shred失败: {:?}", e),
}
}
Ok(())
}
cargo run