-
Notifications
You must be signed in to change notification settings - Fork 57
/
attestations_test.go
136 lines (113 loc) · 3.95 KB
/
attestations_test.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
125
126
127
128
129
130
131
132
133
134
135
136
package e2e_test
import (
"context"
"testing"
"github.com/omni-network/omni/e2e/types"
"github.com/omni-network/omni/lib/cchain"
"github.com/omni-network/omni/lib/cchain/provider"
"github.com/omni-network/omni/lib/k1util"
"github.com/omni-network/omni/lib/netconf"
"github.com/omni-network/omni/lib/xchain"
e2e "github.com/cometbft/cometbft/test/e2e/pkg"
"github.com/stretchr/testify/require"
)
// TestApprovedAttestations tests that all halo instances contain approved attestations
// for at least half of all the source chain blocks.
func TestApprovedAttestations(t *testing.T) {
t.Parallel()
testNode(t, func(t *testing.T, network netconf.Network, node *e2e.Node, portals []Portal) {
t.Helper()
// Only archive nodes have the necessary state to fetch all attestations
if node.Mode != types.ModeArchive {
return
}
client, err := node.Client()
require.NoError(t, err)
cprov := provider.NewABCI(client, network.ID)
ctx := context.Background()
for _, portal := range portals {
for _, chainVer := range portal.Chain.ChainVersions() {
atts, err := fetchAllAtts(ctx, cprov, chainVer, node.StartAt > 0)
require.NoError(t, err)
// Only non-empty blocks are attested to, and we don't know how many that should be, so just ensure it isn't 0.
require.NotEmpty(t, atts, "No attestations for chain version: %v", chainVer)
}
}
// Ensure at least one (genesis) consensus chain approved attestation
consChain, ok := network.OmniConsensusChain()
require.True(t, ok)
for _, chainVer := range consChain.ChainVersions() {
atts, err := fetchAllAtts(ctx, cprov, chainVer, node.StartAt > 0)
require.NoError(t, err)
require.NotEmpty(t, atts)
}
})
}
// TestApprovedAttestations tests that all halo instances contain approved attestations
// for at least half of all the source chain blocks.
func TestApprovedValUpdates(t *testing.T) {
t.Parallel()
testNode(t, func(t *testing.T, network netconf.Network, node *e2e.Node, portals []Portal) {
t.Helper()
ctx := context.Background()
// See if this node has a validator update
var hasUpdate bool
var power int64
for _, powers := range node.Testnet.ValidatorUpdates {
for n, p := range powers {
if n.Name == node.Name {
hasUpdate = true
power = p
}
}
}
if !hasUpdate {
return // Nothing to test
}
client, err := node.Client()
require.NoError(t, err)
cprov := provider.NewABCI(client, network.ID)
addr, err := k1util.PubKeyToAddress(node.PrivvalKey.PubKey())
require.NoError(t, err)
t.Logf("Looking for validator update: %s, %d", addr.Hex(), power)
consChain, ok := network.OmniConsensusChain()
require.True(t, ok)
valSetID := consChain.DeployHeight
for {
vals, ok, err := cprov.PortalValidatorSet(ctx, valSetID)
require.NoError(t, err)
require.True(t, ok, "Validator update not found in any set: node=%s, valSetID=%v", node.Name, valSetID)
for _, val := range vals {
t.Logf("Got validator update set=%d: %s, %d", valSetID, val.Address.Hex(), val.Power)
if val.Address == addr && val.Power == power {
return // Validator update found and confirmed.
}
}
// If update not found, there must be more sets
valSetID++
}
})
}
func fetchAllAtts(ctx context.Context, cprov cchain.Provider, chainVer xchain.ChainVersion, nodeIsDelayed bool) ([]xchain.Attestation, error) {
fromOffset := uint64(1) // Start at initialXAttestOffset
var resp []xchain.Attestation
for {
atts, err := cprov.AttestationsFrom(ctx, chainVer, fromOffset)
if provider.IsErrHistoryPruned(err) && nodeIsDelayed {
// For delayed nodes, we might not have the first attestations.
// Just move on and return what we do find in state.
fromOffset++
continue
}
if err != nil {
return nil, err
}
if len(atts) == 0 { // No more attestation to fetch
break
}
resp = append(resp, atts...)
// Update the from height to fetch the next batch of attestation
fromOffset = atts[len(atts)-1].AttestOffset + 1
}
return resp, nil
}