QOL – fix crash/shutdown reentry bug, make validation faster

This commit is contained in:
Cassandra Heart 2023-09-25 03:45:22 -05:00
parent d1486d5be7
commit 2525c4ce7e
No known key found for this signature in database
GPG Key ID: 6352152859385958
4 changed files with 143 additions and 61 deletions

View File

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"github.com/pkg/errors" "github.com/pkg/errors"
"golang.org/x/sync/errgroup"
"source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/core/curves" "source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/core/curves"
"source.quilibrium.com/quilibrium/monorepo/node/protobufs" "source.quilibrium.com/quilibrium/monorepo/node/protobufs"
) )
@ -36,42 +37,59 @@ func (a *CeremonyApplication) applyTranscript(
) )
} }
g1s := []*curves.PointBls48581G1{} g1s := make([]*curves.PointBls48581G1, len(a.UpdatedTranscript.G1Powers))
eg := errgroup.Group{}
eg.SetLimit(100)
for i := range a.UpdatedTranscript.G1Powers { for i := range a.UpdatedTranscript.G1Powers {
if !bytes.Equal( i := i
a.UpdatedTranscript.G1Powers[i].KeyValue, eg.Go(func() error {
transcript.G1Powers[i].KeyValue, if !bytes.Equal(
) { a.UpdatedTranscript.G1Powers[i].KeyValue,
return errors.Wrap(errors.New("invalid g1s"), "apply transcript") transcript.G1Powers[i].KeyValue,
} ) {
return errors.Wrap(errors.New("invalid g1s"), "apply transcript")
}
g1 := &curves.PointBls48581G1{} g1 := &curves.PointBls48581G1{}
x, err := g1.FromAffineCompressed(a.UpdatedTranscript.G1Powers[i].KeyValue) x, err := g1.FromAffineCompressed(a.UpdatedTranscript.G1Powers[i].KeyValue)
if err != nil { if err != nil {
return errors.Wrap(err, "apply transcript") return errors.Wrap(err, "apply transcript")
} }
g1, _ = x.(*curves.PointBls48581G1) g1, _ = x.(*curves.PointBls48581G1)
g1s = append(g1s, g1) g1s[i] = g1
return nil
})
} }
g2s := []*curves.PointBls48581G2{} g2s := make([]*curves.PointBls48581G2, len(a.UpdatedTranscript.G2Powers))
for i := range a.UpdatedTranscript.G2Powers { for i := range a.UpdatedTranscript.G2Powers {
if !bytes.Equal( i := i
a.UpdatedTranscript.G2Powers[i].KeyValue, eg.Go(func() error {
transcript.G2Powers[i].KeyValue, if !bytes.Equal(
) { a.UpdatedTranscript.G2Powers[i].KeyValue,
return errors.Wrap(errors.New("invalid g2s"), "apply transcript") transcript.G2Powers[i].KeyValue,
} ) {
return errors.Wrap(errors.New("invalid g2s"), "apply transcript")
}
g2 := &curves.PointBls48581G2{} g2 := &curves.PointBls48581G2{}
x, err := g2.FromAffineCompressed(a.UpdatedTranscript.G2Powers[i].KeyValue) x, err := g2.FromAffineCompressed(a.UpdatedTranscript.G2Powers[i].KeyValue)
if err != nil { if err != nil {
return errors.Wrap(err, "apply transcript") return errors.Wrap(err, "apply transcript")
} }
g2, _ = x.(*curves.PointBls48581G2) g2, _ = x.(*curves.PointBls48581G2)
g2s = append(g2s, g2) g2s[i] = g2
return nil
})
}
if err := eg.Wait(); err != nil {
return err
} }
g1Witnesses := []*curves.PointBls48581G1{} g1Witnesses := []*curves.PointBls48581G1{}

View File

