Skip to content

Commit 8bb4151

Browse files
committed
Fix for blockchain_sync
1 parent 448ebe7 commit 8bb4151

4 files changed

Lines changed: 200 additions & 12 deletions

File tree

apps/tpnode/src/blockchain_reader.erl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,22 @@ handle_cast({tpic, From, #{
341341
})),
342342
{noreply, State};
343343

344+
handle_cast({update,#{temporary:=_,header:=#{height:=H1, parent:=Par}=Hdr,hash:=Hash1}=NewTmp},
345+
#{lastblock:=#{header:=#{height:=H0}, hash:=Hash0 }}=State) ->
346+
if(H1==H0+1 andalso Par==Hash0) ->
347+
{noreply, State#{tmpblock=>NewTmp}};
348+
true ->
349+
?LOG_NOTICE("Incompatible tmp block ~s arrived to RDR: ~p", [blkid(Hash1),Hdr]),
350+
if(H1=/=H0+1) ->
351+
?LOG_NOTICE("Height mismatch ~p =/= ~p",[H1,H0+1]);
352+
(Par=/=Hash1) ->
353+
?LOG_NOTICE("Parent hash mismatch ~p =/= ~p",[Hash0,Hash1]);
354+
true ->
355+
?LOG_NOTICE("Can't understand what is wrong",[])
356+
end,
357+
{noreply, get_last(State)}
358+
end;
359+
344360
handle_cast(update, State) ->
345361
{noreply, get_last(State)};
346362

apps/tpnode/src/blockchain_sync.erl

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,44 @@ chainstate() ->
7676
init(_Args) ->
7777
{ok, LDB}=ldb:open(utils:dbpath(db)),
7878
{ok, get_last(#{
79-
ldb=>LDB
79+
ldb=>LDB,
80+
last_res=>undefined
8081
})}.
8182

83+
handle_call(last_res, _From, State) ->
84+
{reply, maps:get(last_res,State,not_found), State};
85+
86+
handle_call({runsync_h,N}, _From, State) ->
87+
#{header:=#{height:=MyHeight}, hash:=MyLastHash}=blockchain:last_meta(),
88+
stout:log(runsync, [ {node, nodekey:node_name()}, {where, got_info} ]),
89+
?LOG_DEBUG("got runsync, myHeight: ~p, myLastHash: ~p", [MyHeight, blkid(MyLastHash)]),
90+
{H,T} = case N of
91+
any -> {any, any};
92+
I when is_integer(I) ->
93+
{I, any};
94+
{I, J} when is_integer(I), is_integer(J) ->
95+
{I, J}
96+
end,
97+
98+
?LOG_DEBUG("use default list of candidates"),
99+
Candidates = sort_rnd(
100+
lists:filter(
101+
fun(_) when H==any, T==any -> true;
102+
({_, #{last_height:=CH}}) when CH==H, T==any -> true;
103+
({_, #{last_height:=CH,last_temp:=CT}}) when CH==H, CT==T -> true;
104+
(_) -> false
105+
end,
106+
tpiccall(
107+
<<"blockchain">>,
108+
#{null=><<"sync_request">>},
109+
[last_hash, last_height, chain, last_temp]
110+
)
111+
)
112+
),
113+
self() ! {runsync, Candidates},
114+
{reply, {ok, Candidates}, State};
115+
116+
82117
handle_call({runsync, NewChain}, _From, State) ->
83118
stout:log(runsync, [ {node, nodekey:node_name()}, {where, call} ]),
84119
self() ! runsync,
@@ -180,31 +215,35 @@ handle_info({bbyb_sync, Hash},
180215
?LOG_DEBUG("run bbyb sync res ~p",[BBRes]),
181216
case BBRes of
182217
sync_cont ->
183-
{noreply, State};
218+
{noreply, State#{last_res => {erlang:system_time(),sync_cont}}};
184219
done ->
185220
synchronizer ! imready,
186221
{noreply,
187-
maps:without([sync, syncblock, sync_peer, sync_candidates, bbsync_pid], State)
222+
maps:without([sync, syncblock, sync_peer, sync_candidates, bbsync_pid],
223+
State#{last_res => {erlang:system_time(),done}})
188224
};
189225
{broken_block, C1} ->
190226
{noreply,
191227
maps:without([sync, syncblock, sync_peer, sync_candidates, bbsync_pid],
192228
State#{
193-
sync_candidates => C1
229+
sync_candidates => C1,
230+
last_res => {erlang:system_time(),broken_block}
194231
})
195232
};
196233
{broken_sync, C1} ->
197234
{noreply,
198235
maps:without([sync, syncblock, sync_peer, sync_candidates, bbsync_pid],
199236
State#{
200-
sync_candidates => C1
237+
sync_candidates => C1,
238+
last_res => {erlang:system_time(), broken_sync}
201239
})
202240
};
203241
{noresponse, C1} ->
204242
{noreply,
205243
maps:without([sync, syncblock, sync_peer, sync_candidates, bbsync_pid],
206244
State#{
207-
sync_candidates => C1
245+
sync_candidates => C1,
246+
last_res => {erlang:system_time(),noresponse}
208247
})
209248
}
210249
end;

apps/tpnode/src/blockchain_updater.erl

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,9 @@ handle_call({new_block, #{hash:=BlockHash,
349349
})
350350
})
351351
}),
352-
gen_server:cast(blockchain_reader,update),
352+
gen_server:cast(blockchain_reader,{update,MBlk}),
353353
gen_server:cast(tpnode_ws_dispatcher, {new_block, MBlk}),
354+
354355
{reply, ok, State#{
355356
tmpblock=>MBlk
356357
}};
@@ -657,7 +658,7 @@ handle_cast({signature, BlockHash, _Sigs}, State) ->
657658
[blkid(BlockHash) ]),
658659
T=maps:get(unksig,State,0),
659660
if(T>=2) ->
660-
self() ! checksync,
661+
blockchain_sync ! checksync,
661662
{noreply, State};
662663
true ->
663664
{noreply, State#{unksig=>T+1}}
@@ -728,6 +729,43 @@ handle_info({continue_cleanup,N}, #{ldb:=LDB,clean_iterator:=Iterator}=State) ->
728729
{noreply, maps:without([clean_iterator], State)}
729730
end;
730731

732+
handle_info(check_mgmt, #{settings:=Sets}=State) ->
733+
InChain=try
734+
settings:get(
735+
[<<"current">>,<<"management">>,<<"uri">>],
736+
Sets,
737+
undefined
738+
)
739+
catch Ec:Ee:S ->
740+
?LOG_ERROR("~p:~p @ ~p...",[Ec,Ee,hd(S)]),
741+
undefined
742+
end,
743+
if InChain == undefined ->
744+
{noreply, State};
745+
is_binary(InChain) ->
746+
InChain1=binary_to_list(InChain),
747+
MgmtCfg=utils:read_cfg(mgmt_cfg,undefined),
748+
InCfg=case MgmtCfg of
749+
Cfg when is_list(Cfg) ->
750+
proplists:get_value(management,Cfg,undefined);
751+
_ ->
752+
undefined
753+
end,
754+
if InChain1 == InCfg ->
755+
{noreply, State};
756+
is_list(MgmtCfg) -> % OVERRIDE MANAGEMENT URL IN CONFIG
757+
?LOG_INFO("Check mgmt ~p ~p",[InCfg,InChain]),
758+
utils:update_cfg(mgmt_cfg,[{management,InChain1},{http,[]},{https,[]}]),
759+
{noreply, State};
760+
true -> % no config
761+
?LOG_INFO("Check mgmt ~p ~p",[InCfg,InChain]),
762+
utils:update_cfg(mgmt_cfg,[{management,InChain1}]),
763+
{noreply, State}
764+
end;
765+
true ->
766+
{noreply, State}
767+
end;
768+
731769
handle_info(_Info, State) ->
732770
?LOG_NOTICE("BC unhandled info ~p", [_Info]),
733771
{noreply, State}.

apps/tpnode/src/tpnode_httpapi.erl

Lines changed: 99 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,12 @@ h(Method, [<<"playground">>|Path], Req) ->
119119
h(Method, [<<"api">>|Path], Req) ->
120120
h(Method, Path, Req);
121121

122-
h(<<"GET">>, [<<"node">>, <<"status">>], _Req) ->
122+
h(<<"GET">>, [<<"node">>, <<"status">>], Req) ->
123123
Chain=chainsettings:get_val(mychain),
124124
#{hash:=Hash,
125125
header:=Header1}=Blk=blockchain:last_meta(),
126126
Temp=maps:get(temporary,Blk,false),
127-
BinPacker=packer(_Req),
127+
BinPacker=packer(Req),
128128
Header=maps:map(
129129
fun(roots, V) ->
130130
[ if is_binary(RV) ->
@@ -173,6 +173,41 @@ h(<<"GET">>, [<<"node">>, <<"status">>], _Req) ->
173173
[]
174174
end,
175175
{Ver, _BuildTime}=tpnode:ver(),
176+
BRLB = begin
177+
QS=cowboy_req:parse_qs(Req),
178+
case proplists:get_value(<<"brlb">>, QS) of
179+
undefined -> undefined;
180+
_ ->
181+
try
182+
#{hash:=BVHas,
183+
header:=#{chain := BVCh,
184+
height := BVHei,
185+
parent := BVPar,
186+
roots := BVRoots}
187+
}=BVB=gen_server:call(blockchain_reader,last_block),
188+
maps:merge(
189+
#{hash=>BinPacker(BVHas),
190+
header=>#{
191+
chain=>BVCh,
192+
height=>BVHei,
193+
parent=>BinPacker(BVPar),
194+
roots=>[ if is_binary(RV) ->
195+
[N, BinPacker(RV)];
196+
true ->
197+
[N, RV]
198+
end || {N,RV} <- BVRoots ]
199+
}
200+
},
201+
maps:with([temporary],BVB)
202+
)
203+
catch Ec1:Ee1:S1 ->
204+
?LOG_ERROR("blockchain_reader last_block error: ~p:~p~n~p",
205+
[Ec1, Ee1, hd(S1)]),
206+
#{ error => true }
207+
end
208+
end
209+
end,
210+
176211
answer(
177212
#{ result => <<"ok">>,
178213
status => #{
@@ -193,6 +228,7 @@ h(<<"GET">>, [<<"node">>, <<"status">>], _Req) ->
193228
gen_server:call(blockvote, status)
194229
catch _:_ -> #{ error => true }
195230
end,
231+
blockchain_reader_lastblock => BRLB,
196232
xchain_inbound => try
197233
gen_server:call(xchain_dispatcher, peers)
198234
catch _:_ -> #{ error => true }
@@ -226,8 +262,15 @@ h(<<"GET">>, [<<"node">>, <<"chainstate">>], _Req) ->
226262
});
227263

