Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgradable smart contracts and updated quotation flow #2497

Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c8e7b2c
feat: quoting upgrade nodeside with WIP client side
grumbach Dec 5, 2024
a958cdf
chore: revert client side attempt
grumbach Dec 5, 2024
b0c59dc
feat: add payment vault smart contract interface
mickvandijke Dec 5, 2024
7cbeb17
feat: added payment vault deploy fn
mickvandijke Dec 5, 2024
849de7e
chore: update verify data payment logic
mickvandijke Dec 5, 2024
0bf810a
feat: require 1/3 of nodes to have the data to stop quoting
grumbach Dec 6, 2024
37555c9
chore: fix compile issues in evmlib, various fixes in node and networ…
grumbach Dec 6, 2024
4ee7f93
test: add reach through proxy test
mickvandijke Dec 5, 2024
34d7004
chore: tinkering with the quote flow
mickvandijke Dec 8, 2024
38b851c
feat: wip new quoting payment integration
grumbach Dec 9, 2024
57ee232
chore: notes for takeover
grumbach Dec 9, 2024
89f1357
Merge pull request #2507 from grumbach/feat-upgradable-smart-contract…
mickvandijke Dec 9, 2024
f93e902
feat: pay returns a receipt
mickvandijke Dec 9, 2024
918d236
chore: autonomi compiles!
mickvandijke Dec 9, 2024
ffdaa02
fix: put validation verify payment import and input
mickvandijke Dec 9, 2024
0279010
Merge pull request #2511 from mickvandijke/feat-upgradable-smart-cont…
grumbach Dec 10, 2024
e8bb869
feat: compiling CLI along with various fixes
grumbach Dec 10, 2024
e8876a6
feat(node): carry out quote's payee neighbourhood check
maqi Dec 9, 2024
2556e09
chore: update payment vault interface
mickvandijke Dec 10, 2024
61e9b94
fix: include unpaid store quotes in receipt
mickvandijke Dec 10, 2024
61f0f22
fix: add rate limit to get market price RPC calls
mickvandijke Dec 10, 2024
d89cca5
Merge pull request #2517 from mickvandijke/feat-upgradable-smart-cont…
maqi Dec 10, 2024
32e1df5
Merge pull request #2513 from maqi/node_neighbourhood_verify
maqi Dec 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
574 changes: 502 additions & 72 deletions Cargo.lock

Large diffs are not rendered by default.

65 changes: 3 additions & 62 deletions ant-evm/src/data_payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
// KIND, either express or implied. Please review the Licences for the specific language governing
// permissions and limitations relating to use of the SAFE Network Software.

use crate::{AttoTokens, EvmError};
use evmlib::common::TxHash;
use crate::EvmError;
use evmlib::{
common::{Address as RewardsAddress, QuoteHash},
utils::dummy_address,
common::{Address as RewardsAddress, QuoteHash, TxHash}, quoting_metrics::QuotingMetrics, utils::dummy_address
};
use libp2p::{identity::PublicKey, PeerId};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -42,64 +40,17 @@ impl ProofOfPayment {
}
}

/// Quoting metrics that got used to generate a quote, or to track peer's status.
#[derive(
Clone, Eq, PartialEq, PartialOrd, Ord, Hash, Serialize, Deserialize, custom_debug::Debug,
)]
pub struct QuotingMetrics {
/// the records stored
pub close_records_stored: usize,
/// the max_records configured
pub max_records: usize,
/// number of times that got paid
pub received_payment_count: usize,
/// the duration that node keeps connected to the network, measured in hours
pub live_time: u64,
/// network density from this node's perspective, which is the responsible_range as well
/// This could be calculated via sampling, or equation calculation.
pub network_density: Option<[u8; 32]>,
/// estimated network size
pub network_size: Option<u64>,
}

