regiusmark 0.3.0

Regius Mark core blockchain library.
Documentation
use crate::{
    script::{EvalErr, EvalErrType},
    serializer::*,
};
use std::io::{self, Cursor};

pub type SkipFlags = u8;

#[allow(clippy::identity_op)]
pub const SKIP_NONE: u8 = 1 << 0;
pub const SKIP_REWARD_TX: u8 = 1 << 1;

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum BlockErr {
    InvalidBlockHeight,
    InvalidMerkleRoot,
    InvalidSignature,
    InvalidPrevHash,
    InvalidHash,
    Tx(TxErr),
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum TxErr {
    ScriptEval(EvalErr),
    ScriptHashMismatch,
    ScriptRetFalse,
    Arithmetic,
    InsufficientBalance,
    InvalidFeeAmount,
    TooManySignatures,
    TxTooLarge,
    TxProhibited,
    TxExpired,
    TxDupe,
}

impl TxErr {
    pub fn serialize(self, buf: &mut Vec<u8>) {
        match self {
            TxErr::ScriptEval(err) => {
                buf.push(0x00);
                buf.push_u32(err.pos);
                buf.push(err.err as u8);
            }
            TxErr::ScriptHashMismatch => buf.push(0x01),
            TxErr::ScriptRetFalse => buf.push(0x02),
            TxErr::Arithmetic => buf.push(0x03),
            TxErr::InsufficientBalance => buf.push(0x04),
            TxErr::InvalidFeeAmount => buf.push(0x05),
            TxErr::TooManySignatures => buf.push(0x06),
            TxErr::TxTooLarge => buf.push(0x07),
            TxErr::TxProhibited => buf.push(0x08),
            TxErr::TxExpired => buf.push(0x09),
            TxErr::TxDupe => buf.push(0x0A),
        }
    }

    pub fn deserialize(cursor: &mut Cursor<&[u8]>) -> io::Result<Self> {
        let tag = cursor.take_u8()?;
        Ok(match tag {
            0x00 => {
                let pos = cursor.take_u32()?;
                let kind = match cursor.take_u8()? {
                    t if t == EvalErrType::UnexpectedEOF as u8 => EvalErrType::UnexpectedEOF,
                    t if t == EvalErrType::UnknownOp as u8 => EvalErrType::UnknownOp,
                    t if t == EvalErrType::InvalidItemOnStack as u8 => {
                        EvalErrType::InvalidItemOnStack
                    }
                    t if t == EvalErrType::StackOverflow as u8 => EvalErrType::StackOverflow,
                    t if t == EvalErrType::StackUnderflow as u8 => EvalErrType::StackUnderflow,
                    _ => {
                        return Err(io::Error::new(
                            io::ErrorKind::InvalidData,
                            "failed to deserialize EvalErrType",
                        ))
                    }
                };
                TxErr::ScriptEval(EvalErr::new(pos, kind))
            }
            0x01 => TxErr::ScriptHashMismatch,
            0x02 => TxErr::ScriptRetFalse,
            0x03 => TxErr::Arithmetic,
            0x04 => TxErr::InsufficientBalance,
            0x05 => TxErr::InvalidFeeAmount,
            0x06 => TxErr::TooManySignatures,
            0x07 => TxErr::TxTooLarge,
            0x08 => TxErr::TxProhibited,
            0x09 => TxErr::TxExpired,
            0x0A => TxErr::TxDupe,
            _ => {
                return Err(io::Error::new(
                    io::ErrorKind::InvalidData,
                    "failed to deserialize TxErr",
                ))
            }
        })
    }
}