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

540 change runtime resolve address to return an actorid #549

Merged
merged 19 commits into from
Aug 29, 2022

Conversation

lyswifter
Copy link
Contributor

@lyswifter lyswifter commented Aug 16, 2022

resolves #540

@lyswifter lyswifter linked an issue Aug 16, 2022 that may be closed by this pull request
@lyswifter
Copy link
Contributor Author

In some places, the code Address::new_id are not useful for network beside mainnet, the usage of NETWORK_DEFAULT maybe not reasonable I think.

@anorth
Copy link
Member

anorth commented Aug 16, 2022

That NETWORK_DEFAULT value looks like it's supposed to be set by a build flag. This implementation of Address differs from the Go one that it copied. I don't think we should worry about it here, but I can see potential problems for testnets.

@@ -234,7 +234,7 @@ impl Actor {
})?;

let code_id = rt
.get_actor_code_cid(&provider)
.get_actor_code_cid(&Address::new_id(provider))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, we've ended up with a bunch of places now where we resolve to an ID then immediately wrap it again for another syscall.

Here I think we should change get_actor_code_cid to take an ActorID too. You'll have to wrap it in an address one level lower to meet the SDK, but I'll try to get the SDK changed to match too, later.

@@ -244,7 +244,7 @@ impl Actor {
));
}

let (_, worker, controllers) = request_miner_control_addrs(rt, provider)?;
let (_, worker, controllers) = request_miner_control_addrs(rt, Address::new_id(provider))?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change request_miner_control_addrs to accept an ActorID and wrap it lower down.

let mut client_lockup =
total_client_lockup.get(&client_id).cloned().unwrap_or_default();
client_lockup += deal.proposal.client_balance_requirement();

