Skip to content

Commit 8c5b933

Browse files
authored
Merge pull request #186 from OffchainLabs/arbitrary-prune-point
Allow pruning to multiple targets, including without snapshots
2 parents 86b963d + 7ba1099 commit 8c5b933

File tree

5 files changed

+378
-200
lines changed

5 files changed

+378
-200
lines changed

cmd/geth/snapshot.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,15 +179,19 @@ func pruneState(ctx *cli.Context) error {
179179
log.Error("Too many arguments given")
180180
return errors.New("too many arguments")
181181
}
182-
var targetRoot common.Hash
182+
var targetRoots []common.Hash
183183
if ctx.NArg() == 1 {
184-
targetRoot, err = parseRoot(ctx.Args().First())
184+
root, err := parseRoot(ctx.Args().First())
185185
if err != nil {
186186
log.Error("Failed to resolve state root", "err", err)
187187
return err
188188
}
189+
targetRoots = append(targetRoots, root)
190+
} else {
191+
// Prune to the last snapshot
192+
targetRoots = append(targetRoots, common.Hash{})
189193
}
190-
if err = pruner.Prune(targetRoot); err != nil {
194+
if err = pruner.Prune(targetRoots); err != nil {
191195
log.Error("Failed to prune state", "err", err)
192196
return err
193197
}

core/blockchain.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,13 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, root common.Hash, repair bo
647647
// if the historical chain pruning is enabled. In that case the logic
648648
// needs to be improved here.
649649
if !bc.HasState(bc.genesisBlock.Root()) {
650+
// Arbitrum: we have a later block with state; use that instead.
651+
if lastFullBlock != 0 {
652+
blockNumber = lastFullBlock
653+
newHeadBlock = bc.GetBlock(lastFullBlockHash, lastFullBlock)
654+
log.Debug("Rewound to block with state but not snapshot", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash())
655+
break
656+
}
650657
if err := CommitGenesisState(bc.db, bc.genesisBlock.Hash()); err != nil {
651658
log.Crit("Failed to commit genesis state", "err", err)
652659
}

core/state/pruner/bloom.go

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,17 @@
1717
package pruner
1818

1919
import (
20+
"bufio"
2021
"encoding/binary"
2122
"errors"
23+
"fmt"
24+
"io"
2225
"os"
2326

2427
"github.com/ethereum/go-ethereum/common"
2528
"github.com/ethereum/go-ethereum/core/rawdb"
2629
"github.com/ethereum/go-ethereum/log"
30+
"github.com/ethereum/go-ethereum/rlp"
2731
bloomfilter "github.com/holiman/bloomfilter/v2"
2832
)
2933

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

7478
// NewStateBloomFromDisk loads the state bloom from the given file.
7579
// In this case the assumption is held the bloom filter is complete.
76-
func NewStateBloomFromDisk(filename string) (*stateBloom, error) {
77-
bloom, _, err := bloomfilter.ReadFile(filename)
80+
func NewStateBloomFromDisk(filename string) (*stateBloom, []common.Hash, error) {
81+
f, err := os.Open(filename)
7882
if err != nil {
79-
return nil, err
83+
return nil, nil, err
8084
}
81-
return &stateBloom{bloom: bloom}, nil
85+
defer f.Close()
86+
r := bufio.NewReader(f)
87+
version := []byte{0}
88+
_, err = io.ReadFull(r, version)
89+
if err != nil {
90+
return nil, nil, err
91+
}
92+
if version[0] != 0 {
93+
return nil, nil, fmt.Errorf("unknown state bloom filter version %v", version[0])
94+
}
95+
var roots []common.Hash
96+
err = rlp.Decode(r, &roots)
97+
if err != nil {
98+
return nil, nil, err
99+
}
100+
bloom, _, err := bloomfilter.ReadFrom(r)
101+
if err != nil {
102+
return nil, nil, err
103+
}
104+
return &stateBloom{bloom: bloom}, roots, nil
82105
}
83106

84107
// Commit flushes the bloom filter content into the disk and marks the bloom
85108
// as complete.
86-
func (bloom *stateBloom) Commit(filename, tempname string) error {
87-
// Write the bloom out into a temporary file
88-
_, err := bloom.bloom.WriteFile(tempname)
109+
func (bloom *stateBloom) Commit(filename, tempname string, roots []common.Hash) error {
110+
f, err := os.OpenFile(tempname, os.O_RDWR|os.O_CREATE, 0666)
89111
if err != nil {
90112
return err
91113
}
92-
// Ensure the file is synced to disk
93-
f, err := os.OpenFile(tempname, os.O_RDWR, 0666)
114+
_, err = f.Write([]byte{0}) // version
94115
if err != nil {
95116
return err
96117
}
118+
err = rlp.Encode(f, roots)
119+
if err != nil {
120+
return err
121+
}
122+
// Write the bloom out into a temporary file
123+
_, err = bloom.bloom.WriteTo(f)
124+
if err != nil {
125+
return err
126+
}
127+
// Ensure the file is synced to disk
97128
if err := f.Sync(); err != nil {
98129
f.Close()
99130
return err
@@ -130,3 +161,11 @@ func (bloom *stateBloom) Delete(key []byte) error { panic("not supported") }
130161
func (bloom *stateBloom) Contain(key []byte) (bool, error) {
131162
return bloom.bloom.Contains(stateBloomHasher(key)), nil
132163
}
164+
165+
func (bloom *stateBloom) FalsePosititveProbability() float64 {
166+
return bloom.bloom.FalsePosititveProbability()
167+
}
168+
169+
func (bloom *stateBloom) Size() uint64 {
170+
return bloom.bloom.M()
171+
}

0 commit comments

Comments
 (0)