use super::ser::{EpeeRead, EpeeWrite, Reader, write_var_bytes, write_vec};
use super::types::Value256;
use super::variant::tag;
use super::varint::append_varint;
use crate::error::Result;
#[derive(Clone, Copy, Debug)]
pub struct Signature64(pub [u8; 64]);
impl Default for Signature64 {
fn default() -> Signature64 {
Signature64([0u8; 64])
}
}
impl EpeeWrite for Signature64 {
fn write_epee(&self, out: &mut Vec<u8>) {
out.extend_from_slice(&self.0);
}
}
impl EpeeRead for Signature64 {
fn read_epee(r: &mut Reader<'_>) -> Result<Self> {
let mut v = [0u8; 64];
v.copy_from_slice(r.read_exact(64)?);
Ok(Signature64(v))
}
}
#[derive(Clone, Copy, Debug)]
pub enum GatewayOwnerSignature {
Schnorr {
c: Value256,
y: Value256,
},
Eth(Signature64),
Eddsa(Signature64),
}
impl GatewayOwnerSignature {
pub fn tag(&self) -> u8 {
match self {
GatewayOwnerSignature::Schnorr { .. } => tag::GENERIC_SCHNORR_SIG_S,
GatewayOwnerSignature::Eth(_) => tag::ETH_SIGNATURE,
GatewayOwnerSignature::Eddsa(_) => tag::EDDSA_SIGNATURE,
}
}
}
impl EpeeWrite for GatewayOwnerSignature {
fn write_epee(&self, out: &mut Vec<u8>) {
out.push(self.tag());
match self {
GatewayOwnerSignature::Schnorr { c, y } => {
c.write_epee(out);
y.write_epee(out);
}
GatewayOwnerSignature::Eth(v) | GatewayOwnerSignature::Eddsa(v) => v.write_epee(out),
}
}
}
impl EpeeRead for GatewayOwnerSignature {
fn read_epee(r: &mut Reader<'_>) -> Result<Self> {
Ok(match r.read_byte()? {
tag::GENERIC_SCHNORR_SIG_S => GatewayOwnerSignature::Schnorr {
c: Value256::read_epee(r)?,
y: Value256::read_epee(r)?,
},
tag::ETH_SIGNATURE => GatewayOwnerSignature::Eth(Signature64::read_epee(r)?),
tag::EDDSA_SIGNATURE => GatewayOwnerSignature::Eddsa(Signature64::read_epee(r)?),
other => return Err(crate::err!("unsupported gateway signature tag {other}")),
})
}
}
#[derive(Clone, Copy, Debug)]
pub struct GatewaySig {
pub version: u64,
pub sign: GatewayOwnerSignature,
}
impl EpeeWrite for GatewaySig {
fn write_epee(&self, out: &mut Vec<u8>) {
append_varint(out, self.version);
self.sign.write_epee(out);
}
}
impl EpeeRead for GatewaySig {
fn read_epee(r: &mut Reader<'_>) -> Result<Self> {
let version = r.read_varint()?;
if version > 0 {
return Err(crate::err!("unsupported gateway_sig version {version}"));
}
Ok(GatewaySig {
version,
sign: GatewayOwnerSignature::read_epee(r)?,
})
}
}
#[derive(Clone, Copy, Debug, Default)]
pub struct ZcGwBalanceProof {
pub c: Value256,
pub y0: Value256,
pub y1: Value256,
pub y2: Value256,
}
impl EpeeWrite for ZcGwBalanceProof {
fn write_epee(&self, out: &mut Vec<u8>) {
self.c.write_epee(out);
self.y0.write_epee(out);
self.y1.write_epee(out);
self.y2.write_epee(out);
}
}
impl EpeeRead for ZcGwBalanceProof {
fn read_epee(r: &mut Reader<'_>) -> Result<Self> {
Ok(ZcGwBalanceProof {
c: Value256::read_epee(r)?,
y0: Value256::read_epee(r)?,
y1: Value256::read_epee(r)?,
y2: Value256::read_epee(r)?,
})
}
}
#[derive(Clone, Copy, Debug)]
pub enum GatewayOwnerKey {
PubKey(Value256),
Eth([u8; 33]),
Eddsa(Value256),
}
impl GatewayOwnerKey {
pub fn tag(&self) -> u8 {
match self {
GatewayOwnerKey::PubKey(_) => tag::PUB_KEY,
GatewayOwnerKey::Eth(_) => tag::ETH_PUBLIC_KEY,
GatewayOwnerKey::Eddsa(_) => tag::EDDSA_PUBLIC_KEY,
}
}
}
impl EpeeWrite for GatewayOwnerKey {
fn write_epee(&self, out: &mut Vec<u8>) {
out.push(self.tag());
match self {
GatewayOwnerKey::PubKey(v) | GatewayOwnerKey::Eddsa(v) => v.write_epee(out),
GatewayOwnerKey::Eth(v) => out.extend_from_slice(v),
}
}
}
impl EpeeRead for GatewayOwnerKey {
fn read_epee(r: &mut Reader<'_>) -> Result<Self> {
Ok(match r.read_byte()? {
tag::PUB_KEY => GatewayOwnerKey::PubKey(Value256::read_epee(r)?),
tag::ETH_PUBLIC_KEY => {
let mut v = [0u8; 33];
v.copy_from_slice(r.read_exact(33)?);
GatewayOwnerKey::Eth(v)
}
tag::EDDSA_PUBLIC_KEY => GatewayOwnerKey::Eddsa(Value256::read_epee(r)?),
other => return Err(crate::err!("unsupported gateway owner key tag {other}")),
})
}
}
#[derive(Clone, Copy, Debug, Default)]
pub struct GatewayEtcField;
impl EpeeWrite for GatewayEtcField {
fn write_epee(&self, out: &mut Vec<u8>) {
out.push(tag::DUMMY);
}
}
impl EpeeRead for GatewayEtcField {
fn read_epee(r: &mut Reader<'_>) -> Result<Self> {
match r.read_byte()? {
tag::DUMMY => Ok(GatewayEtcField),
other => Err(crate::err!("unsupported gateway etc field tag {other}")),
}
}
}
#[derive(Clone, Debug)]
pub struct GatewayAddressDescriptorBase {
pub version: u64,
pub owner_key: GatewayOwnerKey,
pub etc: Vec<GatewayEtcField>,
pub meta_info: String,
}
impl EpeeWrite for GatewayAddressDescriptorBase {
fn write_epee(&self, out: &mut Vec<u8>) {
append_varint(out, self.version);
self.owner_key.write_epee(out);
write_vec(&self.etc, out);
write_var_bytes(self.meta_info.as_bytes(), out);
}
}
impl EpeeRead for GatewayAddressDescriptorBase {
fn read_epee(r: &mut Reader<'_>) -> Result<Self> {
let version = r.read_varint()?;
if version > 0 {
return Err(crate::err!(
"unsupported gateway address descriptor version {version}"
));
}
Ok(GatewayAddressDescriptorBase {
version,
owner_key: GatewayOwnerKey::read_epee(r)?,
etc: r.read_vec()?,
meta_info: r.read_var_string()?,
})
}
}
#[derive(Clone, Debug)]
pub enum GatewayAddressDescriptorOperationKind {
Register {
version: u64,
view_pub_key: Value256,
descriptor: GatewayAddressDescriptorBase,
},
Update {
version: u64,
address_id: Value256,
descriptor: GatewayAddressDescriptorBase,
},
}
impl GatewayAddressDescriptorOperationKind {
pub fn tag(&self) -> u8 {
match self {
GatewayAddressDescriptorOperationKind::Register { .. } => {
tag::GATEWAY_ADDRESS_DESCRIPTOR_OPERATION_REGISTER
}
GatewayAddressDescriptorOperationKind::Update { .. } => {
tag::GATEWAY_ADDRESS_DESCRIPTOR_OPERATION_UPDATE
}
}
}
}
impl EpeeWrite for GatewayAddressDescriptorOperationKind {
fn write_epee(&self, out: &mut Vec<u8>) {
out.push(self.tag());
match self {
GatewayAddressDescriptorOperationKind::Register {
version,
view_pub_key,
descriptor,
} => {
append_varint(out, *version);
view_pub_key.write_epee(out);
descriptor.write_epee(out);
}
GatewayAddressDescriptorOperationKind::Update {
version,
address_id,
descriptor,
} => {
append_varint(out, *version);
address_id.write_epee(out);
descriptor.write_epee(out);
}
}
}
}
impl EpeeRead for GatewayAddressDescriptorOperationKind {
fn read_epee(r: &mut Reader<'_>) -> Result<Self> {
let t = r.read_byte()?;
let version = r.read_varint()?;
if version > 0 {
return Err(crate::err!(
"unsupported gateway address operation version {version}"
));
}
Ok(match t {
tag::GATEWAY_ADDRESS_DESCRIPTOR_OPERATION_REGISTER => {
GatewayAddressDescriptorOperationKind::Register {
version,
view_pub_key: Value256::read_epee(r)?,
descriptor: GatewayAddressDescriptorBase::read_epee(r)?,
}
}
tag::GATEWAY_ADDRESS_DESCRIPTOR_OPERATION_UPDATE => {
GatewayAddressDescriptorOperationKind::Update {
version,
address_id: Value256::read_epee(r)?,
descriptor: GatewayAddressDescriptorBase::read_epee(r)?,
}
}
other => {
return Err(crate::err!(
"unsupported gateway address operation tag {other}"
));
}
})
}
}
#[derive(Clone, Debug)]
pub struct GatewayAddressDescriptorOperation {
pub version: u64,
pub operation: GatewayAddressDescriptorOperationKind,
}
impl EpeeWrite for GatewayAddressDescriptorOperation {
fn write_epee(&self, out: &mut Vec<u8>) {
append_varint(out, self.version);
self.operation.write_epee(out);
}
}
impl EpeeRead for GatewayAddressDescriptorOperation {
fn read_epee(r: &mut Reader<'_>) -> Result<Self> {
let version = r.read_varint()?;
if version > 0 {
return Err(crate::err!(
"unsupported gateway address descriptor operation version {version}"
));
}
Ok(GatewayAddressDescriptorOperation {
version,
operation: GatewayAddressDescriptorOperationKind::read_epee(r)?,
})
}
}