Skip to content

Commit 84fb6a8

Browse files
committed
refactor: split test files
1 parent 1c5ecfe commit 84fb6a8

File tree

5 files changed

+613
-561
lines changed

5 files changed

+613
-561
lines changed

adaptor/adaptor.go

Lines changed: 41 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -13,90 +13,82 @@ import (
1313
"github.com/ava-labs/avalanchego/snow/engine/snowman/block"
1414
)
1515

16-
// ChainVM defines the required functionality to be converted into a Snowman VM.
17-
// See the respective methods on [block.ChainVM] and [snowman.Block] for
18-
// detailed documentation.
19-
type ChainVM[B Block] interface {
16+
// ChainVM defines the functionality required in order to be converted into a
17+
// Snowman VM. See the respective methods on [block.ChainVM] and [snowman.Block]
18+
// for detailed documentation.
19+
type ChainVM[BP BlockProperties] interface {
2020
common.VM
2121

22-
GetBlock(context.Context, ids.ID) (B, error)
23-
ParseBlock(context.Context, []byte) (B, error)
24-
BuildBlock(context.Context) (B, error)
22+
GetBlock(context.Context, ids.ID) (BP, error)
23+
ParseBlock(context.Context, []byte) (BP, error)
24+
BuildBlock(context.Context) (BP, error)
2525

2626
// Transferred from [snowman.Block].
27-
VerifyBlock(context.Context, B) error
28-
AcceptBlock(context.Context, B) error
29-
RejectBlock(context.Context, B) error
27+
VerifyBlock(context.Context, BP) error
28+
AcceptBlock(context.Context, BP) error
29+
RejectBlock(context.Context, BP) error
3030

3131
SetPreference(context.Context, ids.ID) error
3232
LastAccepted(context.Context) (ids.ID, error)
3333
GetBlockIDAtHeight(context.Context, uint64) (ids.ID, error)
3434
}
3535

36-
// Block is a read-only subset of [snowman.Block]. The state-modifying methods
37-
// required by Snowman consensus are, instead, present on [ChainVM].
38-
type Block interface {
36+
// BlockProperties is a read-only subset of [snowman.Block]. The state-modifying
37+
// methods required by Snowman consensus are, instead, present on [ChainVM].
38+
type BlockProperties interface {
3939
ID() ids.ID
4040
Parent() ids.ID
4141
Bytes() []byte
4242
Height() uint64
4343
Timestamp() time.Time
4444
}
4545

46-
type CompatibleChainVM[B Block] interface {
47-
block.ChainVM
48-
AsRawBlock(snowman.Block) (B, bool)
46+
// Convert transforms a generic [ChainVM] into a standard [block.ChainVM]. All
47+
// [snowman.Block] values returned by methods of the returned chain will be of
48+
// the concrete type [Block] with type parameter `BP`.
49+
func Convert[BP BlockProperties](vm ChainVM[BP]) block.ChainVM {
50+
return &adaptor[BP]{vm}
4951
}
5052

51-
// Convert transforms a generic [ChainVM] into a standard [block.ChainVM].
52-
func Convert[B Block](vm ChainVM[B]) CompatibleChainVM[B] {
53-
return &adaptor[B]{vm}
53+
type adaptor[BP BlockProperties] struct {
54+
ChainVM[BP]
5455
}
5556

56-
type adaptor[B Block] struct {
57-
ChainVM[B]
57+
// Block is an implementation of [snowman.Block], used by chains returned by
58+
// [Convert]. The [BlockProperties] can be accessed with [Block.Unwrap].
59+
type Block[BP BlockProperties] struct {
60+
b BP
61+
vm ChainVM[BP]
5862
}
5963

60-
func (vm adaptor[B]) newBlock(b B, err error) (snowman.Block, error) {
64+
// Unwrap returns the [BlockProperties] carried by b.
65+
func (b Block[BP]) Unwrap() BP { return b.b }
66+
67+
func (vm adaptor[BP]) newBlock(b BP, err error) (snowman.Block, error) {
6168
if err != nil {
6269
return nil, err
6370
}
64-
return blk[B]{b, vm.ChainVM}, nil
71+
return Block[BP]{b, vm.ChainVM}, nil
6572
}
6673

67-
func (vm adaptor[B]) GetBlock(ctx context.Context, blkID ids.ID) (snowman.Block, error) {
74+
func (vm adaptor[BP]) GetBlock(ctx context.Context, blkID ids.ID) (snowman.Block, error) {
6875
return vm.newBlock(vm.ChainVM.GetBlock(ctx, blkID))
6976
}
7077

71-
func (vm adaptor[B]) ParseBlock(ctx context.Context, blockBytes []byte) (snowman.Block, error) {
78+
func (vm adaptor[BP]) ParseBlock(ctx context.Context, blockBytes []byte) (snowman.Block, error) {
7279
return vm.newBlock(vm.ChainVM.ParseBlock(ctx, blockBytes))
7380
}
7481

75-
func (vm adaptor[B]) BuildBlock(ctx context.Context) (snowman.Block, error) {
82+
func (vm adaptor[BP]) BuildBlock(ctx context.Context) (snowman.Block, error) {
7683
return vm.newBlock(vm.ChainVM.BuildBlock(ctx))
7784
}
7885

79-
func (vm adaptor[B]) AsRawBlock(b snowman.Block) (B, bool) {
80-
switch b := b.(type) {
81-
case blk[B]:
82-
return b.b, true
83-
default:
84-
var zero B
85-
return zero, false
86-
}
87-
}
88-
89-
type blk[B Block] struct {
90-
b B
91-
vm ChainVM[B]
92-
}
93-
94-
func (b blk[B]) Verify(ctx context.Context) error { return b.vm.VerifyBlock(ctx, b.b) }
95-
func (b blk[B]) Accept(ctx context.Context) error { return b.vm.AcceptBlock(ctx, b.b) }
96-
func (b blk[B]) Reject(ctx context.Context) error { return b.vm.RejectBlock(ctx, b.b) }
86+
func (b Block[BP]) Verify(ctx context.Context) error { return b.vm.VerifyBlock(ctx, b.b) }
87+
func (b Block[BP]) Accept(ctx context.Context) error { return b.vm.AcceptBlock(ctx, b.b) }
88+
func (b Block[BP]) Reject(ctx context.Context) error { return b.vm.RejectBlock(ctx, b.b) }
9789

98-
func (b blk[B]) ID() ids.ID { return b.b.ID() }
99-
func (b blk[B]) Parent() ids.ID { return b.b.Parent() }
100-
func (b blk[B]) Bytes() []byte { return b.b.Bytes() }
101-
func (b blk[B]) Height() uint64 { return b.b.Height() }
102-
func (b blk[B]) Timestamp() time.Time { return b.b.Timestamp() }
90+
func (b Block[BP]) ID() ids.ID { return b.b.ID() }
91+
func (b Block[BP]) Parent() ids.ID { return b.b.Parent() }
92+
func (b Block[BP]) Bytes() []byte { return b.b.Bytes() }
93+
func (b Block[BP]) Height() uint64 { return b.b.Height() }
94+
func (b Block[BP]) Timestamp() time.Time { return b.b.Timestamp() }

blocks/snow.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
_ "github.com/ava-labs/libevm/core/types"
1414
)
1515

16-
var _ adaptor.Block = (*Block)(nil)
16+
var _ adaptor.BlockProperties = (*Block)(nil)
1717

1818
// ID returns [types.Block.Hash] from the embedded [types.Block].
1919
func (b *Block) ID() ids.ID {

cmp_test.go

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package sae
2+
3+
import (
4+
"context"
5+
"math/big"
6+
"sync/atomic"
7+
"testing"
8+
9+
"github.com/arr4n/sink"
10+
snowcommon "github.com/ava-labs/avalanchego/snow/engine/common"
11+
"github.com/ava-labs/avalanchego/utils/logging"
12+
"github.com/ava-labs/avalanchego/vms/components/gas"
13+
"github.com/ava-labs/libevm/common"
14+
"github.com/ava-labs/libevm/core/state"
15+
"github.com/ava-labs/libevm/core/state/snapshot"
16+
"github.com/ava-labs/libevm/core/types"
17+
"github.com/ava-labs/libevm/ethdb"
18+
"github.com/ava-labs/libevm/params"
19+
"github.com/ava-labs/strevm/blocks"
20+
"github.com/ava-labs/strevm/gastime"
21+
"github.com/ava-labs/strevm/proxytime"
22+
"github.com/ava-labs/strevm/saexec"
23+
"github.com/google/go-cmp/cmp"
24+
"github.com/google/go-cmp/cmp/cmpopts"
25+
"github.com/stretchr/testify/require"
26+
)
27+
28+
func cmpReceiptsByHash() cmp.Options {
29+
return cmp.Options{
30+
cmp.Transformer("receiptHash", func(r *types.Receipt) common.Hash {
31+
if r == nil {
32+
return common.Hash{}
33+
}
34+
return r.TxHash
35+
}),
36+
}
37+
}
38+
39+
func cmpBigInts() cmp.Options {
40+
return cmp.Options{
41+
cmp.Comparer(func(a, b *big.Int) bool {
42+
if a == nil || b == nil {
43+
return a == nil && b == nil
44+
}
45+
return a.Cmp(b) == 0
46+
}),
47+
}
48+
}
49+
50+
func cmpTimes() cmp.Options {
51+
return cmp.Options{
52+
cmp.AllowUnexported(
53+
gastime.TimeMarshaler{},
54+
proxytime.Time[gas.Gas]{},
55+
),
56+
cmpopts.IgnoreFields(gastime.TimeMarshaler{}, "canotoData"),
57+
cmpopts.IgnoreFields(proxytime.Time[gas.Gas]{}, "canotoData"),
58+
}
59+
}
60+
61+
func cmpBlocks() cmp.Options {
62+
return cmp.Options{
63+
cmpBigInts(),
64+
cmpTimes(),
65+
cmp.Comparer(func(a, b *types.Block) bool {
66+
return a.Hash() == b.Hash()
67+
}),
68+
cmp.Comparer(func(a, b types.Receipts) bool {
69+
return types.DeriveSha(a, trieHasher()) == types.DeriveSha(b, trieHasher())
70+
}),
71+
cmpopts.EquateComparable(
72+
// We're not running tests concurrently with anything that will
73+
// modify [Block.accepted] nor [Block.executed] so this is safe.
74+
// Using a [cmp.Transformer] would make the linter complain about
75+
// copying.
76+
atomic.Bool{},
77+
),
78+
}
79+
}
80+
81+
func cmpVMs(ctx context.Context, tb testing.TB) cmp.Options {
82+
var zeroVM VM
83+
84+
return cmp.Options{
85+
cmpBlocks(),
86+
cmp.AllowUnexported(
87+
VM{},
88+
last{},
89+
saexec.Executor{},
90+
),
91+
cmpopts.IgnoreUnexported(params.ChainConfig{}),
92+
cmpopts.IgnoreFields(VM{}, "preference"),
93+
cmpopts.IgnoreTypes(
94+
zeroVM.snowCtx,
95+
zeroVM.mempool,
96+
&snapshot.Tree{},
97+
),
98+
cmpopts.IgnoreInterfaces(struct{ snowcommon.AppHandler }{}),
99+
cmpopts.IgnoreInterfaces(struct{ ethdb.Database }{}),
100+
cmpopts.IgnoreInterfaces(struct{ logging.Logger }{}),
101+
cmpopts.IgnoreInterfaces(struct{ state.Database }{}),
102+
cmp.Transformer("block_map_mu", func(mu sink.Mutex[blockMap]) blockMap {
103+
bm, err := sink.FromMutex(ctx, mu, func(bm blockMap) (blockMap, error) {
104+
return bm, nil
105+
})
106+
require.NoError(tb, err)
107+
return bm
108+
}),
109+
cmp.Transformer("atomic_block", func(p atomic.Pointer[blocks.Block]) *blocks.Block {
110+
return p.Load()
111+
}),
112+
cmp.Transformer("state_dump", func(db *state.StateDB) state.Dump {
113+
return db.RawDump(&state.DumpConfig{})
114+
}),
115+
}
116+
}

0 commit comments

Comments
 (0)