228264
h(<<"POST">>, [<<"node">>, <<"runsync">>], _Req) ->
229-
blockchain_sync ! runsync,
230-
answer(#{ result => <<"ok">> });
265+
R=list_to_binary(
266+
[ io_lib:format("~p~n",
267+
[ gen_server:call(blockchain_sync, {runsync_h, any}) ]
268+
) ]
269+
),
270+
answer(#{
271+
result => <<"ok">>,
272+
candidates => R
273+
});
231274

232275
h(<<"POST">>, [<<"node">>, <<"new_peer">>], Req) ->
233276
{RemoteIP, _Port}=cowboy_req:peer(Req),
@@ -936,6 +979,58 @@ h(<<"GET">>, [<<"settings">>|Path], Req) ->
936979
#{jsx=>[ strict, {error_handler, EHF} ]}
937980
);
938981

982+
983+
h(<<"POST">>, [<<"debug">>, <<"runsync">>|N], _Req) ->
984+
Q = case N of
985+
[NN] ->
986+
{runsync_h, binary_to_integer(NN)};
987+
[NN,TT] ->
988+
{runsync_h, {binary_to_integer(NN),binary_to_integer(TT)}};
989+
[] ->
990+
{runsync_h, any}
991+
end,
992+
try
993+
R=case gen_server:call(blockchain_sync, Q) of
994+
{ok, RR} when is_list(RR)->
995+
lists:foldl(
996+
fun({{PubKey,Service, _}, Map},A) ->
997+
Node=case chainsettings:is_net_node(PubKey) of
998+
{ok, NNN} -> NNN;
999+
_ -> PubKey
1000+
end,
1001+
[ [ [Node, Service], Map ] | A ];
1002+
({Key,Map},A) ->
1003+
[[list_to_binary( [ io_lib:format("~p", [ [Key] ]) ]),
1004+
list_to_binary( [ io_lib:format("~p", [ [Map] ]) ]) ]|A];
1005+
(Other,A) ->
1006+
[list_to_binary( [ io_lib:format("( (~p) )", [ [Other] ]) ])|A]
1007+
end, [], RR);
1008+
{ok, RR} ->
1009+
list_to_binary( [ io_lib:format("d:~p", [ RR ]) ]);
1010+
Other ->
1011+
list_to_binary( [ io_lib:format("o:~p", [ Other ]) ])
1012+
end,
1013+
answer(#{
1014+
result => <<"ok">>,
1015+
res => R
1016+
})
1017+
catch Ec:Ee:S ->
1018+
err(
1019+
10008,
1020+
iolist_to_binary(io_lib:format("Error: ~p:~p at ~p", [Ec,Ee,S])),
1021+
#{},
1022+
#{http_code=>500}
1023+
)
1024+
end;
1025+
1026+
h(<<"POST">>, [<<"debug">>, <<"last_sync_res">>], _Req) ->
1027+
R0=gen_server:call(blockchain_sync, last_res),
1028+
R=list_to_binary( [ io_lib:format("~p", [ R0 ]) ]),
1029+
answer(#{
1030+
result => <<"ok">>,
1031+
res => R
1032+
});
1033+
9391034
h(<<"POST">>, [<<"debug">>,<<"bcupdater_reloadset">>], Req) ->
9401035
BinPacker=packer(Req),
9411036
EHF=fun([{Type, Str}|Tokens],{parser, State, Handler, Stack}, Conf) ->

0 commit comments

Comments
 (0)