@ -70,7 +70,7 @@ func ProcessRound(
for !participants[j].IsDone() { for !participants[j].IsDone() {
var err error var err error
if isReceiver { if isReceiver {
msg, err = recv(seq, append(append([]byte{}, roundPeers[j]...), i...)) msg, err = recv(seq, roundPeers[j])
if err != nil { if err != nil {
return err return err
} }
@ -81,13 +81,13 @@ func ProcessRound(
return err return err
} }
err = send(seq, append(append([]byte{}, i...), roundPeers[j]...), next) err = send(seq, roundPeers[j], next)
if err != nil { if err != nil {
return err return err
} }
if !isReceiver { if !isReceiver {
msg, err = recv(seq, append(append([]byte{}, roundPeers[j]...), i...)) msg, err = recv(seq, roundPeers[j])
if err != nil { if err != nil {
return err return err
} }

View File

@ -196,36 +196,39 @@ func TestProcessRound(t *testing.T) {
peerSecrets = append(peerSecrets, secrets) peerSecrets = append(peerSecrets, secrets)
originalPeerSecrets = append(originalPeerSecrets, originalSecrets) originalPeerSecrets = append(originalPeerSecrets, originalSecrets)
} }
messages := syncmap.Map{} messages := syncmap.Map{}
send := func(seq int, dst, msg []byte) error { send := func(peer []byte) func(seq int, dst, msg []byte) error {
fmt.Printf("send %d bytes for seq %d to %+x\n", len(msg), seq, dst) return func(seq int, dst, msg []byte) error {
fmt.Printf("send %d bytes for seq %d to %+x\n", len(msg), seq, dst)
b := byte(seq) b := byte(seq)
dst = append(append([]byte{}, b), dst...) dst = append(append(append([]byte{}, b), peer...), dst...)
if msg == nil { if msg == nil {
msg = []byte{0x01} msg = []byte{0x01}
}
messages.Store(string(dst), string(msg))
return nil
} }
messages.Store(string(dst), string(msg))
return nil
} }
recv := func(seq int, src []byte) ([]byte, error) { recv := func(peer []byte) func(seq int, src []byte) ([]byte, error) {
fmt.Printf("recv %d from %+x\n", seq, src) return func(seq int, src []byte) ([]byte, error) {
fmt.Printf("recv %d from %+x\n", seq, src)
b := byte(seq) b := byte(seq)
bsrc := append(append([]byte{}, b), src...) bsrc := append(append(append([]byte{}, b), src...), peer...)
msg, ok := messages.LoadAndDelete(string(bsrc)) msg, ok := messages.LoadAndDelete(string(bsrc))
for !ok { for !ok {
fmt.Printf("no message yet, waiting for recv %d from %+x\n", seq, src) fmt.Printf("no message yet, waiting for recv %d from %+x\n", seq, src)
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
msg, ok = messages.LoadAndDelete(string(bsrc)) msg, ok = messages.LoadAndDelete(string(bsrc))
}
return []byte(msg.(string)), nil
} }
return []byte(msg.(string)), nil
} }
for j := 1; j < 4; j++ { for j := 1; j < 4; j++ {
@ -244,8 +247,8 @@ func TestProcessRound(t *testing.T) {
idkPoints, idkPoints,
peerSecrets[i], peerSecrets[i],
curves.BLS48581G1(), curves.BLS48581G1(),
send, send(peerPoints[i]),
recv, recv(peerPoints[i]),
[]byte{0x01}, []byte{0x01},
) )
require.NoError(t, err) require.NoError(t, err)

View File

@ -45,6 +45,8 @@ type CeremonyExecutionEngine struct {
activeClockFrame *protobufs.ClockFrame activeClockFrame *protobufs.ClockFrame
alreadyPublishedShare bool alreadyPublishedShare bool
alreadyPublishedTranscript bool alreadyPublishedTranscript bool
seenMessageMap map[string]bool
seenMessageMx sync.Mutex
} }
func NewCeremonyExecutionEngine( func NewCeremonyExecutionEngine(
@ -71,6 +73,8 @@ func NewCeremonyExecutionEngine(
participantMx: sync.Mutex{}, participantMx: sync.Mutex{},
peerChannels: map[string]*p2p.PublicP2PChannel{}, peerChannels: map[string]*p2p.PublicP2PChannel{},
alreadyPublishedShare: false, alreadyPublishedShare: false,
seenMessageMx: sync.Mutex{},
seenMessageMap: map[string]bool{},
} }
provingKey, _, publicKeyBytes, provingKeyAddress := e.clock.GetProvingKey( provingKey, _, publicKeyBytes, provingKeyAddress := e.clock.GetProvingKey(
@ -329,7 +333,17 @@ func (e *CeremonyExecutionEngine) RunWorker() {
zap.Uint64("current_round", app.RoundCount), zap.Uint64("current_round", app.RoundCount),
) )
e.ensureSecrets(app) if len(e.activeSecrets) == 0 {
// If we ended up in the scenario where we do not have any secrets
// available but we're in the round, we should politely leave.
for _, p := range app.ActiveParticipants {
if bytes.Equal(p.KeyValue, e.proverPublicKey) {
e.publishDroppedParticipant(e.proverPublicKey)
break
}
}
continue
}
shouldConnect := false shouldConnect := false
position := 0 position := 0
@ -339,6 +353,7 @@ func (e *CeremonyExecutionEngine) RunWorker() {
if bytes.Equal(p.KeyValue, e.proverPublicKey) { if bytes.Equal(p.KeyValue, e.proverPublicKey) {
shouldConnect = true shouldConnect = true
position = i position = i
break
} }
} }
} }
@ -378,6 +393,7 @@ func (e *CeremonyExecutionEngine) RunWorker() {
err := e.participateRound(app) err := e.participateRound(app)
if err != nil { if err != nil {
e.logger.Error("error while participating in round", zap.Error(err)) e.logger.Error("error while participating in round", zap.Error(err))
e.publishDroppedParticipant(e.proverPublicKey)
} }
} }
} else if len(app.ActiveParticipants) == 1 && } else if len(app.ActiveParticipants) == 1 &&
@ -411,7 +427,19 @@ func (e *CeremonyExecutionEngine) RunWorker() {
} }
} }
if !e.alreadyPublishedShare { shouldPublish := false
for _, p := range app.ActiveParticipants {
if bytes.Equal(p.KeyValue, e.proverPublicKey) {
shouldPublish = true
break
}
}
if !e.alreadyPublishedShare && shouldPublish {
if len(e.activeSecrets) == 0 {
e.publishDroppedParticipant(e.proverPublicKey)
continue
}
err := e.publishTranscriptShare(app) err := e.publishTranscriptShare(app)
if err != nil { if err != nil {
e.logger.Error( e.logger.Error(
@ -620,8 +648,14 @@ func (e *CeremonyExecutionEngine) participateRound(
return errors.Wrap(err, "participate round") return errors.Wrap(err, "participate round")
} }
spk, err := e.keyManager.GetAgreementKey("q-ratchet-spk")
if err != nil {
return errors.Wrap(err, "participate round")
}
idkPoint := curves.ED448().Point.Generator().Mul(idk) idkPoint := curves.ED448().Point.Generator().Mul(idk)
idks := []curves.Point{} idks := []curves.Point{}
initiator := false
for _, p := range app.ActiveParticipants { for _, p := range app.ActiveParticipants {
if !bytes.Equal(p.KeyValue, e.proverPublicKey) { if !bytes.Equal(p.KeyValue, e.proverPublicKey) {
ic, err := e.keyStore.GetLatestKeyBundle(p.KeyValue) ic, err := e.keyStore.GetLatestKeyBundle(p.KeyValue)
@ -647,8 +681,35 @@ func (e *CeremonyExecutionEngine) participateRound(
if err != nil { if err != nil {
return errors.Wrap(err, "participate round") return errors.Wrap(err, "participate round")
} }
receiverSpk, err := curves.ED448().Point.FromAffineCompressed(
kba.SignedPreKey.GetPublicKeySignatureEd448().PublicKey.KeyValue,
)
if err != nil {
return errors.Wrap(err, "participate round")
}
if _, ok := e.peerChannels[string(p.KeyValue)]; !ok {
e.peerChannels[string(p.KeyValue)], err = p2p.NewPublicP2PChannel(
e.proverPublicKey,
p.KeyValue,
initiator,
idk,
spk,
receiverIdk,
receiverSpk,
curves.ED448(),
e.keyManager,
e.pubSub,
)
if err != nil {
return errors.Wrap(err, "participate round")
}
}
idks = append(idks, receiverIdk) idks = append(idks, receiverIdk)
} else { } else {
initiator = true
idks = append(idks, idkPoint) idks = append(idks, idkPoint)
} }
} }
@ -666,19 +727,19 @@ func (e *CeremonyExecutionEngine) participateRound(
idks, idks,
e.activeSecrets, e.activeSecrets,
curves.BLS48581G1(), curves.BLS48581G1(),
func(i int, filter, msg []byte) error { func(i int, receiver []byte, msg []byte) error {
return e.peerChannels[string(filter[len(e.proverPublicKey):])].Send(msg) return e.peerChannels[string(receiver)].Send(msg)
}, },
func(i int, filter []byte) ([]byte, error) { func(i int, sender []byte) ([]byte, error) {
msg, err := e.peerChannels[string( msg, err := e.peerChannels[string(
filter[:len(e.proverPublicKey)], sender,
)].Receive() )].Receive()
if err != nil { if err != nil {
e.publishDroppedParticipant(filter[:len(e.proverPublicKey)]) e.publishDroppedParticipant(sender)
return nil, err return nil, err
} else { } else {
if i == 0 { if i == 0 {
e.publishLastSeenParticipant(filter[:len(e.proverPublicKey)]) e.publishLastSeenParticipant(sender)
} }
return msg, nil return msg, nil
} }