Contractless/src/rpc/commands/add_network_node.rs

73 lines
2.6 KiB
Rust

use crate::records::memory::network_mapping::structs::{AddAddressParams, SignedNodeEdit};
use crate::records::memory::network_mapping::NodeInfo;
use crate::records::memory::response_channels::Command;
use crate::rpc::read_bytes_from_stream;
use crate::rpc::responses::RpcResponse;
use crate::sled::Db;
use crate::wallets::structures::Wallet;
use crate::Arc;
use crate::Mutex;
use crate::TcpStream;
pub async fn add_network_node(
connections_key: &str,
stream_locked: Arc<Mutex<TcpStream>>,
db: &Db,
wallet_key: &str,
map: Arc<Mutex<Command>>,
) -> Result<(u32, RpcResponse), String> {
// Command 28 carries the signed node-add payload directly after the
// UID: node address, node IP, signer, timestamp, and signature.
let (uid, _) =
read_bytes_from_stream::read_uid_from_stream(connections_key, stream_locked.clone())
.await?;
let address_bytes = read_bytes_from_stream::read_short_address_from_stream(
connections_key,
stream_locked.clone(),
)
.await?;
let address = Wallet::bytes_to_short_address(&address_bytes)
.ok_or_else(|| "error: Invalid short address bytes".to_string())?;
let ip =
read_bytes_from_stream::read_ip_from_stream(connections_key, stream_locked.clone()).await?;
let added_by_bytes = read_bytes_from_stream::read_usize_from_stream(
connections_key,
Wallet::ADDRESS_BYTES_LENGTH,
stream_locked.clone(),
)
.await?;
let added_by = if added_by_bytes.iter().all(|&byte| byte == 0) {
String::new()
} else {
Wallet::bytes_to_long_address(added_by_bytes)
};
let added_timestamp =
read_bytes_from_stream::read_u64_from_stream(connections_key, stream_locked.clone())
.await?;
let added_signature =
read_bytes_from_stream::read_signature_from_stream(connections_key, stream_locked.clone())
.await?;
let remote_ip = read_bytes_from_stream::read_caller_ip(stream_locked).await?;
// NodeInfo owns the signature checks, local re-signing rules, and
// in-memory/broadcast side effects for the actual add operation.
let result = NodeInfo::add_address(AddAddressParams {
map,
edit: SignedNodeEdit {
address,
ip,
modified_by: added_by,
modified_timestamp: added_timestamp,
modified_signature: added_signature,
},
blocks_mined: 0_u8,
remote_ip,
db: db.clone(),
wallet_key: wallet_key.to_string(),
connections_key: connections_key.to_string(),
})
.await;
Ok((uid, result))
}