@@ -43,6 +43,7 @@ Developer Notes
43
43
- [ Suggestions and examples] ( #suggestions-and-examples )
44
44
- [ Release notes] ( #release-notes )
45
45
- [ RPC interface guidelines] ( #rpc-interface-guidelines )
46
+ - [ Internal interface guidelines] ( #internal-interface-guidelines )
46
47
47
48
<!-- markdown-toc end -->
48
49
@@ -1100,3 +1101,124 @@ A few guidelines for introducing and reviewing new RPC interfaces:
1100
1101
timestamps in the documentation.
1101
1102
1102
1103
- * Rationale* : User-facing consistency.
1104
+
1105
+ Internal interface guidelines
1106
+ -----------------------------
1107
+
1108
+ Internal interfaces between parts of the codebase that are meant to be
1109
+ independent (node, wallet, GUI), are defined in
1110
+ [ ` src/interfaces/ ` ] ( ../src/interfaces/ ) . The main interface classes defined
1111
+ there are [ ` interfaces::Chain ` ] ( ../src/interfaces/chain.h ) , used by wallet to
1112
+ access the node's latest chain state,
1113
+ [ ` interfaces::Node ` ] ( ../src/interfaces/node.h ) , used by the GUI to control the
1114
+ node, and [ ` interfaces::Wallet ` ] ( ../src/interfaces/wallet.h ) , used by the GUI
1115
+ to control an individual wallet. There are also more specialized interface
1116
+ types like [ ` interfaces::Handler ` ] ( ../src/interfaces/handler.h )
1117
+ [ ` interfaces::ChainClient ` ] ( ../src/interfaces/chain.h ) passed to and from
1118
+ various interface methods.
1119
+
1120
+ Interface classes are written in a particular style so node, wallet, and GUI
1121
+ code doesn't need to run in the same process, and so the class declarations
1122
+ work more easily with tools and libraries supporting interprocess
1123
+ communication:
1124
+
1125
+ - Interface classes should be abstract and have methods that are [ pure
1126
+ virtual] ( https://en.cppreference.com/w/cpp/language/abstract_class ) . This
1127
+ allows multiple implementations to inherit from the same interface class,
1128
+ particularly so one implementation can execute functionality in the local
1129
+ process, and other implementations can forward calls to remote processes.
1130
+
1131
+ - Interface method definitions should wrap existing functionality instead of
1132
+ implementing new functionality. Any substantial new node or wallet
1133
+ functionality should be implemented in [ ` src/node/ ` ] ( ../src/node/ ) or
1134
+ [ ` src/wallet/ ` ] ( ../src/wallet/ ) and just exposed in
1135
+ [ ` src/interfaces/ ` ] ( ../src/interfaces/ ) instead of being implemented there,
1136
+ so it can be more modular and accessible to unit tests.
1137
+
1138
+ - Interface method parameter and return types should either be serializable or
1139
+ be other interface classes. Interface methods shouldn't pass references to
1140
+ objects that can't be serialized or accessed from another process.
1141
+
1142
+ Examples:
1143
+
1144
+ ``` c++
1145
+ // Good: takes string argument and returns interface class pointer
1146
+ virtual unique_ptr<interfaces::Wallet> loadWallet (std::string filename) = 0;
1147
+
1148
+ // Bad: returns CWallet reference that can't be used from another process
1149
+ virtual CWallet& loadWallet(std::string filename) = 0;
1150
+ ```
1151
+
1152
+ ```c++
1153
+ // Good: accepts and returns primitive types
1154
+ virtual bool findBlock(const uint256& hash, int& out_height, int64_t& out_time) = 0;
1155
+
1156
+ // Bad: returns pointer to internal node in a linked list inaccessible to
1157
+ // other processes
1158
+ virtual const CBlockIndex* findBlock(const uint256& hash) = 0;
1159
+ ```
1160
+
1161
+ ``` c++
1162
+ // Good: takes plain callback type and returns interface pointer
1163
+ using TipChangedFn = std::function<void (int block_height, int64_t block_time)>;
1164
+ virtual std::unique_ptr<interfaces::Handler> handleTipChanged (TipChangedFn fn) = 0;
1165
+
1166
+ // Bad: returns boost connection specific to local process
1167
+ using TipChangedFn = std::function<void(int block_height, int64_t block_time)>;
1168
+ virtual boost::signals2::scoped_connection connectTipChanged(TipChangedFn fn) = 0;
1169
+ ```
1170
+
1171
+ - For consistency and friendliness to code generation tools, interface method
1172
+ input and inout parameters should be ordered first and output parameters
1173
+ should come last.
1174
+
1175
+ Example:
1176
+
1177
+ ```c++
1178
+ // Good: error output param is last
1179
+ virtual bool broadcastTransaction(const CTransactionRef& tx, CAmount max_fee, std::string& error) = 0;
1180
+
1181
+ // Bad: error output param is between input params
1182
+ virtual bool broadcastTransaction(const CTransactionRef& tx, std::string& error, CAmount max_fee) = 0;
1183
+ ```
1184
+
1185
+ - For friendliness to code generation tools, interface methods should not be
1186
+ overloaded:
1187
+
1188
+ Example:
1189
+
1190
+ ``` c++
1191
+ // Good: method names are unique
1192
+ virtual bool disconnectByAddress (const CNetAddr& net_addr) = 0;
1193
+ virtual bool disconnectById(NodeId id) = 0;
1194
+
1195
+ // Bad: methods are overloaded by type
1196
+ virtual bool disconnect(const CNetAddr& net_addr) = 0;
1197
+ virtual bool disconnect(NodeId id) = 0;
1198
+ ```
1199
+
1200
+ - For consistency and friendliness to code generation tools, interface method
1201
+ names should be `lowerCamelCase` and standalone function names should be
1202
+ `UpperCamelCase`.
1203
+
1204
+ Examples:
1205
+
1206
+ ```c++
1207
+ // Good: lowerCamelCase method name
1208
+ virtual void blockConnected(const CBlock& block, int height) = 0;
1209
+
1210
+ // Bad: uppercase class method
1211
+ virtual void BlockConnected(const CBlock& block, int height) = 0;
1212
+ ```
1213
+
1214
+ ``` c++
1215
+ // Good: UpperCamelCase standalone function name
1216
+ std::unique_ptr<Node> MakeNode (LocalInit& init);
1217
+
1218
+ // Bad: lowercase standalone function
1219
+ std::unique_ptr<Node > makeNode(LocalInit& init);
1220
+ ```
1221
+
1222
+ Note: This last convention isn't generally followed outside of
1223
+ [`src/interfaces/`](../src/interfaces/), though it did come up for discussion
1224
+ before in [#14635](https://github.com/bitcoin/bitcoin/pull/14635).
0 commit comments