Skip to content

Commit

Permalink
Merge pull request #186 from OffchainLabs/arbitrary-prune-point
Browse files Browse the repository at this point in the history
Allow pruning to multiple targets, including without snapshots
  • Loading branch information
PlasmaPower authored Apr 13, 2023
2 parents 86b963d + 7ba1099 commit 8c5b933
Show file tree
Hide file tree
Showing 5 changed files with 378 additions and 200 deletions.
10 changes: 7 additions & 3 deletions cmd/geth/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,19 @@ func pruneState(ctx *cli.Context) error {
log.Error("Too many arguments given")
return errors.New("too many arguments")
}
var targetRoot common.Hash
var targetRoots []common.Hash
if ctx.NArg() == 1 {
targetRoot, err = parseRoot(ctx.Args().First())
root, err := parseRoot(ctx.Args().First())
if err != nil {
log.Error("Failed to resolve state root", "err", err)
return err
}
targetRoots = append(targetRoots, root)
} else {
// Prune to the last snapshot
targetRoots = append(targetRoots, common.Hash{})
}
if err = pruner.Prune(targetRoot); err != nil {
if err = pruner.Prune(targetRoots); err != nil {
log.Error("Failed to prune state", "err", err)
return err
}
Expand Down
7 changes: 7 additions & 0 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,13 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, root common.Hash, repair bo
// if the historical chain pruning is enabled. In that case the logic
// needs to be improved here.
if !bc.HasState(bc.genesisBlock.Root()) {
// Arbitrum: we have a later block with state; use that instead.
if lastFullBlock != 0 {
blockNumber = lastFullBlock
newHeadBlock = bc.GetBlock(lastFullBlockHash, lastFullBlock)
log.Debug("Rewound to block with state but not snapshot", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash())
break
}
if err := CommitGenesisState(bc.db, bc.genesisBlock.Hash()); err != nil {
log.Crit("Failed to commit genesis state", "err", err)
}
Expand Down
57 changes: 48 additions & 9 deletions core/state/pruner/bloom.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@
package pruner

import (
"bufio"
"encoding/binary"
"errors"
"fmt"
"io"
"os"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp"
bloomfilter "github.com/holiman/bloomfilter/v2"
)

Expand Down Expand Up @@ -73,27 +77,54 @@ func newStateBloomWithSize(size uint64) (*stateBloom, error) {

// NewStateBloomFromDisk loads the state bloom from the given file.
// In this case the assumption is held the bloom filter is complete.
func NewStateBloomFromDisk(filename string) (*stateBloom, error) {
bloom, _, err := bloomfilter.ReadFile(filename)
func NewStateBloomFromDisk(filename string) (*stateBloom, []common.Hash, error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
return nil, nil, err
}
return &stateBloom{bloom: bloom}, nil
defer f.Close()
r := bufio.NewReader(f)
version := []byte{0}
_, err = io.ReadFull(r, version)
if err != nil {
return nil, nil, err
}
if version[0] != 0 {
return nil, nil, fmt.Errorf("unknown state bloom filter version %v", version[0])
}
var roots []common.Hash
err = rlp.Decode(r, &roots)
if err != nil {
return nil, nil, err
}
bloom, _, err := bloomfilter.ReadFrom(r)
if err != nil {
return nil, nil, err
}
return &stateBloom{bloom: bloom}, roots, nil
}

// Commit flushes the bloom filter content into the disk and marks the bloom
// as complete.
func (bloom *stateBloom) Commit(filename, tempname string) error {
// Write the bloom out into a temporary file
_, err := bloom.bloom.WriteFile(tempname)
func (bloom *stateBloom) Commit(filename, tempname string, roots []common.Hash) error {
f, err := os.OpenFile(tempname, os.O_RDWR|os.O_CREATE, 0666)
if err != nil {
return err
}
// Ensure the file is synced to disk
f, err := os.OpenFile(tempname, os.O_RDWR, 0666)
_, err = f.Write([]byte{0}) // version
if err != nil {
return err
}
err = rlp.Encode(f, roots)
if err != nil {
return err
}
// Write the bloom out into a temporary file
_, err = bloom.bloom.WriteTo(f)
if err != nil {
return err
}
// Ensure the file is synced to disk
if err := f.Sync(); err != nil {
f.Close()
return err
Expand Down Expand Up @@ -130,3 +161,11 @@ func (bloom *stateBloom) Delete(key []byte) error { panic("not supported") }
func (bloom *stateBloom) Contain(key []byte) (bool, error) {
return bloom.bloom.Contains(stateBloomHasher(key)), nil
}

func (bloom *stateBloom) FalsePosititveProbability() float64 {
return bloom.bloom.FalsePosititveProbability()
}

func (bloom *stateBloom) Size() uint64 {
return bloom.bloom.M()
}
Loading

0 comments on commit 8c5b933

Please sign in to comment.