1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Copyright 2015-2020 Parity Technologies (UK) Ltd.
// This file is part of OpenEthereum.

// OpenEthereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// OpenEthereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with OpenEthereum.  If not, see <http://www.gnu.org/licenses/>.

//! Spec seal.

use ethereum_types::{H256, H520, H64};
use ethjson;
use rlp::RlpStream;

/// Classic ethereum seal.
pub struct Ethereum {
    /// Seal nonce.
    pub nonce: H64,
    /// Seal mix hash.
    pub mix_hash: H256,
}

impl Into<Generic> for Ethereum {
    fn into(self) -> Generic {
        let mut s = RlpStream::new_list(2);
        s.append(&self.mix_hash).append(&self.nonce);
        Generic(s.out())
    }
}

/// AuthorityRound seal.
pub struct AuthorityRound {
    /// Seal step.
    pub step: usize,
    /// Seal signature.
    pub signature: H520,
}

/// Tendermint seal.
pub struct Tendermint {
    /// Seal round.
    pub round: usize,
    /// Proposal seal signature.
    pub proposal: H520,
    /// Precommit seal signatures.
    pub precommits: Vec<H520>,
}

impl Into<Generic> for AuthorityRound {
    fn into(self) -> Generic {
        let mut s = RlpStream::new_list(2);
        s.append(&self.step).append(&self.signature);
        Generic(s.out())
    }
}

impl Into<Generic> for Tendermint {
    fn into(self) -> Generic {
        let mut stream = RlpStream::new_list(3);
        stream
            .append(&self.round)
            .append(&self.proposal)
            .append_list(&self.precommits);
        Generic(stream.out())
    }
}

pub struct Generic(pub Vec<u8>);

/// Genesis seal type.
pub enum Seal {
    /// Classic ethereum seal.
    Ethereum(Ethereum),
    /// AuthorityRound seal.
    AuthorityRound(AuthorityRound),
    /// Tendermint seal.
    Tendermint(Tendermint),
    /// Generic RLP seal.
    Generic(Generic),
}

impl From<ethjson::spec::Seal> for Seal {
    fn from(s: ethjson::spec::Seal) -> Self {
        match s {
            ethjson::spec::Seal::Ethereum(eth) => Seal::Ethereum(Ethereum {
                nonce: eth.nonce.into(),
                mix_hash: eth.mix_hash.into(),
            }),
            ethjson::spec::Seal::AuthorityRound(ar) => Seal::AuthorityRound(AuthorityRound {
                step: ar.step.into(),
                signature: ar.signature.into(),
            }),
            ethjson::spec::Seal::Tendermint(tender) => Seal::Tendermint(Tendermint {
                round: tender.round.into(),
                proposal: tender.proposal.into(),
                precommits: tender.precommits.into_iter().map(Into::into).collect(),
            }),
            ethjson::spec::Seal::Generic(g) => Seal::Generic(Generic(g.into())),
        }
    }
}

impl Into<Generic> for Seal {
    fn into(self) -> Generic {
        match self {
            Seal::Generic(generic) => generic,
            Seal::Ethereum(eth) => eth.into(),
            Seal::AuthorityRound(ar) => ar.into(),
            Seal::Tendermint(tender) => tender.into(),
        }
    }
}