feat: add helper to create bootstrap addresses (#269)
This commit is contained in:
parent
ea9c4e8b59
commit
e117a2723a
5 changed files with 69 additions and 25 deletions
|
|
@ -17,3 +17,4 @@ pallas-codec = { version = "0.19.0-alpha.0", path = "../pallas-codec" }
|
|||
base58 = "0.2.0"
|
||||
bech32 = "0.9.1"
|
||||
thiserror = "1.0.31"
|
||||
crc = "3.0.1"
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ pub type StakeholderId = Blake2b224;
|
|||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum AddrDistr {
|
||||
Variant0(StakeholderId),
|
||||
Variant1,
|
||||
SingleKeyDistribution(StakeholderId),
|
||||
BootstrapEraDistribution,
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::Decode<'b, C> for AddrDistr {
|
||||
|
|
@ -24,8 +24,8 @@ impl<'b, C> minicbor::Decode<'b, C> for AddrDistr {
|
|||
let variant = d.u32()?;
|
||||
|
||||
match variant {
|
||||
0 => Ok(AddrDistr::Variant0(d.decode_with(ctx)?)),
|
||||
1 => Ok(AddrDistr::Variant1),
|
||||
0 => Ok(AddrDistr::SingleKeyDistribution(d.decode_with(ctx)?)),
|
||||
1 => Ok(AddrDistr::BootstrapEraDistribution),
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"invalid variant for addrdstr",
|
||||
)),
|
||||
|
|
@ -40,14 +40,14 @@ impl minicbor::Encode<()> for AddrDistr {
|
|||
_ctx: &mut (),
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
AddrDistr::Variant0(x) => {
|
||||
AddrDistr::SingleKeyDistribution(x) => {
|
||||
e.array(2)?;
|
||||
e.u32(0)?;
|
||||
e.encode(x)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
AddrDistr::Variant1 => {
|
||||
AddrDistr::BootstrapEraDistribution => {
|
||||
e.array(1)?;
|
||||
e.u32(1)?;
|
||||
|
||||
|
|
@ -101,8 +101,8 @@ impl<C> minicbor::Encode<C> for AddrType {
|
|||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum AddrAttrProperty {
|
||||
AddrDistr(AddrDistr),
|
||||
Bytes(ByteVec),
|
||||
Unparsed(u8, ByteVec),
|
||||
DerivationPath(ByteVec),
|
||||
NetworkTag(ByteVec),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::Decode<'b, C> for AddrAttrProperty {
|
||||
|
|
@ -111,8 +111,11 @@ impl<'b, C> minicbor::Decode<'b, C> for AddrAttrProperty {
|
|||
|
||||
match key {
|
||||
0 => Ok(AddrAttrProperty::AddrDistr(d.decode_with(ctx)?)),
|
||||
1 => Ok(AddrAttrProperty::Bytes(d.decode_with(ctx)?)),
|
||||
x => Ok(AddrAttrProperty::Unparsed(x, d.decode_with(ctx)?)),
|
||||
1 => Ok(AddrAttrProperty::DerivationPath(d.decode_with(ctx)?)),
|
||||
2 => Ok(AddrAttrProperty::NetworkTag(d.decode_with(ctx)?)),
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"unknown tag for address attribute",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -125,19 +128,19 @@ impl<C> minicbor::Encode<C> for AddrAttrProperty {
|
|||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
AddrAttrProperty::AddrDistr(x) => {
|
||||
e.u32(0)?;
|
||||
e.u8(0)?;
|
||||
e.encode(x)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
AddrAttrProperty::Bytes(x) => {
|
||||
e.u32(1)?;
|
||||
AddrAttrProperty::DerivationPath(x) => {
|
||||
e.u8(1)?;
|
||||
e.encode(x)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
AddrAttrProperty::Unparsed(a, b) => {
|
||||
e.encode(a)?;
|
||||
AddrAttrProperty::NetworkTag(b) => {
|
||||
e.u8(2)?;
|
||||
e.encode(b)?;
|
||||
|
||||
Ok(())
|
||||
|
|
@ -146,7 +149,7 @@ impl<C> minicbor::Encode<C> for AddrAttrProperty {
|
|||
}
|
||||
}
|
||||
|
||||
pub type AddrAttr = OrderPreservingProperties<AddrAttrProperty>;
|
||||
pub type AddrAttrs = OrderPreservingProperties<AddrAttrProperty>;
|
||||
|
||||
#[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, PartialOrd)]
|
||||
pub struct AddressPayload {
|
||||
|
|
@ -154,7 +157,7 @@ pub struct AddressPayload {
|
|||
pub root: AddressId,
|
||||
|
||||
#[n(1)]
|
||||
pub attributes: AddrAttr,
|
||||
pub attributes: AddrAttrs,
|
||||
|
||||
#[n(2)]
|
||||
pub addrtype: AddrType,
|
||||
|
|
@ -167,19 +170,49 @@ pub struct ByronAddress {
|
|||
payload: TagWrap<ByteVec, 24>,
|
||||
|
||||
#[n(1)]
|
||||
crc: u64,
|
||||
crc: u32,
|
||||
}
|
||||
|
||||
const CRC: crc::Crc<u32> = crc::Crc::<u32>::new(&crc::CRC_32_ISO_HDLC);
|
||||
|
||||
impl ByronAddress {
|
||||
pub fn new(payload: &[u8], crc: u64) -> Self {
|
||||
pub fn new(payload: &[u8], crc: u32) -> Self {
|
||||
Self {
|
||||
payload: TagWrap(ByteVec::from(Vec::from(payload))),
|
||||
crc,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_bootstrap(
|
||||
root: AddressId,
|
||||
addrtype: AddrType,
|
||||
network_tag: Option<Vec<u8>>,
|
||||
) -> Self {
|
||||
let payload = AddressPayload {
|
||||
root,
|
||||
attributes: match network_tag {
|
||||
Some(x) => vec![
|
||||
AddrAttrProperty::AddrDistr(AddrDistr::BootstrapEraDistribution),
|
||||
AddrAttrProperty::NetworkTag(x.into()),
|
||||
]
|
||||
.into(),
|
||||
None => vec![AddrAttrProperty::AddrDistr(
|
||||
AddrDistr::BootstrapEraDistribution,
|
||||
)]
|
||||
.into(),
|
||||
},
|
||||
addrtype,
|
||||
};
|
||||
|
||||
let payload = minicbor::to_vec(payload).unwrap();
|
||||
|
||||
let c = CRC.checksum(&payload);
|
||||
|
||||
ByronAddress::new(&payload, c)
|
||||
}
|
||||
|
||||
pub fn from_bytes(value: &[u8]) -> Result<Self, Error> {
|
||||
pallas_codec::minicbor::decode(value).map_err(|_| Error::InvalidByronCbor)
|
||||
pallas_codec::minicbor::decode(value).map_err(Error::InvalidByronCbor)
|
||||
}
|
||||
|
||||
// Tries to decode an address from its hex representation
|
||||
|
|
@ -208,7 +241,7 @@ impl ByronAddress {
|
|||
}
|
||||
|
||||
pub fn decode(&self) -> Result<AddressPayload, Error> {
|
||||
minicbor::decode(&self.payload.0).map_err(|_| Error::InvalidByronCbor)
|
||||
minicbor::decode(&self.payload.0).map_err(Error::InvalidByronCbor)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -230,6 +263,10 @@ mod tests {
|
|||
#[test]
|
||||
fn payload_matches() {
|
||||
let addr = ByronAddress::from_base58(TEST_VECTOR).unwrap();
|
||||
|
||||
let crc2 = CRC.checksum(addr.payload.as_ref());
|
||||
assert_eq!(crc2, addr.crc);
|
||||
|
||||
let payload = addr.decode().unwrap();
|
||||
assert_eq!(payload.root.to_string(), ROOT_HASH);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ pub enum Error {
|
|||
#[error("invalid operation for address content")]
|
||||
InvalidForContent,
|
||||
|
||||
#[error("invalid CBOR for Byron address")]
|
||||
InvalidByronCbor,
|
||||
#[error("invalid CBOR for Byron address {0}")]
|
||||
InvalidByronCbor(pallas_codec::minicbor::decode::Error),
|
||||
|
||||
#[error("unkown hrp for network {0:08b}")]
|
||||
UnknownNetworkHrp(u8),
|
||||
|
|
@ -377,7 +377,7 @@ parse_shelley_fn!(parse_type_7, script_hash);
|
|||
// type 8 (1000) are Byron addresses
|
||||
fn parse_type_8(header: u8, payload: &[u8]) -> Result<Address, Error> {
|
||||
let vec = [&[header], payload].concat();
|
||||
let inner = pallas_codec::minicbor::decode(&vec).map_err(|_| Error::InvalidByronCbor)?;
|
||||
let inner = pallas_codec::minicbor::decode(&vec).map_err(Error::InvalidByronCbor)?;
|
||||
Ok(Address::Byron(inner))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -254,6 +254,12 @@ impl<P> Deref for OrderPreservingProperties<P> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<P> From<Vec<P>> for OrderPreservingProperties<P> {
|
||||
fn from(value: Vec<P>) -> Self {
|
||||
OrderPreservingProperties(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b, C, P> minicbor::decode::Decode<'b, C> for OrderPreservingProperties<P>
|
||||
where
|
||||
P: Decode<'b, C>,
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ pub struct Address {
|
|||
pub payload: TagWrap<ByteVec, 24>,
|
||||
|
||||
#[n(1)]
|
||||
pub crc: u64,
|
||||
pub crc: u32,
|
||||
}
|
||||
|
||||
// Transactions
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue