Cost accounting testing notes

  1. As a deployer I want to:
    1. be able to provide phlos for my deploy
    2. know the status of my deploy
    3.  get refunded with any left phlos
  2. As a node operator I want to:
    1. run the computation only if there's enough phlo to cover it
    2. be paid for the work

- user can provide a phlo limit DONE - needs tests
- only positive values are allowed DONE - needs test
- use phlo from the input arguments DONE - needs test
- create a way to check the deploy status (hash of the block : hash of the deploy?) TBD
- return phlos that are left after executing the deploy DONE - needs test

- stop the computation as soon as deploy runs out of phlo:
# we should charge for:

  • substitutions - cost of substitution is proportional to the binary size of the data after the substitution DONE - with a unit test
  • spatial match - should short-circuit during the match DONE - with a unit test
  • interaction with tuplespace (constant cost of produce and consume - to be decided how much)
  • spatial match in RSpace - test that the cost is properly updated with the cost of spatial match in RSpace. DONE - with a unit test
  • method calls - test that we charge for all the methods.
  • interaction with registry (boils down to cost for interacting with tuplespace)- test that cost of interaction with the registry is a cost for interaction with underlying Tuplespace.

- return the cost of the deploy to RuntimeManager DONE - with a unit test

We need to test that when multiple threads reduce if one of them uses up all the phlos the other threads will interrupt as soon as they see the new value.

Cost accounting logic

Because Rholang interpreter is multi threaded within the deploy and we need to share phlo limit it means there will be races to the current state of cost account. The approach taken is that we check the state before charging and right after, short circuting if we ever go below 0 phlos left. The worst case scenario is that some expensive computation (A) will check current phlos left, use it as its limit (A1) and charge right after (A2). If between (A1) and (A2) some other thread will update the cost account and run out of phlos the (A) computation won't be interrupted but will fail when trying to update the cost account. This is as good as we can get anyway because when interpreter goes into the Tuplespace it is disconnected from the current cost account anyway. 

It occured to me now that we should probably have two ways of getting current balance: one for simply reading it and another for reading and using it as a starting value (this should throw an error if value is below 0). The former is used at the end of the deploy in RuntimeManager for things like charging the wallet, refunding etc, the latter would be used when we disconnect from the interpreter and want to continue with everything available - ie spatial matcher and rspace.