Skip to main content

solsim


Discord Chat Downloads

Tests Lint

Introduction

solsim is the Solana complex systems simulator. It simulates behavior of dynamical systems—DeFi protocols, DAO governance, cryptocurrencies, and more—built on the Solana blockchain.

Philosophy

Define your system how you see fit.

solsim will simulate its behavior and collect its results in a structured, straightforward manner.

Usage

  1. Implement initial_step and step methods.
  2. From each, return the current state, i.e. a dictionary mapping variables to current values.
  3. Specify the variables you'd like to "watch."
  4. Instantiate a Simulation, call .run().
  5. Receive a pandas DataFrame containing values of "watched" variables at each step in time.

With Solana

from anchorpy import Context
from solana.keypair import Keypair
from solsim.simulation import Simulation

class SomeSolanaSystem(BaseSolanaSystem):
    def __init__(self):
        super().__init__("path/to/workspace")
        self.account = Keypair()
        self.pubkey = self.account.public_key
        self.program = self.workspace["my_anchor_program"]  # solsim gives a Anchor program workspace (self.workspace).

    async def initial_step(self):
        self.program.rpc["initialize"]()  # Make RPC calls to your Anchor program.
        await self.client.request_airdrop(self.pubkey, 10)  # solsim gives you a Solana API client (self.client).
        return {"balance": await self.client.get_balance(self.pubkey)}

    async def step(self, state, history):
        self.program.rpc["submit_uniswap_trade"](
            ctx=Context(accounts={"account": self.pubkey}, signers=[self.account])
        )
        return {"balance": await self.client.get_balance(self.account)}


simulation = Simulation(system=SomeSolanaSystem(), watchlist=("balance"))
results = simulation.run(steps_per_run=5)  # Returns pandas DataFrame of results.

Without Solana

class SomeSystem(BaseSystem):
    def __init__(self, population):
        self.pop = population

    def initial_step(self):
        return {"population": self.pop}

    def step(self, state, history):
        return {"population": state["population"] * 1.1}


simulation = Simulation(system=SomeSystem(), watchlist=("population"))
results = simulation.run(steps_per_run=5)

CLI

Simulations can also be run via CLI. Instead of calling simulation.run(), simply:

  1. Call simulation.cli()
  2. Run your simulation as e.g. python path/to/file.py run --num-runs 3

Results Explorer

solsim gives you a streamlit app to explore results, e.g.

To automatically start this app following simulation, invoke one of the following:

  • simulation.run(visualize_results=True)
  • --viz-results flag in the CLI runner, e.g. python path/to/file.py run --viz-results

Installation

First, install Anchor.

Library

pip install solsim

Development

Install poetry. Then,

git clone --recurse-submodules https://github.com/cavaunpeu/solsim.git
cd solsim
poetry install
poetry shell

Detailed Usage

With Solana

First, write your Solana program. solsim prefers you do this in Anchor. Then,

  1. Write a system class that inherits from BaseSolanaSystem.
  2. Call super().__init__("path/to/program") in its __init__.
  3. Implement initial_step and step methods. (Since you'll interact with Solana asynchronously, these methods should be async.)

In 2., solsim exposes the following attributes to your system instance:

  • self.workspace: IDL clients for the Solana programs that comprise your system (via anchorpy).

For example, these clients let you interact with your respective programs' RPC endpoints.

  • self.client: a general Solana client (via solana-py).

This client lets you interact with Solana's RPC endpoints. Documentation here.

Finally,

  1. Define a watchlist: variables (returned in initial_step and step) you'd like to "watch."
  2. Instantiate and run your simulation, e.g. Simulation(MySystem(), watchlist).run(steps_per_run=10).

Without Solana

  1. Write a system class that inherits from BaseSystem.
  2. Implement initial_step and step methods.
  3. Define a watchlist.
  4. Instantiate and run your simulation.

Examples

Drunken Escrow

Agents are randomly paired to exchange random amounts of foo_coin and bar_coin via an Anchor escrow contract in each timestep.

  • Run: python -m examples.drunken_escrow.
  • Code: here.
  • Expected output (numbers may vary):
(.venv) ➜  solsim git:(main) $ python -m examples.drunken_escrow
Waiting for Solana localnet cluster to start (~10s) ...
Steps completed: 100%|████████████████████████████████████████████████████████████████████████████████████| 4/4 [00:27<00:00,  6.82s/it]
   step  mean_balance_spread  mean_swap_amount  num_swaps
0    -1            40.000000         30.666667          3
1     0            58.000000         12.000000          3
2     1            60.666667          4.000000          3
3     2            83.333333         21.500000          2

Lotka-Volterra

The Lotka-Volterra model is a classic dynamical system in the field of ecology that tracks the evolution of interdependent predator and prey populations.

  • Run: python -m examples.lotka_volterra.
  • Code: here.
  • Expected output:
(.venv) ➜  solsim git:(main) ✗ python -m examples.lotka_volterra
Steps completed: 100%|█████████████████████████████████████████████████████████████████████████████████| 4/4 [00:00<00:00, 28581.29it/s]
   step  food_supply  population_size
0    -1     1000.000            50.00
1     0      995.000            60.00
2     1      989.000            69.95
3     2      982.005            79.84

This implementation inspired by cadCAD Edu.

Inspiration

solsim humbly builds on the shoulders of the giants that are cadCAD and tokenspice, among others.

Release files for solsim 0.1.7

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for solsim 0.1.7
File Size Uploaded
solsim-0.1.7.tar.gz 11.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for solsim 0.1.7
File Interpreter ABI Platform
solsim-0.1.7-py3-none-any.whl Python 3 none any Details

Total release size: 20.7 kB

Release files / solsim-0.1.7.tar.gz

Download URL solsim-0.1.7.tar.gz
Size 11.3 kB
Tags Source
SHA-256 checksum
How to use checksums
6dca42cb6a7a3462ad9da027dc9e6a084f0d8f1f90cf10af01217a88a18e5ff3
BLAKE2b-256 checksum
How to use checksums
99ba38240ab9156432d9ca9063a987226180577b61e72bb9e3f0305a37635d63
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.12 CPython/3.10.2 Linux/5.11.0-1028-azure

Release files / solsim-0.1.7-py3-none-any.whl

Download URL solsim-0.1.7-py3-none-any.whl
Size 9.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2095068379977ac170bbd34611fa53b7049b271dd6aabbc492ce3ce8ba486955
BLAKE2b-256 checksum
How to use checksums
5cc6e88fc961a63349a6ddeaccb041ec6e5bb42f3c10bacccd2d2fac635b725d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.12 CPython/3.10.2 Linux/5.11.0-1028-azure

Release history Release notifications | RSS feed

This release

0.1.7 This release

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page