anchor.diff:    [Res] = execute_sequential([Fun]),
     Res.
   
  -read_write_tx(Node, Key, Value) ->
  +execute_blocking_sequential(Funs) when is_list(Funs) ->
  +  lists:reverse(lists:foldl(fun(F, Acc) ->
  +    Res = F(),
  +    timer:sleep(200),
  +    [Res | Acc]
  +  end, [], Funs));
  +
  +execute_blocking_sequential(Fun) ->
  +  [Res] = execute_blocking_sequential([Fun]),
  +  Res.
  +
  +read_write_tx(Node, Assignments) when is_list(Assignments) ->
  +  Keys = lists:map(fun({Key, _}) -> Key end, Assignments),
     fun(From) ->
       transaction(Node, From, [
  -      fun(T, _) -> read_objects(Node, T, Key) end,
  -      fun(T, _) -> update_objects(Node, T, {Key, Value}) end
  -    ])
  -  end.
  +      fun(T, _) -> read_objects(Node, T, Keys) end,
  +      fun(T, _) -> update_objects(Node, T, Assignments) end
  +    ])
  +  end;
  +
  +read_write_tx(Node, Assignment) ->
  +  read_write_tx(Node, [Assignment]).
  +
  +blocking_read_write_tx(Node, Assignments) when is_list(Assignments) ->
  +  Keys = lists:map(fun({Key, _}) -> Key end, Assignments),
  +  fun() ->
  +    blocking_transaction(Node, [
  +      fun(T, _) -> read_objects(Node, T, Keys) end,
  +      fun(T, _) -> update_objects(Node, T, Assignments) end
  +    ])
  +  end;
  +
  +blocking_read_write_tx(Node, Assignment) ->
  +  blocking_read_write_tx(Node, [Assignment]).
   
   read_only_tx(Node, Key) ->
     fun(From) ->
  
positive.code:   [{Key, assign, Value}].
  
  transaction(Node, Dst, Statements) ->
    {ok, T} = rpc:call(Node, antidote, start_transaction, [ignore, []]),
    Last = lists:foldl(fun(F, Acc) -> F(T, Acc) end, [], Statements),
    CT = rpc:call(Node, antidote, commit_transaction, [T]),
    Dst ! {CT, Last}.
  
negative.code: 
    ?assertMatch(ok, Status),
    ?assertEqual([20], Payload).
  
  read_log_test(Node) ->
    Key = ?KEY(read_log),
    BaseValue = initial_value,
  
    Updates = 15,
    UpdateTxs = lists:map(
      fun(N) -> blocking_read_write_tx(Node, {Key, N}) end,
      lists:seq(0, Updates)
    ),
  
    %% First, set the key to some initial value we can validate later
    _ = execute_blocking_sequential([blocking_read_write_tx(Node, {Key, BaseValue})]),
  
    %% Validate that the base value went through
    {{Status, _}, {_, Payload}} = execute_blocking_sequential(blocking_read_only_tx(Node, Key)),
    ?assertMatch(ok, Status),
    ?assertEqual([BaseValue], Payload),
  
    %% Now start a long-running transaction
    {ok, Tx} = start_transaction(Node),
  
    %% Pick up a dependency on the previous transaction
    {ok, Read1} = read_objects(Node, Tx, Key),
    ?assertEqual([BaseValue], Read1),
  
    timer:sleep(100),
  
    %% Now stress the partition by forcing it to garbage collect
    Res = execute_blocking_sequential(UpdateTxs),
    ?assert(lists:all(fun({{ok, _}, _}) -> true; (_) -> false end, Res)),
  
    %% Now read again. Because we picked up an empty clock,
    %% the snapshot should no longer be in memory, and has to
    %% be retrieved from the event log.
    {ok, SecondRead} = read_objects(Node, Tx, Key),
    ?assertEqual([BaseValue], SecondRead),
  
    {ok, []} = commit_transaction(Node, Tx),
    ok.
  
  %% Util functions
  
  