mirror of https://github.com/nucypher/nucypher.git
PolicyManager: multiple policies in one tx
parent
8668a49dab
commit
787fe2ffc7
|
@ -0,0 +1 @@
|
||||||
|
PolicyManager: creating multiple policies in one tx
|
|
@ -315,6 +315,98 @@ contract PolicyManager is Upgradeable {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @notice Create multiple policies with the same owner, nodes and length
|
||||||
|
* @dev Generate policy id before creation
|
||||||
|
* @param _policyIds Policy ids
|
||||||
|
* @param _policyOwner Policy owner. Zero address means sender is owner
|
||||||
|
* @param _endTimestamp End timestamp of the policy in seconds
|
||||||
|
* @param _nodes Nodes that will handle policy
|
||||||
|
*/
|
||||||
|
function createPolicies(
|
||||||
|
bytes16[] calldata _policyIds,
|
||||||
|
address _policyOwner,
|
||||||
|
uint64 _endTimestamp,
|
||||||
|
address[] calldata _nodes
|
||||||
|
)
|
||||||
|
external payable
|
||||||
|
{
|
||||||
|
require(
|
||||||
|
_endTimestamp > block.timestamp &&
|
||||||
|
msg.value > 0 &&
|
||||||
|
_policyIds.length > 1
|
||||||
|
);
|
||||||
|
|
||||||
|
require(address(this).balance <= MAX_BALANCE);
|
||||||
|
uint16 currentPeriod = getCurrentPeriod();
|
||||||
|
uint16 endPeriod = uint16(_endTimestamp / secondsPerPeriod) + 1;
|
||||||
|
uint256 numberOfPeriods = endPeriod - currentPeriod;
|
||||||
|
uint128 feeRate = uint128(msg.value.div(_nodes.length) / numberOfPeriods / _policyIds.length);
|
||||||
|
require(feeRate > 0 && feeRate * numberOfPeriods * _nodes.length * _policyIds.length == msg.value);
|
||||||
|
|
||||||
|
for (uint256 i = 0; i < _policyIds.length; i++) {
|
||||||
|
Policy storage policy = policies[_policyIds[i]];
|
||||||
|
require(
|
||||||
|
_policyIds[i] != RESERVED_POLICY_ID &&
|
||||||
|
policy.feeRate == 0 &&
|
||||||
|
!policy.disabled
|
||||||
|
);
|
||||||
|
|
||||||
|
policy.sponsor = msg.sender;
|
||||||
|
policy.startTimestamp = uint64(block.timestamp);
|
||||||
|
policy.endTimestamp = _endTimestamp;
|
||||||
|
policy.feeRate = feeRate;
|
||||||
|
|
||||||
|
if (_policyOwner != msg.sender && _policyOwner != address(0)) {
|
||||||
|
policy.owner = _policyOwner;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint256 j = 0; j < _nodes.length; j++) {
|
||||||
|
policy.arrangements.push(ArrangementInfo(_nodes[j], 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
emit PolicyCreated(
|
||||||
|
_policyIds[i],
|
||||||
|
msg.sender,
|
||||||
|
_policyOwner == address(0) ? msg.sender : _policyOwner,
|
||||||
|
feeRate,
|
||||||
|
policy.startTimestamp,
|
||||||
|
policy.endTimestamp,
|
||||||
|
_nodes.length
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
int256 fee = int256(_policyIds.length * feeRate);
|
||||||
|
|
||||||
|
for (uint256 i = 0; i < _nodes.length; i++) {
|
||||||
|
address node = _nodes[i];
|
||||||
|
require(node != RESERVED_NODE);
|
||||||
|
NodeInfo storage nodeInfo = nodes[node];
|
||||||
|
require(nodeInfo.previousFeePeriod != 0 &&
|
||||||
|
nodeInfo.previousFeePeriod < currentPeriod &&
|
||||||
|
feeRate >= getMinFeeRate(nodeInfo));
|
||||||
|
// Check default value for feeDelta
|
||||||
|
if (nodeInfo.feeDelta[currentPeriod] == DEFAULT_FEE_DELTA) {
|
||||||
|
nodeInfo.feeDelta[currentPeriod] = fee;
|
||||||
|
} else {
|
||||||
|
// Overflow protection removed, because ETH total supply less than uint255/int256
|
||||||
|
nodeInfo.feeDelta[currentPeriod] += fee;
|
||||||
|
}
|
||||||
|
if (nodeInfo.feeDelta[endPeriod] == DEFAULT_FEE_DELTA) {
|
||||||
|
nodeInfo.feeDelta[endPeriod] = -fee;
|
||||||
|
} else {
|
||||||
|
nodeInfo.feeDelta[endPeriod] -= fee;
|
||||||
|
}
|
||||||
|
// Reset to default value if needed
|
||||||
|
if (nodeInfo.feeDelta[currentPeriod] == 0) {
|
||||||
|
nodeInfo.feeDelta[currentPeriod] = DEFAULT_FEE_DELTA;
|
||||||
|
}
|
||||||
|
if (nodeInfo.feeDelta[endPeriod] == 0) {
|
||||||
|
nodeInfo.feeDelta[endPeriod] = DEFAULT_FEE_DELTA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @notice Get policy owner
|
* @notice Get policy owner
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -448,7 +448,26 @@ def estimate_gas(analyzer: AnalyzeGas = None) -> None:
|
||||||
policy_functions.revokePolicy(policy_id_3),
|
policy_functions.revokePolicy(policy_id_3),
|
||||||
{'from': alice2})
|
{'from': alice2})
|
||||||
|
|
||||||
for index in range(5):
|
transact(staker_functions.commitToNextPeriod(), {'from': staker1})
|
||||||
|
transact(staker_functions.commitToNextPeriod(), {'from': staker2})
|
||||||
|
transact(staker_functions.commitToNextPeriod(), {'from': staker3})
|
||||||
|
testerchain.time_travel(periods=1)
|
||||||
|
#
|
||||||
|
# Batch granting
|
||||||
|
#
|
||||||
|
policy_id_1 = os.urandom(int(Policy.POLICY_ID_LENGTH))
|
||||||
|
policy_id_2 = os.urandom(int(Policy.POLICY_ID_LENGTH))
|
||||||
|
current_timestamp = testerchain.w3.eth.getBlock('latest').timestamp
|
||||||
|
end_timestamp = current_timestamp + (number_of_periods - 1) * one_period
|
||||||
|
value = 3 * number_of_periods * rate
|
||||||
|
transact_and_log("Creating 2 policies (3 nodes, 100 periods, pre-committed)",
|
||||||
|
policy_functions.createPolicies([policy_id_1, policy_id_2],
|
||||||
|
alice1,
|
||||||
|
end_timestamp,
|
||||||
|
[staker1, staker2, staker3]),
|
||||||
|
{'from': alice1, 'value': 2 * value})
|
||||||
|
|
||||||
|
for index in range(4):
|
||||||
transact(staker_functions.commitToNextPeriod(), {'from': staker1})
|
transact(staker_functions.commitToNextPeriod(), {'from': staker1})
|
||||||
testerchain.time_travel(periods=1)
|
testerchain.time_travel(periods=1)
|
||||||
transact(staker_functions.mint(), {'from': staker1})
|
transact(staker_functions.mint(), {'from': staker1})
|
||||||
|
|
Loading…
Reference in New Issue