API Trace Rendering Extension Point

This post presents how API traces, generated for sbuilder formal models, can be inspected, and how the output can be modified using api-call-init extension point of tla-trace-filter -tool.

Sbuilder possibility operators may generate traces, which demonstrate that behaviour given by the operator is present in the model checking state space. An API trace is a sequence of steps, where a step includes the state of the formal model before the API call, interface operation called and its parameters bindings, and the state of formal model after the API call. This post shows to how to extend rendering of formal model API traces.

1 SBuilder User’s Guide Blog Series

A series of posts comprising a User’s Guide for sbuilder-eth plugin in SBuilder tool:

  • Truffle install: documents steps to install Truffle Ethereum development environment to Node-js.
  • Sbuilder install: shows steps to install sbuilder-eth GEM to Truffle Ethereum development environment. After installation a minimal configuration is used to validate that the installation was successful.
  • Managing state space generation in Sbuilder: expolore, how to state space explosion manifests itself in formal models created by Sbuilder -tool, and how state space explosion can be controlled by limiting cardinality of domain sets in application data model.
  • Simple Bank contract: use a simple 10 line Solidity contract containing two (subtle) “bugs” (=violations of correctness promise), and a demonstrates, how to use invariants in Sbuilder to find these violations.
  • Sbuilder generated correctness criteria: demonstrates using Sbuilder generated correctness criteria. The criteria presented include ensuring correctness of 1) contract function return values, 2) contract type, and 3) account balances on blockchain.
  • Demonstrate Sbuilder Translation Results (Wallet-1): use a very contrived example to demonstrate, how to include manually crafted TLA+ snippets into a formal model created by SBuilder. The main purpose is to 1) show, how to bind TLA code with Solidity interfaces, 2) understand TLA -files generated in Sbuilder translation, and 3) explain, how Sbuilder “possibility” operator relates to model checking formal model correctness. A more realistic example of using manual TLA+ to specify is given in another post.
  • Translate Solidity Automatically (Wallet-2): explains how to integrate manually crafted and automatically translated TLA+ snippets to work together in a Sbuilder formal model.
  • API Trace Extension Point (Wallet-3): presents how API traces, generated for sbuilder formal models, can be inspected, and how the output can be modified using api-call-init extension point of tla-trace-filter -tool.

Rest of this blog entry assumes that sbuilder-eth GEM and has been installed to a Truffle Ethereum development environment as documented in a previous blog post.

2 Assumptions

The examples used in this post assume that the possibility operator dummy_created for setup wallet-1 introduced in a previous blog post has been executed,

 export POSSIBILITY=dummy_created; SETUP=wallet-1 npm run-script sbuilder-possible

and that the formal model trace exists in a file gen/$SETUP/tlc.out.

3 API Trace Rendering Extension Point

Sbuilder Formal model API traces are outputted with tla-trace-filter.rb api-calls -command, which previosly, in Sbuilder installation on Truffle, was configured as npm script sbuilder-api in file package.json:

"sbuilder-api": "bundle exec tla-trace-filter.rb api-calls $SETUP --src-dir=. --solc-line",

3.1 Read Instructions In api-call-init.mustache File

Trace Rendering Extension Point uses Mustache template -tool. The extension is activated by overriding mustache/api-call-init.mustache file within tla-trace-filter GEM.

Instructions for the extension point are shown with the command:

 cat $(bundle show tla-trace-filter)/mustache/api-call-init.mustache

The output shows:

