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

feat(networking): add TransactionWithPayment #2514

Merged
merged 3 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
1 change: 1 addition & 0 deletions ant-networking/src/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,7 @@ impl SwarmDriver {
}
RecordKind::ChunkWithPayment
| RecordKind::RegisterWithPayment
| RecordKind::TransactionWithPayment
| RecordKind::ScratchpadWithPayment => {
error!("Record {record_key:?} with payment shall not be stored locally.");
return Err(NetworkError::InCorrectRecordHeader);
Expand Down
1 change: 1 addition & 0 deletions ant-networking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,7 @@ impl Network {
match kind {
RecordKind::Chunk
| RecordKind::ChunkWithPayment
| RecordKind::TransactionWithPayment
| RecordKind::RegisterWithPayment
| RecordKind::ScratchpadWithPayment => {
error!("Encountered a split record for {pretty_key:?} with unexpected RecordKind {kind:?}, skipping.");
Expand Down
50 changes: 50 additions & 0 deletions ant-node/src/put_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,55 @@ impl Node {
}
result
}
RecordKind::TransactionWithPayment => {
let (payment, transaction) =
try_deserialize_record::<(ProofOfPayment, Transaction)>(&record)?;

// check if the deserialized value's TransactionAddress matches the record's key
let net_addr = NetworkAddress::from_transaction_address(transaction.address());
let key = net_addr.to_record_key();
let pretty_key = PrettyPrintRecordKey::from(&key);
if record.key != key {
warn!(
"Record's key {pretty_key:?} does not match with the value's TransactionAddress, ignoring PUT."
);
return Err(Error::RecordKeyMismatch);
}

let already_exists = self.validate_key_and_existence(&net_addr, &key).await?;

// The transaction may already exist during the replication.
// The payment shall get deposit to self even the transaction already presents.
// However, if the transaction already presents, the incoming one maybe for edit only.
b-zee marked this conversation as resolved.
Show resolved Hide resolved
// Hence the corresponding payment error shall not be thrown out.
if let Err(err) = self
.payment_for_us_exists_and_is_still_valid(&net_addr, payment)
.await
{
if already_exists {
debug!("Payment of the incoming exists transaction {pretty_key:?} having error {err:?}");
} else {
error!("Payment of the incoming non-exist transaction {pretty_key:?} having error {err:?}");
return Err(err);
}
}

let res = self
.validate_merge_and_store_transactions(vec![transaction], &key)
.await;
if res.is_ok() {
let content_hash = XorName::from_content(&record.value);

// Notify replication_fetcher to mark the attempt as completed.
// Send the notification earlier to avoid it got skipped due to:
// the record becomes stored during the fetch because of other interleaved process.
self.network().notify_fetch_completed(
record.key.clone(),
RecordType::NonChunk(content_hash),
);
}
res
}
RecordKind::Register => {
let register = try_deserialize_record::<SignedRegister>(&record)?;

Expand Down Expand Up @@ -282,6 +331,7 @@ impl Node {
match record_header.kind {
// A separate flow handles payment for chunks and registers
RecordKind::ChunkWithPayment
| RecordKind::TransactionWithPayment
| RecordKind::RegisterWithPayment
| RecordKind::ScratchpadWithPayment => {
warn!("Prepaid record came with Payment, which should be handled in another flow");
Expand Down
3 changes: 3 additions & 0 deletions ant-protocol/src/storage/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub enum RecordKind {
Chunk,
ChunkWithPayment,
Transaction,
TransactionWithPayment,
Register,
RegisterWithPayment,
Scratchpad,
Expand All @@ -54,6 +55,7 @@ impl Serialize for RecordKind {
Self::RegisterWithPayment => serializer.serialize_u32(4),
Self::Scratchpad => serializer.serialize_u32(5),
Self::ScratchpadWithPayment => serializer.serialize_u32(6),
Self::TransactionWithPayment => serializer.serialize_u32(7),
}
}
}
Expand All @@ -72,6 +74,7 @@ impl<'de> Deserialize<'de> for RecordKind {
4 => Ok(Self::RegisterWithPayment),
5 => Ok(Self::Scratchpad),
6 => Ok(Self::ScratchpadWithPayment),
7 => Ok(Self::TransactionWithPayment),
_ => Err(serde::de::Error::custom(
"Unexpected integer for RecordKind variant",
)),
Expand Down
Loading