fluencelabs/aquavm

Bug: fold and canon can lead to an invalid state merging

mikevoronov opened this issue · 0 comments

Due to current values stream merging scheme it's possible to merge states in inappropriate way if canon is used inside fold.

For example, given the annotated AIR script:

(seq
    (seq
        (call "relay" ("kad" "neighborhood") ["relay"] neighs_top) ; ok = ["p1"]
        (seq
            (call "p1" ("kad" "neighborhood") ["p1"] neighs_inner) ; ok =["p1"]
            (par
                (call "relay" ("peer" "identify") ["relay"] $external_addresses) ; behaviour = echo
                (call "p1" ("peer" "identify") ["p1"] $external_addresses) ; behaviour = echo
            )
        )
    )
    (seq
        (new $monotonic_stream
            (fold $external_addresses elem
                (seq
                    (ap "asd" $monotonic_stream)
                    (canon "relay" $monotonic_stream #result)
                )
            )
        )
        (call "client" ("return" "") [$external_addresses neighs_inner] x) ; ok = null
    )
)

when executed cyclically on the nodes "client", "relay" and "p1", eventually gives an outcome with an internal error:

RawAVMOutcome { 
   ret_code: 20000,
   error_message: "on instruction 'canon \"relay\" $monotonic_stream #result' trace handler encountered an error: position 6 from canon result CanonResult { stream_elements_pos: [6, 8] } hasn't been met yet",
   data: [...],
   call_requests: {},
   next_peer_pks: []
}

It happens because on merging previous and current data, unmet calls from the current data are all put into the same generation in the new data without particular order, and their ordering doesn't match the execution order.