{{!

  api-call-init.mustache: define rendering for 'api-call' command
  
  Override this template to use other than default rendering.

  This template is called once for a 'tla-trace-filter.rb api-call'.
  It initialize four mappings: 

  - API_INPUT_INIT : render state before API call
  - API_CALL_INIT : render API interface and API input parameters
  - API_RETURN_INIT : render API interface and API return parameters
  - API_OUTPUT_INIT : render state after API call

  These mappings wrap mustache lambda sections, which contain a YAML
  formatted hash mapping interface operation to a name of mustache
  partial template. Two special keys are used: 1) 'default'
  (=template to use if no other found), and 2) 'empty' (=template to
  use if 'interface.interface_operation' is nil).

  Example:

  Demo(): solidity-constructor
  Demo(execute): solidity-message
  empty: api-call-empty
  default: api-call-input

  Which reads:
  - inteface operation "Demo()" uses mustache partial 'solidity-constructor.mustache'
  - interface Demo(execute) use partial 'solidity-message.mustache
  - undedefined interface operation (initial state) use partial 'api-call-empty.mustache'
  - all other interface operations use  template 'api-call-input.mustache'

  Search parth of these template files is configured using command line option --mustache
  
}}{{!

   Configure templates to render state before API call

}}{{#API_INPUT_STATE_INIT}}
default: api-call-input
empty: api-call-input
{{/API_INPUT_STATE_INIT}}{{!

 Configure templates to render API CALL
 
}}{{#API_CALL_INIT}}
default: api-call-default
{{/API_CALL_INIT}}{{!

 Configure templates to render API_RETURN
 
}}{{#API_RETURN_INIT}}
default: api-call-return
empty: api-call-return
{{/API_RETURN_INIT}}{{!

    Configure templates to render state after API call
    
}}{{#API_OUTPUT_STATE_INIT}}
default: api-call-output
empty: api-call-output
{{/API_OUTPUT_STATE_INIT}}{{!

  Do not output new-line

Local Variables:
require-final-newline: nil
End:
}}

3.2 Create a Directory to Hold Extension Partials

For an example, start by creating a directory testcase-templates to hold extension templates:

 mkdir testcase-templates

3.3 Override api-call-init.mustache

Create file testcase-templates/api-call-init.mustache to override default api-call-init.mustache in tla-trace-filter GEM.

In this example, we instruct tla-trace-filer.rb to use template demo-call.mustache to render API calls to Wallet() interface:

{{!

  Modify rendering API calls to Wallet() interface operation.
  Use defaults for otherwise.

}}
{{#API_CALL_INIT}}
Wallet(): demo-call
{{/API_CALL_INIT}}

3.4 Implement Partial Template to Render API Call

Create a file in testcase-templates/demo-call.mustache

{{!
     demo-call.mustache: render state before making API call
}}
CALL-WALLET:{{now}} {{interface.interface_operation}}( value: {{{api_input.value }}}, sender: {{api_input.sender}}, owners: {{{api_input._owners.to_a }}} )

to implement API call for Wallet() constructor, as configured above.

4 Output Sbuilder API Trace

4.1 Default Sbuilder API Trace Output

In Sbuilder installation on Truffle , we have bound tla-trace-filter.rb api-calls -command to npm script sbuilder-api. This command outputs default Sbuilder API trace

  SETUP=wallet-1 npm run-script sbuilder-api

The output for example setup wallet-1 shows the following API calls and formal parameter bindings:

CALL:1 geth(newAccount)( {"sender"=>nil, "originator"=>nil, "value"=>0, "recipient"=>nil} )
CALL:2 Wallet()( {"sender"=>"d_eth_address_1", "originator"=>nil, "value"=>0, "_owners"=>#<Set: {"d_eth_address_1", "d_eth_address_3"}>} )
CALL:3 Wallet(execute)( {"sender"=>nil, "originator"=>nil, "value"=>0, "recipient"=>"d_eth_address_2", "_undersigners"=>#<Set: {"d_eth_address_1", "d_eth_address_3"}>, "_nonce"=>0} )

4.2 Extended Sbuilder API Trace Output

To use the template extension created, we have to pass extension directory testcase-templates/ to tla-trace-filter.rb -command using --mustache option

export SETUP=wallet-1 && bundle exec tla-trace-filter.rb api-calls $SETUP --src-dir=. --solc-line --mustache=testcase-templates/

Comparing output of this command with the default output

0a1,3
> 
> > bundle exec tla-trace-filter.rb api-calls $SETUP --src-dir=. --solc-line
> 
73c76,77
< CALL-WALLET:2 Wallet()( value: 0, sender: d_eth_address_1, owners: ["d_eth_address_1", "d_eth_address_3"] )
---
> 
> CALL:2 Wallet()( {"sender"=>"d_eth_address_1", "originator"=>nil, "value"=>0, "_owners"=>#<Set: {"d_eth_address_1", "d_eth_address_3"}>} )

demonstrates that Wallet() constructor API gets rendered differently.

5 Use Case For The Extension Point

The extension point presented here can be used to generate test cases on implementation.

One possible use of the extension point is to implement unit tests of system services. In this case, a step in a formal model API trace is translated to a unit test case. Step before state is translated to actions in unit test setup initializing service environment to a known state, step API call parameters are mapped to parameters of the service call, and step after state is mapped to unit test assertions.

Another possibility is to use the formal model API traces to define system tests. In this case, the initial state in a formal model trace is mapped to system initialization, each step in the formal model API trace is translated to a service API call with parameters mapped from step formal model parameters, and step output state is mapped to assertions validating implementation state after each system test service call.

Unit tests extracted from formal model API traces validate that a service plays its role in a longer chain of operations. In addition, because units test execute in isolation, infrastructure required is simpler compared to running system wide tests based on formal model traces.

For an implementation refer to tla-trace-arch, a set of mustache templates extending tla-trace-filter -tool to create a self extracting achieve for API traces generated, when model checking formal models created by Sbuilder -tool.

6 Changes

Date Change
2018-01-03 Added reference to ‘tla-trace-arch’

7 Version Information

  • Language environments:
    • node version: v6.11.4
      • testrpc version: 6.0.3
      • Truffle version: 4.0.3
    • ruby version : ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
    • java version =java version “1.8.0_151″=
  • Sbuilder GEM versions:
    • sbuilder version: =sbuilder.rb – 0.3.8 =
    • sbuilder-eth: Translate Ethereum Solidity to Sbuilder AL version = * sbuilder-eth (0.0.4)=
    • sbuilder-al: Translate SBuilder AL langauage to TLA+ language = * sbuilder-al (0.0.8)=
    • tla-trace-filter: Command line utility to process TLA+tools output = * tla-trace-filter (0.0.4)=
    • tla-parser-s: Utility to parse TLA+ language = * tla-parser-s (0.2.5)=

8 Fin

This post has presented an extension point to avail formal model API traces for example in creating unit tests or system test on implementation. Obviously, infrastructure is needed to map formal model values to implementation values, and to execute test cases.

7 thoughts on “API Trace Rendering Extension Point

Leave a comment