-
Notifications
You must be signed in to change notification settings - Fork 120
/
Copy pathzcash-rpc-block-template-to-proposal
executable file
·227 lines (168 loc) · 7.53 KB
/
zcash-rpc-block-template-to-proposal
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
#!/usr/bin/env bash
set -euo pipefail
# Gets a block template from a Zcash node instance,
# turns it into a block proposal using `block-template-to-proposal`,
# and sends it to one or more Zcash node instances (which can include the same node).
#
# If there are multiple proposal ports, displays a diff of the responses.
#
# Uses `zcash-cli` with the RPC ports supplied on the command-line.
function usage()
{
echo "Usage:"
echo "$0 block-template-rpc-port proposal-rpc-port [extra-proposal-rpc-port...] -- [extra-block-template-rpc-json-fields] [extra-proposal-rpc-fields]"
}
# Override the commands used by this script using these environmental variables:
ZCASH_CLI="${ZCASH_CLI:-zcash-cli}"
DIFF="${DIFF:-diff --unified --color=always}"
BLOCK_TEMPLATE_TO_PROPOSAL="${BLOCK_TEMPLATE_TO_PROPOSAL:-block-template-to-proposal}"
# time how long a command takes to run
TIME="time"
# display the current date and time
DATE="date --rfc-3339=seconds"
# Override the settings for this script using these environmental variables:
TIME_SOURCES="${TIME_SOURCES:-CurTime MinTime MaxTime ClampedNow}"
# Process arguments
if [ $# -lt 2 ]; then
usage
exit 1
fi
TEMPLATE_RPC_PORT=$1
shift
PROPOSAL_RPC_PORTS=""
while [ -n "${1:-}" ] && [ "${1-}" != "--" ]; do
PROPOSAL_RPC_PORTS="$PROPOSAL_RPC_PORTS $1"
shift
done
if [ "${1-}" == "--" ]; then
shift
fi
TEMPLATE_ARG=""
if [ $# -ge 1 ]; then
TEMPLATE_ARG="${1:-}"
shift
fi
TEMPLATE_ARG_FULL="{ \"mode\": \"template\" ${TEMPLATE_ARG:+, $TEMPLATE_ARG} }"
PROPOSAL_ARG=""
if [ $# -ge 1 ]; then
PROPOSAL_ARG="${1:-}"
shift
fi
PROPOSAL_ARG_NO_DATA="{ \"mode\": \"proposal\", \"data\": \"...\" ${PROPOSAL_ARG:+, $PROPOSAL_ARG} }"
if [ $# -ge 1 ]; then
usage
exit 1
fi
$DATE
# Use an easily identified temp directory name,
# but fall back to the default temp name if `mktemp` does not understand `--suffix`.
ZCASH_RPC_TMP_DIR=$(mktemp --suffix=.block-template-proposal -d 2>/dev/null || mktemp -d)
TEMPLATE_NODE_RELEASE_INFO="$ZCASH_RPC_TMP_DIR/template-check-getinfo.json"
PROPOSAL_NODES_RELEASE_INFO_BASE="$ZCASH_RPC_TMP_DIR/proposal-check-getinfo"
echo "Checking getblocktemplate node release info..."
$ZCASH_CLI -rpcport="$TEMPLATE_RPC_PORT" getinfo > "$TEMPLATE_NODE_RELEASE_INFO"
TEMPLATE_NODE=$(cat "$TEMPLATE_NODE_RELEASE_INFO" | grep '"subversion"' | \
cut -d: -f2 | cut -d/ -f2 | \
tr 'A-Z' 'a-z' | sed 's/magicbean/zcashd/ ; s/zebra$/zebrad/')
echo "Connected to $TEMPLATE_NODE (port $TEMPLATE_RPC_PORT) for getblocktemplate $TEMPLATE_ARG_FULL"
echo
echo "Checking proposal nodes release info..."
for PORT in $PROPOSAL_RPC_PORTS; do
PROPOSAL_NODE_RELEASE_INFO=$PROPOSAL_NODES_RELEASE_INFO_BASE.$PORT.json
$ZCASH_CLI -rpcport="$PORT" getinfo > "$PROPOSAL_NODE_RELEASE_INFO"
PROPOSAL_NODE=$(cat "$PROPOSAL_NODE_RELEASE_INFO" | grep '"subversion"' | \
cut -d: -f2 | cut -d/ -f2 | \
tr 'A-Z' 'a-z' | sed 's/magicbean/zcashd/ ; s/zebra$/zebrad/')
echo "Connected to $PROPOSAL_NODE (port $PORT) for getblocktemplate $PROPOSAL_ARG_NO_DATA"
done
echo
TEMPLATE_NODE_BLOCKCHAIN_INFO="$ZCASH_RPC_TMP_DIR/template-check-getblockchaininfo.json"
PROPOSAL_NODES_BLOCKCHAIN_INFO_BASE="$ZCASH_RPC_TMP_DIR/proposal-check-getblockchaininfo"
echo "Checking $TEMPLATE_NODE template network and tip height..."
$ZCASH_CLI -rpcport="$TEMPLATE_RPC_PORT" getblockchaininfo > "$TEMPLATE_NODE_BLOCKCHAIN_INFO"
TEMPLATE_NET=$(cat "$TEMPLATE_NODE_BLOCKCHAIN_INFO" | grep '"chain"' | cut -d: -f2 | tr -d ' ,"')
TEMPLATE_HEIGHT=$(cat "$TEMPLATE_NODE_BLOCKCHAIN_INFO" | grep '"blocks"' | cut -d: -f2 | tr -d ' ,"')
echo "Checking proposal nodes network and tip height..."
for PORT in $PROPOSAL_RPC_PORTS; do
PROPOSAL_NODE_BLOCKCHAIN_INFO=$PROPOSAL_NODES_BLOCKCHAIN_INFO_BASE.$PORT.json
$ZCASH_CLI -rpcport="$PORT" getblockchaininfo > "$PROPOSAL_NODE_BLOCKCHAIN_INFO"
PROPOSAL_NET=$(cat "$PROPOSAL_NODE_BLOCKCHAIN_INFO" | grep '"chain"' | cut -d: -f2 | tr -d ' ,"')
PROPOSAL_HEIGHT=$(cat "$PROPOSAL_NODE_BLOCKCHAIN_INFO" | grep '"blocks"' | cut -d: -f2 | tr -d ' ,"')
if [ "$PROPOSAL_NET" != "$TEMPLATE_NET" ]; then
echo "WARNING: sending block templates between different networks:"
echo "$TEMPLATE_NODE (RPC port $TEMPLATE_RPC_PORT) template is on: $TEMPLATE_NET"
echo "RPC port $PORT proposal is on: $PROPOSAL_NET"
echo
fi
if [ "$PROPOSAL_HEIGHT" -ne "$TEMPLATE_HEIGHT" ]; then
echo "WARNING: proposing block templates at different heights:"
echo "$TEMPLATE_NODE (RPC port $TEMPLATE_RPC_PORT) template is on: $TEMPLATE_HEIGHT"
echo "RPC port $PORT proposal is on: $PROPOSAL_HEIGHT"
echo
fi
done
echo
TEMPLATE_NODE_TEMPLATE_RESPONSE="$ZCASH_RPC_TMP_DIR/template-getblocktemplate-template.json"
echo "getblocktemplate template request ($TEMPLATE_NODE port $TEMPLATE_RPC_PORT):"
echo "getblocktemplate $TEMPLATE_ARG_FULL"
echo
echo "Querying $TEMPLATE_NODE $TEMPLATE_NET chain at height >=$TEMPLATE_HEIGHT..."
$DATE
$TIME $ZCASH_CLI -rpcport="$TEMPLATE_RPC_PORT" getblocktemplate "$TEMPLATE_ARG_FULL" > "$TEMPLATE_NODE_TEMPLATE_RESPONSE"
echo "Block template data is in $TEMPLATE_NODE_TEMPLATE_RESPONSE"
#cat "$TEMPLATE_NODE_TEMPLATE_RESPONSE"
echo
PROPOSAL_DATA_BASE="$ZCASH_RPC_TMP_DIR/proposal-data"
echo "Turning the template into block proposal data using $BLOCK_TEMPLATE_TO_PROPOSAL..."
for TIME_SOURCE in $TIME_SOURCES; do
PROPOSAL_DATA="$PROPOSAL_DATA_BASE.$TIME_SOURCE.json"
PROPOSAL_DEBUG="$PROPOSAL_DATA_BASE.$TIME_SOURCE.debug"
echo -n '{ "mode": "proposal", ' > "$PROPOSAL_DATA"
echo -n '"data": "' >> "$PROPOSAL_DATA"
cat "$TEMPLATE_NODE_TEMPLATE_RESPONSE" | \
$BLOCK_TEMPLATE_TO_PROPOSAL \
2> "$PROPOSAL_DEBUG" | \
(tr -d '\r\n' || true) \
>> "$PROPOSAL_DATA"
echo -n '"' >> "$PROPOSAL_DATA"
echo -n "${PROPOSAL_ARG:+, $PROPOSAL_ARG} }" >> "$PROPOSAL_DATA"
done
echo "Block proposal data is in $PROPOSAL_DATA_BASE*"
#cat "$PROPOSAL_DATA_BASE"*
echo
echo
echo "getblocktemplate proposal submissions:"
echo "getblocktemplate $PROPOSAL_ARG_NO_DATA"
$DATE
echo
PROPOSAL_NODES_PROPOSAL_RESPONSE_BASE="$ZCASH_RPC_TMP_DIR/proposal-check-getblocktemplate-proposal"
PROPOSAL_NODES_PROPOSAL_RESPONSE_LIST=""
for TIME_SOURCE in $TIME_SOURCES; do
PROPOSAL_DATA="$PROPOSAL_DATA_BASE.$TIME_SOURCE.json"
for PORT in $PROPOSAL_RPC_PORTS; do
PROPOSAL_NODE_PROPOSAL_RESPONSE=$PROPOSAL_NODES_PROPOSAL_RESPONSE_BASE.$TIME_SOURCE.$PORT.json
PROPOSAL_NODES_PROPOSAL_RESPONSE_LIST="${PROPOSAL_NODES_PROPOSAL_RESPONSE_LIST:+$PROPOSAL_NODES_PROPOSAL_RESPONSE_LIST }$PROPOSAL_NODE_PROPOSAL_RESPONSE"
# read the proposal data from a file, to avoid command-line length limits
cat "$PROPOSAL_DATA" | \
$TIME $ZCASH_CLI -rpcport="$PORT" -stdin getblocktemplate \
> "$PROPOSAL_NODE_PROPOSAL_RESPONSE" || \
echo "$ZCASH_CLI -rpcport=$PORT exited with an error"
done
done
echo
echo "Proposal response diffs between ports $PROPOSAL_RPC_PORTS and time sources $TIME_SOURCES:"
$DIFF --from-file=$PROPOSAL_NODES_PROPOSAL_RESPONSE_LIST && \
echo "getblocktemplate proposal responses were identical"
echo
EXIT_STATUS=0
for RESPONSE in $PROPOSAL_NODES_PROPOSAL_RESPONSE_LIST; do
if [ -s "$RESPONSE" ]; then
echo "Node said proposal was invalid, error response from $RESPONSE:"
cat "$RESPONSE"
EXIT_STATUS=1
else
echo "Node said proposal was valid, empty success response in $RESPONSE"
fi
done
$DATE
exit $EXIT_STATUS