Skip to content

Commit 748103d

Browse files
committed
experimental: add Chain interface schema and tests (PR 29409)
1 parent 7a38083 commit 748103d

8 files changed

Lines changed: 544 additions & 1 deletion

File tree

build.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ fn main() {
22
println!("cargo:rerun-if-changed=capnp");
33
capnpc::CompilerCommand::new()
44
.src_prefix("capnp")
5+
.file("capnp/chain.capnp")
56
.file("capnp/common.capnp")
67
.file("capnp/echo.capnp")
8+
.file("capnp/handler.capnp")
79
.file("capnp/init.capnp")
810
.file("capnp/mining.capnp")
911
.file("capnp/proxy.capnp")

capnp/chain.capnp

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
# Copyright (c) The Bitcoin Core developers
2+
# Distributed under the MIT software license, see the accompanying
3+
# file COPYING or https://opensource.org/license/mit.
4+
5+
@0x94f21a4864bd2c65;
6+
7+
using Cxx = import "/capnp/c++.capnp";
8+
$Cxx.namespace("ipc::capnp::messages");
9+
10+
using Proxy = import "proxy.capnp";
11+
12+
using Common = import "common.capnp";
13+
using Handler = import "handler.capnp";
14+
15+
interface Chain $Proxy.wrap("interfaces::Chain") {
16+
destroy @0 (context :Proxy.Context) -> ();
17+
getHeight @1 (context :Proxy.Context) -> (result :Int32, hasResult :Bool);
18+
getBlockHash @2 (context :Proxy.Context, height :Int32) -> (result :Data);
19+
haveBlockOnDisk @3 (context :Proxy.Context, height :Int32) -> (result :Bool);
20+
findLocatorFork @4 (context :Proxy.Context, locator :Data) -> (result :Int32, hasResult :Bool);
21+
hasBlockFilterIndex @5 (context :Proxy.Context, filterType :UInt8) -> (result :Bool);
22+
blockFilterMatchesAny @6 (context :Proxy.Context, filterType :UInt8, blockHash :Data, filterSet :List(Data)) -> (result :Bool, hasResult :Bool);
23+
findBlock @7 (context :Proxy.Context, hash :Data, block :FoundBlockParam) -> (block :FoundBlockResult, result :Bool);
24+
findFirstBlockWithTimeAndHeight @8 (context :Proxy.Context, minTime :Int64, minHeight :Int32, block :FoundBlockParam) -> (block :FoundBlockResult, result :Bool);
25+
findAncestorByHeight @9 (context :Proxy.Context, blockHash :Data, ancestorHeight :Int32, ancestor :FoundBlockParam) -> (ancestor :FoundBlockResult, result :Bool);
26+
findAncestorByHash @10 (context :Proxy.Context, blockHash :Data, ancestorHash :Data, ancestor :FoundBlockParam) -> (ancestor :FoundBlockResult, result :Bool);
27+
findCommonAncestor @11 (context :Proxy.Context, blockHash1 :Data, blockHash2 :Data, ancestor :FoundBlockParam, block1 :FoundBlockParam, block2 :FoundBlockParam) -> (ancestor :FoundBlockResult, block1 :FoundBlockResult, block2 :FoundBlockResult, result :Bool);
28+
findCoins @12 (context :Proxy.Context, coins :List(Common.Pair(Data, Data))) -> (coins :List(Common.Pair(Data, Data)));
29+
guessVerificationProgress @13 (context :Proxy.Context, blockHash :Data) -> (result :Float64);
30+
hasBlocks @14 (context :Proxy.Context, blockHash :Data, minHeight :Int32, maxHeight: Int32, hasMaxHeight :Bool) -> (result :Bool);
31+
isRBFOptIn @15 (context :Proxy.Context, tx :Data) -> (result :Int32);
32+
isInMempool @16 (context :Proxy.Context, txid :Data) -> (result :Bool);
33+
hasDescendantsInMempool @17 (context :Proxy.Context, txid :Data) -> (result :Bool);
34+
broadcastTransaction @18 (context :Proxy.Context, tx: Data, maxTxFee :Int64, broadcastMethod :Int32) -> (error: Text, result :Bool);
35+
getTransactionAncestry @19 (context :Proxy.Context, txid :Data) -> (ancestors :UInt64, descendants :UInt64, ancestorsize :UInt64, ancestorfees :Int64);
36+
calculateIndividualBumpFees @20 (context :Proxy.Context, outpoints :List(Data), targetFeerate :Data) -> (result: List(Common.PairInt64(Data)));
37+
calculateCombinedBumpFee @21 (context :Proxy.Context, outpoints :List(Data), targetFeerate :Data) -> (result :Int64, hasResult :Bool);
38+
getPackageLimits @22 (context :Proxy.Context) -> (ancestors :UInt32, descendants :UInt32);
39+
checkChainLimits @23 (context :Proxy.Context, tx :Data) -> (result :Common.ResultVoid);
40+
estimateSmartFee @24 (context :Proxy.Context, numBlocks :Int32, conservative :Bool, wantCalc :Bool) -> (calc :Common.FeeCalculation, result :Data);
41+
estimateMaxBlocks @25 (context :Proxy.Context) -> (result :UInt32);
42+
mempoolMinFee @26 (context :Proxy.Context) -> (result :Data);
43+
relayMinFee @27 (context :Proxy.Context) -> (result :Data);
44+
relayIncrementalFee @28 (context :Proxy.Context) -> (result :Data);
45+
relayDustFee @29 (context :Proxy.Context) -> (result :Data);
46+
havePruned @30 (context :Proxy.Context) -> (result :Bool);
47+
getPruneHeight @31 (context :Proxy.Context) -> (result: Int32, hasResult: Bool);
48+
isReadyToBroadcast @32 (context :Proxy.Context) -> (result :Bool);
49+
isInitialBlockDownload @33 (context :Proxy.Context) -> (result :Bool);
50+
shutdownRequested @34 (context :Proxy.Context) -> (result :Bool);
51+
initMessage @35 (context :Proxy.Context, message :Text) -> ();
52+
initWarning @36 (context :Proxy.Context, message :Common.BilingualStr) -> ();
53+
initError @37 (context :Proxy.Context, message :Common.BilingualStr) -> ();
54+
showProgress @38 (context :Proxy.Context, title :Text, progress :Int32, resumePossible :Bool) -> ();
55+
handleNotifications @39 (context :Proxy.Context, notifications :ChainNotifications) -> (result :Handler.Handler);
56+
waitForNotificationsIfTipChanged @40 (context :Proxy.Context, oldTip :Data) -> ();
57+
waitForNotifications @41 (context :Proxy.Context) -> ();
58+
handleRpc @42 (context :Proxy.Context, command :RPCCommand) -> (result :Handler.Handler);
59+
rpcEnableDeprecated @43 (context :Proxy.Context, method :Text) -> (result :Bool);
60+
getSetting @44 (context :Proxy.Context, name :Text) -> (result :Text);
61+
getSettingsList @45 (context :Proxy.Context, name :Text) -> (result :List(Text));
62+
getRwSetting @46 (context :Proxy.Context, name :Text) -> (result :Text);
63+
updateRwSetting @47 (context :Proxy.Context, name :Text, update: SettingsUpdateCallback) -> (result :Bool);
64+
overwriteRwSetting @48 (context :Proxy.Context, name :Text, value :Text, action :Int32) -> (result :Bool);
65+
deleteRwSettings @49 (context :Proxy.Context, name :Text, action: Int32) -> (result :Bool);
66+
requestMempoolTransactions @50 (context :Proxy.Context, notifications :ChainNotifications) -> ();
67+
hasAssumedValidChain @51 (context :Proxy.Context) -> (result :Bool);
68+
}
69+
70+
interface ChainNotifications $Proxy.wrap("interfaces::Chain::Notifications") {
71+
destroy @0 (context :Proxy.Context) -> ();
72+
transactionAddedToMempool @1 (context :Proxy.Context, tx :Data) -> ();
73+
transactionRemovedFromMempool @2 (context :Proxy.Context, tx :Data, reason :Int32) -> ();
74+
blockConnected @3 (context :Proxy.Context, role: ChainstateRole, block :BlockInfo) -> ();
75+
blockDisconnected @4 (context :Proxy.Context, block :BlockInfo) -> ();
76+
updatedBlockTip @5 (context :Proxy.Context) -> ();
77+
chainStateFlushed @6 (context :Proxy.Context, role: ChainstateRole, locator :Data) -> ();
78+
}
79+
80+
interface ChainClient $Proxy.wrap("interfaces::ChainClient") {
81+
destroy @0 (context :Proxy.Context) -> ();
82+
registerRpcs @1 (context :Proxy.Context) -> ();
83+
verify @2 (context :Proxy.Context) -> (result :Bool);
84+
load @3 (context :Proxy.Context) -> (result :Bool);
85+
start @4 (context :Proxy.Context, scheduler :Void) -> ();
86+
stop @5 (context :Proxy.Context) -> ();
87+
setMockTime @6 (context :Proxy.Context, time :Int64) -> ();
88+
schedulerMockForward @7 (context :Proxy.Context, deltaSeconds :Int64) -> ();
89+
}
90+
91+
struct RPCCommand $Proxy.wrap("CRPCCommand") {
92+
category @0 :Text;
93+
name @1 :Text;
94+
actor @2 :ActorCallback;
95+
argNames @3 :List(RPCArg);
96+
uniqueId @4 :Int64 $Proxy.name("unique_id");
97+
}
98+
99+
# Representation of std::pair<std::string, bool> in CRPCCommand
100+
struct RPCArg {
101+
name @0 :Text;
102+
namedOnly @1: Bool;
103+
}
104+
105+
interface ActorCallback $Proxy.wrap("ProxyCallback<CRPCCommand::Actor>") {
106+
call @0 (context :Proxy.Context, request :JSONRPCRequest, response :Text, lastCallback :Bool) -> (error :Text $Proxy.exception("std::exception"), rpcError :Text $Proxy.exception("UniValue"), typeError :Text $Proxy.exception("UniValue::type_error"), helpResult :HelpResult $Proxy.exception("HelpResult"), response :Text, result: Bool);
107+
}
108+
109+
struct HelpResult {
110+
message @0 :Text;
111+
}
112+
113+
struct JSONRPCRequest $Proxy.wrap("JSONRPCRequest") {
114+
id @0 :Text;
115+
method @1 :Text $Proxy.name("strMethod");
116+
params @2 :Text;
117+
mode @3 :Int32;
118+
uri @4 :Text $Proxy.name("URI");
119+
authUser @5 :Text;
120+
peerAddr @6 :Text;
121+
version @7: Int32 $Proxy.name("m_json_version");
122+
}
123+
124+
struct FoundBlockParam {
125+
wantHash @0 :Bool;
126+
wantHeight @1 :Bool;
127+
wantTime @2 :Bool;
128+
wantMaxTime @3 :Bool;
129+
wantMtpTime @4 :Bool;
130+
wantInActiveChain @5 :Bool;
131+
wantLocator @6 :Bool;
132+
nextBlock @7: FoundBlockParam;
133+
wantData @8 :Bool;
134+
}
135+
136+
struct FoundBlockResult {
137+
hash @0 :Data;
138+
height @1 :Int32;
139+
time @2 :Int64;
140+
maxTime @3 :Int64;
141+
mtpTime @4 :Int64;
142+
inActiveChain @5 :Bool;
143+
locator @6 :Data;
144+
nextBlock @7: FoundBlockResult;
145+
data @8 :Data;
146+
found @9 :Bool;
147+
}
148+
149+
struct BlockInfo $Proxy.wrap("interfaces::BlockInfo") {
150+
# Fields skipped below with Proxy.skip are pointer fields manually handled
151+
# by CustomBuildMessage / CustomPassMessage overloads.
152+
hash @0 :Data $Proxy.skip;
153+
prevHash @1 :Data $Proxy.skip;
154+
height @2 :Int32 = -1;
155+
fileNumber @3 :Int32 = -1 $Proxy.name("file_number");
156+
dataPos @4 :UInt32 = 0 $Proxy.name("data_pos");
157+
data @5 :Data $Proxy.skip;
158+
undoData @6 :Data $Proxy.skip;
159+
chainTimeMax @7 :UInt32 = 0 $Proxy.name("chain_time_max");
160+
}
161+
162+
struct ChainstateRole $Proxy.wrap("kernel::ChainstateRole") {
163+
validated @0 :Bool;
164+
historical @1 :Bool;
165+
}
166+
167+
interface SettingsUpdateCallback $Proxy.wrap("ProxyCallback<interfaces::SettingsUpdate>") {
168+
destroy @0 (context :Proxy.Context) -> ();
169+
call @1 (context :Proxy.Context, value :Text) -> (value :Text, result: Int32, hasResult: Bool);
170+
}

capnp/common.capnp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,52 @@ struct BlockRef $Proxy.wrap("interfaces::BlockRef") {
1313
hash @0 :Data;
1414
height @1 :Int32;
1515
}
16+
17+
struct FeeCalculation $Proxy.wrap("FeeCalculation") {
18+
est @0 :EstimationResult;
19+
reason @1 :Int32;
20+
desiredTarget @2 :Int32;
21+
returnedTarget @3 :Int32;
22+
bestHeight @4 :UInt32 $Proxy.name("best_height");
23+
}
24+
25+
struct EstimationResult $Proxy.wrap("EstimationResult") {
26+
pass @0 :EstimatorBucket;
27+
fail @1 :EstimatorBucket;
28+
decay @2 :Float64;
29+
scale @3 :UInt32;
30+
}
31+
32+
struct EstimatorBucket $Proxy.wrap("EstimatorBucket") {
33+
start @0 :Float64;
34+
end @1 :Float64;
35+
withinTarget @2 :Float64;
36+
totalConfirmed @3 :Float64;
37+
inMempool @4 :Float64;
38+
leftMempool @5 :Float64;
39+
}
40+
41+
struct BilingualStr $Proxy.wrap("bilingual_str") {
42+
original @0 :Text;
43+
translated @1 :Text;
44+
}
45+
46+
struct Result(Value) {
47+
value @0 :Value;
48+
error @1: BilingualStr;
49+
}
50+
51+
# Wrapper for util::Result<void>
52+
struct ResultVoid(Value) {
53+
error @0: BilingualStr;
54+
}
55+
56+
struct Pair(Key, Value) {
57+
key @0 :Key;
58+
value @1 :Value;
59+
}
60+
61+
struct PairInt64(Key) {
62+
key @0 :Key;
63+
value @1 :Int64;
64+
}

capnp/handler.capnp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright (c) The Bitcoin Core developers
2+
# Distributed under the MIT software license, see the accompanying
3+
# file COPYING or https://opensource.org/license/mit.
4+
5+
@0xebd8f46e2f369076;
6+
7+
using Cxx = import "/capnp/c++.capnp";
8+
$Cxx.namespace("ipc::capnp::messages");
9+
10+
using Proxy = import "proxy.capnp";
11+
12+
interface Handler $Proxy.wrap("interfaces::Handler") {
13+
destroy @0 (context :Proxy.Context) -> ();
14+
disconnect @1 (context :Proxy.Context) -> ();
15+
}

capnp/init.capnp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,23 @@ using Cxx = import "/capnp/c++.capnp";
88
$Cxx.namespace("ipc::capnp::messages");
99

1010
using Proxy = import "proxy.capnp";
11+
using Chain = import "chain.capnp";
1112
using Echo = import "echo.capnp";
1213
using Mining = import "mining.capnp";
1314

1415
interface Init $Proxy.wrap("interfaces::Init") {
1516
construct @0 (threadMap: Proxy.ThreadMap) -> (threadMap :Proxy.ThreadMap);
1617
makeEcho @1 (context :Proxy.Context) -> (result :Echo.Echo);
18+
19+
# DEPRECATED: no longer supported; server returns an error.
1720
makeMiningOld2 @2 () -> ();
21+
1822
makeMining @3 (context :Proxy.Context) -> (result :Mining.Mining);
23+
24+
# Upstream uses ordinal @4 for `makeRpc`. This Rust crate does not bind
25+
# the Rpc interface yet, but the ordinal must be present so the schema
26+
# matches the wire protocol. Declared as a no-op stub.
27+
makeRpcStub @4 () -> ();
28+
29+
makeChain @5 (context :Proxy.Context) -> (result :Chain.Chain);
1930
}

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ capnp::generated_code!(pub mod common_capnp);
33
capnp::generated_code!(pub mod echo_capnp);
44
capnp::generated_code!(pub mod proxy_capnp);
55
capnp::generated_code!(pub mod mining_capnp);
6+
capnp::generated_code!(pub mod handler_capnp);
7+
capnp::generated_code!(pub mod chain_capnp);

0 commit comments

Comments
 (0)