Skip to content
This repository has been archived by the owner on Jan 29, 2024. It is now read-only.

Commit

Permalink
set network address for validator (#69)
Browse files Browse the repository at this point in the history
  • Loading branch information
adlrocha authored Mar 20, 2023
1 parent 2648fb6 commit f5e54ad
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 0 deletions.
34 changes: 34 additions & 0 deletions subnet-actor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub enum Method {
Leave = frc42_dispatch::method_hash!("Leave"),
Kill = frc42_dispatch::method_hash!("Kill"),
SubmitCheckpoint = frc42_dispatch::method_hash!("SubmitCheckpoint"),
SetValidatorNetAddr = frc42_dispatch::method_hash!("SetValidatorNetAddr"),
Reward = frc42_dispatch::method_hash!("Reward"),
}

Expand Down Expand Up @@ -358,6 +359,38 @@ impl SubnetActor for Actor {
}
}

/// This impl includes methods that are not required by the subnet actor
/// trait.
impl Actor {
/// Sets a new net address to an existing validator
pub fn set_validator_net_addr(
rt: &mut impl Runtime,
params: JoinParams,
) -> Result<Option<RawBytes>, ActorError> {
rt.validate_immediate_caller_type(CALLER_TYPES_SIGNABLE.iter())?;
let caller = rt.message().caller();

rt.transaction(|st: &mut State, _rt| {
// if the caller is a validator allow him to change his net addr
if let Some(index) = st
.validator_set
.validators()
.iter()
.position(|x| x.addr == caller)
{
st.validator_set
.validators_mut()
.get_mut(index)
.map(|x| x.net_addr = params.validator_net_addr);
} else {
return Err(actor_error!(forbidden, "caller is not a validator"));
}
Ok(())
})?;
Ok(None)
}
}

impl ActorCode for Actor {
type Methods = Method;

Expand All @@ -368,5 +401,6 @@ impl ActorCode for Actor {
Kill => kill,
SubmitCheckpoint => submit_checkpoint,
Reward => reward,
SetValidatorNetAddr => set_validator_net_addr,
}
}
2 changes: 2 additions & 0 deletions subnet-actor/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ pub const TESTING_ID: u64 = 339;
#[derive(Clone, Debug, Serialize_tuple, Deserialize_tuple, PartialEq, Eq)]
pub struct Validator {
pub addr: Address,
// TODO: We currently support a single validator address for validators,
// in the future we should consider supporting more than one multiaddr.
pub net_addr: String,
// voting power for the validator determined by its stake in the
// network.
Expand Down
73 changes: 73 additions & 0 deletions subnet-actor/tests/actor_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,79 @@ mod test {
);
}

#[test]
fn test_set_net_addr_works() {
let mut runtime = construct_runtime();

let caller = Address::new_id(10);
let validator = Address::new_id(100);
let params = JoinParams {
validator_net_addr: validator.to_string(),
};
let gateway = Address::new_id(IPC_GATEWAY_ADDR);

// join
let value = TokenAmount::from_atto(MIN_COLLATERAL_AMOUNT);
runtime.set_value(value.clone());
runtime.set_balance(value.clone());
runtime.set_caller(*ACCOUNT_ACTOR_CODE_ID, caller.clone());
runtime.expect_validate_caller_type(SIG_TYPES.clone());
runtime.expect_send(
gateway.clone(),
ipc_gateway::Method::Register as u64,
None,
TokenAmount::from_atto(MIN_COLLATERAL_AMOUNT),
None,
ExitCode::new(0),
);
runtime
.call::<Actor>(
Method::Join as u64,
IpldBlock::serialize_cbor(&params).unwrap(),
)
.unwrap();

// modify net address
let new_addr = String::from("test_addr");
let params = JoinParams {
validator_net_addr: new_addr.clone(),
};

runtime.set_caller(*ACCOUNT_ACTOR_CODE_ID, caller.clone());
runtime.expect_validate_caller_type(SIG_TYPES.clone());
runtime
.call::<Actor>(
Method::SetValidatorNetAddr as u64,
IpldBlock::serialize_cbor(&params).unwrap(),
)
.unwrap();

let st: State = runtime.get_state();

if let Some(val) = st
.validator_set
.validators()
.iter()
.find(|x| x.addr == caller)
{
assert_eq!(val.net_addr, new_addr);
} else {
panic!("validator address not set correctly")
}

// user which is not a validator tries to change address
let caller = Address::new_id(11);
runtime.set_caller(*ACCOUNT_ACTOR_CODE_ID, caller.clone());
runtime.expect_validate_caller_type(SIG_TYPES.clone());
expect_abort(
ExitCode::USR_FORBIDDEN,
runtime.call::<Actor>(
Method::SetValidatorNetAddr as u64,
IpldBlock::serialize_cbor(&params).unwrap(),
),
);
}

#[test]
fn test_join_works() {
let mut runtime = construct_runtime();
Expand Down

0 comments on commit f5e54ad

Please sign in to comment.