mirror of
https://github.com/QuilibriumNetwork/ceremonyclient.git
synced 2026-03-05 16:27:28 +08:00
* .20 testing * Read in the debug by env variable (#514) * v2.1.0.19 * enhanced error logging, fix seniority marker join blocker, fix sync message size limit defaults * resolve signature failure * additional error logging for merge-related signatures * fix: one-shot sync message size, app shard TC signature size, collector/hotstuff race condition, expired joins blocking new joins due to pruning disable * remove compat with old 2.0.0 blossomsub * fix: resolve abandoned prover joins * reload prover registry * fix stale worker proposal edge * add full sanity check on join before submitting to identify bug * resolve non-fallthrough condition that should be fallthrough * fix: resolve rare SIGFPE, fix orphan expired joins blocking workers from reallocating * add reconnect fallback if no peers are found with variable reconnect time (#511) Co-authored-by: Tyler Sturos <55340199+tjsturos@users.noreply.github.com> * update base peer count to 1 (#513) * fix: expired prover join frames, starting port ranges, proposer getting stuck, and seniority on joins * fix: panic on shutdown, libp2p discovery picking inaccessible peers, coverage event check not in shutdown logic, amend app shard worker behavior to mirror global for prover root reconciliation * fix: shutdown scenario quirks, reload hanging * fix: do not bailout early on shutdown of coverage check * fix: force registry refresh on worker waiting for registration * add more logging to wait for prover * fix: worker manager refreshes the filter on allocation, snapshots blocking close on shutdown * tweak: force shutdown after five seconds for app worker * fix: don't loop when shutting down * fix: slight reordering, also added named workers to trace hanging shutdowns * use deterministic key for peer id of workers to stop flagging workers as sybil attacks * fix: remove pubsub stop from app consensus engine as it shouldn't manage pubsub lifecycle, integrate shutdown context to PerformSync to prevent stuck syncs from halting respawn * fix: blossomsub pubsub interface does not properly track subscription status * fix: subscribe order to avoid nil panic * switch from dnsaddr to dns4 * add missing quic-v1 * additional logging to isolate respawn quirks * fix: dnsaddr -> dns4 for blossomsub * allow debug env var to be read --------- Co-authored-by: Cassandra Heart <cassandra@quilibrium.com> Co-authored-by: Tyler Sturos <55340199+tjsturos@users.noreply.github.com> Co-authored-by: Cassandra Heart <7929478+CassOnMars@users.noreply.github.com> * fix newPebbleDB constructor config param (#517) * fix: high CPU overhead in initial worker behaviors/ongoing sync * faster docker builds with better caching * qol: add extra data to node info, and query metrics from command line * leave proposals for overcrowded shards * hub-and-spoke global message broadcasts * small tweaks to cli output for join frames --------- Co-authored-by: winged-pegasus <55340199+winged-pegasus@users.noreply.github.com> Co-authored-by: Tyler Sturos <55340199+tjsturos@users.noreply.github.com> Co-authored-by: Black Swan <3999712+blacks1ne@users.noreply.github.com>
236 lines
7.4 KiB
Go
236 lines
7.4 KiB
Go
package tests
|
|
|
|
import (
|
|
"bytes"
|
|
crand "crypto/rand"
|
|
"crypto/sha512"
|
|
"math/big"
|
|
"math/rand"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/cloudflare/circl/sign/ed448"
|
|
"github.com/stretchr/testify/mock"
|
|
"go.uber.org/zap"
|
|
"source.quilibrium.com/quilibrium/monorepo/config"
|
|
hg "source.quilibrium.com/quilibrium/monorepo/hypergraph"
|
|
pebblestore "source.quilibrium.com/quilibrium/monorepo/node/store"
|
|
"source.quilibrium.com/quilibrium/monorepo/types/crypto"
|
|
"source.quilibrium.com/quilibrium/monorepo/types/hypergraph"
|
|
"source.quilibrium.com/quilibrium/monorepo/types/mocks"
|
|
"source.quilibrium.com/quilibrium/monorepo/types/store"
|
|
"source.quilibrium.com/quilibrium/monorepo/types/tries"
|
|
)
|
|
|
|
type Operation struct {
|
|
Type string // "AddVertex", "RemoveVertex", "AddHyperedge", "RemoveHyperedge"
|
|
Vertex hypergraph.Vertex
|
|
Hyperedge hypergraph.Hyperedge
|
|
}
|
|
|
|
func TestConvergence(t *testing.T) {
|
|
numParties := 4
|
|
numOperations := 10000
|
|
enc := &mocks.MockVerifiableEncryptor{}
|
|
incProver := &mocks.MockInclusionProver{}
|
|
vep := &mocks.MockVerEncProof{}
|
|
ve := &mocks.MockVerEnc{}
|
|
pub, _, _ := ed448.GenerateKey(crand.Reader)
|
|
mockCommit := make([]byte, 74)
|
|
mockCommit[0] = 0x02
|
|
crand.Read(mockCommit[1:])
|
|
incProver.On("CommitRaw", mock.Anything, mock.Anything).Return(mockCommit, nil)
|
|
ve.On("ToBytes").Return([]byte{})
|
|
ve.On("GetStatement").Return(make([]byte, 74))
|
|
vep.On("Compress").Return(ve)
|
|
enc.On("Encrypt", make([]byte, 20), []byte(pub)).Return([]crypto.VerEncProof{
|
|
vep,
|
|
})
|
|
data := enc.Encrypt(make([]byte, 20), pub)
|
|
verenc := data[0].Compress()
|
|
vertices := make([]hypergraph.Vertex, numOperations)
|
|
dataTree := &tries.VectorCommitmentTree{}
|
|
for _, d := range []hypergraph.Encrypted{verenc} {
|
|
dataBytes := d.ToBytes()
|
|
id := sha512.Sum512(dataBytes)
|
|
dataTree.Insert(id[:], dataBytes, d.GetStatement(), big.NewInt(int64(len(data)*55)))
|
|
}
|
|
dataTree.Commit(incProver, false)
|
|
for i := 0; i < numOperations; i++ {
|
|
vertices[i] = hg.NewVertex(
|
|
[32]byte{byte((i >> 8) % 256), byte((i % 256))},
|
|
[32]byte{byte((i >> 8) / 256), byte(i / 256)},
|
|
dataTree.Commit(incProver, false),
|
|
dataTree.GetSize(),
|
|
)
|
|
}
|
|
|
|
hyperedges := make([]hypergraph.Hyperedge, numOperations/100)
|
|
for i := 0; i < numOperations/100; i++ {
|
|
hyperedges[i] = hg.NewHyperedge(
|
|
[32]byte{0, 0, byte((i >> 8) % 256), byte(i % 256)},
|
|
[32]byte{0, 0, byte((i >> 8) / 256), byte(i / 256)},
|
|
)
|
|
for j := 0; j < 3; j++ {
|
|
v := vertices[rand.Intn(len(vertices))]
|
|
hyperedges[i].AddExtrinsic(v)
|
|
}
|
|
}
|
|
|
|
operations1 := make([]Operation, numOperations)
|
|
operations2 := make([]Operation, numOperations)
|
|
operations3 := make([]Operation, numOperations)
|
|
operations4 := make([]Operation, numOperations)
|
|
for i := 0; i < numOperations; i++ {
|
|
op := rand.Intn(2)
|
|
switch op {
|
|
case 0:
|
|
operations1[i] = Operation{Type: "AddVertex", Vertex: vertices[i]}
|
|
case 1:
|
|
operations2[i] = Operation{Type: "AddVertex", Vertex: vertices[i]}
|
|
}
|
|
}
|
|
for i := 0; i < numOperations; i++ {
|
|
op := rand.Intn(2)
|
|
switch op {
|
|
case 0:
|
|
operations3[i] = Operation{Type: "AddHyperedge", Hyperedge: hyperedges[rand.Intn(len(hyperedges))]}
|
|
case 1:
|
|
operations4[i] = Operation{Type: "RemoveHyperedge", Hyperedge: hyperedges[rand.Intn(len(hyperedges))]}
|
|
}
|
|
}
|
|
|
|
crdts := make([]*hg.HypergraphCRDT, numParties)
|
|
var store0 store.KVDB
|
|
for i := 0; i < numParties; i++ {
|
|
logger, _ := zap.NewDevelopment()
|
|
s := pebblestore.NewPebbleDB(logger, &config.Config{DB: &config.DBConfig{InMemoryDONOTUSE: true, Path: ".configtest/store"}}, 0)
|
|
if i == 0 {
|
|
store0 = s
|
|
}
|
|
hgs := pebblestore.NewPebbleHypergraphStore(&config.DBConfig{InMemoryDONOTUSE: true, Path: ".configtest/store"}, s, logger, enc, incProver)
|
|
crdts[i] = hg.NewHypergraph(logger, hgs, incProver, []int{}, &Nopthenticator{}, 200)
|
|
hgs.MarkHypergraphAsComplete()
|
|
}
|
|
|
|
for i := 0; i < numParties; i++ {
|
|
rand.Seed(time.Now().UnixNano())
|
|
rand.Shuffle(len(operations1), func(i, j int) { operations1[i], operations1[j] = operations1[j], operations1[i] })
|
|
rand.Shuffle(len(operations2), func(i, j int) { operations2[i], operations2[j] = operations2[j], operations2[i] })
|
|
rand.Shuffle(len(operations3), func(i, j int) { operations3[i], operations3[j] = operations3[j], operations3[i] })
|
|
rand.Shuffle(len(operations4), func(i, j int) { operations4[i], operations4[j] = operations4[j], operations4[i] })
|
|
|
|
for _, op := range operations1 {
|
|
switch op.Type {
|
|
case "AddVertex":
|
|
crdts[i].AddVertex(nil, op.Vertex)
|
|
case "RemoveVertex":
|
|
crdts[i].RemoveVertex(nil, op.Vertex)
|
|
case "AddHyperedge":
|
|
crdts[i].AddHyperedge(nil, op.Hyperedge)
|
|
case "RemoveHyperedge":
|
|
crdts[i].RemoveHyperedge(nil, op.Hyperedge)
|
|
}
|
|
}
|
|
for _, op := range operations2 {
|
|
switch op.Type {
|
|
case "AddVertex":
|
|
crdts[i].AddVertex(nil, op.Vertex)
|
|
case "RemoveVertex":
|
|
crdts[i].RemoveVertex(nil, op.Vertex)
|
|
case "AddHyperedge":
|
|
crdts[i].AddHyperedge(nil, op.Hyperedge)
|
|
case "RemoveHyperedge":
|
|
crdts[i].RemoveHyperedge(nil, op.Hyperedge)
|
|
}
|
|
}
|
|
for _, op := range operations3 {
|
|
switch op.Type {
|
|
case "AddVertex":
|
|
crdts[i].AddVertex(nil, op.Vertex)
|
|
case "RemoveVertex":
|
|
crdts[i].RemoveVertex(nil, op.Vertex)
|
|
case "AddHyperedge":
|
|
crdts[i].AddHyperedge(nil, op.Hyperedge)
|
|
case "RemoveHyperedge":
|
|
crdts[i].RemoveHyperedge(nil, op.Hyperedge)
|
|
}
|
|
}
|
|
for _, op := range operations4 {
|
|
switch op.Type {
|
|
case "AddVertex":
|
|
crdts[i].AddVertex(nil, op.Vertex)
|
|
case "RemoveVertex":
|
|
crdts[i].RemoveVertex(nil, op.Vertex)
|
|
case "AddHyperedge":
|
|
crdts[i].AddHyperedge(nil, op.Hyperedge)
|
|
case "RemoveHyperedge":
|
|
crdts[i].RemoveHyperedge(nil, op.Hyperedge)
|
|
}
|
|
}
|
|
}
|
|
|
|
crdts[0].GetSize(nil, nil)
|
|
|
|
for _, v := range vertices {
|
|
state := crdts[0].LookupVertex(v)
|
|
for i := 1; i < numParties; i++ {
|
|
if crdts[i].LookupVertex(v) != state {
|
|
t.Errorf("Vertex %v has different state in CRDT %d", v, i)
|
|
}
|
|
}
|
|
}
|
|
for _, h := range hyperedges {
|
|
state := crdts[0].LookupHyperedge(h)
|
|
for i := 1; i < numParties; i++ {
|
|
if crdts[i].LookupHyperedge(h) != state {
|
|
t.Errorf("Hyperedge %v has different state in CRDT %d, %v", h, i, state)
|
|
}
|
|
}
|
|
}
|
|
|
|
logger, _ := zap.NewDevelopment()
|
|
hgs := pebblestore.NewPebbleHypergraphStore(&config.DBConfig{InMemoryDONOTUSE: true, Path: ".configtest/store"}, store0, logger, enc, incProver)
|
|
compload, err := hgs.LoadHypergraph(&Nopthenticator{}, 200)
|
|
if err != nil {
|
|
t.Errorf("Could not load hg, %v", err)
|
|
}
|
|
|
|
for _, v := range vertices {
|
|
state := crdts[0].LookupVertex(v)
|
|
if compload.LookupVertex(v) != state {
|
|
t.Errorf("Vertex %v has different state in loaded CRDT", v)
|
|
}
|
|
if state {
|
|
loadvert, err := compload.GetVertex(v.GetID())
|
|
if err != nil {
|
|
t.Errorf("Vertex %v could not be loaded in loaded CRDT, %v", v, err)
|
|
}
|
|
|
|
vb1 := v.ToBytes()
|
|
vb2 := loadvert.ToBytes()
|
|
if !bytes.Equal(vb1, vb2) {
|
|
t.Errorf("Vertex %v does not match the one loaded in loaded CRDT\n%x\n%x", v, vb1, vb2)
|
|
}
|
|
}
|
|
}
|
|
for _, h := range hyperedges {
|
|
state := crdts[0].LookupHyperedge(h)
|
|
if compload.LookupHyperedge(h) != state {
|
|
t.Errorf("Hyperedge %v has different state in loaded CRDT", h)
|
|
}
|
|
if state {
|
|
loadhe, err := compload.GetHyperedge(h.GetID())
|
|
if err != nil {
|
|
t.Errorf("Hyperedge %v could not be loaded in loaded CRDT, %v", h, err)
|
|
}
|
|
|
|
hb1 := h.ToBytes()
|
|
hb2 := loadhe.ToBytes()
|
|
if !bytes.Equal(hb1, hb2) {
|
|
t.Errorf("Hyperedge %v does not match the one loaded in loaded CRDT\n%x\n%x", h, hb1, hb2)
|
|
}
|
|
}
|
|
}
|
|
}
|