Skip to content

Commit

Permalink
Merge pull request AleoNet#1912 from AleoHQ/feat/storage-dev
Browse files Browse the repository at this point in the history
Adds an optional dev ID for storage
  • Loading branch information
howardwu authored Sep 5, 2022
2 parents f8c0d95 + cd97c64 commit 19181b1
Show file tree
Hide file tree
Showing 14 changed files with 578 additions and 725 deletions.
367 changes: 201 additions & 166 deletions Cargo.lock

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ path = "./environment"
version = "2.0.2"

[dependencies.snarkvm]
#path = "../snarkVM"
git = "https://github.com/AleoHQ/snarkVM.git"
rev = "1db1f75"
features = ["circuit", "console", "parallel", "utilities"]
rev = "b2cee23"
features = ["circuit", "console", "parallel", "rest", "utilities"]

[dependencies.aleo-std]
version = "0.1.14"
Expand Down Expand Up @@ -130,6 +131,9 @@ optional = true
[dev-dependencies.rusty-hook]
version = "0.11.2"

[dev-dependencies.serial_test]
version = "0.9.0"

[dev-dependencies.tempfile]
version = "3.2"

Expand Down
3 changes: 2 additions & 1 deletion environment/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ version = "1.0.144"
version = "1"

[dependencies.snarkvm]
#path = "../../snarkVM"
git = "https://github.com/AleoHQ/snarkVM.git"
rev = "1db1f75"
rev = "b2cee23"
features = ["console", "utilities"]

[dependencies.tokio]
Expand Down
136 changes: 77 additions & 59 deletions snarkos/ledger/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,36 @@
// You should have received a copy of the GNU General Public License
// along with the snarkOS library. If not, see <https://www.gnu.org/licenses/>.

mod server;
pub use server::*;

use crate::{handle_dispatch_error, BlockDB, Data, ProgramDB};
use snarkvm::prelude::*;

use colored::Colorize;
use futures::StreamExt;
use indexmap::IndexMap;
use once_cell::race::OnceBox;
use parking_lot::RwLock;
use std::{
net::{IpAddr, SocketAddr},
sync::Arc,
};
use tokio::task;
use warp::{reply, Filter, Rejection, Reply};

pub(crate) type InternalLedger<N> = snarkvm::prelude::Ledger<N, BlockDB<N>, ProgramDB<N>>;
// pub(crate) type InternalLedger<N> = snarkvm::prelude::Ledger<N, BlockMemory<N>, ProgramMemory<N>>;

pub(crate) type InternalServer<N> = snarkvm::prelude::Server<N, BlockDB<N>, ProgramDB<N>>;
// pub(crate) type InternalServer<N> = snarkvm::prelude::Server<N, BlockMemory<N>, ProgramMemory<N>>;

pub(crate) type Peers<N> = Arc<RwLock<IndexMap<SocketAddr, crate::Sender<N>>>>;

