This is the info for these aspects.
When the section experiences churn it triggers a relocation event. The relocated nodes get an increment to their age. The code is in sn_routing/src/relocation.rs.
/// Find all nodes to relocate after a churn event and create the relocate
/// actions for them.
...
// Find the peers that pass the relocation check and take only the oldest
// ones to avoid
// relocating too many nodes at the same time.
let candidates: Vec<_> = section
.members()
.joined()
.filter(|info| check(info.peer.age(), churn_signature))
.collect();
The nodes for relocation are chosen by the ones of age that matches the number of trailing zeros in the signature. Note there is no tiebreaker. All nodes matching that age are relocated. Maybe some risk here but probably not (source).
// Relocation check - returns whether a member with the given age is a
// candidate for relocation on
// a churn event with the given signature.
pub(crate) fn check(age: u8, churn_signature: &bls::Signature) -> bool {
// Evaluate the formula: `signature % 2^age == 0` Which is the same
// as checking the signature
// has at least `age` trailing zero bits.
trailing_zeros(&churn_signature.to_bytes()[..]) >= age as u32
}
The number of churn events needed to relocate is approximately double for each age, but may be more or may be less depending on chance.
On relocation those nodes age increments by 1 (source).
impl RelocateDetails {
pub(crate) fn new(
...
peer.age().saturating_add(1),
Each node from the relocation candidates are sent to a different section. This is chosen by the hash of the node name and the churned node (source)
// Compute the destination for the node with `relocating_name` to be
// relocated to. `churn_name` is
// the name of the joined/left node that triggered the relocation.
fn destination(relocating_name: &XorName, churn_name: &XorName) -> XorName {
let combined_name = xor(relocating_name, churn_name);
XorName(crypto::sha3_256(&combined_name.0))
}
Personally I would prefer to see this include the hash of the churn signature since it cannot be known in advance. If we use just these two node names then nodes can precompute their possible future relocation destinations and to me that seems like an unnecessary risk which could be avoided. Better to have their future destination remain a mystery until the churn happens.
The higher level details of relocations can be found in approved.rs, eg relocate_peers
is called whenever there is a handle_online_event
or handle_offline_event
.
It will be possible to know to some degree, but it’s not like it will be known network-wide as some sort of ‘globally available piece of information’. Nodes could calculate approximations.
eg elders could look at their list of full vaults and their not-full vaults and do some calcs on how much each vault is storing, what their section prefix is, assume other sections look roughly the same… so it’d be an approximate calc.
I don’t think adults or clients would be able to do this but maybe could derive some info from storecost? There may be a related question here about how uploaders can verify the storecost is legit, some analogy with bitcoin tx fees maybe… not sure and getting a bit far from the original point now!
We expect to see just less than 50% of nodes full most of the time. If there’s more than 50% full nodes new nodes will continuously join until it’s lower. If there’s significantly less than 50% full nodes then the existing nodes will (hopefully) fill fairly quickly since storage will be quite cheap. So it should always be very close to 50% full nodes.
I personally don’t like this mechanism, but for the testnet it’s simple enough and will allow tests to happen.
Data is distributed fairly evenly (more in chunk distribution within sections).
A node will become full if it’s smaller than half the other nodes in the section. If a node can always stay in the top half of the nodes it will probably never become full.
Depends a lot on how to interpret this. Spare capacity isn’t measured. Full vs not-full is measured. So if you mean both networks have 50% full nodes but one network has 1 PB spare but the other network has 100 PB spare, they would both have the same storecost and reward since the spare space is not incuded in the reward or storecost algorithm.
Spare space (which is not measured directly) has an indirect affect only on new membership, since a lot of spare space will take longer to reach 50% full nodes, it also takes longer before new nodes can join.