Skip to content

Commit

Permalink
Subplanner support (#22)
Browse files Browse the repository at this point in the history
* Use Command objects as keys instead of ints

* Add test for commands not in the planner, and refactor plan method

* Refactor to permit recursion more easily

* Lint changes

* Implement subplanners

* Format

* === instead of ==

* Add docs on subplans

* Support read-only subcommands

* Support read-only subcommands

* Read-only subplans don't update the state

* Read-only subplans don't update the state

* Update README

* Lockfile

Co-authored-by: Jeff Reiner <[email protected]>
  • Loading branch information
Arachnid and mirshko authored Jun 27, 2021
1 parent 9e368a2 commit 1ed2bd2
Show file tree
Hide file tree
Showing 7 changed files with 13,319 additions and 1,116 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,25 @@ Once you are done planning operations, generate the program:
```javascript
const { commands, state } = planner.plan();
```

### Subplans
In some cases it may be useful to be able to instantiate nested instances of the weiroll VM - for example, when using flash loans, or other systems that function by making a callback to your code. The weiroll planner supports this via 'subplans'.

To make a subplan, construct the operations that should take place inside the nested instance normally, then pass the planner object to a contract function that executes the subplan, and pass that to the outer planner's `.addSubplan()` function instead of `.add()`.

For example, suppose you want to call a nested instance to do some math:

```javascript
const subplanner = new Planner();
const sum = subplanner.add(Math.add(1, 2));

const planner = new Planner();
planner.addSubplan(Weiroll.execute(subplanner, subplanner.state));
planner.add(Events.logUint(sum));

const {commands, state} = planner.plan();
```

Subplan functions must specify which argument receives the current state using the special variable `Planner.state`, and must take exactly one subplanner and one state argument. Subplan functions must either return an updated state or nothing.

If a subplan returns updated state, return values created in a subplanner, such as `sum` above, can be referenced in the outer scope, and even in other subplans, as long as they are referenced after the command that produces them. Subplans that do not return updated state are read-only, and return values defined inside them cannot be referenced outside them.
13,797 changes: 12,804 additions & 993 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@
"typescript": "^4.3.3"
},
"dependencies": {
"ethers": "^5.3.1",
"heap-js": "^2.1.5"
"ethers": "^5.3.1"
}
}
2 changes: 0 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,5 @@ export {
ContractFunction,
FunctionCall,
Value,
LiteralValue,
ReturnValue,
Planner,
} from './planner';
Loading

0 comments on commit 1ed2bd2

Please sign in to comment.