Skip to content

Commit

Permalink
Merge pull request #7 from weaveVM/dev
Browse files Browse the repository at this point in the history
feat: v0.1.2
  • Loading branch information
charmful0x authored Aug 13, 2024
2 parents 75056d4 + 91deccb commit e6e151d
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 62 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "wvm-archiver"
version = "0.1.1"
version = "0.1.2"
edition = "2021"
description = "EL data pipeline for WVM testnet v0"
authors = ["charmful0x <rani@decent.land>"]
Expand Down
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,26 @@ The WeaveVM Archiver node operates as follows:

As mentioned, PlanetScale is used for cloud indexing, which allows a WeaveVM Archiver node to expose its WeaveVM data as a RESTful API.

### WeaveVM Archiver node instance info

```bash
curl -X GET https://your_app.shuttleapp.rs/info
```
**returns:**

```rs
pub struct InfoServerResponse {
first_block: Option<u64>,
last_block: Option<u64>,
total_archived_blocks: u64,
archiver_balance: U256,
archiver_address: String,
network_name: String,
network_chain_id: u32,
network_rpc: String,
}
```

### Retrieve the WVM archive TXID for a given EVM block ID

```bash
Expand Down
12 changes: 6 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::utils::archive_block::archive;
use crate::utils::schema::Network;
use crate::utils::planetscale::{ps_archive_block, ps_get_latest_block_id};
use crate::utils::server_handlers::{handle_block, weave_gm};
use crate::utils::schema::Network;
use crate::utils::server_handlers::{handle_block, handle_info, handle_weave_gm};
use axum::{routing::get, Router};
use std::thread;
use std::time::Duration;
use axum::{routing::get, Router};
use tokio::task;

mod utils;
Expand All @@ -19,8 +19,9 @@ async fn main() -> shuttle_axum::ShuttleAxum {
println!("\n{:#?}\n\n", network);
// server routes
let router = Router::new()
.route("/", get(weave_gm))
.route("/block/:id", get(handle_block));
.route("/", get(handle_weave_gm))
.route("/info", get(handle_info))
.route("/block/:id", get(handle_block));

// poll blocks & archive in parallel
task::spawn(async move {
Expand All @@ -40,4 +41,3 @@ async fn main() -> shuttle_axum::ShuttleAxum {

Ok(router.into())
}

2 changes: 1 addition & 1 deletion src/utils/env_var.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ pub fn get_env_var(key: &str) -> Result<String, env::VarError> {
Ok(val) => Ok(val),
Err(e) => Err(e),
}
}
}
4 changes: 2 additions & 2 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pub mod archive_block;
pub mod env_var;
pub mod get_block;
pub mod schema;
pub mod transaction;
pub mod planetscale;
pub mod schema;
pub mod server_handlers;
pub mod transaction;
70 changes: 46 additions & 24 deletions src/utils/planetscale.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,33 @@
use crate::utils::env_var::get_env_var;
use crate::utils::schema::{Network, PsGetBlockTxid};
use planetscale_driver::{PSConnection, query};
use crate::utils::schema::{Network, PsGetBlockTxid, PsGetExtremeBlock};
use anyhow::Error;
use planetscale_driver::{query, PSConnection};
use serde_json::Value;

async fn ps_init() -> PSConnection {

let host = get_env_var("DATABASE_HOST").unwrap();
let username = get_env_var("DATABASE_USERNAME").unwrap();
let password = get_env_var("DATABASE_PASSWORD").unwrap();

let conn: PSConnection = PSConnection::new(
&host,
&username,
&password,
);
let conn: PSConnection = PSConnection::new(&host, &username, &password);

conn
conn
}

pub async fn ps_archive_block(network_block_id: &u64, wvm_calldata_txid: &str) -> Result<(), Error> {
pub async fn ps_archive_block(
network_block_id: &u64,
wvm_calldata_txid: &str,
) -> Result<(), Error> {
// format to the table VAR(66) limitation
let wvm_calldata_txid = wvm_calldata_txid.trim_matches('"');
let wvm_calldata_txid = wvm_calldata_txid.trim_matches('"');
let conn = ps_init().await;

let res = query("INSERT INTO WeaveVMArchiver(NetworkBlockId, WeaveVMArchiveTxid) VALUES($0, \"$1\")")
.bind(network_block_id)
.bind(wvm_calldata_txid)
.execute(&conn)
.await;
let res =
query("INSERT INTO WeaveVMArchiver(NetworkBlockId, WeaveVMArchiveTxid) VALUES($0, \"$1\")")
.bind(network_block_id)
.bind(wvm_calldata_txid)
.execute(&conn)
.await;

match res {
Ok(result) => {
Expand All @@ -46,7 +45,11 @@ pub async fn ps_get_latest_block_id() -> u64 {
let network = Network::config();
let conn = ps_init().await;

let latest_archived: u64 = query("SELECT MAX(NetworkBlockId) AS LatestNetworkBlockId FROM WeaveVMArchiver;").fetch_scalar(&conn).await.unwrap_or(network.start_block);
let latest_archived: u64 =
query("SELECT MAX(NetworkBlockId) AS LatestNetworkBlockId FROM WeaveVMArchiver;")
.fetch_scalar(&conn)
.await
.unwrap_or(network.start_block);
// return latest archived block in planetscale + 1
// so the process can start archiving from latest_archived + 1
latest_archived + 1
Expand All @@ -55,13 +58,32 @@ pub async fn ps_get_latest_block_id() -> u64 {
pub async fn ps_get_archived_block_txid(id: u64) -> Value {
let conn = ps_init().await;

let query_formatted = format!("SELECT WeaveVMArchiveTxid FROM WeaveVMArchiver WHERE NetworkBlockId = {}", id);
let txid: PsGetBlockTxid =
query(&query_formatted)
.fetch_one(&conn)
.await
.unwrap();
let query_formatted = format!(
"SELECT WeaveVMArchiveTxid FROM WeaveVMArchiver WHERE NetworkBlockId = {}",
id
);
let txid: PsGetBlockTxid = query(&query_formatted).fetch_one(&conn).await.unwrap();

let res = serde_json::json!(txid);
res
}
}

pub async fn ps_get_blocks_extremes(extreme: &str) -> Value {
let conn = ps_init().await;

let query_type = match extreme {
"first" => "ASC",
"last" => "DESC",
_ => panic!("invalid extreme value. Use 'first' or 'last'."),
};

let query_formatted = format!(
"SELECT NetworkBlockId FROM WeaveVMArchiver ORDER BY NetworkBlockId {} LIMIT 1;",
query_type
);

let query: PsGetExtremeBlock = query(&query_formatted).fetch_one(&conn).await.unwrap();

let res = serde_json::json!(query);
res
}
81 changes: 60 additions & 21 deletions src/utils/schema.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use crate::utils::env_var::get_env_var;
use crate::utils::transaction::get_archiver_balance;
use borsh::to_vec;
use borsh_derive::{BorshDeserialize, BorshSerialize};
use ethers::types::U256;
use ethers_providers::{Http, Provider};
use planetscale_driver::Database;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::convert::TryFrom;
use std::fs::File;
use std::io::{Read, Write};
use planetscale_driver::Database;

#[derive(Serialize, Deserialize, Debug)]
pub struct Network {
Expand Down Expand Up @@ -57,26 +59,26 @@ impl Network {
pub struct Block {
pub base_fee_per_gas: Option<String>, // "baseFeePerGas"
pub blob_gas_used: Option<String>, // "blobGasUsed"
pub difficulty: Option<String>, // "difficulty"
pub difficulty: Option<String>, // "difficulty"
pub excess_blob_gas: Option<String>, // "excessBlobGas"
pub extra_data: Option<String>, // "extraData"
pub gas_limit: Option<String>, // "gasLimit"
pub gas_used: Option<String>, // "gasUsed"
pub hash: Option<String>, // "hash"
pub logs_bloom: Option<String>, // "logsBloom"
pub miner: Option<String>, // "miner"
pub mix_hash: Option<String>, // "mixHash"
pub nonce: Option<String>, // "nonce"
pub number: Option<String>, // "number"
pub extra_data: Option<String>, // "extraData"
pub gas_limit: Option<String>, // "gasLimit"
pub gas_used: Option<String>, // "gasUsed"
pub hash: Option<String>, // "hash"
pub logs_bloom: Option<String>, // "logsBloom"
pub miner: Option<String>, // "miner"
pub mix_hash: Option<String>, // "mixHash"
pub nonce: Option<String>, // "nonce"
pub number: Option<String>, // "number"
pub parent_beacon_block_root: Option<String>, // "parentBeaconBlockRoot"
pub parent_hash: Option<String>, // "parentHash"
pub receipts_root: Option<String>, // "receiptsRoot"
pub parent_hash: Option<String>, // "parentHash"
pub receipts_root: Option<String>, // "receiptsRoot"
pub seal_fields: Vec<String>, // "sealFields" as an array of strings
pub sha3_uncles: Option<String>, // "sha3Uncles"
pub size: Option<String>, // "size"
pub state_root: Option<String>, // "stateRoot"
pub timestamp: Option<String>, // "timestamp"
pub total_difficulty: Option<String>, // "totalDifficulty"
pub sha3_uncles: Option<String>, // "sha3Uncles"
pub size: Option<String>, // "size"
pub state_root: Option<String>, // "stateRoot"
pub timestamp: Option<String>, // "timestamp"
pub total_difficulty: Option<String>, // "totalDifficulty"
pub transactions: Vec<String>, // "transactions" as an array of strings
}

Expand All @@ -94,8 +96,45 @@ impl Block {
}
}


#[derive(Database, Debug, Serialize)]
pub struct PsGetBlockTxid {
pub wvm_archive_txid : String
}
pub wvm_archive_txid: String,
}

#[derive(Database, Debug, Serialize)]
pub struct PsGetExtremeBlock {
pub block_id: u64,
}

#[derive(Debug, Serialize)]
pub struct InfoServerResponse {
first_block: Option<u64>,
last_block: Option<u64>,
total_archived_blocks: u64,
archiver_balance: U256,
archiver_address: String,
network_name: String,
network_chain_id: u32,
network_rpc: String,
}

impl InfoServerResponse {
pub async fn new(first_block: Option<u64>, last_block: Option<u64>) -> InfoServerResponse {
let network = Network::config();
let total_archived_blocks = last_block.unwrap_or(0) - first_block.unwrap_or(0);
let archiver_balance = get_archiver_balance().await;
let archiver_balance = Some(archiver_balance).unwrap();

let instance: InfoServerResponse = InfoServerResponse {
archiver_balance,
first_block,
last_block,
total_archived_blocks,
archiver_address: network.archiver_address,
network_name: network.name,
network_chain_id: network.network_chain_id,
network_rpc: network.network_rpc,
};
instance
}
}
21 changes: 15 additions & 6 deletions src/utils/server_handlers.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
use crate::utils::planetscale::ps_get_archived_block_txid;
use crate::utils::planetscale::{ps_get_archived_block_txid, ps_get_blocks_extremes};
use crate::utils::schema::InfoServerResponse;
use axum::{extract::Path, response::Json};
use serde_json::Value;
use axum::{
extract::Path,
response::Json
};

pub async fn weave_gm() -> &'static str {
pub async fn handle_weave_gm() -> &'static str {
"WeaveGM!"
}

Expand All @@ -14,3 +12,14 @@ pub async fn handle_block(Path(id): Path<u64>) -> Json<Value> {
Json(txid)
}

pub async fn handle_info() -> Json<Value> {
let first = ps_get_blocks_extremes("first").await;
let last = ps_get_blocks_extremes("last").await;

let first_block = first.get("block_id").unwrap().as_u64();
let last_block = last.get("block_id").unwrap().as_u64();
let stats_res = InfoServerResponse::new(first_block, last_block).await;

let res = serde_json::to_value(&stats_res).unwrap();
Json(res)
}
10 changes: 9 additions & 1 deletion src/utils/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ async fn assert_non_zero_balance(provider: &Provider<Http>, address: &Address) {
assert!(balance > 0.into());
}

pub async fn get_archiver_balance() -> U256 {
let network = Network::config();
let provider = Network::provider(&network, true).await;
let address = network.archiver_address.parse::<Address>().unwrap();
let balance = provider.get_balance(address, None).await.unwrap();
balance
}

async fn send_transaction(
client: &Client,
address_from: &Address,
Expand All @@ -51,4 +59,4 @@ async fn send_transaction(

println!("\nWeaveVM Archiving TXID: {}", txid);
Ok(txid)
}
}

0 comments on commit e6e151d

Please sign in to comment.