Skip to content

Commit 7d8161c

Browse files
vm2 transfer to entity
1 parent b3d6bf3 commit 7d8161c

7 files changed

Lines changed: 114 additions & 31 deletions

File tree

executor/wasm/tests/integration.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use casper_executor_wasm_interface::executor::{
2828
MintMethods, SystemMenu,
2929
};
3030

31-
use casper_executor_wasm::testing::DEFAULT_STABLE_DELEGATOR_PUBLIC_KEY;
31+
use casper_executor_wasm::testing::{DEFAULT_CHAIN_NAME, DEFAULT_STABLE_DELEGATOR_PUBLIC_KEY};
3232
use casper_storage::{
3333
data_access_layer::{
3434
prefixed_values::{PrefixedValuesRequest, PrefixedValuesResult},
@@ -44,6 +44,7 @@ use casper_storage::{
4444

4545
use casper_types::{
4646
account::AccountHash,
47+
bytesrepr::ToBytes,
4748
execution::RetValue,
4849
system::auction::{BidAddr, BidKind},
4950
BlockHash, BlockTime, Digest, EntityAddr, Key, RuntimeArgs, StoredValue, Timestamp,
@@ -274,6 +275,11 @@ fn should_call_system_transfer() {
274275
exec_system_call(SystemMenu::Mint(MintMethods::Transfer), None);
275276
}
276277

278+
#[test]
279+
fn should_call_system_transfer_purse() {
280+
exec_system_call(SystemMenu::Mint(MintMethods::TransferPurse), None);
281+
}
282+
277283
#[test]
278284
fn should_call_system_burn() {
279285
exec_system_call(SystemMenu::Mint(MintMethods::Burn), None);
@@ -1312,7 +1318,7 @@ fn supports_named_args_convention() {
13121318
.with_caller_key(Key::Account(*DEFAULT_ACCOUNT_HASH))
13131319
.with_gas_limit(DEFAULT_GAS_LIMIT)
13141320
.with_transaction_hash(TRANSACTION_HASH)
1315-
.with_target(ExecutionKind::Stored {
1321+
.with_execution_kind(ExecutionKind::Stored {
13161322
address: *contract_hash,
13171323
entry_point: "deposit_tokens".to_string(),
13181324
})

executor/wasm_host/src/host.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -986,7 +986,9 @@ pub fn casper_system<S: GlobalStateReader + 'static, E: Executor + 'static>(
986986
let cost = match &option {
987987
SystemMenu::Mint(mint_opt) => match mint_opt {
988988
MintMethods::Burn => caller.context().mint_costs.burn as u64,
989-
MintMethods::Transfer => caller.context().mint_costs.transfer as u64,
989+
MintMethods::Transfer | MintMethods::TransferPurse => {
990+
caller.context().mint_costs.transfer as u64
991+
}
990992
},
991993
SystemMenu::Auction(auction_opt) => match auction_opt {
992994
AuctionMethods::Activate => caller.context().auction_costs.activate_bid,

executor/wasm_host/src/system.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,66 @@ pub fn native_exec<A, T: ToBytes, R: GlobalStateReader + 'static>(
667667
}
668668
}
669669
MintMethods::Transfer => {
670+
let ret = bytesrepr::deserialize_from_slice::<&Bytes, (EntityAddr, u64)>(&input);
671+
if let Err(err) = &ret {
672+
debug!(?err, "bytesrepr error in native_exec Transfer");
673+
}
674+
let unpacked = ret.map_err(|_err| {
675+
ExecuteError::InternalHost(InternalHostError::TypeConversion)
676+
})?;
677+
let target_entity = unpacked.0;
678+
if target_entity.is_system() {
679+
debug!("attempt to pass system address from userland");
680+
return Err(ExecuteError::InternalHost(
681+
InternalHostError::InvalidEntityAddr,
682+
));
683+
}
684+
685+
let target = match tracking_copy.runtime_footprint_by_entity_addr(target_entity) {
686+
Ok(target_runtime_footprint) => match target_runtime_footprint.main_purse() {
687+
Some(target_purse) => URef::new(target_purse.addr(), AccessRights::ADD),
688+
None => {
689+
return Err(ExecuteError::InternalHost(
690+
InternalHostError::UnexpectedEntityKind,
691+
))
692+
}
693+
},
694+
Err(err) => {
695+
debug!(
696+
?err,
697+
?target_entity,
698+
"runtime_footprint_by_entity_addr failed"
699+
);
700+
return Err(ExecuteError::InternalHost(InternalHostError::TrackingCopy));
701+
}
702+
};
703+
704+
let source = match tracking_copy.main_purse_by_key(&caller_key) {
705+
Ok(uref) => uref,
706+
Err(err) => return Err(ExecuteError::Api(err.to_string())),
707+
};
708+
709+
let args = TransferArgs::new(
710+
runtime_native_config,
711+
transaction_hash,
712+
Arc::clone(&address_generator),
713+
initiator,
714+
caller_key,
715+
gas_usage.remaining_points().into(),
716+
source,
717+
target,
718+
// amount
719+
unpacked.1.into(),
720+
);
721+
match system::transfer(&mut tracking_copy, runtime_footprint, args) {
722+
Ok(ret) => match ret.to_bytes() {
723+
Ok(ret_bytes) => Ok(Some(Bytes::from(ret_bytes))),
724+
Err(_) => Err(DispatchError::Api(ApiError::Formatting)),
725+
},
726+
Err(err) => Err(err),
727+
}
728+
}
729+
MintMethods::TransferPurse => {
670730
let ret = bytesrepr::deserialize_from_slice::<&Bytes, (URefAddr, u64)>(&input);
671731
if let Err(err) = &ret {
672732
debug!(?err, "bytesrepr error in native_exec Transfer");

executor/wasm_interface/src/executor.rs

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ impl ExecuteWithProviderResult {
363363
pub enum MintMethods {
364364
Burn,
365365
Transfer,
366+
TransferPurse,
366367
}
367368

368369
/// Available options for interacting with the system auction.
@@ -390,30 +391,20 @@ impl TryFrom<u32> for SystemMenu {
390391
type Error = ();
391392

392393
fn try_from(value: u32) -> Result<Self, Self::Error> {
393-
if value == 0 {
394-
Ok(SystemMenu::Mint(MintMethods::Transfer))
395-
} else if value == 1 {
396-
Ok(SystemMenu::Mint(MintMethods::Burn))
397-
} else if value == 100 {
398-
Ok(SystemMenu::Auction(AuctionMethods::Activate))
399-
} else if value == 101 {
400-
Ok(SystemMenu::Auction(AuctionMethods::Bid))
401-
} else if value == 102 {
402-
Ok(SystemMenu::Auction(AuctionMethods::Withdraw))
403-
} else if value == 103 {
404-
Ok(SystemMenu::Auction(AuctionMethods::Delegate))
405-
} else if value == 104 {
406-
Ok(SystemMenu::Auction(AuctionMethods::Undelegate))
407-
} else if value == 105 {
408-
Ok(SystemMenu::Auction(AuctionMethods::Redelegate))
409-
} else if value == 106 {
410-
Ok(SystemMenu::Auction(AuctionMethods::AddReservation))
411-
} else if value == 107 {
412-
Ok(SystemMenu::Auction(AuctionMethods::CancelReservation))
413-
} else if value == 108 {
414-
Ok(SystemMenu::Auction(AuctionMethods::ChangePublicKey))
415-
} else {
416-
Err(())
394+
match value {
395+
0 => Ok(SystemMenu::Mint(MintMethods::Transfer)),
396+
1 => Ok(SystemMenu::Mint(MintMethods::TransferPurse)),
397+
2 => Ok(SystemMenu::Mint(MintMethods::Burn)),
398+
100 => Ok(SystemMenu::Auction(AuctionMethods::Activate)),
399+
101 => Ok(SystemMenu::Auction(AuctionMethods::Bid)),
400+
102 => Ok(SystemMenu::Auction(AuctionMethods::Withdraw)),
401+
103 => Ok(SystemMenu::Auction(AuctionMethods::Delegate)),
402+
104 => Ok(SystemMenu::Auction(AuctionMethods::Undelegate)),
403+
105 => Ok(SystemMenu::Auction(AuctionMethods::Redelegate)),
404+
106 => Ok(SystemMenu::Auction(AuctionMethods::AddReservation)),
405+
107 => Ok(SystemMenu::Auction(AuctionMethods::CancelReservation)),
406+
108 => Ok(SystemMenu::Auction(AuctionMethods::ChangePublicKey)),
407+
_ => Err(()),
417408
}
418409
}
419410
}
@@ -423,7 +414,8 @@ impl From<SystemMenu> for u32 {
423414
match value {
424415
SystemMenu::Mint(mint) => match mint {
425416
MintMethods::Transfer => 0,
426-
MintMethods::Burn => 1,
417+
MintMethods::TransferPurse => 1,
418+
MintMethods::Burn => 2,
427419
},
428420
SystemMenu::Auction(auction) => match auction {
429421
AuctionMethods::Activate => 100,

executor/wasm_interface/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ pub enum InternalHostError {
123123
ConfigBuilderError(String),
124124
#[error("invalid public key")]
125125
InvalidPublicKey,
126+
#[error("invalid entity address")]
127+
InvalidEntityAddr,
126128
}
127129

128130
/// The outcome of a call.

smart_contracts/contracts/vm2/vm2-system-caller/src/lib.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ pub mod exports {
55
casper::{casper_system, ret},
66
casper_executor_wasm_common::flags::ReturnFlags,
77
prelude::*,
8-
types::{DelegatorKind, PublicKey, Reservation, SystemContractOption},
8+
types::{DelegatorKind, EntityAddr, PublicKey, Reservation, SystemContractOption},
99
};
1010

1111
#[casper(export)]
@@ -21,6 +21,15 @@ pub mod exports {
2121
};
2222
let input = match option {
2323
SystemContractOption::Transfer => {
24+
let entity_addr = EntityAddr::Account([
25+
158, 17, 242, 57, 55, 151, 207, 10, 36, 74, 126, 15, 148, 172, 106, 131, 189,
26+
124, 170, 34, 9, 239, 243, 182, 232, 2, 20, 162, 136, 218, 113, 238,
27+
]);
28+
let input =
29+
borsh::to_vec(&(entity_addr, 100u64)).expect("Serialization to succeed");
30+
Some(input)
31+
}
32+
SystemContractOption::TransferPurse => {
2433
let uref_addr: casper_contract_sdk::types::Address = [
2534
134, 139, 79, 97, 16, 65, 173, 186, 126, 93, 235, 111, 229, 224, 29, 144, 186,
2635
66, 74, 244, 236, 214, 63, 64, 207, 67, 100, 16, 45, 199, 96, 170,

smart_contracts/sdk/src/types.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ impl From<AddressSecp256k1> for PublicKey {
4444
}
4545
}
4646

47+
#[repr(u32)]
48+
#[derive(Debug, Copy, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
49+
#[borsh(crate = "crate::serializers::borsh", use_discriminant = true)]
50+
pub enum EntityAddr {
51+
/// PublicKey bytes.
52+
Account(Address) = 1,
53+
/// Purse address bytes.
54+
SmartContract(Address) = 2,
55+
}
56+
4757
#[repr(u32)]
4858
#[derive(Debug, Copy, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
4959
#[borsh(crate = "crate::serializers::borsh", use_discriminant = true)]
@@ -83,7 +93,8 @@ impl Reservation {
8393
#[repr(u32)]
8494
pub enum SystemContractOption {
8595
Transfer = 0,
86-
Burn = 1,
96+
TransferPurse = 1,
97+
Burn = 2,
8798
ActivateBid = 100,
8899
Bid = 101,
89100
Withdraw = 102,
@@ -107,7 +118,8 @@ impl TryFrom<u32> for SystemContractOption {
107118
fn try_from(value: u32) -> Result<Self, Self::Error> {
108119
match value {
109120
0 => Ok(SystemContractOption::Transfer),
110-
1 => Ok(SystemContractOption::Burn),
121+
1 => Ok(SystemContractOption::TransferPurse),
122+
2 => Ok(SystemContractOption::Burn),
111123
100 => Ok(SystemContractOption::ActivateBid),
112124
101 => Ok(SystemContractOption::Bid),
113125
102 => Ok(SystemContractOption::Withdraw),

0 commit comments

Comments
 (0)