Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature request: API to persist local changes alongside contracts/storage fetched from RPC #162

Open
0xalpharush opened this issue Jun 26, 2024 · 1 comment

Comments

@0xalpharush
Copy link

I would like to be able to deploy contracts and interact with them, simulating a live network (block and timestamp increasing monotonically). It would be great if this were compatible with forking state from an RPC and maintaining a record of what is overridden locally

@lmittmann
Copy link
Owner

lmittmann commented Jun 27, 2024

The BlockContext of a VM can currently only be set during creation. However, I think you can still achieve what you want using VM.{Snapshot,Rollback}.

// 1. create client to fork state with
client := w3.MustDial("http://localhost:8545")
defer client.Close()

// 2. create fetcher that always fetches form the forkBlock
forkBlock := big.NewInt(20_000_000)
fetcher := w3vm.NewRPCFetcher(client, new(big.Int).Sub(forkBlock, w3.Big1))

var snap *state.StateDB
// 3. iterate over 10 blocks starting from forkBlock
for i := range 10 {
	// 3.1. construct header for block i, you could also build your own one instead of fetching
	blockNumber := new(big.Int).Add(forkBlock, big.NewInt(int64(i)))
	var header types.Header
	if err := client.Call(
		eth.HeaderByNumber(forkBlock).Returns(&header),
	); err != nil {
		t.Fatalf("Failed to get header %v: %v", blockNumber, err)
	}

	// 3.2. create VM with fetcher and current header
	vm, err := w3vm.New(
		w3vm.WithFetcher(fetcher),
		w3vm.WithHeader(&header),
	)
	if err != nil {
		t.Fatalf("Failed to create VM: %v", err)
	}

	// 3.3. if this is not the first block, rollback to the end-of-block state of the previous block
	if snap != nil {
		vm.Rollback(snap)
	}

	// 3.4. apply messages for the current block
	// ...

	// 3.5. snapshot the current state at the end of the block
	snap = vm.Snapshot()
}

Making the BlockContext of a VM updateable would be a nice addition, PR's welcome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants