Skip to content
This repository was archived by the owner on Apr 9, 2024. It is now read-only.

Commit 34518b1

Browse files
committed
fix: from items must not contain the to item.
1 parent 5390a4b commit 34518b1

File tree

3 files changed

+57
-2
lines changed

3 files changed

+57
-2
lines changed

core/rpc/core/src/error.rs

+4
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ pub enum CoreError {
124124

125125
#[display(fmt = "Invalid tx prebuilt {}", _0)]
126126
InvalidTxPrebuilt(String),
127+
128+
#[display(fmt = "From items must not contain the to item")]
129+
FromContainTo,
127130
}
128131

129132
impl RpcError for CoreError {
@@ -166,6 +169,7 @@ impl RpcError for CoreError {
166169
CoreError::CannotFindACPCell => -10052,
167170
CoreError::TransferAmountMustPositive => -10053,
168171
CoreError::InvalidFeeChange => -10054,
172+
CoreError::FromContainTo => -10055,
169173

170174
CoreError::UDTIsNotEnough => -10060,
171175

core/rpc/core/src/impl/build_tx.rs

+32-2
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,15 @@ impl<C: CkbRpc> MercuryRpcImpl<C> {
562562
utils::check_same_enum_value(payload.from.items.iter().collect())?;
563563
let mut payload = payload;
564564
payload.from.items = utils::dedup_json_items(payload.from.items);
565-
565+
self.check_from_contain_to(
566+
payload.from.items.iter().collect(),
567+
payload
568+
.to
569+
.to_infos
570+
.iter()
571+
.map(|to_info| to_info.address.to_owned())
572+
.collect(),
573+
)?;
566574
for to_info in &payload.to.to_infos {
567575
match u128::from_str(&to_info.amount) {
568576
Ok(amount) => {
@@ -1569,13 +1577,35 @@ impl<C: CkbRpc> MercuryRpcImpl<C> {
15691577
if payload.from.len() > MAX_ITEM_NUM || payload.to.len() > MAX_ITEM_NUM {
15701578
return Err(CoreError::ExceedMaxItemNum.into());
15711579
}
1572-
15731580
let mut from_items = vec![];
15741581
for address in &payload.from {
15751582
let identity = utils::address_to_identity(address)?;
15761583
from_items.push(JsonItem::Identity(identity.encode()));
15771584
}
15781585
from_items = utils::dedup_json_items(from_items);
1586+
self.check_from_contain_to(
1587+
from_items.iter().collect(),
1588+
payload
1589+
.to
1590+
.iter()
1591+
.map(|to_info| to_info.address.to_owned())
1592+
.collect(),
1593+
)?;
1594+
for to_info in &payload.to {
1595+
match u128::from_str(&to_info.amount) {
1596+
Ok(amount) => {
1597+
if amount == 0u128 {
1598+
return Err(CoreError::TransferAmountMustPositive.into());
1599+
}
1600+
}
1601+
Err(_) => {
1602+
return Err(CoreError::InvalidRpcParams(
1603+
"To amount should be a valid u128 number".to_string(),
1604+
)
1605+
.into());
1606+
}
1607+
}
1608+
}
15791609

15801610
let mut to_items = vec![];
15811611
for ToInfo { address, .. } in &payload.to {

core/rpc/core/src/impl/utils.rs

+21
Original file line numberDiff line numberDiff line change
@@ -2827,6 +2827,27 @@ impl<C: CkbRpc> MercuryRpcImpl<C> {
28272827
}
28282828
false
28292829
}
2830+
2831+
pub(crate) fn check_from_contain_to(
2832+
&self,
2833+
from_items: Vec<&JsonItem>,
2834+
to_addresses: Vec<String>,
2835+
) -> InnerResult<()> {
2836+
let mut from_secp_lock_args_set = HashSet::new();
2837+
for json_item in from_items {
2838+
let item = Item::try_from(json_item.to_owned())?;
2839+
let args = self.get_secp_lock_args_by_item(item)?;
2840+
from_secp_lock_args_set.insert(args);
2841+
}
2842+
for to_address in to_addresses {
2843+
let to_item = Item::Identity(address_to_identity(&to_address)?);
2844+
let to_secp_lock_args = self.get_secp_lock_args_by_item(to_item)?;
2845+
if from_secp_lock_args_set.contains(&to_secp_lock_args) {
2846+
return Err(CoreError::FromContainTo.into());
2847+
}
2848+
}
2849+
Ok(())
2850+
}
28302851
}
28312852

28322853
pub(crate) fn is_dao_withdraw_unlock(

0 commit comments

Comments
 (0)