@@ -1018,3 +1018,42 @@ def test_xpay_bip353(node_factory):
10181018
10191019 node_factory .join_nodes ([l2 , l1 ])
10201020 l2 .
rpc .
xpay (
'[email protected] ' ,
100 )
1021+
1022+
1023+ @pytest .mark .xfail (strict = True )
1024+ def test_xpay_blockheight_mismatch (node_factory , bitcoind , executor ):
1025+ """We should wait a (reasonable) amount if the final node gives us a blockheight that would explain our failure."""
1026+ l1 , l2 , l3 = node_factory .line_graph (3 , wait_for_announce = True )
1027+ sync_blockheight (bitcoind , [l1 , l2 , l3 ])
1028+
1029+ # Pin `send` at the current height. by not returning the next
1030+ # blockhash. This error is special-cased not to count as the
1031+ # backend failing since it is used to poll for the next block.
1032+ def mock_getblockhash (req ):
1033+ return {
1034+ "id" : req ['id' ],
1035+ "error" : {
1036+ "code" : - 8 ,
1037+ "message" : "Block height out of range"
1038+ }
1039+ }
1040+
1041+ l1 .daemon .rpcproxy .mock_rpc ('getblockhash' , mock_getblockhash )
1042+ bitcoind .generate_block (4 )
1043+ sync_blockheight (bitcoind , [l2 , l3 ])
1044+ l1_height = l1 .rpc .getinfo ()['blockheight' ]
1045+ l3_height = l3 .rpc .getinfo ()['blockheight' ]
1046+
1047+ inv = l3 .rpc .invoice (42 , 'lbl' , 'desc' )['bolt11' ]
1048+
1049+ # This will wait, then fail.
1050+ with pytest .raises (RpcError , match = f'Timed out waiting for blockheight { l3_height } ' ):
1051+ l1 .rpc .xpay (invstring = inv , retry_for = 10 )
1052+
1053+ # This will succeed, because we wait for the blocks.
1054+ fut = executor .submit (l1 .rpc .xpay , invstring = inv , retry_for = 60 )
1055+ l1 .daemon .wait_for_log (fr"Our blockheight may be too low: waiting .* seconds for height { l3_height } \(we are at { l1_height } \)" )
1056+
1057+ # Now let it catch up, and it will retry, and succeed.
1058+ l1 .daemon .rpcproxy .mock_rpc ('getblockhash' )
1059+ fut .result (TIMEOUT )
0 commit comments