-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathChannelConfigStore.sol
More file actions
149 lines (128 loc) · 6.73 KB
/
ChannelConfigStore.sol
File metadata and controls
149 lines (128 loc) · 6.73 KB
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
147
148
149
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.19;
import {ConfirmedOwner} from "../../../shared/access/ConfirmedOwner.sol";
import {EnumerableSet} from "@openzeppelin/contracts@4.8.3/utils/structs/EnumerableSet.sol";
import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol";
import {IChannelConfigStore} from "./interfaces/IChannelConfigStore.sol";
contract ChannelConfigStore is ConfirmedOwner, IChannelConfigStore, ITypeAndVersion {
// This contract uses uint32 for donIds when they are function arguments and
// uint256 elsewhere (e.g. in storage or event params). This inconsistency is
// ugly, but we maintain it for backwards compatibility.
using EnumerableSet for EnumerableSet.UintSet;
event NewChannelDefinition(uint256 indexed donId, uint32 version, string url, bytes32 sha);
event ChannelDefinitionAdded(uint256 indexed donId, ChannelAdderId indexed channelAdderId, string url, bytes32 sha);
event ChannelAdderSet(uint256 indexed donId, ChannelAdderId indexed channelAdderId, bool allowed);
event ChannelAdderAddressSet(ChannelAdderId indexed channelAdderId, address adderAddress);
/// @notice Thrown when a caller is not authorized to add channel definitions.
error UnauthorizedChannelAdder();
/// @notice Thrown when a ChannelAdderId is reserved.
error ReservedChannelAdderId();
// We reserve the ChannelAdderIds 0 through 999. 1 is used by the offchain code to internally
// represent the owner. The others are reserved for future use.
ChannelAdderId internal constant MIN_CHANNEL_ADDER_ID = ChannelAdderId.wrap(1000);
constructor() ConfirmedOwner(msg.sender) {}
/// @notice The version of a channel definition keyed by DON ID.
// Increments by 1 on every update.
mapping(uint256 => uint256) internal s_channelDefinitionVersions;
/// @notice Mapping from channel adder ID to its corresponding address
mapping(ChannelAdderId => address) internal s_channelAdderAddresses;
/// @notice Mapping from DON ID to the set of allowed channel adder IDs
mapping(uint256 => EnumerableSet.UintSet) internal s_allowedChannelAdders;
/// @notice Allows the owner to arbitrarily set channel definitions to the specified DON.
/// Unlike the channel adder, the owner can not only add, but also modify and delete
/// channel definitions. The DON enforces (in its consensus rules), that the channel
/// definitions provided by the owner are well-formed.
/// @param donId The DON ID
/// @param url The URL of the channel definition
/// @param sha The SHA hash of the channel definition
function setChannelDefinitions(uint32 donId, string calldata url, bytes32 sha) external onlyOwner {
uint32 newVersion = uint32(++s_channelDefinitionVersions[uint256(donId)]);
emit NewChannelDefinition(donId, newVersion, url, sha);
}
/// @notice Allows a channel adder to add channel definitions to the specified DON.
/// The DON enforces (in its consensus rules), that the channel definitions provided
/// by the channel adder are well-formed, purely additive, and do not overload the DON.
/// @param donId The DON ID
/// @param channelAdderId The channel adder ID
/// @param url The URL of the channel definition
/// @param sha The SHA hash of the channel definition
function addChannelDefinitions(
uint32 donId,
ChannelAdderId channelAdderId,
string calldata url,
bytes32 sha
) external {
if (msg.sender != s_channelAdderAddresses[channelAdderId]) {
revert UnauthorizedChannelAdder();
}
if (!s_allowedChannelAdders[donId].contains(ChannelAdderId.unwrap(channelAdderId))) {
revert UnauthorizedChannelAdder();
}
emit ChannelDefinitionAdded(donId, channelAdderId, url, sha);
}
/// @notice Sets the address for a channel adder ID
/// @param channelAdderId The channel adder ID
/// @param adderAddress The address to associate with the channel adder ID.
/// Set this to the zero address (or some other address that cannot make
/// calls) to disable the channel adder.
function setChannelAdderAddress(ChannelAdderId channelAdderId, address adderAddress) external onlyOwner {
if (ChannelAdderId.unwrap(channelAdderId) < ChannelAdderId.unwrap(MIN_CHANNEL_ADDER_ID)) {
revert ReservedChannelAdderId();
}
s_channelAdderAddresses[channelAdderId] = adderAddress;
emit ChannelAdderAddressSet(channelAdderId, adderAddress);
}
/// @notice Sets whether a channel adder ID is allowed for a DON
/// @param donId The DON ID
/// @param channelAdderId The channel adder ID
/// @param allowed Whether the channel adder should be allowed or removed
function setChannelAdder(uint32 donId, ChannelAdderId channelAdderId, bool allowed) external onlyOwner {
if (ChannelAdderId.unwrap(channelAdderId) < ChannelAdderId.unwrap(MIN_CHANNEL_ADDER_ID)) {
revert ReservedChannelAdderId();
}
if (allowed) {
s_allowedChannelAdders[donId].add(ChannelAdderId.unwrap(channelAdderId));
} else {
s_allowedChannelAdders[donId].remove(ChannelAdderId.unwrap(channelAdderId));
}
emit ChannelAdderSet(donId, channelAdderId, allowed);
}
/// @notice Gets the address associated with a channel adder ID
/// @param channelAdderId The channel adder ID
/// @return The address associated with the channel adder ID
function getChannelAdderAddress(
ChannelAdderId channelAdderId
) external view returns (address) {
return s_channelAdderAddresses[channelAdderId];
}
/// @notice Checks if a channel adder is allowed for a DON
/// @param donId The DON ID
/// @param channelAdderId The channel adder ID
/// @return True if the channel adder is allowed for the DON
function isChannelAdderAllowed(uint32 donId, ChannelAdderId channelAdderId) external view returns (bool) {
return s_allowedChannelAdders[donId].contains(ChannelAdderId.unwrap(channelAdderId));
}
/// @notice Gets all allowed channel adder IDs for a DON
/// @param donId The DON ID
/// @return allowedChannelAdderIds An array of allowed channel adder IDs
function getAllowedChannelAdders(
uint32 donId
) external view returns (ChannelAdderId[] memory allowedChannelAdderIds) {
// Not very gas efficient, but we don't expect this function to be called
// from onchain anyways.
uint256[] memory values = s_allowedChannelAdders[donId].values();
allowedChannelAdderIds = new ChannelAdderId[](values.length);
for (uint256 i = 0; i < values.length; i++) {
allowedChannelAdderIds[i] = ChannelAdderId.wrap(uint32(values[i]));
}
return allowedChannelAdderIds;
}
function typeAndVersion() external pure override returns (string memory) {
return "ChannelConfigStore 1.0.0";
}
function supportsInterface(
bytes4 interfaceId
) external pure returns (bool) {
return interfaceId == type(IChannelConfigStore).interfaceId;
}
}