Skip to content

Commit 4b94f56

Browse files
committed
Merkle-ize X-Chain state
Signed-off-by: Joshua Kim <[email protected]>
1 parent 14cb603 commit 4b94f56

File tree

19 files changed

+1198
-134
lines changed

19 files changed

+1198
-134
lines changed

database/memdb/db.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package memdb
55

66
import (
77
"context"
8+
"fmt"
89
"slices"
910
"strings"
1011
"sync"
@@ -38,6 +39,21 @@ func New() *Database {
3839
return NewWithSize(DefaultSize)
3940
}
4041

42+
// Copy returns a Database with the same key-value pairs as db
43+
func Copy(db *Database) (*Database, error) {
44+
db.lock.Lock()
45+
defer db.lock.Unlock()
46+
47+
result := New()
48+
for k, v := range db.db {
49+
if err := result.Put([]byte(k), v); err != nil {
50+
return nil, fmt.Errorf("failed to insert key: %w", err)
51+
}
52+
}
53+
54+
return result, nil
55+
}
56+
4157
// NewWithSize returns a map pre-allocated to the provided size with the
4258
// Database interface methods implemented.
4359
func NewWithSize(size int) *Database {

vms/avm/block/executor/block.go

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,15 @@ func (b *Block) Verify(context.Context) error {
8080
if err != nil {
8181
txID := tx.ID()
8282
b.manager.mempool.MarkDropped(txID, err)
83-
return err
83+
return fmt.Errorf("failed to syntactically verify tx %s: %w", txID, err)
8484
}
8585
}
8686

8787
// Verify that the parent exists.
8888
parentID := b.Parent()
8989
parent, err := b.manager.GetStatelessBlock(parentID)
9090
if err != nil {
91-
return err
91+
return fmt.Errorf("failed to get parent %s: %w", parentID, err)
9292
}
9393

9494
// Verify that currentBlkHeight = parentBlkHeight + 1.
@@ -105,7 +105,11 @@ func (b *Block) Verify(context.Context) error {
105105

106106
stateDiff, err := state.NewDiff(parentID, b.manager)
107107
if err != nil {
108-
return err
108+
return fmt.Errorf(
109+
"failed to initialize state diff on state at %s: %w",
110+
parentID,
111+
err,
112+
)
109113
}
110114

111115
parentChainTime := stateDiff.GetTimestamp()
@@ -138,7 +142,7 @@ func (b *Block) Verify(context.Context) error {
138142
if err != nil {
139143
txID := tx.ID()
140144
b.manager.mempool.MarkDropped(txID, err)
141-
return err
145+
return fmt.Errorf("failed to semantically verify tx %s: %w", txID, err)
142146
}
143147

144148
// Apply the txs state changes to the state.
@@ -155,7 +159,7 @@ func (b *Block) Verify(context.Context) error {
155159
if err != nil {
156160
txID := tx.ID()
157161
b.manager.mempool.MarkDropped(txID, err)
158-
return err
162+
return fmt.Errorf("failed to execute tx %s: %w", txID, err)
159163
}
160164

161165
// Verify that the transaction we just executed didn't consume inputs
@@ -188,7 +192,11 @@ func (b *Block) Verify(context.Context) error {
188192
// already imported in a currently processing block.
189193
err = b.manager.VerifyUniqueInputs(parentID, blockState.importedInputs)
190194
if err != nil {
191-
return err
195+
return fmt.Errorf(
196+
"failed to verify unique inputs on state at %s: %w",
197+
parent,
198+
err,
199+
)
192200
}
193201

194202
// Now that the block has been executed, we can add the block data to the
@@ -201,7 +209,7 @@ func (b *Block) Verify(context.Context) error {
201209
return nil
202210
}
203211

204-
func (b *Block) Accept(context.Context) error {
212+
func (b *Block) Accept(ctx context.Context) error {
205213
blkID := b.ID()
206214
defer b.manager.free(blkID)
207215

@@ -246,12 +254,16 @@ func (b *Block) Accept(context.Context) error {
246254
return err
247255
}
248256

257+
checksum, err := b.manager.state.Checksum(ctx)
258+
if err != nil {
259+
return fmt.Errorf("failed to get checksum: %w", err)
260+
}
249261
b.manager.backend.Ctx.Log.Trace(
250262
"accepted block",
251263
zap.Stringer("blkID", blkID),
252264
zap.Uint64("height", b.Height()),
253265
zap.Stringer("parentID", b.Parent()),
254-
zap.Stringer("checksum", b.manager.state.Checksum()),
266+
zap.Stringer("checksum", checksum),
255267
)
256268
return nil
257269
}

vms/avm/block/executor/block_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ func TestBlockAccept(t *testing.T) {
749749
// because we mock the call to shared memory
750750
mockManagerState.EXPECT().CommitBatch().Return(nil, nil)
751751
mockManagerState.EXPECT().Abort()
752-
mockManagerState.EXPECT().Checksum().Return(ids.Empty)
752+
mockManagerState.EXPECT().Checksum(gomock.Any()).Return(ids.Empty, nil)
753753

754754
mockSharedMemory := atomicmock.NewSharedMemory(ctrl)
755755
mockSharedMemory.EXPECT().Apply(gomock.Any(), gomock.Any()).Return(nil)

vms/avm/block/executor/manager.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ type Manager interface {
5151
func NewManager(
5252
mempool mempool.Mempool,
5353
metrics metrics.Metrics,
54-
state state.State,
54+
state state.Interface,
5555
backend *executor.Backend,
5656
clk *mockable.Clock,
5757
onAccept func(*txs.Tx) error,
@@ -72,7 +72,7 @@ func NewManager(
7272

7373
type manager struct {
7474
backend *executor.Backend
75-
state state.State
75+
state state.Interface
7676
metrics metrics.Metrics
7777
mempool mempool.Mempool
7878
clk *mockable.Clock

vms/avm/environment_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ func setup(tb testing.TB, c *envConfig) *environment {
113113
}
114114

115115
vm := &VM{
116-
Config: vmStaticConfig,
116+
Config: vmStaticConfig,
117+
StateMigrationFactory: NoStateMigrationFactory{},
117118
}
118119

119120
vmDynamicConfig := DefaultConfig

vms/avm/factory.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,11 @@ type Factory struct {
1616
}
1717

1818
func (f *Factory) New(logging.Logger) (interface{}, error) {
19-
return &VM{Config: f.Config}, nil
19+
return &VM{
20+
Config: f.Config,
21+
StateMigrationFactory: GForkStateMigrationFactory{
22+
CommitFrequency: 1_000,
23+
},
24+
},
25+
nil
2026
}

0 commit comments

Comments
 (0)