mirror of
https://github.com/jwinterm/mwixnet.git
synced 2026-10-26 08:48:32 +01:00
basic reorg protection
(cherry picked from commit e3696ed73c2012f20205b98099f397ad799fcff4)
This commit is contained in:
+26
-7
@@ -4,13 +4,14 @@ use grin_api::json_rpc::{build_request, Request, Response};
|
||||
use grin_api::{client, LocatedTxKernel};
|
||||
use grin_api::{OutputPrintable, OutputType, Tip};
|
||||
use grin_core::consensus::COINBASE_MATURITY;
|
||||
use grin_core::core::{Input, OutputFeatures, Transaction};
|
||||
use grin_core::core::{Committed, Input, OutputFeatures, Transaction};
|
||||
use grin_util::ToHex;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use serde_json::json;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::Arc;
|
||||
use grin_core::core::hash::Hash;
|
||||
use thiserror::Error;
|
||||
|
||||
#[async_trait]
|
||||
@@ -21,8 +22,8 @@ pub trait GrinNode: Send + Sync {
|
||||
output_commit: &Commitment,
|
||||
) -> Result<Option<OutputPrintable>, NodeError>;
|
||||
|
||||
/// Gets the height of the chain tip
|
||||
async fn async_get_chain_height(&self) -> Result<u64, NodeError>;
|
||||
/// Gets the height and hash of the chain tip
|
||||
async fn async_get_chain_tip(&self) -> Result<(u64, Hash), NodeError>;
|
||||
|
||||
/// Posts a transaction to the grin node
|
||||
async fn async_post_tx(&self, tx: &Transaction) -> Result<(), NodeError>;
|
||||
@@ -108,6 +109,23 @@ pub async fn async_build_input(
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
pub async fn async_is_tx_valid(node: &Arc<dyn GrinNode>, tx: &Transaction) -> Result<bool, NodeError> {
|
||||
let next_block_height = node.async_get_chain_tip().await?.0 + 1;
|
||||
for input_commit in &tx.inputs_committed() {
|
||||
if !async_is_spendable(&node, &input_commit, next_block_height).await? {
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
|
||||
for output_commit in &tx.outputs_committed() {
|
||||
if async_is_unspent(&node, &output_commit).await? {
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
/// HTTP (JSON-RPC) implementation of the 'GrinNode' trait
|
||||
#[derive(Clone)]
|
||||
pub struct HttpGrinNode {
|
||||
@@ -176,7 +194,7 @@ impl GrinNode for HttpGrinNode {
|
||||
Ok(Some(outputs[0].clone()))
|
||||
}
|
||||
|
||||
async fn async_get_chain_height(&self) -> Result<u64, NodeError> {
|
||||
async fn async_get_chain_tip(&self) -> Result<(u64, Hash), NodeError> {
|
||||
let params = json!([]);
|
||||
let tip_json = self
|
||||
.async_send_request::<serde_json::Value>("get_tip", ¶ms)
|
||||
@@ -184,7 +202,7 @@ impl GrinNode for HttpGrinNode {
|
||||
let tip =
|
||||
serde_json::from_value::<Tip>(tip_json).map_err(NodeError::DecodeResponseError)?;
|
||||
|
||||
Ok(tip.height)
|
||||
Ok((tip.height, Hash::from_hex(tip.last_block_pushed.as_str()).unwrap()))
|
||||
}
|
||||
|
||||
async fn async_post_tx(&self, tx: &Transaction) -> Result<(), NodeError> {
|
||||
@@ -226,6 +244,7 @@ pub mod mock {
|
||||
use grin_onion::crypto::secp::Commitment;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::RwLock;
|
||||
use grin_core::core::hash::Hash;
|
||||
|
||||
/// Implementation of 'GrinNode' trait that mocks a grin node instance.
|
||||
/// Use only for testing purposes.
|
||||
@@ -299,8 +318,8 @@ pub mod mock {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
async fn async_get_chain_height(&self) -> Result<u64, NodeError> {
|
||||
Ok(100)
|
||||
async fn async_get_chain_tip(&self) -> Result<(u64, Hash), NodeError> {
|
||||
Ok((100, Hash::default()))
|
||||
}
|
||||
|
||||
async fn async_post_tx(&self, tx: &Transaction) -> Result<(), NodeError> {
|
||||
|
||||
Reference in New Issue
Block a user