#[allow(dead_code)]
pub struct Ledger<N: Network> {
/// The internal ledger.
ledger: RwLock<InternalLedger<N>>,
/// The current peers.
peers: RwLock<IndexMap<SocketAddr, crate::Sender<N>>>,
/// The ledger.
ledger: Arc<RwLock<InternalLedger<N>>>,
/// The server.
server: OnceBox<Server<N>>,
server: InternalServer<N>,
/// The peers.
peers: Peers<N>,
/// The account private key.
private_key: PrivateKey<N>,
/// The account view key.
Expand All @@ -52,81 +54,97 @@ pub struct Ledger<N: Network> {

impl<N: Network> Ledger<N> {
/// Initializes a new instance of the ledger.
pub fn load(private_key: PrivateKey<N>) -> Result<Arc<Self>> {
// Derive the view key and address.
let view_key = ViewKey::try_from(private_key)?;
let address = Address::try_from(&view_key)?;

pub(super) fn new_with_genesis(private_key: PrivateKey<N>, genesis_block: Block<N>, dev: Option<u16>) -> Result<Arc<Self>> {
// Initialize the ledger.
let ledger = Arc::new(Self {
ledger: RwLock::new(InternalLedger::open()?),
peers: Default::default(),
server: OnceBox::new(),
private_key,
view_key,
address,
});
let ledger = match InternalLedger::new_with_genesis(&genesis_block, genesis_block.signature().to_address(), dev) {
Ok(ledger) => Arc::new(RwLock::new(ledger)),
Err(_) => {
// Open the internal ledger.
let ledger = InternalLedger::open(dev)?;
// Ensure the ledger contains the correct genesis block.
match ledger.contains_block_hash(&genesis_block.hash())? {
true => Arc::new(RwLock::new(ledger)),
false => bail!("Incorrect genesis block (run 'snarkos clean' and try again)"),
}
}
};

// Initialize the server.
let server = Server::<N>::start(ledger.clone())?;
ledger
.server
.set(Box::new(server))
.map_err(|_| anyhow!("Failed to save the server"))?;
// Return the ledger.
Self::from(ledger, private_key)
}

/// Opens an instance of the ledger.
pub fn load(private_key: PrivateKey<N>, dev: Option<u16>) -> Result<Arc<Self>> {
// Initialize the ledger.
let ledger = Arc::new(RwLock::new(InternalLedger::open(dev)?));
// Return the ledger.
Ok(ledger)
Self::from(ledger, private_key)
}

/// Initializes a new instance of the ledger.
pub(super) fn new_with_genesis(private_key: PrivateKey<N>, genesis_block: Block<N>) -> Result<Arc<Self>> {
pub fn from(ledger: Arc<RwLock<InternalLedger<N>>>, private_key: PrivateKey<N>) -> Result<Arc<Self>> {
// Derive the view key and address.
let view_key = ViewKey::try_from(private_key)?;
let address = Address::try_from(&view_key)?;

// Initialize the internal ledger.
let internal_ledger = match InternalLedger::new_with_genesis(&genesis_block, genesis_block.signature().to_address()) {
Ok(ledger) => ledger,
Err(_) => {
let ledger = InternalLedger::open()?;

// Check if the ledger contains the correct genesis block.
if !ledger.contains_block_hash(&genesis_block.hash())? {
bail!("Genesis block mismatch (please remove the existing ledger and try again)")
}
// Initialize the peers.
let peers: Peers<N> = Default::default();

// Initialize the additional routes.
#[allow(clippy::let_and_return)]
let additional_routes = {
// GET /testnet3/node/address
let get_node_address = warp::get()
.and(warp::path!("testnet3" / "node" / "address"))
.and(with(address))
.and_then(|address: Address<N>| async move { Ok::<_, Rejection>(reply::json(&address.to_string())) });

// GET /testnet3/peers/count
let get_peers_count = warp::get()
.and(warp::path!("testnet3" / "peers" / "count"))
.and(with(peers.clone()))
.and_then(get_peers_count);

// GET /testnet3/peers/all
let get_peers_all = warp::get()
.and(warp::path!("testnet3" / "peers" / "all"))
.and(with(peers.clone()))
.and_then(get_peers_all);

/// Returns the number of peers connected to the node.
async fn get_peers_count<N: Network>(peers: Peers<N>) -> Result<impl Reply, Rejection> {
Ok(reply::json(&peers.read().len()))
}

ledger
/// Returns the peers connected to the node.
async fn get_peers_all<N: Network>(peers: Peers<N>) -> Result<impl Reply, Rejection> {
Ok(reply::json(&peers.read().keys().map(|addr| addr.ip()).collect::<Vec<IpAddr>>()))
}
};

// Initialize the ledger.
let ledger = Arc::new(Self {
ledger: RwLock::new(internal_ledger),
peers: Default::default(),
server: OnceBox::new(),
private_key,
view_key,
address,
});
get_node_address.or(get_peers_count).or(get_peers_all)
};

// Initialize the server.
let server = Server::<N>::start(ledger.clone())?;
ledger
.server
.set(Box::new(server))
.map_err(|_| anyhow!("Failed to save the server"))?;
let server = InternalServer::<N>::start(ledger.clone(), Some(additional_routes), None)?;

// Return the ledger.
Ok(ledger)
Ok(Arc::new(Self {
ledger,
server,
peers,
private_key,
view_key,
address,
}))
}

/// Returns the ledger.
pub(super) const fn ledger(&self) -> &RwLock<InternalLedger<N>> {
pub(super) const fn ledger(&self) -> &Arc<RwLock<InternalLedger<N>>> {
&self.ledger
}

/// Returns the connected peers.
pub(super) const fn peers(&self) -> &RwLock<IndexMap<SocketAddr, crate::Sender<N>>> {
pub(super) const fn peers(&self) -> &Peers<N> {
&self.peers
}
}
Expand Down
Loading

0 comments on commit 19181b1

Please sign in to comment.