-
Notifications
You must be signed in to change notification settings - Fork 0
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
Feature: move partitions #8
base: master
Are you sure you want to change the base?
Changes from 7 commits
924722e
da95dbb
e502709
eaf5370
2fa9693
8725420
d534373
36caece
badb691
fd39aac
daab781
0271369
c046cc6
3eac91e
181dc2e
8eb2243
394ea44
d1fdb0f
0804565
0353a28
bc9e6a1
c1d88a2
37d7d03
89bcb74
79ab15d
39d6447
0bd0611
c01b54c
ccdb45f
b775fa8
a5290cc
bf13558
9195aa1
70fd5fe
511e170
d16077c
9ed53b8
15d5ac1
5744223
e8f0a22
194b7cd
5e400d2
c1159c5
cb5e3c4
faa4873
7bc1156
f7b7bd7
3b25fdc
f3ddb23
9c8517a
3c6a374
271e3c0
d2202ab
d276241
b2dc66c
fcc4cc0
7619065
6e91261
9964257
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -128,6 +128,7 @@ pub enum Method { | |
ChangeBeneficiary = 30, | ||
GetBeneficiary = 31, | ||
ExtendSectorExpiration2 = 32, | ||
MovePartitions = 33, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 类似下面,用exported方法 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 相当于hash一个方法数出来 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. frc42规范是这样的 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这个知道,我指的是什么情况需要用exported方法?因为CompactPartitions也没用。貌似exported方法的好处是可以从evm调,暂时应该还没这个需求。 |
||
// Method numbers derived from FRC-0042 standards | ||
ChangeWorkerAddressExported = frc42_dispatch::method_hash!("ChangeWorkerAddress"), | ||
ChangePeerIDExported = frc42_dispatch::method_hash!("ChangePeerID"), | ||
|
@@ -2995,6 +2996,297 @@ impl Actor { | |
Ok(()) | ||
} | ||
|
||
fn move_partitions( | ||
rt: &impl Runtime, | ||
mut params: MovePartitionsParams, | ||
) -> Result<(), ActorError> { | ||
let policy = rt.policy(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 可以挪到第一个条件下面 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
if params.from_deadline == params.to_deadline { | ||
return Err(actor_error!(illegal_argument, "from_deadline == to_deadline")); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could be deleted if we fail it when !deadline_available_for_move earlier (before the transaction handling). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as reply for |
||
if params.from_deadline >= policy.wpost_period_deadlines | ||
|| params.to_deadline >= policy.wpost_period_deadlines | ||
{ | ||
return Err(actor_error!( | ||
illegal_argument, | ||
"invalid deadline {}", | ||
if params.from_deadline >= policy.wpost_period_deadlines { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 直接返回from/to就行了,用户自行判断 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
params.from_deadline | ||
} else { | ||
params.to_deadline | ||
} | ||
)); | ||
} | ||
|
||
let partitions = &mut params.partitions; | ||
|
||
rt.transaction(|state: &mut State, rt| { | ||
let info = get_miner_info(rt.store(), state)?; | ||
|
||
rt.validate_immediate_caller_is(&[info.worker, info.owner])?; | ||
|
||
let store = rt.store(); | ||
let current_deadline = state.deadline_info(policy, rt.curr_epoch()); | ||
let mut deadlines = | ||
state.load_deadlines(store).map_err(|e| e.wrap("failed to load deadlines"))?; | ||
|
||
// only try to do synchronous Window Post verification if from_deadline doesn't satisfy deadline_available_for_compaction | ||
if !deadline_available_for_compaction( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 建议把这些检查都封装到move里面,这里调一下move函数,函数有点太长了,deadline_available_for_compaction最后也抽到deadline_available_for_move里面,毕竟还是两个功能,现在可以套用,以后不一定可以套用。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 主要是verify_windowed_post篇幅比较长,另外2处verify_windowed_post也是这个风格,先跟风下-_-b There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这里两个check后续的处理不一样,所以没法合成一个判断。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 还是说指的是to_deadline的deadline_available_for_compaction判断?那个倒是可以跟deadline_available_for_move合并,不过错误消息要改下 |
||
policy, | ||
current_deadline.period_start, | ||
params.from_deadline, | ||
rt.curr_epoch(), | ||
) { | ||
// the heavy path: try to do synchronous Window Post verification | ||
|
||
// current deadline must be in the dispute window to satisfy the condition of synchronous Window POST verification | ||
if !deadline_available_for_optimistic_post_dispute( | ||
policy, | ||
current_deadline.period_start, | ||
params.from_deadline, | ||
rt.curr_epoch(), | ||
) { | ||
return Err(actor_error!( | ||
forbidden, | ||
"cannot move from deadline {} when !deadline_available_for_compaction && !deadline_available_for_optimistic_post_dispute", | ||
params.from_deadline | ||
)); | ||
} | ||
|
||
|
||
let dl_current = deadlines | ||
.load_deadline(policy, rt.store(), params.from_deadline) | ||
.map_err(|e| { | ||
e.downcast_default(ExitCode::USR_ILLEGAL_STATE, "failed to load deadline") | ||
})?; | ||
|
||
let proofs_snapshot = | ||
dl_current.optimistic_proofs_snapshot_amt(store).map_err(|e| { | ||
e.downcast_default( | ||
ExitCode::USR_ILLEGAL_STATE, | ||
"failed to load proofs snapshot", | ||
) | ||
})?; | ||
|
||
let partitions_snapshot = | ||
dl_current.partitions_snapshot_amt(store).map_err(|e| { | ||
e.downcast_default( | ||
ExitCode::USR_ILLEGAL_STATE, | ||
"failed to load partitions snapshot", | ||
) | ||
})?; | ||
|
||
// Load sectors for the dispute. | ||
let sectors = | ||
Sectors::load(rt.store(), &dl_current.sectors_snapshot).map_err(|e| { | ||
e.downcast_default( | ||
ExitCode::USR_ILLEGAL_STATE, | ||
"failed to load sectors array", | ||
) | ||
})?; | ||
|
||
proofs_snapshot | ||
.for_each(|_, window_proof| { | ||
let mut all_sectors = | ||
Vec::<BitField>::with_capacity(window_proof.partitions.len() as usize); | ||
let mut all_ignored = | ||
Vec::<BitField>::with_capacity(window_proof.partitions.len() as usize); | ||
|
||
for partition_idx in window_proof.partitions.iter() { | ||
let partition = partitions_snapshot | ||
.get(partition_idx) | ||
.map_err(|e| { | ||
e.downcast_default( | ||
ExitCode::USR_ILLEGAL_STATE, | ||
"failed to load partitions snapshot for proof", | ||
) | ||
})? | ||
.ok_or_else(|| { | ||
actor_error!( | ||
illegal_state, | ||
"failed to load partitions snapshot for proof" | ||
) | ||
})?; | ||
all_sectors.push(partition.sectors.clone()); | ||
all_ignored.push(partition.terminated.clone()); | ||
// fail early since remove_partitions will fail when there're faults anyway. | ||
if !partition.faults.is_empty() { | ||
return Err(anyhow::anyhow!("unable to do synchronous Window POST verification while there're faults in from deadline {}", | ||
params.from_deadline | ||
)); | ||
} | ||
} | ||
|
||
// Load sector infos for proof, substituting a known-good sector for known-faulty sectors. | ||
// Note: this is slightly sub-optimal, loading info for the recovering sectors again after they were already | ||
// loaded above. | ||
let sector_infos = sectors | ||
.load_for_proof( | ||
&BitField::union(&all_sectors), | ||
&BitField::union(&all_ignored), | ||
) | ||
.map_err(|e| { | ||
e.downcast_default( | ||
ExitCode::USR_ILLEGAL_STATE, | ||
"failed to load sectors for post verification", | ||
) | ||
})?; | ||
if !verify_windowed_post( | ||
rt, | ||
current_deadline.challenge, | ||
§or_infos, | ||
window_proof.proofs.clone(), | ||
) | ||
.map_err(|e| e.wrap("window post failed"))? | ||
{ | ||
return Err(actor_error!( | ||
illegal_argument, | ||
"invalid post was submitted" | ||
) | ||
.into()); | ||
} | ||
Ok(()) | ||
}) | ||
.map_err(|e| { | ||
e.downcast_default(ExitCode::USR_ILLEGAL_STATE, "while removing partitions") | ||
})?; | ||
} | ||
|
||
if !deadline_available_for_compaction( | ||
policy, | ||
current_deadline.period_start, | ||
params.to_deadline, | ||
rt.curr_epoch(), | ||
) { | ||
return Err(actor_error!( | ||
forbidden, | ||
"cannot move to deadline {} during its challenge window, \ | ||
or the prior challenge window, | ||
or before {} epochs have passed since its last challenge window ended", | ||
params.to_deadline, | ||
policy.wpost_dispute_window | ||
)); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this still required if we had done the verification of PoSt? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We only do the verification of from_deadline, but not to_deadline. It's obviously forbidden to change deadline partitions during deadline window and challenge window, not so sure about whether it's possible to allow modifications to the partition during the dispute window though. But the original |
||
|
||
if !deadline_available_for_move( | ||
policy, | ||
params.from_deadline, | ||
params.to_deadline, | ||
current_deadline.index, | ||
) { | ||
return Err(actor_error!( | ||
forbidden, | ||
"cannot move to a deadline which is further from current deadline" | ||
)); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we move this before the transaction handling? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops, seems not , because |
||
|
||
let from_quant = state.quant_spec_for_deadline(policy, params.from_deadline); | ||
let to_quant = state.quant_spec_for_deadline(policy, params.to_deadline); | ||
|
||
let mut from_deadline = | ||
deadlines.load_deadline(policy, store, params.from_deadline).map_err(|e| { | ||
e.downcast_default( | ||
ExitCode::USR_ILLEGAL_STATE, | ||
format!("failed to load deadline {}", params.from_deadline), | ||
) | ||
})?; | ||
let mut to_deadline = | ||
deadlines.load_deadline(policy, store, params.to_deadline).map_err(|e| { | ||
e.downcast_default( | ||
ExitCode::USR_ILLEGAL_STATE, | ||
format!("failed to load deadline {}", params.to_deadline), | ||
) | ||
})?; | ||
|
||
if partitions.len() == 0 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这个条件检查可以挪到前面么 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 0等于全是吗 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 挪到 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 可以上面定义的变量拿到这里吗,定义和使用贴近一点。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 对的,0等于全 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
这些变量下面也要用到。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
let partitions_amt = from_deadline.partitions_amt(rt.store()).map_err(|e| { | ||
e.downcast_default( | ||
ExitCode::USR_ILLEGAL_STATE, | ||
format!("failed to load partitions for deadline {}", params.from_deadline), | ||
) | ||
})?; | ||
|
||
for partition_idx in 0..partitions_amt.count() { | ||
partitions.set(partition_idx); | ||
} | ||
} | ||
|
||
let (live, dead, removed_power) = | ||
from_deadline.remove_partitions(store, partitions, from_quant).map_err(|e| { | ||
hunjixin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
e.downcast_default( | ||
ExitCode::USR_ILLEGAL_STATE, | ||
format!( | ||
"failed to remove partitions from deadline {}", | ||
params.from_deadline | ||
), | ||
) | ||
})?; | ||
|
||
state.delete_sectors(store, &dead).map_err(|e| { | ||
e.downcast_default(ExitCode::USR_ILLEGAL_STATE, "failed to delete dead sectors") | ||
})?; | ||
|
||
let sectors = state.load_sector_infos(store, &live).map_err(|e| { | ||
e.downcast_default(ExitCode::USR_ILLEGAL_STATE, "failed to load moved sectors") | ||
})?; | ||
let proven = true; | ||
let added_power = to_deadline | ||
.add_sectors( | ||
store, | ||
info.window_post_partition_sectors, | ||
proven, | ||
§ors, | ||
info.sector_size, | ||
to_quant, | ||
) | ||
.map_err(|e| { | ||
e.downcast_default( | ||
ExitCode::USR_ILLEGAL_STATE, | ||
"failed to add back moved sectors", | ||
) | ||
})?; | ||
|
||
if removed_power != added_power { | ||
return Err(actor_error!( | ||
illegal_state, | ||
"power changed when compacting partitions: was {:?}, is now {:?}", | ||
removed_power, | ||
added_power | ||
)); | ||
} | ||
|
||
deadlines | ||
.update_deadline(policy, store, params.from_deadline, &from_deadline) | ||
.map_err(|e| { | ||
e.downcast_default( | ||
ExitCode::USR_ILLEGAL_STATE, | ||
format!("failed to update deadline {}", params.from_deadline), | ||
) | ||
})?; | ||
deadlines.update_deadline(policy, store, params.to_deadline, &to_deadline).map_err( | ||
|e| { | ||
e.downcast_default( | ||
ExitCode::USR_ILLEGAL_STATE, | ||
format!("failed to update deadline {}", params.to_deadline), | ||
) | ||
}, | ||
)?; | ||
|
||
state.save_deadlines(store, deadlines).map_err(|e| { | ||
e.downcast_default( | ||
ExitCode::USR_ILLEGAL_STATE, | ||
format!( | ||
"failed to save deadline when move_partitions from {} to {}", | ||
params.from_deadline, params.to_deadline | ||
), | ||
) | ||
})?; | ||
|
||
Ok(()) | ||
})?; | ||
|
||
Ok(()) | ||
} | ||
/// Compacts sector number allocations to reduce the size of the allocated sector | ||
/// number bitfield. | ||
/// | ||
|
@@ -5113,6 +5405,7 @@ impl ActorCode for Actor { | |
ConfirmSectorProofsValid => confirm_sector_proofs_valid, | ||
ChangeMultiaddrs|ChangeMultiaddrsExported => change_multiaddresses, | ||
CompactPartitions => compact_partitions, | ||
MovePartitions => move_partitions, | ||
CompactSectorNumbers => compact_sector_numbers, | ||
ConfirmChangeWorkerAddress|ConfirmChangeWorkerAddressExported => confirm_change_worker_address, | ||
RepayDebt|RepayDebtExported => repay_debt, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The distance should be 0~47.
And, this change makes the function deadline_available_for_move more reasonable. It will automatically return false if currDeadline=fromDeadline
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, fixed!