impl QuotingMetrics {
/// construct an empty QuotingMetrics
pub fn new() -> Self {
Self {
close_records_stored: 0,
max_records: 0,
received_payment_count: 0,
live_time: 0,
network_density: None,
network_size: None,
}
}
}

impl Default for QuotingMetrics {
fn default() -> Self {
Self::new()
}
}

/// A payment quote to store data given by a node to a client
/// Note that the PaymentQuote is a contract between the node and itself to make sure the clients aren’t mispaying.
/// It is NOT a contract between the client and the node.
#[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize, custom_debug::Debug)]
pub struct PaymentQuote {
/// the content paid for
pub content: XorName,
/// how much the node demands for storing the content
/// TODO: to be removed once swtich to `client querying smart_contract`
pub cost: AttoTokens,
/// the local node time when the quote was created
pub timestamp: SystemTime,
/// quoting metrics being used to generate this quote
pub quoting_metrics: QuotingMetrics,
/// list of bad_nodes that client shall not pick as a payee
/// in `serialised` format to avoid cyclic dependent on ant_protocol
#[debug(skip)]
pub bad_nodes: Vec<u8>,
/// the node's wallet address
pub rewards_address: RewardsAddress,
/// the node's libp2p identity public key in bytes (PeerId)
Expand All @@ -115,10 +66,8 @@ impl PaymentQuote {
pub fn zero() -> Self {
Self {
content: Default::default(),
cost: AttoTokens::zero(),
timestamp: SystemTime::now(),
quoting_metrics: Default::default(),
bad_nodes: vec![],
rewards_address: dummy_address(),
pub_key: vec![],
signature: vec![],
Expand All @@ -135,14 +84,11 @@ impl PaymentQuote {
/// returns the bytes to be signed from the given parameters
pub fn bytes_for_signing(
xorname: XorName,
cost: AttoTokens,
timestamp: SystemTime,
quoting_metrics: &QuotingMetrics,
serialised_bad_nodes: &[u8],
rewards_address: &RewardsAddress,
) -> Vec<u8> {
let mut bytes = xorname.to_vec();
bytes.extend_from_slice(&cost.to_bytes());
bytes.extend_from_slice(
&timestamp
.duration_since(SystemTime::UNIX_EPOCH)
Expand All @@ -152,7 +98,6 @@ impl PaymentQuote {
);
let serialised_quoting_metrics = rmp_serde::to_vec(quoting_metrics).unwrap_or_default();
bytes.extend_from_slice(&serialised_quoting_metrics);
bytes.extend_from_slice(serialised_bad_nodes);
bytes.extend_from_slice(rewards_address.as_slice());
bytes
}
Expand All @@ -161,10 +106,8 @@ impl PaymentQuote {
pub fn bytes_for_sig(&self) -> Vec<u8> {
Self::bytes_for_signing(
self.content,
self.cost,
self.timestamp,
&self.quoting_metrics,
&self.bad_nodes,
&self.rewards_address,
)
}
Expand Down Expand Up @@ -217,13 +160,11 @@ impl PaymentQuote {
}

/// test utility to create a dummy quote
pub fn test_dummy(xorname: XorName, cost: AttoTokens) -> Self {
pub fn test_dummy(xorname: XorName) -> Self {
Self {
content: xorname,
cost,
timestamp: SystemTime::now(),
quoting_metrics: Default::default(),
bad_nodes: vec![],
pub_key: vec![],
signature: vec![],
rewards_address: dummy_address(),
Expand Down
3 changes: 2 additions & 1 deletion ant-evm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ mod amount;
mod data_payments;
mod error;

pub use data_payments::{PaymentQuote, ProofOfPayment, QuotingMetrics, QUOTE_EXPIRATION_SECS};
pub use evmlib::quoting_metrics::QuotingMetrics;
pub use data_payments::{PaymentQuote, ProofOfPayment, QUOTE_EXPIRATION_SECS};

/// Types used in the public API
pub use amount::{Amount, AttoTokens};
Expand Down
26 changes: 13 additions & 13 deletions ant-networking/src/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
log_markers::Marker,
multiaddr_pop_p2p, GetRecordCfg, GetRecordError, MsgResponder, NetworkEvent, CLOSE_GROUP_SIZE,
};
use ant_evm::{AttoTokens, PaymentQuote, QuotingMetrics};
use ant_evm::{PaymentQuote, QuotingMetrics};
use ant_protocol::{
messages::{Cmd, Request, Response},
storage::{RecordHeader, RecordKind, RecordType},
Expand Down Expand Up @@ -98,10 +98,11 @@ pub enum LocalSwarmCmd {
key: RecordKey,
sender: oneshot::Sender<Option<Record>>,
},
/// GetLocalStoreCost for this node, also with the bad_node list close to the target
GetLocalStoreCost {
/// GetLocalQuotingMetrics for this node
/// Returns the quoting metrics and whether the record at `key` is already stored locally
GetLocalQuotingMetrics {
key: RecordKey,
sender: oneshot::Sender<(AttoTokens, QuotingMetrics, Vec<NetworkAddress>)>,
sender: oneshot::Sender<(QuotingMetrics, bool)>,
},
/// Notify the node received a payment.
PaymentReceived,
Expand Down Expand Up @@ -241,8 +242,8 @@ impl Debug for LocalSwarmCmd {
"LocalSwarmCmd::GetCloseGroupLocalPeers {{ key: {key:?} }}"
)
}
LocalSwarmCmd::GetLocalStoreCost { .. } => {
write!(f, "LocalSwarmCmd::GetLocalStoreCost")
LocalSwarmCmd::GetLocalQuotingMetrics { .. } => {
write!(f, "LocalSwarmCmd::GetLocalQuotingMetrics")
}
LocalSwarmCmd::PaymentReceived => {
write!(f, "LocalSwarmCmd::PaymentReceived")
Expand Down Expand Up @@ -573,8 +574,8 @@ impl SwarmDriver {
cmd_string = "TriggerIntervalReplication";
self.try_interval_replication()?;
}
LocalSwarmCmd::GetLocalStoreCost { key, sender } => {
cmd_string = "GetLocalStoreCost";
LocalSwarmCmd::GetLocalQuotingMetrics { key, sender } => {
cmd_string = "GetLocalQuotingMetrics";
let (
_index,
_total_peers,
Expand All @@ -584,15 +585,14 @@ impl SwarmDriver {
) = self.kbuckets_status();
let estimated_network_size =
Self::estimate_network_size(peers_in_non_full_buckets, num_of_full_buckets);
let (cost, quoting_metrics) = self
let (quoting_metrics, is_already_stored) = self
.swarm
.behaviour_mut()
.kademlia
.store_mut()
.store_cost(&key, Some(estimated_network_size as u64));
.quoting_metrics(&key, Some(estimated_network_size as u64));

self.record_metrics(Marker::StoreCost {
cost: cost.as_atto(),
self.record_metrics(Marker::QuotingMetrics {
quoting_metrics: &quoting_metrics,
});

Expand Down Expand Up @@ -630,7 +630,7 @@ impl SwarmDriver {
.retain(|peer_addr| key_address.distance(peer_addr) < boundary_distance);
}

let _res = sender.send((cost, quoting_metrics, bad_nodes));
let _res = sender.send((quoting_metrics, is_already_stored));
}
LocalSwarmCmd::PaymentReceived => {
cmd_string = "PaymentReceived";
Expand Down
2 changes: 1 addition & 1 deletion ant-networking/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ pub enum NetworkError {
OutgoingResponseDropped(Response),

#[error("Error setting up behaviour: {0}")]
BahviourErr(String),
BehaviourErr(String),

#[error("Register already exists at this address")]
RegisterAlreadyExists,
Expand Down
Loading
Loading