-
Notifications
You must be signed in to change notification settings - Fork 107
/
runtime_prune.go
124 lines (104 loc) · 3.05 KB
/
runtime_prune.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package runtime
import (
"context"
"fmt"
"time"
"github.com/oasisprotocol/oasis-core/go/oasis-test-runner/env"
"github.com/oasisprotocol/oasis-core/go/oasis-test-runner/oasis"
"github.com/oasisprotocol/oasis-core/go/oasis-test-runner/scenario"
"github.com/oasisprotocol/oasis-core/go/runtime/client/api"
"github.com/oasisprotocol/oasis-core/go/runtime/history"
)
// RuntimePrune is the runtime prune scenario.
var RuntimePrune scenario.Scenario = newRuntimePruneImpl()
const (
// pruneNumKept is the number of last blocks the pruner should keep.
pruneNumKept = 5
// pruneTxCount is the number of txs that should be submitted (as we
// are the only submitter, this is also the number of blocks).
pruneTxCount = 10
// pruneInterval is the prune interval.
pruneInterval = 1 * time.Second
)
type runtimePruneImpl struct {
Scenario
}
func newRuntimePruneImpl() scenario.Scenario {
return &runtimePruneImpl{
Scenario: *NewScenario("runtime-prune", nil),
}
}
func (sc *runtimePruneImpl) Clone() scenario.Scenario {
return &runtimePruneImpl{
Scenario: *sc.Scenario.Clone().(*Scenario),
}
}
func (sc *runtimePruneImpl) Fixture() (*oasis.NetworkFixture, error) {
f, err := sc.Scenario.Fixture()
if err != nil {
return nil, err
}
// Avoid unexpected blocks.
f.Network.SetMockEpoch()
// Configure pruning.
f.Runtimes[1].Pruner = oasis.RuntimePrunerCfg{
Strategy: history.PrunerStrategyKeepLast,
Interval: pruneInterval,
NumKept: pruneNumKept,
}
return f, nil
}
func (sc *runtimePruneImpl) Run(ctx context.Context, _ *env.Env) error {
if err := sc.Net.Start(); err != nil {
return err
}
fixture, err := sc.Fixture()
if err != nil {
return err
}
if _, err = sc.initialEpochTransitions(ctx, fixture); err != nil {
return err
}
c := sc.Net.ClientController().RuntimeClient
// Submit transactions.
for i := 0; i < pruneTxCount; i++ {
sc.Logger.Info("submitting transaction to runtime",
"seq", i,
)
if _, err = sc.submitKeyValueRuntimeInsertTx(ctx, KeyValueRuntimeID, uint64(i), "hello", fmt.Sprintf("world %d", i), false, 0); err != nil {
return err
}
}
// Wait long enough that something should be pruned.
time.Sleep(pruneInterval + 1*time.Second)
// Once the transactions are complete, check if blocks got pruned.
sc.Logger.Info("fetching latest block")
latestBlk, err := c.GetBlock(ctx, &api.GetBlockRequest{
RuntimeID: KeyValueRuntimeID,
Round: api.RoundLatest,
})
if err != nil {
return fmt.Errorf("failed to fetch latest block: %w", err)
}
sc.Logger.Info("checking if blocks got pruned correctly",
"latest_round", latestBlk.Header.Round,
)
for i := uint64(0); i <= latestBlk.Header.Round; i++ {
_, err = c.GetBlock(ctx, &api.GetBlockRequest{
RuntimeID: KeyValueRuntimeID,
Round: i,
})
if i <= latestBlk.Header.Round-pruneNumKept {
// Block should be pruned.
if err == nil {
return fmt.Errorf("block %d should be pruned but is not", i)
}
} else {
// Block should not be pruned.
if err != nil {
return fmt.Errorf("block %d is pruned but it shouldn't be", i)
}
}
}
return nil
}