ceremonyclient/node/execution/ceremony/application/ceremony_application_in_progress.go
2023-09-24 21:43:35 -05:00

253 lines
6.2 KiB
Go

package application
import (
"bytes"
"encoding/binary"
"github.com/pkg/errors"
"source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/core/curves"
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
)
func (a *CeremonyApplication) applySeenProverAttestation(
seenProverAttestation *protobufs.CeremonySeenProverAttestation,
) error {
if seenProverAttestation.SeenProverKey == nil ||
seenProverAttestation.SeenProverKey.KeyValue == nil {
return errors.Wrap(
errors.New("signature is nil"),
"apply seen prover attestation",
)
}
inParticipantList := false
for _, p := range a.ActiveParticipants {
if bytes.Equal(p.KeyValue, seenProverAttestation.SeenProverKey.KeyValue) {
inParticipantList = true
break
}
}
if !inParticipantList {
return errors.Wrap(
errors.New("prover not in active participant list"),
"apply seen prover attestation",
)
}
b := binary.BigEndian.AppendUint64(
[]byte("lastseen"),
seenProverAttestation.LastSeenFrame,
)
b = append(b, seenProverAttestation.SeenProverKey.KeyValue...)
signature := seenProverAttestation.GetProverSignature()
if signature == nil {
return errors.Wrap(
errors.New("signature is nil"),
"apply seen prover attestation",
)
}
if err := signature.Verify(b); err != nil {
return errors.Wrap(err, "apply seen prover attestation")
}
replaced := false
for i, att := range a.LatestSeenProverAttestations {
if bytes.Equal(
att.SeenProverKey.KeyValue,
seenProverAttestation.SeenProverKey.KeyValue,
) &&
bytes.Equal(
att.ProverSignature.PublicKey.KeyValue,
seenProverAttestation.ProverSignature.PublicKey.KeyValue,
) && att.LastSeenFrame < seenProverAttestation.LastSeenFrame {
a.LatestSeenProverAttestations[i] = att
replaced = true
break
}
}
if !replaced {
a.LatestSeenProverAttestations = append(
a.LatestSeenProverAttestations,
seenProverAttestation,
)
}
return nil
}
func (a *CeremonyApplication) applyDroppedProverAttestation(
droppedProverAttestation *protobufs.CeremonyDroppedProverAttestation,
) error {
if droppedProverAttestation.DroppedProverKey == nil ||
droppedProverAttestation.DroppedProverKey.KeyValue == nil {
return errors.Wrap(
errors.New("signature is nil"),
"apply dropped prover attestation",
)
}
inParticipantList := false
for _, p := range a.ActiveParticipants {
if bytes.Equal(
p.KeyValue,
droppedProverAttestation.DroppedProverKey.KeyValue,
) {
inParticipantList = true
break
}
}
if !inParticipantList {
return errors.Wrap(
errors.New("prover not in active participant list"),
"apply dropped prover attestation",
)
}
b := binary.BigEndian.AppendUint64(
[]byte("dropped"),
droppedProverAttestation.LastSeenFrame,
)
b = append(b, droppedProverAttestation.DroppedProverKey.KeyValue...)
signature := droppedProverAttestation.GetProverSignature()
if signature == nil {
return errors.Wrap(
errors.New("signature is nil"),
"apply dropped prover attestation",
)
}
if err := signature.Verify(b); err != nil {
return errors.Wrap(err, "apply dropped prover attestation")
}
replaced := false
for i, att := range a.DroppedParticipantAttestations {
if bytes.Equal(
att.DroppedProverKey.KeyValue,
droppedProverAttestation.DroppedProverKey.KeyValue,
) &&
bytes.Equal(
att.ProverSignature.PublicKey.KeyValue,
droppedProverAttestation.ProverSignature.PublicKey.KeyValue,
) && att.LastSeenFrame < droppedProverAttestation.LastSeenFrame {
a.DroppedParticipantAttestations[i] = att
replaced = true
break
}
}
if !replaced {
a.DroppedParticipantAttestations = append(
a.DroppedParticipantAttestations,
droppedProverAttestation,
)
}
return nil
}
func (a *CeremonyApplication) applyTranscriptCommit(
transcriptCommit *protobufs.CeremonyTranscriptCommit,
) error {
if transcriptCommit.ContributionSignature == nil ||
transcriptCommit.ProverSignature == nil ||
transcriptCommit.ContributionSignature.PublicKey == nil ||
transcriptCommit.ProverSignature.PublicKey == nil {
return errors.Wrap(
errors.New("signature is nil"),
"apply transcript commit",
)
}
point, err := curves.BLS48581G2().Point.FromAffineCompressed(
transcriptCommit.ContributionSignature.PublicKey.KeyValue,
)
if err != nil {
return errors.Wrap(err, "apply transcript commit")
}
if err := VerifySignatureOfProverKey(
transcriptCommit.ProverSignature.PublicKey.KeyValue,
transcriptCommit.ContributionSignature.Signature,
point,
); err != nil {
return errors.Wrap(err, "apply transcript commit")
}
if err := transcriptCommit.ProverSignature.Verify(
transcriptCommit.ContributionSignature.PublicKey.KeyValue,
); err != nil {
return errors.Wrap(err, "apply transcript commit")
}
inParticipantList := false
for _, p := range a.ActiveParticipants {
if bytes.Equal(
p.KeyValue,
transcriptCommit.ProverSignature.PublicKey.KeyValue,
) {
inParticipantList = true
break
}
}
if !inParticipantList {
return errors.Wrap(
errors.New("prover not in active participant list"),
"apply transcript commit",
)
}
maxRounds := uint64(1)
for i := 0; i < len(a.ActiveParticipants)-1; i++ {
maxRounds = maxRounds << 1
}
if len(a.TranscriptRoundAdvanceCommits) == 0 {
a.TranscriptRoundAdvanceCommits = []*protobufs.CeremonyAdvanceRound{
{
Commits: []*protobufs.CeremonyTranscriptCommit{},
},
}
}
if len(a.TranscriptRoundAdvanceCommits[a.RoundCount-1].Commits) ==
len(a.ActiveParticipants) {
if maxRounds ==
uint64(len(a.TranscriptRoundAdvanceCommits)) {
return errors.Wrap(
errors.New("round limit exceeded"),
"apply transcript commit",
)
}
a.TranscriptRoundAdvanceCommits = append(
a.TranscriptRoundAdvanceCommits,
&protobufs.CeremonyAdvanceRound{
Commits: []*protobufs.CeremonyTranscriptCommit{
transcriptCommit,
},
},
)
a.RoundCount++
} else {
for _, c := range a.TranscriptRoundAdvanceCommits[a.RoundCount-1].Commits {
if bytes.Equal(
c.ProverSignature.PublicKey.KeyValue,
transcriptCommit.ProverSignature.PublicKey.KeyValue,
) {
return nil
}
}
a.TranscriptRoundAdvanceCommits[a.RoundCount-1].Commits = append(
a.TranscriptRoundAdvanceCommits[a.RoundCount-1].Commits,
transcriptCommit,
)
}
return nil
}