-
Notifications
You must be signed in to change notification settings - Fork 174
/
EigenDAServiceManager.sol
146 lines (124 loc) · 6.29 KB
/
EigenDAServiceManager.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;
import {Pausable} from "eigenlayer-core/contracts/permissions/Pausable.sol";
import {IPauserRegistry} from "eigenlayer-core/contracts/interfaces/IPauserRegistry.sol";
import {ServiceManagerBase, IAVSDirectory} from "eigenlayer-middleware/ServiceManagerBase.sol";
import {BLSSignatureChecker} from "eigenlayer-middleware/BLSSignatureChecker.sol";
import {IRegistryCoordinator} from "eigenlayer-middleware/interfaces/IRegistryCoordinator.sol";
import {IStakeRegistry} from "eigenlayer-middleware/interfaces/IStakeRegistry.sol";
import {EigenDAServiceManagerStorage} from "./EigenDAServiceManagerStorage.sol";
import {EigenDAHasher} from "../libraries/EigenDAHasher.sol";
/**
* @title Primary entrypoint for procuring services from EigenDA.
* @author Layr Labs, Inc.
* @notice This contract is used for:
* - initializing the data store by the disperser
* - confirming the data store by the disperser with inferred aggregated signatures of the quorum
* - freezing operators as the result of various "challenges"
*/
contract EigenDAServiceManager is EigenDAServiceManagerStorage, ServiceManagerBase, BLSSignatureChecker, Pausable {
using EigenDAHasher for BatchHeader;
using EigenDAHasher for ReducedBatchHeader;
uint8 internal constant PAUSED_CONFIRM_BATCH = 0;
/// @notice when applied to a function, ensures that the function is only callable by the `batchConfirmer`.
modifier onlyBatchConfirmer() {
require(msg.sender == batchConfirmer, "onlyBatchConfirmer: not from batch confirmer");
_;
}
constructor(
IAVSDirectory __avsDirectory,
IRegistryCoordinator __registryCoordinator,
IStakeRegistry __stakeRegistry
)
BLSSignatureChecker(__registryCoordinator)
ServiceManagerBase(__avsDirectory, __registryCoordinator, __stakeRegistry)
{
_disableInitializers();
}
function initialize(
IPauserRegistry _pauserRegistry,
uint256 _initialPausedStatus,
address _initialOwner,
address _batchConfirmer
)
public
initializer
{
_initializePauser(_pauserRegistry, _initialPausedStatus);
_transferOwnership(_initialOwner);
_setBatchConfirmer(_batchConfirmer);
}
/**
* @notice This function is used for
* - submitting data availabilty certificates,
* - check that the aggregate signature is valid,
* - and check whether quorum has been achieved or not.
*/
function confirmBatch(
BatchHeader calldata batchHeader,
NonSignerStakesAndSignature memory nonSignerStakesAndSignature
) external onlyWhenNotPaused(PAUSED_CONFIRM_BATCH) onlyBatchConfirmer() {
// make sure the information needed to derive the non-signers and batch is in calldata to avoid emitting events
require(tx.origin == msg.sender, "EigenDAServiceManager.confirmBatch: header and nonsigner data must be in calldata");
// make sure the stakes against which the Batch is being confirmed are not stale
require(
batchHeader.referenceBlockNumber < block.number, "EigenDAServiceManager.confirmBatch: specified referenceBlockNumber is in future"
);
require(
(batchHeader.referenceBlockNumber + BLOCK_STALE_MEASURE) >= uint32(block.number),
"EigenDAServiceManager.confirmBatch: specified referenceBlockNumber is too far in past"
);
//make sure that the quorumNumbers and signedStakeForQuorums are of the same length
require(
batchHeader.quorumNumbers.length == batchHeader.signedStakeForQuorums.length,
"EigenDAServiceManager.confirmBatch: quorumNumbers and signedStakeForQuorums must be of the same length"
);
// calculate reducedBatchHeaderHash which nodes signed
bytes32 reducedBatchHeaderHash = batchHeader.hashBatchHeaderToReducedBatchHeader();
// check the signature
(
QuorumStakeTotals memory quorumStakeTotals,
bytes32 signatoryRecordHash
) = checkSignatures(
reducedBatchHeaderHash,
batchHeader.quorumNumbers, // use list of uint8s instead of uint256 bitmap to not iterate 256 times
batchHeader.referenceBlockNumber,
nonSignerStakesAndSignature
);
// check that signatories own at least a threshold percentage of each quourm
for (uint i = 0; i < batchHeader.signedStakeForQuorums.length; i++) {
// we don't check that the signedStakeForQuorums are not >100 because a greater value would trivially fail the check, implying
// signed stake > total stake
require(
quorumStakeTotals.signedStakeForQuorum[i] * THRESHOLD_DENOMINATOR >=
quorumStakeTotals.totalStakeForQuorum[i] * uint8(batchHeader.signedStakeForQuorums[i]),
"EigenDAServiceManager.confirmBatch: signatories do not own at least threshold percentage of a quorum"
);
}
// store the metadata hash
uint32 batchIdMemory = batchId;
bytes32 batchHeaderHash = batchHeader.hashBatchHeader();
batchIdToBatchMetadataHash[batchIdMemory] = EigenDAHasher.hashBatchHashedMetadata(batchHeaderHash, signatoryRecordHash, uint32(block.number));
emit BatchConfirmed(reducedBatchHeaderHash, batchIdMemory);
// increment the batchId
batchId = batchIdMemory + 1;
}
/// @notice This function is used for changing the batch confirmer
function setBatchConfirmer(address _batchConfirmer) external onlyOwner() {
_setBatchConfirmer(_batchConfirmer);
}
/// @notice changes the batch confirmer
function _setBatchConfirmer(address _batchConfirmer) internal {
address previousBatchConfirmer = batchConfirmer;
batchConfirmer = _batchConfirmer;
emit BatchConfirmerChanged(previousBatchConfirmer, batchConfirmer);
}
/// @notice Returns the current batchId
function taskNumber() external view returns (uint32) {
return batchId;
}
/// @notice Given a reference block number, returns the block until which operators must serve.
function latestServeUntilBlock(uint32 referenceBlockNumber) external view returns (uint32) {
return referenceBlockNumber + STORE_DURATION_BLOCKS + BLOCK_STALE_MEASURE;
}
}