From 79caa8decbb21228cf3f5cbe32fbf972c40e70dc Mon Sep 17 00:00:00 2001 From: Magnus Ahltorp Date: Mon, 27 Oct 2014 01:30:15 +0100 Subject: Check that entries are actually present when receiving new STH from merge nodes --- src/frontend.erl | 55 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 7 deletions(-) (limited to 'src/frontend.erl') diff --git a/src/frontend.erl b/src/frontend.erl index a8a8b9e..9c69517 100644 --- a/src/frontend.erl +++ b/src/frontend.erl @@ -39,13 +39,33 @@ request(post, "ct/frontend/sendsth", Input) -> {error, E} -> html("sendentry: bad input:", E); {struct, PropList} -> + OldSize = db:size(), Treesize = proplists:get_value(<<"tree_size">>, PropList), - - ok = db:set_treesize(Treesize), - - ht:reset_tree([db:size() - 1]), - - success({[{result, <<"ok">>}]}) + Indexsize = db:indexsize(), + + if + Treesize < OldSize -> + html("Size is older than current size", OldSize); + Treesize == OldSize -> + success({[{result, <<"ok">>}]}); + Treesize > Indexsize -> + html("Has too few entries", Indexsize); + true -> + NewEntries = db:leafhash_for_indices(OldSize, Treesize - 1), + lager:debug("old size: ~p new size: ~p entries: ~p", + [OldSize, Treesize, NewEntries]), + + Errors = check_entries(NewEntries, OldSize, Treesize - 1), + + case Errors of + [] -> + ok = db:set_treesize(Treesize), + ht:reset_tree([db:size() - 1]), + success({[{result, <<"ok">>}]}); + _ -> + html("Database not complete", Errors) + end + end end; request(get, "ct/frontend/currentposition", _Query) -> @@ -56,19 +76,40 @@ request(get, "ct/frontend/currentposition", _Query) -> request(get, "ct/frontend/missingentries", _Query) -> Size = db:size(), Missing = fetchmissingentries(Size), + lager:debug("missingentries: ~p", [Missing]), success({[{result, <<"ok">>}, - {entries, Missing}]}). + {entries, lists:map(fun (Entry) -> base64:encode(Entry) end, + Missing)}]}). +check_entries(Entries, Start, End) -> + lists:foldl(fun ({Hash, Index}, Acc) -> + case check_entry(Hash, Index) of + ok -> + Acc; + Error -> + [Error | Acc] + end + end, [], lists:zip(Entries, lists:seq(Start, End))). + +check_entry(Hash, Index) -> + case db:get_by_leaf_hash(Hash) of + notfound -> + {notfound, Index}; + _ -> + ok + end. fetchmissingentries(Index) -> lists:reverse(fetchmissingentries(Index, [])). fetchmissingentries(Index, Acc) -> + lager:debug("index ~p", [Index]), case db:leafhash_for_index(Index) of noentry -> Acc; Hash -> case db:entry_for_leafhash(Hash) of noentry -> + lager:debug("didn't find hash ~p", [Hash]), fetchmissingentries(Index + 1, [Hash | Acc]); _ -> fetchmissingentries(Index + 1, Acc) -- cgit v1.1