let client_balance_ok = msm.balance_covered(client, &client_lockup).map_err(|e| {
let client_balance_ok = msm.balance_covered(Address::new_id(client_id), &client_lockup).map_err(|e| {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, it's a good prompt to only use resolved addresses for lookups

@@ -4025,7 +4025,7 @@ where
));
}

Ok(resolved)
Ok(Address::new_id(resolved))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably just return the ActorID here, unless that causes lots of churn at caller.s

actors/miner/src/lib.rs Show resolved Hide resolved
@@ -147,7 +147,7 @@ impl Actor {
sv.channel_addr
)
})?;
if pch_addr != svpch_id_addr {
if pch_addr != Address::new_id(svpch_id_addr) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative here, where we know we have an ID address, is
pch_addr.id().unwrap() == svpch_id

The unwrap is a bit unpleasant and kinda points to us later changing message.receiver() to return the actor ID too. But it's probably better than wrapping all the time. I could be convinced otherwise. Any thoughts @ZenGround0 ?

@@ -25,17 +26,19 @@ where
{
// if we are able to resolve it to an ID address, return the resolved address
if let Some(addr) = rt.resolve_address(address) {
return Ok(addr);
return Ok(Address::new_id(addr));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we change this to return ActorID? Would that cause lots of noise at callers?

@lyswifter
Copy link
Contributor Author

I had changed get_actor_code_cid to receive an ActorID as input, you could have a check.
By the way I don't know why the first CI was failed for this PR, could you give me some tips?

Copy link
Member

@anorth anorth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, getting close now. There are still some wrappings we could purge, but I'm happy to do them incrementally after landing this.

Err(e) => {
return Err(actor_error!(forbidden; "caller {} transfer to id address is not support, {}", caller_addr, e))
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace this with rt.message().caller().id().unwrap(). The syscall guarantees this will work. The same goes for message().receiver() and a number of other places where the runtime makes this promise.

(We might later consider caller() returning an ID, but that would be a larger change)

let mut client_lockup =
total_client_lockup.get(&client_id).cloned().unwrap_or_default();
client_lockup += deal.proposal.client_balance_requirement();

let client_balance_ok = msm.balance_covered(client, &client_lockup).map_err(|e| {
let client_balance_ok = msm.balance_covered(Address::new_id(client_id), &client_lockup).map_err(|e| {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change balance_covered to accept an ActorID

@@ -1307,17 +1306,19 @@ where
.resolve_address(addr)
.ok_or_else(|| actor_error!(illegal_argument, "failed to resolve address {}", addr))?;

let nominal_addr = Address::new_id(nominal);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this down to just before its first use.

@@ -306,6 +306,8 @@ impl Actor {
)
})?;

let resolved_new_signer = Address::new_id(resolved_new_signer);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change is_signer to take an ActorID instead, then just inline this new_id call when pushing onto st.signers.

Err(e) => {
return Err(actor_error!(forbidden; "caller {} transfer to id address is not support, {}", caller_addr, e))
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just unwrap(), the VM guarantees this

match self.get_id_address(address) {
None => None,
Some(addr) => {
if let &Payload::ID(id) = addr.payload() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can't fail, can it? Just unwrap()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe for some tests unable_to_resolve_client_address, we should reserve this. How do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree we need the match block for get_id_address. If it fails to resolve, it should return none. But if it returns Some then the value must be an ID address that we can unwrap.

self.v.normalize_address(addr)
fn resolve_address(&self, addr: &Address) -> Option<ActorID> {
if let Some(normalize_addr) = self.v.normalize_address(addr) {
if let &Payload::ID(id) = normalize_addr.payload() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unwrap

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This maybe also need reserve for some tests

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same. We need the outer if let, but the inner one can't fail.

@lyswifter
Copy link
Contributor Author

you can take a look at those changes

Copy link
Member

@anorth anorth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this is looking good to me now. I will request a second look from @ZenGround0. We don't need to fully push through IDs everywhere and I think this provides a good balance.

match self.get_id_address(address) {
None => None,
Some(addr) => {
if let &Payload::ID(id) = addr.payload() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree we need the match block for get_id_address. If it fails to resolve, it should return none. But if it returns Some then the value must be an ID address that we can unwrap.

self.v.normalize_address(addr)
fn resolve_address(&self, addr: &Address) -> Option<ActorID> {
if let Some(normalize_addr) = self.v.normalize_address(addr) {
if let &Payload::ID(id) = normalize_addr.payload() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same. We need the outer if let, but the inner one can't fail.

@anorth anorth requested a review from ZenGround0 August 17, 2022 22:12
@anorth
Copy link
Member

anorth commented Aug 17, 2022

Build is failing due to formatting. Run cargo fmt to fix

@jennijuju jennijuju requested a review from anorth August 19, 2022 02:24
Copy link
Member

@anorth anorth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't merge until @ZenGround0 has time to take a look.

Copy link
Contributor

@ZenGround0 ZenGround0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only thing I'm worried about is the change to the test, if the test isn't actually broken this is good to go. The other comments are all nitpicking. It would be very nice if you change all ActorID typed variables and related function names to have names that are not x_addr but instead x_id since addresses and actor ids are distinct.

@@ -53,14 +53,14 @@ fil_actors_runtime::wasm_trampoline!(Actor);

fn request_miner_control_addrs<BS, RT>(
rt: &mut RT,
miner_addr: Address,
miner_addr: ActorID,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

miner_id

@@ -235,7 +235,7 @@ impl Actor {

let code_id = rt
.get_actor_code_cid(&provider)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: change name above to provider_id

@@ -25,7 +25,7 @@ pub struct CreateActorArgs {
/// Holds the response of a call to runtime.ResolveAddress
#[derive(Serialize_tuple, Deserialize_tuple)]
pub struct ResolveAddressResponse {
pub address: Address,
pub address: ActorID,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pub id: ActorID

@@ -528,15 +529,17 @@ where
// Return true when the funds in escrow for the input address can cover an additional lockup of amountToLock
pub(super) fn balance_covered(
&self,
addr: Address,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Since this is keyed by address it would make sense for this code to expect an address, not change its internal logic to better adapt to the caller.

deal.verified_deal = true;

// add funds for cient using it's BLS address -> will be resolved and persisted
add_participant_funds(&mut rt, client_bls, deal.client_balance_requirement());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking: What's going on here? I don't think this change should break this test?

@@ -147,7 +147,7 @@ impl Actor {
sv.channel_addr
)
})?;
if pch_addr != svpch_id_addr {
if pch_addr.id().unwrap() != svpch_id_addr {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: its a bit nicer to make svpch_id_addr an address to do the comparison because then there is no code path to panic

ALso svpch_id not svpch_id_addr

@@ -158,7 +159,7 @@ impl Actor {
// if this fails, we can assume the miner is responsible and avoid failing here.
let reward_params = ext::miner::ApplyRewardParams { reward: total_reward.clone(), penalty };
let res = rt.send(
miner_addr,
Address::new_id(miner_addr),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

miner_id

@@ -436,6 +444,8 @@ impl Actor {
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change the name of the above resolve_to_id_addr to resolve_to_id or resolve_addr_to_id or resolve_to_actor_id

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change comment "failed to resolve addr {} to ID"

address,
)
})
if let Some(addr) = rt.resolve_address(address) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some(id)

pub fn is_signer(&self, address: &Address) -> bool {
self.signers.contains(address)
pub fn is_signer(&self, id: &ActorID) -> bool {
self.signers.contains(&Address::new_id(*id))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is to act as a level of protection to ensure that we don't do bogus checks of non id addresses against addresses that are resolved to id addresses.

If we go this route why not also do this on purge_approvals? This also implies we should add st accessors for push, retain etc that take ActorIDs and do the address wrapping internal to the state.

You could also argue that this is unnecessary and then this could go back to taking in an address. It would be good to be consistent.

@lyswifter
Copy link
Contributor Author

@ZenGround0 I had do some modifies to your suggestions,you can have a review.

@ZenGround0
Copy link
Contributor

Changes look good but the test is still modified, I'm guessing its failing and need to investigate why before approving.

@@ -729,7 +729,8 @@ fn provider_and_client_addresses_are_resolved_before_persisting_state_and_sent_t
let end_epoch = start_epoch + 200 * EPOCHS_IN_DAY;
rt.set_epoch(start_epoch);

let mut deal = generate_deal_proposal(client_bls, provider_bls, start_epoch, end_epoch);
let mut deal =
generate_deal_proposal(client_resolved, provider_resolved, start_epoch, end_epoch);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Undo all changes to this file. The point of this test is to use the bls addresses to make sure the actor resolves things correctly. Your code change doesn't break this test.

@@ -374,7 +374,7 @@ fn fail_to_resolve_provider_address() {

let mut rt = setup();
let mut deal = generate_deal_proposal(CLIENT_ADDR, PROVIDER_ADDR, start_epoch, end_epoch);
deal.provider = new_bls_addr(100);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Undo this change as well please.

@lyswifter
Copy link
Contributor Author

I did some fixes and revert the client and provider address to its original, you can take a check @ZenGround0

@anorth anorth enabled auto-merge (squash) August 29, 2022 02:38
@anorth anorth merged commit d19f9ff into master Aug 29, 2022
@anorth anorth deleted the 540-change-runtime-resolve_address-to-return-an-actorid branch August 29, 2022 03:03
Stebalien pushed a commit that referenced this pull request Aug 31, 2022
Co-authored-by: lyswifter <ly70835@163.com>
shamb0 pushed a commit to shamb0/builtin-actors that referenced this pull request Jan 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Change Runtime resolve_address to return an ActorID
3 participants