Skip to content
This repository was archived by the owner on Mar 5, 2024. It is now read-only.
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 41 additions & 7 deletions src/blockchain_worker.erl
Original file line number Diff line number Diff line change
Expand Up @@ -879,21 +879,29 @@ reset_ledger_to_snap(Hash, Height, State) ->
snapshot_sync(State1#state{snapshot_info=SnapInfo}).

start_sync(#state{blockchain = Chain, swarm_tid = SwarmTID} = State) ->
case get_random_peer(SwarmTID) of
Peer = get_configured_or_random_peer(SwarmTID),
case Peer of
no_peers ->
%% try again later when there's peers
schedule_sync(State);
RandomPeer ->
{Pid, Ref} = start_block_sync(SwarmTID, Chain, RandomPeer, [], <<>>),
Peer ->
{Pid, Ref} = start_block_sync(SwarmTID, Chain, Peer, [], <<>>),
lager:info("new block sync starting with Pid: ~p, Ref: ~p, Peer: ~p",
[Pid, Ref, RandomPeer]),
[Pid, Ref, Peer]),
State#state{sync_pid = Pid, sync_ref = Ref}
end.

get_configured_or_random_peer(SwarmTID) ->
case get_configured_sync_peer(SwarmTID) of
undefined-> get_random_peer(SwarmTID);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
undefined-> get_random_peer(SwarmTID);
undefined -> get_random_peer(SwarmTID);

P -> P
end.

-spec get_random_peer(SwarmTID :: ets:tab()) -> no_peers | string().
get_random_peer(SwarmTID) ->
lager:debug("Get random peer"),
Peerbook = libp2p_swarm:peerbook(SwarmTID),
%% limit peers to random connections with public addresses
%% limit peers to connections with a public address
F = fun(Peer) ->
case application:get_env(blockchain, testing, false) of
false ->
Expand All @@ -906,9 +914,35 @@ get_random_peer(SwarmTID) ->
case libp2p_peerbook:random(Peerbook, [], F, 100) of
false -> no_peers;
{Addr, _Peer} ->
"/p2p/" ++ libp2p_crypto:bin_to_b58(Addr)
libp2p_crypto:pubkey_bin_to_p2p(Addr)
end.

-spec get_configured_sync_peer(ets:tab()) -> string() | undefined.
get_configured_sync_peer(SwarmTID) ->
case application:get_env(blockchain, sync_peers, []) of
[] ->
lager:debug("No sync_peers configured"),
undefined;
ConfiguredPeers ->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ConfiguredPeers ->
ConfiguredPeers when is_list(ConfiguredPeers) ->

Copy link
Contributor Author

@joecaswell joecaswell Apr 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as we're validating, we should check [P | _] when is_list(P) to make sure it is a list of strings, also should gracefully fail back to random so the node will still try to sync if the config is pooched.

Peerbook = libp2p_swarm:peerbook(SwarmTID),
{Left, Right} = lists:split(rand:uniform(length(ConfiguredPeers)), ConfiguredPeers),
get_configured_sync_peer(SwarmTID, Peerbook, Right ++ Left)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this "cutting the deck" of configured peers so to speak? just a cheaper version of shuffling the list?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, exactly. We only need one peer, the rest of the list is only used if the chosen one fails to connect.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

slick solution 👍

end.

get_configured_sync_peer(SwarmTID, Peerbook, [ Peer | RestPeers ]) ->
case libp2p_swarm:connect(SwarmTID, Peer) of
{ok, _Session} ->
lager:debug("Connected to configured peer ~p",[Peer]),
Peer;
_Error ->
lager:debug("Failed to connect to configured peer ~p: ~p",[Peer, _Error]),
get_configured_sync_peer(SwarmTID, Peerbook, RestPeers)
end;
get_configured_sync_peer(_SwarmTID, _, []) ->
% unable to connect to any of the provided peers
lager:debug("Failed to connect to any configured peer"),
undefined.

reset_sync_timer(State) ->
lager:info("try again in ~p", [?SYNC_TIME]),
erlang:cancel_timer(State#state.sync_timer),
Expand Down Expand Up @@ -1028,7 +1062,7 @@ grab_snapshot(Height, Hash) ->
Chain = blockchain_worker:blockchain(),
SwarmTID = blockchain_swarm:tid(),

case get_random_peer(SwarmTID) of
case get_configured_or_random_peer(SwarmTID) of
no_peers -> {error, no_peers};
Peer ->
case libp2p_swarm:dial_framed_stream(SwarmTID,
Expand Down