|
| 1 | +package cronjob |
| 2 | + |
| 3 | +import ( |
| 4 | + globalConfig "flare-indexer/config" |
| 5 | + "flare-indexer/database" |
| 6 | + "flare-indexer/indexer/config" |
| 7 | + "flare-indexer/indexer/context" |
| 8 | + "flare-indexer/indexer/pchain" |
| 9 | + "flare-indexer/indexer/shared" |
| 10 | + "flare-indexer/utils" |
| 11 | + "sort" |
| 12 | + "testing" |
| 13 | + "time" |
| 14 | + |
| 15 | + "github.com/bradleyjkemp/cupaloy" |
| 16 | + "github.com/ethereum/go-ethereum/common" |
| 17 | + "github.com/stretchr/testify/assert" |
| 18 | + "github.com/stretchr/testify/require" |
| 19 | +) |
| 20 | + |
| 21 | +func uptimeVotingCronjobTestConfig(epochStart time.Time) *config.Config { |
| 22 | + cfg := &config.Config{ |
| 23 | + Chain: globalConfig.ChainConfig{ |
| 24 | + ChainAddressHRP: "localflare", |
| 25 | + ChainID: 31337, |
| 26 | + EthRPCURL: "http://127.0.0.1:8545", |
| 27 | + PrivateKey: "0xd49743deccbccc5dc7baa8e69e5be03298da8688a15dd202e20f15d5e0e9a9fb", |
| 28 | + }, |
| 29 | + UptimeCronjob: config.UptimeConfig{ |
| 30 | + CronjobConfig: config.CronjobConfig{ |
| 31 | + Enabled: true, |
| 32 | + TimeoutSeconds: 30, |
| 33 | + }, |
| 34 | + EpochConfig: config.EpochConfig{ |
| 35 | + Start: utils.Timestamp{Time: epochStart}, |
| 36 | + Period: 90 * time.Second, |
| 37 | + }, |
| 38 | + VotingInterval: 60 * time.Second, |
| 39 | + EnableVoting: true, |
| 40 | + UptimeThreshold: 0.8, |
| 41 | + }, |
| 42 | + VotingCronjob: config.VotingConfig{ |
| 43 | + ContractAddress: common.HexToAddress("0x7c2C195CD6D34B8F845992d380aADB2730bB9C6F"), |
| 44 | + }, |
| 45 | + PChainIndexer: config.IndexerConfig{ |
| 46 | + Enabled: true, |
| 47 | + TimeoutMillis: 3000, |
| 48 | + BatchSize: 200, |
| 49 | + StartIndex: 0, |
| 50 | + }, |
| 51 | + DB: globalConfig.DBConfig{ |
| 52 | + Username: database.MysqlTestUser, |
| 53 | + Password: database.MysqlTestPassword, |
| 54 | + Host: database.MysqlTestHost, |
| 55 | + Port: database.MysqlTestPort, |
| 56 | + Database: "flare_indexer_indexer", |
| 57 | + LogQueries: false, |
| 58 | + }, |
| 59 | + } |
| 60 | + return cfg |
| 61 | + |
| 62 | +} |
| 63 | + |
| 64 | +func createTestUptimeVotingCronjob(epochStart time.Time) (*uptimeVotingCronjob, *shared.ChainIndexerBase, error) { |
| 65 | + ctx, err := context.BuildTestContext(uptimeVotingCronjobTestConfig(epochStart)) |
| 66 | + if err != nil { |
| 67 | + return nil, nil, err |
| 68 | + } |
| 69 | + cronjob, err := NewUptimeVotingCronjob(ctx) |
| 70 | + if err != nil { |
| 71 | + return nil, nil, err |
| 72 | + } |
| 73 | + |
| 74 | + indexer := &shared.ChainIndexerBase{ |
| 75 | + StateName: pchain.StateName, |
| 76 | + IndexerName: "P-chain Blocks Test", |
| 77 | + Client: testClient, |
| 78 | + DB: ctx.DB(), |
| 79 | + Config: ctx.Config().PChainIndexer, |
| 80 | + BatchIndexer: pchain.NewPChainBatchIndexer(ctx, testClient, testRPCClient), |
| 81 | + } |
| 82 | + return cronjob, indexer, nil |
| 83 | +} |
| 84 | + |
| 85 | +// Requires a running hardhat node |
| 86 | +// from the flare-smart-contracts project, branch origin/staking-tests |
| 87 | +// with yarn staking_test |
| 88 | +func TestUptimeVoting(t *testing.T) { |
| 89 | + now := time.Unix(1675348249, 0) |
| 90 | + |
| 91 | + // Epoch starts "now" |
| 92 | + votingCronjob, indexer, err := createTestUptimeVotingCronjob(now) |
| 93 | + require.NoError(t, err) |
| 94 | + |
| 95 | + uptimeCronjob, err := createTestUptimeCronjob() |
| 96 | + require.NoError(t, err) |
| 97 | + |
| 98 | + // Run indexer to allow uptime client test to fetch validator data |
| 99 | + err = indexer.IndexBatch() |
| 100 | + require.NoError(t, err) |
| 101 | + |
| 102 | + testUptimeClient.SetNow(now) |
| 103 | + votingCronjob.time.SetNow(now) |
| 104 | + for i := 0; i < 10; i++ { |
| 105 | + if err := uptimeCronjob.Call(); err != nil { |
| 106 | + t.Fatal(err) |
| 107 | + } |
| 108 | + if err := votingCronjob.Call(); err != nil { |
| 109 | + t.Fatal(err) |
| 110 | + } |
| 111 | + testUptimeClient.Time.AdvanceNow(10 * time.Second) |
| 112 | + votingCronjob.time.AdvanceNow(10 * time.Second) |
| 113 | + } |
| 114 | + aggr, err := database.FetchAggregations(votingCronjob.db) |
| 115 | + require.NoError(t, err) |
| 116 | + assert.Equal(t, 4, len(aggr)) |
| 117 | + |
| 118 | + // Sort by nodeID and compare to snapshots |
| 119 | + sort.Slice(aggr, func(i, j int) bool { |
| 120 | + return aggr[i].NodeID < aggr[j].NodeID |
| 121 | + }) |
| 122 | + aggrNodeIDs := utils.Map(aggr, func(a *database.UptimeAggregation) string { |
| 123 | + return a.NodeID |
| 124 | + }) |
| 125 | + aggrValue := utils.Map(aggr, func(a *database.UptimeAggregation) int64 { |
| 126 | + return a.Value |
| 127 | + }) |
| 128 | + cupaloy.SnapshotT(t, aggrNodeIDs, aggrValue) |
| 129 | +} |
0 commit comments