Open ehildenb opened 4 years ago
set_free_balance
function https://github.com/runtimeverification/polkadot-verification/pull/15pyk
programmatic runner/initial state builder, updating several parts of KWasm build system and updating the way tokens are handled by the haskell backend https://github.com/kframework/wasm-semantics/pull/204 https://github.com/runtimeverification/polkadot-verification/pull/180 <Int RESERVED_BALANCE
in account-reaped
rule actually should be EXISTENTIAL_DEPOSIT <Int RESERVED_BALANCE
.set_free_balance
.(\/ lhs(SEMANTIC_RULES)) -> (\/ lhs(GENERATED_SPECS))
won't work, because the semantic rules contain completely unrelated steps for our initial state (which is basically just (invoke 156)
. Instead, we want to check that the generated rules cover the entire input space of our initial state, something like <k> (invoke 156) ... </k> <valStack> X : Y : Z : .ValStack </valStack> == \/ lhs(GENERATED_SPECS)
.br_if
opcode), have the haskell backend summarize that sub-trace. The summary will contain the constraints added by executing up to that point, so we can then ask Z3 for a model of the constraints up to that point along with the branch condition being true/false. For now we agreed that we'll just do simple random sampling from the input space.DomainValue
sorts): https://github.com/kframework/wasm-semantics/pull/204i32.load
followed by i32.store
to the same address leaves state unchanged) to figure out what lemmas will be needed for basic memory operations.--coverage
option for ability to get rule traces: ###K PR### ###LLVM PR###store K (load K) => .
proof, with PR ###HERE###. This requires lemmas over #setRange(...#range(...)...) => ...
and #range(...#setRange(...)...) => ...
, which are true in the "intended" model of KWasm, but the functions #range
and #setRange
are non-trivial. So we are increasing our trusted base size by including these lemmas.pyk
execution harness for KWasm/polkadot: https://github.com/runtimeverification/polkadot-verification/pull/18--coverage
mode for generating rule traces: https://github.com/runtimeverification/polkadot-verification/pull/28strict
works, explain how environment/substitution based semantics work/differ.set_reserved_balance
spec: #46Makefile
: #44 set_balance
:### `set_balance`
syntax Bool ::= ensureRoot ( AccountId ) [function]
// ---------------------------------------------------
rule ensureRoot(_) => false [owise]
rule [[ ensureRoot(ACCTID) => true ]] <adminAccounts> ADMINS </adminAccounts> requires ACCTID in ADMINS
syntax Action ::= "set_balance" "(" AccountId "," AccountId "," Int "," Int ")"
// -------------------------------------------------------------------------------
rule <k> set_balance(ORIGIN, WHO, FREE_BALANCE', RESERVED_BALANCE')
=> imbalance_event(FREE_BALANCE, FREE_BALANCE')
~> set_free_balance(WHO, FREE_BALANCE')
~> imbalance_event(RESERVED_BALANCE, RESERVED_BALANCE')
~> set_reserved_balance(WHO, RESERVED_BALANCE')
...
</k>
<account>
<accountID> WHO </accountID>
<balance> FREE_BALANCE | RESERVED_BALANCE </balance>
...
</account>
requires ensureRoot(ORIGIN)
rule <k> R:Result => . ... </k>
syntax Event ::= PositiveImbalance ( Int ) | NegativeImbalance ( Int )
// ----------------------------------------------------------------------
syntax Action ::= imbalance_event ( Int , Int )
// -----------------------------------------------
rule <k> imbalance_event(ORIG, NEW) => . ... </k>
requires NEW ==Int ORIG
rule <k> imbalance_event(ORIG, NEW) => . ... </k>
<events> ... (.List => PositiveImbalance(NEW -Int ORIG)) </events>
requires NEW >Int ORIG
rule <k> imbalance_event(ORIG, NEW) => . ... </k>
<events> ... (.List => NegativeImbalance(NEW -Int ORIG)) </events>
requires NEW <Int ORIG
totalBalance
cell for that, and square it up on this rule application.set_free_balance
and set_reserved_balance
with the rule <k> R:Result => . ... </k>
, which probably should be handled better with call frames. For this example we don't need it, since the return values aren't being used.Looks something like this.
If we have the initial program: (i32.const 1) ~> (i32.const 2) ~> (i32.add)
and the Wasm semantics contain the following rules
1: <k> (ITYPE.const X) => <ITYPE> X ... </k>
2: <k> <ITYPE> VAL => . ... </k>
<valstack> ST => <ITYPE> VAL : ST </valstack>
3: <k> (ITYPE.add) => <ITYPE> #trunc(ITYPE, X + Y) </k>
<valstack> <ITYPE> X: <ITYPE> Y : ST => ST </valstack>
then the rules will be applied in this order: 1 2 1 2 3 2
The rule merger takes pairs of rules and merges them into a single step. So rule 1 and 2 would merge to
1_2_merged: <k> (ITYPE.const X) => . ... </k>
<valstack> ST => <ITYPE> X : ST </valstack>
And the entire sequence would merge to
1_2_1_2_3_merged: <k> (ITYPE.const X) ~> (ITYPE.const Y) ~> (ITYPE.add) => . ... </k>
<valstack> ST => <ITYPE> #trunc(ITYPE, X + Y) : ST </valstack>
In the end we end up with one or more descriptions of the entire execution along one path in the Wasm code.
These descriptions then become a full generated specification of the program (in our case the program is set_balance
).
We then prove an inclusion between the hand-written specification and our generated specifications.
<curModIdx>
to <modInst>
, or from function name to function index). Virgil thinks it's possible to do, starting to look more like guided symbolic execution.set_balance
with @DemiMarie-parity yesterday, fixed up some K errors, discussed next steps in the high-level K specification.https://github.com/runtimeverification/polkadot-verification/issues/20#issuecomment-565129659
Map
matching), still not working fully though: https://github.com/kframework/kore/issues/1324#ContextLookup
, which the specification and other implementations resolve ahead of time, but we resolve on the fly. We're going to try and resolve the identifiers ahead of time in KWasm to make it so that we have one less map lookup pr local/global/function/table/memory lookup in the Wasm semantics, which should make rule merging more successful in general.Investigating this rule (which causes rule merging to blow up):
rule <k> label [ TYPES ] { _ } VALSTACK' => . ... </k>
<valstack> VALSTACK => #take(lengthValTypes(TYPES), VALSTACK) ++ VALSTACK' </valstack>
<labelDepth> DEPTH => DEPTH -Int 1 </labelDepth>
I suspect that it's because the #take(...)
ends up on the <valstack>
cell unsimplified, so later rules need to use unify with that.
Ran into bug in definedness condition for Haskell backend, so need to update the submodule to make sure it still exists on master
. Submodule update hasn't gone through in a while, working through the issues there: https://github.com/runtimeverification/polkadot-verification/pull/90
Simple update to Jenkinsfile for readability: https://github.com/runtimeverification/polkadot-verification/pull/93
Cleaning up technical debt discovered while working with Ewasm semantics: https://github.com/kframework/wasm-semantics/pull/309
Adding prover capabilities for working with memory: https://github.com/kframework/wasm-semantics/pull/310/
#take
and #drop
made total: kframework/wasm-semantics#311ByteMap
sort to avoid the #set/#get
unsoundness: kframework/wasm-semantics#321.#ContextLookup
in the semantics by preprocessing the module.local
s, but it means many rules and much boilerplate if we take that approach for eliminating all identifiers. So I'm working on a more general preprocessing function that should be easier to extend. PR here: https://github.com/kframework/wasm-semantics/pull/330.ByteMap
sort in favor of Bytes
sort that backend supports directly here: https://github.com/kframework/wasm-semantics/pull/321. This reduces the lemmas needed dramatically in favor of the backend doing specialized reasoning over the bytemaps.text2core
function working, removes #ContextLookups
. PR in draft, only documentation and formatting remains. kframework/wasm-semantics#333#wrap
operate over byte-widths (simplification): kframework/wasm-semantics#336#getRange
and #setRange
and a 50% reduction in runtime of proofs: kframework/wasm-semantics#338set_free_balance
: #100#ContextLookup
:
Sequence instructions in advance with a function: kframework/wasm-semantics#360
Now there is one rule which causes problems with merging, this one:
rule <k> block VECTYP:VecType IS end => sequenceInstrs(IS) ~> label VECTYP { .Instrs } VALSTACK ... </k>
<valstack> VALSTACK => .ValStack </valstack>
<labelDepth> DEPTH => DEPTH +Int 1 </labelDepth>
Have a strange issue where the execution traces on CI server are very short (just run initialization push; push; call code), but locally they are giving full execution traces and the corresponding rule merges.
Small updates to pyk library, search script, and pykWasm to make more graceful failure modes and better pretty printing of merged rules: #113, kframework/k#1342, and #114
Remove the $PGM
variable from the KWasm semantics, leave running up to the embedder. https://github.com/kframework/wasm-semantics/pull/362
priority
attribute: https://github.com/kframework/kore/pull/1898priority
attribute are encoded by the frontend: https://github.com/kframework/k/issues/1355_
to unused variables in Wasm https://github.com/kframework/wasm-semantics/pull/366make test-search
results in long traces.
make polkadot-runtime-sources
but not make polkadot-runtime-loaded
. Since search.py
grabs the name from the .wat
file but runs the .json
file, the names don't match and the call fails.Polkadot
build step.--coverage
kompilation crashing when importing BYTES
: https://github.com/kframework/k/pull/1394#ContextLookup
for types:
set-balance.md
module with LLVM backendset-balance.md
module.set_account
function to the Action
s in set_balance.md
: https://github.com/paritytech/substrate/blob/e824e8ab0fadec9949ebb8b9e14d98703d6b8d44/frame/balances/src/lib.rs#L494set*balance
as "depracated"Removed half of #ContextLookup
for types: https://github.com/kframework/wasm-semantics/pull/368
#ContextLookup
are not used in the generated Wasm.Remove #ContextLookup
for labels, and desugar function bodies in pre-pass: https://github.com/kframework/wasm-semantics/pull/371
Hypothesis on why update deps is failing: mismatch between which main module is used in kpol vs kwasm.
Project status
Pair programming:
Milestone 3 Generate the Wasm execution specifications of the bytecode: ● a. Generate execution traces of the Wasm code using the LLVM backend and a fuzzing frontend. This will produce sequences of rules in the order that they are executed, called BALANCES-MODULE-TRACE_i (subscripted by _i for the fact that there are many traces). ● B. Do common subsequence analysis on the BALANCES-MODULE-TRACE_i to find common subsequences of rules, and ask the Haskell backend to merge those rules together into rules which take larger steps. Several heuristics for rule merging will be provided, which select different subsequences to do merging with, and we can see which ones perform best. ● Compile the generated merged rules into the semantics with higher priority than the original rules, so that they can be used for both symbolic and concrete execution.
search.py
was putting the instructions to be executed on the <k>
cell, instead of the new <instrs>
cell. The kwasm-polkadot-host.md
also contained instances of using the <k>
cell instead of the <instrs>
cell.
kwasm-polkadot-host.md
file, and built. Build works with slight massaging, but not for rules with #Ceil
side condition.$<pallet_balances::Module<T_I>_as_frame_support::traits::Currency<<T_as_frame_system::Trait>::AccountId>>::transfer::h959b05a069cec0be
post_mutation
.
The approach would be to give specifications of lower-level functions, instead of actually calling them, "coding by contract"-styledeposit_event
function here: https://github.com/paritytech/substrate/blob/f92a86a9506f331a867d36b0aa6b0bff3e462536/frame/balances/src/lib.rs#L612
Add performance measurement code to see the performance impact of merged rules.
krun
:
--bug-report
flag to the --haskell-backend-command "kore-exec --bug-report"
Generates the inputs for the Haskell backend, and necessary command, as a nice tar-ball.--dry-run
flag.
This generates all the required files (by calling the frontend) as well as giving the command that needs to be called on the command line.deposit_event
Unfortunately I didn't think to keep meeting notes from the previous meetings, but I'll do so here for upcoming meetings.