mirror of
https://github.com/QuilibriumNetwork/ceremonyclient.git
synced 2026-02-21 10:27:26 +08:00
* experiment: reject bad peer info messages * v2.1.0.18 preview * add tagged sync * Add missing hypergraph changes * small tweaks to sync * allow local sync, use it for provers with workers * missing file * resolve build error * resolve sync issue, remove raw sync * resolve deletion promotion bug * resolve sync abstraction leak from tree deletion changes * rearrange prover sync * remove pruning from sync * restore removed sync flag * fix: sync, event stream deadlock, heuristic scoring of better shards * resolve hanging shutdown + pubsub proxy issue * further bugfixes: sync (restore old leaf sync), pubsub shutdown, merge events * fix: clean up rust ffi, background coverage events, and sync tweaks * fix: linking issue for channel, connectivity test aggression, sync regression, join tests * fix: disjoint sync, improper application of filter * resolve sync/reel/validation deadlock * adjust sync to handle no leaf edge cases, multi-path segment traversal * use simpler sync * faster, simpler sync with some debug extras * migration to recalculate * don't use batch * square up the roots * fix nil pointer * fix: seniority calculation, sync race condition, migration * make sync dumber * fix: tree deletion issue * fix: missing seniority merge request canonical serialization * address issues from previous commit test * stale workers should be cleared * remove missing gap check * rearrange collect, reduce sync logging noise * fix: the disjoint leaf/branch sync case * nuclear option on sync failures * v2.1.0.18, finalized
293 lines
6.9 KiB
Go
293 lines
6.9 KiB
Go
package ferret
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/pkg/errors"
|
|
generated "source.quilibrium.com/quilibrium/monorepo/ferret/generated/ferret"
|
|
)
|
|
|
|
//go:generate ./generate.sh
|
|
|
|
const (
|
|
ALICE = 1
|
|
BOB = 2
|
|
)
|
|
|
|
type FerretOT struct {
|
|
party int
|
|
ferretCOT *generated.FerretCotManager
|
|
netio *generated.NetIoManager
|
|
}
|
|
|
|
func NewFerretOT(
|
|
party int,
|
|
address string,
|
|
port int,
|
|
threads int,
|
|
length uint64,
|
|
choices []bool,
|
|
malicious bool,
|
|
) (*FerretOT, error) {
|
|
if threads > 1 {
|
|
fmt.Println(
|
|
"!!!WARNING!!! THERE BE DRAGONS. RUNNING MULTITHREADED MODE IN SOME " +
|
|
"SITUATIONS HAS LEAD TO CRASHES AND OTHER ISSUES. IF YOU STILL WISH " +
|
|
"TO DO THIS, YOU WILL NEED TO MANUALLY UPDATE THE BUILD AND REMOVE " +
|
|
"THIS CHECK. DO SO AT YOUR OWN RISK",
|
|
)
|
|
return nil, errors.Wrap(errors.New("invalid thread count"), "new ferret ot")
|
|
}
|
|
|
|
var addr *string
|
|
if address != "" {
|
|
addrCopy := address
|
|
addr = &addrCopy
|
|
}
|
|
|
|
netio := generated.CreateNetioManager(
|
|
int32(party),
|
|
addr,
|
|
int32(port),
|
|
)
|
|
|
|
ferretCOT := generated.CreateFerretCotManager(
|
|
int32(party),
|
|
int32(threads),
|
|
length,
|
|
choices,
|
|
netio,
|
|
malicious,
|
|
)
|
|
|
|
return &FerretOT{
|
|
party: party,
|
|
ferretCOT: ferretCOT,
|
|
netio: netio,
|
|
}, nil
|
|
}
|
|
|
|
func (ot *FerretOT) SendCOT() error {
|
|
if ot.party != ALICE {
|
|
return errors.New("incorrect party")
|
|
}
|
|
|
|
ot.ferretCOT.SendCot()
|
|
|
|
return nil
|
|
}
|
|
|
|
func (ot *FerretOT) RecvCOT() error {
|
|
if ot.party != BOB {
|
|
return errors.New("incorrect party")
|
|
}
|
|
|
|
ot.ferretCOT.RecvCot()
|
|
|
|
return nil
|
|
}
|
|
|
|
func (ot *FerretOT) SendROT() error {
|
|
ot.ferretCOT.SendRot()
|
|
return nil
|
|
}
|
|
|
|
func (ot *FerretOT) RecvROT() error {
|
|
ot.ferretCOT.RecvRot()
|
|
return nil
|
|
}
|
|
|
|
func (ot *FerretOT) SenderGetBlockData(choice bool, index uint64) []byte {
|
|
c := uint8(0)
|
|
if choice {
|
|
c = 1
|
|
}
|
|
return ot.ferretCOT.GetBlockData(c, index)
|
|
}
|
|
|
|
func (ot *FerretOT) ReceiverGetBlockData(index uint64) []byte {
|
|
return ot.ferretCOT.GetBlockData(0, index)
|
|
}
|
|
|
|
// FerretBufferOT is a buffer-based Ferret OT that uses message passing
|
|
// instead of direct TCP connections. This allows routing OT traffic through
|
|
// an external transport (e.g., message channels, proxies).
|
|
type FerretBufferOT struct {
|
|
party int
|
|
ferretCOT *generated.FerretCotBufferManager
|
|
bufferIO *generated.BufferIoManager
|
|
}
|
|
|
|
// NewFerretBufferOT creates a new buffer-based Ferret OT.
|
|
// Unlike NewFerretOT, this doesn't establish any network connections.
|
|
// Instead, the caller is responsible for:
|
|
// 1. Calling DrainSend() to get outgoing data
|
|
// 2. Transmitting that data to the peer via their own transport
|
|
// 3. Receiving data from peer and calling FillRecv() with it
|
|
func NewFerretBufferOT(
|
|
party int,
|
|
threads int,
|
|
length uint64,
|
|
choices []bool,
|
|
malicious bool,
|
|
initialBufferCap int64,
|
|
) (*FerretBufferOT, error) {
|
|
if threads > 1 {
|
|
fmt.Println(
|
|
"!!!WARNING!!! THERE BE DRAGONS. RUNNING MULTITHREADED MODE IN SOME " +
|
|
"SITUATIONS HAS LEAD TO CRASHES AND OTHER ISSUES. IF YOU STILL WISH " +
|
|
"TO DO THIS, YOU WILL NEED TO MANUALLY UPDATE THE BUILD AND REMOVE " +
|
|
"THIS CHECK. DO SO AT YOUR OWN RISK",
|
|
)
|
|
return nil, errors.Wrap(errors.New("invalid thread count"), "new ferret buffer ot")
|
|
}
|
|
|
|
bufferIO := generated.CreateBufferIoManager(initialBufferCap)
|
|
|
|
ferretCOT := generated.CreateFerretCotBufferManager(
|
|
int32(party),
|
|
int32(threads),
|
|
length,
|
|
choices,
|
|
bufferIO,
|
|
malicious,
|
|
)
|
|
|
|
return &FerretBufferOT{
|
|
party: party,
|
|
ferretCOT: ferretCOT,
|
|
bufferIO: bufferIO,
|
|
}, nil
|
|
}
|
|
|
|
// FillRecv fills the receive buffer with data from an external transport.
|
|
// Call this when you receive data from the peer.
|
|
func (ot *FerretBufferOT) FillRecv(data []byte) bool {
|
|
return ot.bufferIO.FillRecv(data)
|
|
}
|
|
|
|
// DrainSend drains up to maxLen bytes from the send buffer.
|
|
// Call this to get data that needs to be sent to the peer.
|
|
func (ot *FerretBufferOT) DrainSend(maxLen uint64) []byte {
|
|
return ot.bufferIO.DrainSend(maxLen)
|
|
}
|
|
|
|
// SendSize returns the number of bytes waiting to be sent.
|
|
func (ot *FerretBufferOT) SendSize() uint64 {
|
|
return ot.bufferIO.SendSize()
|
|
}
|
|
|
|
// RecvAvailable returns the number of bytes available in the receive buffer.
|
|
func (ot *FerretBufferOT) RecvAvailable() uint64 {
|
|
return ot.bufferIO.RecvAvailable()
|
|
}
|
|
|
|
// SetTimeout sets the timeout for blocking receive operations (in milliseconds).
|
|
// Set to -1 for no timeout (blocking forever until data arrives).
|
|
func (ot *FerretBufferOT) SetTimeout(timeoutMs int64) {
|
|
ot.bufferIO.SetTimeout(timeoutMs)
|
|
}
|
|
|
|
// SetError sets an error state that will cause receive operations to fail.
|
|
// Useful for signaling that the connection has been closed.
|
|
func (ot *FerretBufferOT) SetError(message string) {
|
|
ot.bufferIO.SetError(message)
|
|
}
|
|
|
|
// Clear clears all buffers.
|
|
func (ot *FerretBufferOT) Clear() {
|
|
ot.bufferIO.Clear()
|
|
}
|
|
|
|
// Setup runs the OT setup protocol. Must be called after both parties have
|
|
// their BufferIO message transport active (can send/receive data).
|
|
// This is deferred from construction because BufferIO-based OT needs
|
|
// the message channel to be ready before setup can exchange data.
|
|
// Returns true on success, false on error.
|
|
func (ot *FerretBufferOT) Setup() bool {
|
|
return ot.ferretCOT.Setup()
|
|
}
|
|
|
|
// IsSetup returns true if the OT setup has been completed.
|
|
func (ot *FerretBufferOT) IsSetup() bool {
|
|
return ot.ferretCOT.IsSetup()
|
|
}
|
|
|
|
// StateSize returns the size in bytes needed to store the OT state.
|
|
func (ot *FerretBufferOT) StateSize() int64 {
|
|
return ot.ferretCOT.StateSize()
|
|
}
|
|
|
|
// AssembleState serializes the OT state for persistent storage.
|
|
// This allows storing setup data externally instead of in files.
|
|
// Returns nil if serialization fails.
|
|
func (ot *FerretBufferOT) AssembleState() []byte {
|
|
return ot.ferretCOT.AssembleState()
|
|
}
|
|
|
|
// DisassembleState restores the OT state from a buffer (created by AssembleState).
|
|
// This must be called INSTEAD of Setup, not after.
|
|
// Returns true on success.
|
|
func (ot *FerretBufferOT) DisassembleState(data []byte) bool {
|
|
return ot.ferretCOT.DisassembleState(data)
|
|
}
|
|
|
|
func (ot *FerretBufferOT) SendCOT() error {
|
|
if ot.party != ALICE {
|
|
return errors.New("incorrect party")
|
|
}
|
|
|
|
if !ot.ferretCOT.SendCot() {
|
|
return errors.New("send COT failed")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (ot *FerretBufferOT) RecvCOT() error {
|
|
if ot.party != BOB {
|
|
return errors.New("incorrect party")
|
|
}
|
|
|
|
if !ot.ferretCOT.RecvCot() {
|
|
return errors.New("recv COT failed")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (ot *FerretBufferOT) SendROT() error {
|
|
if !ot.ferretCOT.SendRot() {
|
|
return errors.New("send ROT failed")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (ot *FerretBufferOT) RecvROT() error {
|
|
if !ot.ferretCOT.RecvRot() {
|
|
return errors.New("recv ROT failed")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (ot *FerretBufferOT) SenderGetBlockData(choice bool, index uint64) []byte {
|
|
c := uint8(0)
|
|
if choice {
|
|
c = 1
|
|
}
|
|
return ot.ferretCOT.GetBlockData(c, index)
|
|
}
|
|
|
|
func (ot *FerretBufferOT) ReceiverGetBlockData(index uint64) []byte {
|
|
return ot.ferretCOT.GetBlockData(0, index)
|
|
}
|
|
|
|
func (ot *FerretBufferOT) Destroy() {
|
|
if ot.ferretCOT != nil {
|
|
ot.ferretCOT.Destroy()
|
|
}
|
|
if ot.bufferIO != nil {
|
|
ot.bufferIO.Destroy()
|
|
}
|
|
}
|