Add transaction request validation (#390)

This commit is contained in:
petricadaipegsp 2024-11-28 01:13:57 +01:00 committed by GitHub
parent 87f4d7014c
commit 8b61918d43
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 1946 additions and 579 deletions

View File

@ -37,7 +37,7 @@ var mergeCmd = &cobra.Command{
panic(err)
}
pub, err := privKey.GetPublic().Raw()
pubKeyBytes, err := privKey.GetPublic().Raw()
if err != nil {
panic(err)
}
@ -48,7 +48,7 @@ var mergeCmd = &cobra.Command{
addrBytes := addr.FillBytes(make([]byte, 32))
altAddr, err := poseidon.HashBytes([]byte(pub))
altAddr, err := poseidon.HashBytes([]byte(pubKeyBytes))
if err != nil {
panic(err)
}
@ -109,34 +109,20 @@ var mergeCmd = &cobra.Command{
}
}
// Create payload for merge operation
payload := []byte("merge")
for _, coinRef := range coinaddrs {
payload = append(payload, coinRef.Address...)
merge := &protobufs.MergeCoinRequest{
Coins: coinaddrs,
}
// Signing process
sig, err := privKey.Sign(payload)
if err != nil {
if err := merge.SignED448(pubKeyBytes, privKey.Sign); err != nil {
panic(err)
}
if err := merge.Validate(); err != nil {
panic(err)
}
// Send merge request
_, err = client.SendMessage(
context.Background(),
&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Merge{
Merge: &protobufs.MergeCoinRequest{
Coins: coinaddrs,
Signature: &protobufs.Ed448Signature{
Signature: sig,
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: pub,
},
},
},
},
},
merge.TokenRequest(),
)
if err != nil {
panic(err)

View File

@ -98,19 +98,19 @@ func publishMessage(
filter []byte,
message proto.Message,
) error {
any := &anypb.Any{}
if err := any.MarshalFrom(message); err != nil {
a := &anypb.Any{}
if err := a.MarshalFrom(message); err != nil {
return errors.Wrap(err, "publish message")
}
any.TypeUrl = strings.Replace(
any.TypeUrl,
a.TypeUrl = strings.Replace(
a.TypeUrl,
"type.googleapis.com",
"types.quilibrium.com",
1,
)
payload, err := proto.Marshal(any)
payload, err := proto.Marshal(a)
if err != nil {
return errors.Wrap(err, "publish message")
}

View File

@ -29,7 +29,6 @@ var splitCmd = &cobra.Command{
os.Exit(1)
}
payload := []byte("split")
coinaddrHex, _ := strings.CutPrefix(args[0], "0x")
coinaddr, err := hex.DecodeString(coinaddrHex)
if err != nil {
@ -38,7 +37,6 @@ var splitCmd = &cobra.Command{
coin := &protobufs.CoinRef{
Address: coinaddr,
}
payload = append(payload, coinaddr...)
conversionFactor, _ := new(big.Int).SetString("1DCD65000", 16)
amounts := [][]byte{}
@ -51,7 +49,6 @@ var splitCmd = &cobra.Command{
amount = amount.Mul(decimal.NewFromBigInt(conversionFactor, 0))
amountBytes := amount.BigInt().FillBytes(make([]byte, 32))
amounts = append(amounts, amountBytes)
payload = append(payload, amountBytes...)
}
conn, err := GetGRPCClient()
@ -61,37 +58,29 @@ var splitCmd = &cobra.Command{
defer conn.Close()
client := protobufs.NewNodeServiceClient(conn)
key, err := GetPrivKeyFromConfig(NodeConfig)
privKey, err := GetPrivKeyFromConfig(NodeConfig)
if err != nil {
panic(err)
}
pubKeyBytes, err := privKey.GetPublic().Raw()
if err != nil {
panic(err)
}
sig, err := key.Sign(payload)
if err != nil {
split := &protobufs.SplitCoinRequest{
OfCoin: coin,
Amounts: amounts,
}
if err := split.SignED448(pubKeyBytes, privKey.Sign); err != nil {
panic(err)
}
pub, err := key.GetPublic().Raw()
if err != nil {
if err := split.Validate(); err != nil {
panic(err)
}
_, err = client.SendMessage(
context.Background(),
&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Split{
Split: &protobufs.SplitCoinRequest{
OfCoin: coin,
Amounts: amounts,
Signature: &protobufs.Ed448Signature{
Signature: sig,
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: pub,
},
},
},
},
},
split.TokenRequest(),
)
if err != nil {
panic(err)

View File

@ -31,13 +31,16 @@ var transferCmd = &cobra.Command{
defer conn.Close()
client := protobufs.NewNodeServiceClient(conn)
key, err := GetPrivKeyFromConfig(NodeConfig)
privKey, err := GetPrivKeyFromConfig(NodeConfig)
if err != nil {
panic(err)
}
pubKeyBytes, err := privKey.GetPublic().Raw()
if err != nil {
panic(err)
}
var coinaddr *protobufs.CoinRef
payload := []byte("transfer")
toaddr := []byte{}
for i, arg := range args {
addrHex, _ := strings.CutPrefix(arg, "0x")
@ -53,42 +56,28 @@ var transferCmd = &cobra.Command{
coinaddr = &protobufs.CoinRef{
Address: addr,
}
payload = append(payload, addr...)
}
payload = append(payload, toaddr...)
sig, err := key.Sign(payload)
if err != nil {
transfer := &protobufs.TransferCoinRequest{
OfCoin: coinaddr,
ToAccount: &protobufs.AccountRef{
Account: &protobufs.AccountRef_ImplicitAccount{
ImplicitAccount: &protobufs.ImplicitAccount{
Address: toaddr,
},
},
},
}
if err := transfer.SignED448(pubKeyBytes, privKey.Sign); err != nil {
panic(err)
}
pub, err := key.GetPublic().Raw()
if err != nil {
if err := transfer.Validate(); err != nil {
panic(err)
}
_, err = client.SendMessage(
context.Background(),
&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Transfer{
Transfer: &protobufs.TransferCoinRequest{
OfCoin: coinaddr,
ToAccount: &protobufs.AccountRef{
Account: &protobufs.AccountRef_ImplicitAccount{
ImplicitAccount: &protobufs.ImplicitAccount{
Address: toaddr,
},
},
},
Signature: &protobufs.Ed448Signature{
Signature: sig,
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: pub,
},
},
},
},
},
transfer.TokenRequest(),
)
if err != nil {
panic(err)

View File

@ -102,19 +102,19 @@ func (e *DataClockConsensusEngine) insertTxMessage(
filter []byte,
message proto.Message,
) error {
any := &anypb.Any{}
if err := any.MarshalFrom(message); err != nil {
a := &anypb.Any{}
if err := a.MarshalFrom(message); err != nil {
return errors.Wrap(err, "publish message")
}
any.TypeUrl = strings.Replace(
any.TypeUrl,
a.TypeUrl = strings.Replace(
a.TypeUrl,
"type.googleapis.com",
"types.quilibrium.com",
1,
)
payload, err := proto.Marshal(any)
payload, err := proto.Marshal(a)
if err != nil {
return errors.Wrap(err, "publish message")
}
@ -156,19 +156,19 @@ func (e *DataClockConsensusEngine) publishMessage(
filter []byte,
message proto.Message,
) error {
any := &anypb.Any{}
if err := any.MarshalFrom(message); err != nil {
a := &anypb.Any{}
if err := a.MarshalFrom(message); err != nil {
return errors.Wrap(err, "publish message")
}
any.TypeUrl = strings.Replace(
any.TypeUrl,
a.TypeUrl = strings.Replace(
a.TypeUrl,
"type.googleapis.com",
"types.quilibrium.com",
1,
)
payload, err := proto.Marshal(any)
payload, err := proto.Marshal(a)
if err != nil {
return errors.Wrap(err, "publish message")
}

View File

@ -3,7 +3,6 @@ package data
import (
"context"
"crypto"
"encoding/binary"
stderrors "errors"
"fmt"
@ -646,29 +645,18 @@ func (e *DataClockConsensusEngine) Stop(force bool) <-chan error {
e.stateMx.Unlock()
errChan := make(chan error)
msg := []byte("pause")
msg = binary.BigEndian.AppendUint64(msg, e.GetFrame().FrameNumber)
msg = append(msg, e.filter...)
sig, err := e.pubSub.SignMessage(msg)
if err != nil {
pause := &protobufs.AnnounceProverPause{
Filter: e.filter,
FrameNumber: e.GetFrame().FrameNumber,
}
if err := pause.SignED448(e.pubSub.GetPublicKey(), e.pubSub.SignMessage); err != nil {
panic(err)
}
if err := pause.Validate(); err != nil {
panic(err)
}
e.publishMessage(e.txFilter, &protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Pause{
Pause: &protobufs.AnnounceProverPause{
Filter: e.filter,
FrameNumber: e.GetFrame().FrameNumber,
PublicKeySignatureEd448: &protobufs.Ed448Signature{
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: e.pubSub.GetPublicKey(),
},
Signature: sig,
},
},
},
Timestamp: time.Now().UnixMilli(),
})
e.publishMessage(e.txFilter, pause.TokenRequest())
wg := sync.WaitGroup{}
wg.Add(len(e.executionEngines))

View File

@ -297,7 +297,7 @@ func (e *DataClockConsensusEngine) processFrame(
return latestFrame
}
modulo := len(outputs)
proofTree, payload, output, err := tries.PackOutputIntoPayloadAndProof(
proofTree, output, err := tries.PackOutputIntoPayloadAndProof(
outputs,
modulo,
latestFrame,
@ -313,11 +313,16 @@ func (e *DataClockConsensusEngine) processFrame(
e.previousFrameProven = latestFrame
e.previousTree = proofTree
sig, err := e.pubSub.SignMessage(
payload,
)
if err != nil {
panic(err)
mint := &protobufs.MintCoinRequest{
Proofs: output,
}
if err := mint.SignED448(e.pubSub.GetPublicKey(), e.pubSub.SignMessage); err != nil {
e.logger.Error("could not sign mint", zap.Error(err))
return latestFrame
}
if err := mint.Validate(); err != nil {
e.logger.Error("mint validation failed", zap.Error(err))
return latestFrame
}
e.logger.Info(
@ -328,20 +333,7 @@ func (e *DataClockConsensusEngine) processFrame(
zap.Duration("frame_age", frametime.Since(latestFrame)),
)
e.publishMessage(e.txFilter, &protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Mint{
Mint: &protobufs.MintCoinRequest{
Proofs: output,
Signature: &protobufs.Ed448Signature{
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: e.pubSub.GetPublicKey(),
},
Signature: sig,
},
},
},
Timestamp: time.Now().UnixMilli(),
})
e.publishMessage(e.txFilter, mint.TokenRequest())
if e.config.Engine.AutoMergeCoins {
_, addrs, _, err := e.coinStore.GetCoinsForOwner(
@ -356,33 +348,29 @@ func (e *DataClockConsensusEngine) processFrame(
}
if len(addrs) > 25 {
message := []byte("merge")
refs := []*protobufs.CoinRef{}
for _, addr := range addrs {
message = append(message, addr...)
refs = append(refs, &protobufs.CoinRef{
Address: addr,
})
}
sig, _ := e.pubSub.SignMessage(
message,
)
merge := &protobufs.MergeCoinRequest{
Coins: refs,
}
if err := merge.SignED448(
e.pubSub.GetPublicKey(),
e.pubSub.SignMessage,
); err != nil {
e.logger.Error("could not sign merge", zap.Error(err))
return latestFrame
}
if err := merge.Validate(); err != nil {
e.logger.Error("merge validation failed", zap.Error(err))
return latestFrame
}
e.publishMessage(e.txFilter, &protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Merge{
Merge: &protobufs.MergeCoinRequest{
Coins: refs,
Signature: &protobufs.Ed448Signature{
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: e.pubSub.GetPublicKey(),
},
Signature: sig,
},
},
},
Timestamp: time.Now().UnixMilli(),
})
e.publishMessage(e.txFilter, merge.TokenRequest())
}
}
}

View File

@ -34,31 +34,18 @@ func (e *DataClockConsensusEngine) runFrameMessageHandler() {
continue
}
any := &anypb.Any{}
if err := proto.Unmarshal(msg.Payload, any); err != nil {
a := &anypb.Any{}
if err := proto.Unmarshal(msg.Payload, a); err != nil {
e.logger.Error("error while unmarshaling", zap.Error(err))
continue
}
accepted := false
switch any.TypeUrl {
//expand for future message types
case protobufs.ClockFrameType:
accepted = true
default:
}
if !accepted {
e.pubSub.AddPeerScore(message.From, -100000)
continue
}
switch any.TypeUrl {
switch a.TypeUrl {
case protobufs.ClockFrameType:
if err := e.handleClockFrameData(
message.From,
msg.Address,
any,
a,
false,
); err != nil {
e.logger.Debug("could not handle clock frame data", zap.Error(err))
@ -83,21 +70,8 @@ func (e *DataClockConsensusEngine) runTxMessageHandler() {
continue
}
any := &anypb.Any{}
if err := proto.Unmarshal(msg.Payload, any); err != nil {
continue
}
accepted := false
switch any.TypeUrl {
//expand for future message types
case protobufs.TokenRequestType:
accepted = true
default:
}
if !accepted {
e.pubSub.AddPeerScore(message.From, -100000)
a := &anypb.Any{}
if err := proto.Unmarshal(msg.Payload, a); err != nil {
continue
}
@ -122,8 +96,8 @@ func (e *DataClockConsensusEngine) runTxMessageHandler() {
}
for _, appMessage := range messages {
appMsg := &anypb.Any{}
err := proto.Unmarshal(appMessage.Payload, appMsg)
a := &anypb.Any{}
err := proto.Unmarshal(appMessage.Payload, a)
if err != nil {
e.logger.Error(
"could not unmarshal app message",
@ -133,10 +107,10 @@ func (e *DataClockConsensusEngine) runTxMessageHandler() {
continue
}
switch appMsg.TypeUrl {
switch a.TypeUrl {
case protobufs.TokenRequestType:
t := &protobufs.TokenRequest{}
err := proto.Unmarshal(appMsg.Value, t)
err := proto.Unmarshal(a.Value, t)
if err != nil {
e.logger.Debug("could not unmarshal token request", zap.Error(err))
continue
@ -172,31 +146,18 @@ func (e *DataClockConsensusEngine) runInfoMessageHandler() {
continue
}
any := &anypb.Any{}
if err := proto.Unmarshal(msg.Payload, any); err != nil {
a := &anypb.Any{}
if err := proto.Unmarshal(msg.Payload, a); err != nil {
e.logger.Error("error while unmarshaling", zap.Error(err))
continue
}
accepted := false
switch any.TypeUrl {
//expand for future message types
case protobufs.DataPeerListAnnounceType:
accepted = true
default:
}
if !accepted {
e.pubSub.AddPeerScore(message.From, -100000)
continue
}
switch any.TypeUrl {
switch a.TypeUrl {
case protobufs.DataPeerListAnnounceType:
if err := e.handleDataPeerListAnnounce(
message.From,
msg.Address,
any,
a,
); err != nil {
e.logger.Debug("could not handle data peer list announce", zap.Error(err))
}

View File

@ -52,6 +52,9 @@ func (e *DataClockConsensusEngine) validateTxMessage(peerID peer.ID, message *pb
if err := proto.Unmarshal(a.Value, tx); err != nil {
return p2p.ValidationResultReject
}
if err := tx.Validate(); err != nil {
return p2p.ValidationResultReject
}
if mint := tx.GetMint(); mint != nil {
if len(mint.Proofs) < 3 {
return p2p.ValidationResultReject
@ -62,16 +65,6 @@ func (e *DataClockConsensusEngine) validateTxMessage(peerID peer.ID, message *pb
if len(mint.Proofs[2]) != 8 {
return p2p.ValidationResultReject
}
if mint.Signature == nil ||
mint.Signature.PublicKey == nil ||
mint.Signature.PublicKey.KeyValue == nil ||
len(mint.Signature.PublicKey.KeyValue) > 114 {
return p2p.ValidationResultReject
}
head, err := e.dataTimeReel.Head()
if err != nil {
panic(err)
}
// cheap hack for handling protobuf trickery: because protobufs can be
// serialized in infinite ways, message ids can be regenerated simply by
@ -89,9 +82,14 @@ func (e *DataClockConsensusEngine) validateTxMessage(peerID peer.ID, message *pb
e.validationFilter[id] = struct{}{}
e.validationFilterMx.Unlock()
if ok {
e.pubSub.AddPeerScore([]byte(message.From), -1000000)
e.pubSub.AddPeerScore(message.From, -1000000)
return p2p.ValidationResultIgnore
}
head, err := e.dataTimeReel.Head()
if err != nil {
panic(err)
}
if frameNumber+2 < head.FrameNumber {
return p2p.ValidationResultIgnore
}
@ -99,7 +97,6 @@ func (e *DataClockConsensusEngine) validateTxMessage(peerID peer.ID, message *pb
if tx.Timestamp == 0 {
// NOTE: The timestamp was added in later versions of the protocol,
// and as such it is possible to receive requests without it.
// We avoid logging due to this reason.
return p2p.ValidationResultAccept
}
if ts := time.UnixMilli(tx.Timestamp); time.Since(ts) > 10*time.Minute {

View File

@ -186,6 +186,10 @@ func (e *DataClockConsensusEngine) handleMint(
return nil, errors.Wrap(errors.New("wrong destination"), "handle mint")
}
if err := t.Validate(); err != nil {
return nil, errors.Wrap(application.ErrInvalidStateTransition, "handle mint")
}
returnAddr := []byte{}
e.preMidnightMintMx.Lock()
if _, active := e.preMidnightMint[string(
@ -211,17 +215,6 @@ func (e *DataClockConsensusEngine) handleMint(
return nil, errors.Wrap(errors.New("busy"), "handle mint")
}
if t == nil || t.Proofs == nil {
return nil, errors.Wrap(application.ErrInvalidStateTransition, "handle mint")
}
payload := []byte("mint")
for _, p := range t.Proofs {
payload = append(payload, p...)
}
if err := t.Signature.Verify(payload); err != nil {
return nil, errors.Wrap(application.ErrInvalidStateTransition, "handle mint")
}
pk, err := pcrypto.UnmarshalEd448PublicKey(
t.Signature.PublicKey.KeyValue,
)

View File

@ -161,15 +161,12 @@ func (a *TokenApplication) ApplyTransitions(
i := i
switch t := transition.Request.(type) {
case *protobufs.TokenRequest_Mint:
if t == nil || t.Mint.Proofs == nil || t.Mint.Signature == nil {
if t == nil {
fails[i] = transition
continue
}
payload := []byte("mint")
for _, p := range t.Mint.Proofs {
payload = append(payload, p...)
}
if err := t.Mint.Signature.Verify(payload); err != nil {
if err := t.Mint.Validate(); err != nil {
fails[i] = transition
continue
}
@ -177,6 +174,7 @@ func (a *TokenApplication) ApplyTransitions(
t.Mint.Signature.PublicKey.KeyValue,
)
if err != nil {
fails[i] = transition
continue
}

View File

@ -16,19 +16,16 @@ func (a *TokenApplication) handleMerge(
lockMap map[string]struct{},
t *protobufs.MergeCoinRequest,
) ([]*protobufs.TokenOutput, error) {
if err := t.Validate(); err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle merge")
}
newCoin := &protobufs.Coin{}
newTotal := new(big.Int)
newIntersection := make([]byte, 1024)
payload := []byte("merge")
if t == nil || t.Coins == nil || t.Signature == nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle merge")
}
addresses := [][]byte{}
for _, c := range t.Coins {
if c.Address == nil || len(c.Address) != 32 {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle merge")
}
if _, touched := lockMap[string(c.Address)]; touched {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle merge")
}
@ -40,14 +37,6 @@ func (a *TokenApplication) handleMerge(
}
addresses = append(addresses, c.Address)
payload = append(payload, c.Address...)
}
if t.Signature.PublicKey == nil ||
t.Signature.Signature == nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle merge")
}
if err := t.Signature.Verify(payload); err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle merge")
}
addr, err := poseidon.HashBytes(t.Signature.PublicKey.KeyValue)

View File

@ -31,7 +31,7 @@ func (a *TokenApplication) handleMint(
frame *protobufs.ClockFrame,
parallelismMap map[int]uint64,
) ([]*protobufs.TokenOutput, error) {
if t == nil || t.Proofs == nil || t.Signature == nil {
if err := t.Validate(); err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle mint")
}
@ -39,9 +39,7 @@ func (a *TokenApplication) handleMint(
for _, p := range t.Proofs {
payload = append(payload, p...)
}
if err := t.Signature.Verify(payload); err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle mint")
}
pk, err := pcrypto.UnmarshalEd448PublicKey(
t.Signature.PublicKey.KeyValue,
)

View File

@ -13,36 +13,14 @@ func (a *TokenApplication) handleAnnounce(
[]*protobufs.TokenOutput,
error,
) {
var primary *protobufs.Ed448Signature
payload := []byte{}
if t == nil || t.PublicKeySignaturesEd448 == nil ||
len(t.PublicKeySignaturesEd448) == 0 {
if err := t.Validate(); err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle announce")
}
for i, p := range t.PublicKeySignaturesEd448 {
for _, p := range t.PublicKeySignaturesEd448 {
if _, touched := lockMap[string(p.PublicKey.KeyValue)]; touched {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle announce")
}
if p.PublicKey == nil || p.Signature == nil ||
p.PublicKey.KeyValue == nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle announce")
}
if i == 0 {
primary = p
} else {
payload = append(payload, p.PublicKey.KeyValue...)
if err := p.Verify(primary.PublicKey.KeyValue); err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle announce")
}
}
}
if primary == nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle announce")
}
if err := primary.Verify(payload); err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle announce")
}
for _, p := range t.PublicKeySignaturesEd448[1:] {

View File

@ -1,8 +1,6 @@
package application
import (
"encoding/binary"
"github.com/iden3/go-iden3-crypto/poseidon"
pcrypto "github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/peer"
@ -50,25 +48,7 @@ func (a *TokenApplication) handleDataAnnounceProverJoin(
return nil, errors.Wrap(ErrInvalidStateTransition, "handle join")
}
payload := []byte("join")
if t == nil || t.PublicKeySignatureEd448 == nil {
a.Logger.Debug("invalid data for join")
return nil, errors.Wrap(ErrInvalidStateTransition, "handle join")
}
if t.PublicKeySignatureEd448.PublicKey == nil ||
t.PublicKeySignatureEd448.Signature == nil ||
t.PublicKeySignatureEd448.PublicKey.KeyValue == nil ||
t.Filter == nil || len(t.Filter) != 32 {
a.Logger.Debug(
"bad payload",
zap.Uint64("given_frame_number", t.FrameNumber),
zap.Uint64("current_frame_number", currentFrameNumber),
zap.Int("filter_length", len(t.Filter)),
)
if err := t.Validate(); err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle join")
}
@ -79,13 +59,6 @@ func (a *TokenApplication) handleDataAnnounceProverJoin(
return nil, errors.Wrap(ErrInvalidStateTransition, "handle join")
}
payload = binary.BigEndian.AppendUint64(payload, t.FrameNumber)
payload = append(payload, t.Filter...)
if err := t.PublicKeySignatureEd448.Verify(payload); err != nil {
a.Logger.Debug("can't verify signature")
return nil, errors.Wrap(ErrInvalidStateTransition, "handle join")
}
address, err := a.getAddressFromSignature(t.PublicKeySignatureEd448)
if err != nil {

View File

@ -70,10 +70,6 @@ func TestHandleProverJoin(t *testing.T) {
}
addr := addrBI.FillBytes(make([]byte, 32))
payload := []byte("join")
payload = binary.BigEndian.AppendUint64(payload, 0)
payload = append(payload, bytes.Repeat([]byte{0xff}, 32)...)
sig, _ := privKey.Sign(payload)
wprover := qcrypto.NewWesolowskiFrameProver(app.Logger)
gen, _, err := wprover.CreateDataGenesisFrame(
p2p.GetBloomFilter(application.TOKEN_ADDRESS, 256, 3),
@ -87,24 +83,17 @@ func TestHandleProverJoin(t *testing.T) {
app.ClockStore.StageDataClockFrame(selbi.FillBytes(make([]byte, 32)), gen, txn)
app.ClockStore.CommitDataClockFrame(gen.Filter, 0, selbi.FillBytes(make([]byte, 32)), app.Tries, txn, false)
txn.Commit()
join := &protobufs.AnnounceProverJoin{
Filter: bytes.Repeat([]byte{0xff}, 32),
FrameNumber: 0,
}
assert.NoError(t, join.SignED448(pubkey, privKey.Sign))
assert.NoError(t, join.Validate())
app, success, fail, err := app.ApplyTransitions(
1,
&protobufs.TokenRequests{
Requests: []*protobufs.TokenRequest{
&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Join{
Join: &protobufs.AnnounceProverJoin{
Filter: bytes.Repeat([]byte{0xff}, 32),
FrameNumber: 0,
PublicKeySignatureEd448: &protobufs.Ed448Signature{
Signature: sig,
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: pubkey,
},
},
},
},
},
join.TokenRequest(),
},
},
false,
@ -121,24 +110,17 @@ func TestHandleProverJoin(t *testing.T) {
app.ClockStore.StageDataClockFrame(selbi.FillBytes(make([]byte, 32)), frame1, txn)
app.ClockStore.CommitDataClockFrame(frame1.Filter, 1, selbi.FillBytes(make([]byte, 32)), app.Tries, txn, false)
txn.Commit()
join = &protobufs.AnnounceProverJoin{
Filter: bytes.Repeat([]byte{0xff}, 32),
FrameNumber: 0,
}
assert.NoError(t, join.SignED448(pubkey, privKey.Sign))
assert.NoError(t, join.Validate())
_, success, fail, err = app.ApplyTransitions(
2,
&protobufs.TokenRequests{
Requests: []*protobufs.TokenRequest{
&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Join{
Join: &protobufs.AnnounceProverJoin{
Filter: bytes.Repeat([]byte{0xff}, 32),
FrameNumber: 0,
PublicKeySignatureEd448: &protobufs.Ed448Signature{
Signature: sig,
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: pubkey,
},
},
},
},
},
join.TokenRequest(),
},
},
false,
@ -175,7 +157,7 @@ func TestHandleProverJoin(t *testing.T) {
fmt.Printf("%x\n", individualChallenge)
out2, _ := wprover.CalculateChallengeProof(individualChallenge, 10000)
proofTree, payload, output, err := tries.PackOutputIntoPayloadAndProof(
proofTree, output, err := tries.PackOutputIntoPayloadAndProof(
[]merkletree.DataBlock{tries.NewProofLeaf(out1), tries.NewProofLeaf(out2)},
2,
frame2,
@ -183,22 +165,15 @@ func TestHandleProverJoin(t *testing.T) {
)
assert.NoError(t, err)
sig, _ = privKey.Sign(payload)
mint := &protobufs.MintCoinRequest{
Proofs: output,
}
assert.NoError(t, mint.SignED448(pubkey, privKey.Sign))
assert.NoError(t, mint.Validate())
app, success, _, err = app.ApplyTransitions(2, &protobufs.TokenRequests{
Requests: []*protobufs.TokenRequest{
&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Mint{
Mint: &protobufs.MintCoinRequest{
Proofs: output,
Signature: &protobufs.Ed448Signature{
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: pubkey,
},
Signature: sig,
},
},
},
},
mint.TokenRequest(),
},
}, false)
@ -240,7 +215,7 @@ func TestHandleProverJoin(t *testing.T) {
app.ClockStore.CommitDataClockFrame(frame3.Filter, 3, selbi.FillBytes(make([]byte, 32)), app.Tries, txn, false)
txn.Commit()
proofTree, payload, output, err = tries.PackOutputIntoPayloadAndProof(
proofTree, output, err = tries.PackOutputIntoPayloadAndProof(
[]merkletree.DataBlock{tries.NewProofLeaf(out1), tries.NewProofLeaf(out2)},
2,
frame3,
@ -248,22 +223,15 @@ func TestHandleProverJoin(t *testing.T) {
)
assert.NoError(t, err)
sig, _ = privKey.Sign(payload)
mint = &protobufs.MintCoinRequest{
Proofs: output,
}
assert.NoError(t, mint.SignED448(pubkey, privKey.Sign))
assert.NoError(t, mint.Validate())
app, success, _, err = app.ApplyTransitions(3, &protobufs.TokenRequests{
Requests: []*protobufs.TokenRequest{
&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Mint{
Mint: &protobufs.MintCoinRequest{
Proofs: output,
Signature: &protobufs.Ed448Signature{
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: pubkey,
},
Signature: sig,
},
},
},
},
mint.TokenRequest(),
},
}, false)
assert.NoError(t, err)

View File

@ -1,8 +1,6 @@
package application
import (
"encoding/binary"
"github.com/pkg/errors"
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
)
@ -19,17 +17,11 @@ func (a *TokenApplication) handleDataAnnounceProverLeave(
return nil, errors.Wrap(ErrInvalidStateTransition, "handle leave")
}
payload := []byte("leave")
if t == nil || t.PublicKeySignatureEd448 == nil {
if err := t.Validate(); err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle leave")
}
if t.PublicKeySignatureEd448.PublicKey == nil ||
t.PublicKeySignatureEd448.Signature == nil ||
t.PublicKeySignatureEd448.PublicKey.KeyValue == nil ||
t.Filter == nil || len(t.Filter) != 32 ||
t.FrameNumber > currentFrameNumber {
if t.FrameNumber > currentFrameNumber {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle leave")
}
@ -39,13 +31,6 @@ func (a *TokenApplication) handleDataAnnounceProverLeave(
return nil, errors.Wrap(ErrInvalidStateTransition, "handle leave")
}
payload = binary.BigEndian.AppendUint64(payload, t.FrameNumber)
payload = append(payload, t.Filter...)
if err := t.PublicKeySignatureEd448.Verify(payload); err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle leave")
}
address, err := a.getAddressFromSignature(t.PublicKeySignatureEd448)
if err != nil {
return nil, errors.Wrap(err, "handle leave")

View File

@ -1,8 +1,6 @@
package application
import (
"encoding/binary"
"github.com/pkg/errors"
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
)
@ -19,17 +17,11 @@ func (a *TokenApplication) handleDataAnnounceProverPause(
return nil, errors.Wrap(ErrInvalidStateTransition, "handle pause")
}
payload := []byte("pause")
if t == nil || t.PublicKeySignatureEd448 == nil {
if err := t.Validate(); err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle pause")
}
if t.PublicKeySignatureEd448.PublicKey == nil ||
t.PublicKeySignatureEd448.Signature == nil ||
t.PublicKeySignatureEd448.PublicKey.KeyValue == nil ||
t.Filter == nil || len(t.Filter) != 32 ||
t.FrameNumber > currentFrameNumber {
if t.FrameNumber > currentFrameNumber {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle pause")
}
if _, touched := lockMap[string(
@ -38,13 +30,6 @@ func (a *TokenApplication) handleDataAnnounceProverPause(
return nil, errors.Wrap(ErrInvalidStateTransition, "handle pause")
}
payload = binary.BigEndian.AppendUint64(payload, t.FrameNumber)
payload = append(payload, t.Filter...)
if err := t.PublicKeySignatureEd448.Verify(payload); err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle pause")
}
address, err := a.getAddressFromSignature(t.PublicKeySignatureEd448)
if err != nil {
return nil, errors.Wrap(err, "handle pause")

View File

@ -1,8 +1,6 @@
package application
import (
"encoding/binary"
"github.com/pkg/errors"
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
)
@ -19,17 +17,11 @@ func (a *TokenApplication) handleDataAnnounceProverResume(
return nil, errors.Wrap(ErrInvalidStateTransition, "handle resume")
}
payload := []byte("resume")
if t == nil || t.PublicKeySignatureEd448 == nil {
if err := t.Validate(); err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle resume")
}
if t.PublicKeySignatureEd448.PublicKey == nil ||
t.PublicKeySignatureEd448.Signature == nil ||
t.PublicKeySignatureEd448.PublicKey.KeyValue == nil ||
t.Filter == nil || len(t.Filter) != 32 ||
t.FrameNumber > currentFrameNumber {
if t.FrameNumber > currentFrameNumber {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle resume")
}
@ -39,13 +31,6 @@ func (a *TokenApplication) handleDataAnnounceProverResume(
return nil, errors.Wrap(ErrInvalidStateTransition, "handle resume")
}
payload = binary.BigEndian.AppendUint64(payload, t.FrameNumber)
payload = append(payload, t.Filter...)
if err := t.PublicKeySignatureEd448.Verify(payload); err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle resume")
}
address, err := a.getAddressFromSignature(t.PublicKeySignatureEd448)
if err != nil {
return nil, errors.Wrap(err, "handle resume")

View File

@ -16,13 +16,13 @@ func (a *TokenApplication) handleSplit(
lockMap map[string]struct{},
t *protobufs.SplitCoinRequest,
) ([]*protobufs.TokenOutput, error) {
newCoins := []*protobufs.Coin{}
newAmounts := []*big.Int{}
payload := []byte{}
if t.Signature == nil || t.OfCoin == nil || t.OfCoin.Address == nil ||
len(t.OfCoin.Address) != 32 {
if err := t.Validate(); err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle split")
}
newCoins := []*protobufs.Coin{}
newAmounts := []*big.Int{}
coin, err := a.CoinStore.GetCoinByAddress(nil, t.OfCoin.Address)
if err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle split")
@ -32,24 +32,6 @@ func (a *TokenApplication) handleSplit(
return nil, errors.Wrap(ErrInvalidStateTransition, "handle split")
}
payload = append(payload, []byte("split")...)
payload = append(payload, t.OfCoin.Address...)
if len(t.Amounts) > 100 {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle split")
}
for _, a := range t.Amounts {
if len(a) > 32 {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle split")
}
payload = append(payload, a...)
}
if err := t.Signature.Verify(payload); err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle split")
}
addr, err := poseidon.HashBytes(t.Signature.PublicKey.KeyValue)
if err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle split")

View File

@ -16,12 +16,7 @@ func (a *TokenApplication) handleTransfer(
lockMap map[string]struct{},
t *protobufs.TransferCoinRequest,
) ([]*protobufs.TokenOutput, error) {
payload := []byte("transfer")
if t == nil || t.Signature == nil || t.OfCoin == nil ||
t.OfCoin.Address == nil || len(t.OfCoin.Address) != 32 ||
t.ToAccount == nil || t.ToAccount.GetImplicitAccount() == nil ||
t.ToAccount.GetImplicitAccount().Address == nil ||
len(t.ToAccount.GetImplicitAccount().Address) != 32 {
if err := t.Validate(); err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle transfer")
}
@ -34,16 +29,6 @@ func (a *TokenApplication) handleTransfer(
return nil, errors.Wrap(ErrInvalidStateTransition, "handle transfer")
}
payload = append(payload, t.OfCoin.Address...)
payload = append(
payload,
t.ToAccount.GetImplicitAccount().Address...,
)
if err := t.Signature.Verify(payload); err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle transfer")
}
addr, err := poseidon.HashBytes(t.Signature.PublicKey.KeyValue)
if err != nil {
return nil, errors.Wrap(ErrInvalidStateTransition, "handle transfer")

View File

@ -4,7 +4,6 @@ import (
"bytes"
"context"
"crypto"
"encoding/binary"
"encoding/hex"
"math/big"
"slices"
@ -364,11 +363,14 @@ func NewTokenExecutionEngine(
}
if shouldResume {
msg := []byte("resume")
msg = binary.BigEndian.AppendUint64(msg, f.FrameNumber)
msg = append(msg, e.intrinsicFilter...)
sig, err := e.pubSub.SignMessage(msg)
if err != nil {
resume := &protobufs.AnnounceProverResume{
Filter: e.intrinsicFilter,
FrameNumber: f.FrameNumber,
}
if err := resume.SignED448(e.pubSub.GetPublicKey(), e.pubSub.SignMessage); err != nil {
panic(err)
}
if err := resume.Validate(); err != nil {
panic(err)
}
@ -391,21 +393,7 @@ func NewTokenExecutionEngine(
}
e.publishMessage(
append([]byte{0x00}, e.intrinsicFilter...),
&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Resume{
Resume: &protobufs.AnnounceProverResume{
Filter: e.intrinsicFilter,
FrameNumber: f.FrameNumber,
PublicKeySignatureEd448: &protobufs.Ed448Signature{
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: e.pubSub.GetPublicKey(),
},
Signature: sig,
},
},
},
Timestamp: gotime.Now().UnixMilli(),
},
resume.TokenRequest(),
)
}
}()
@ -473,20 +461,20 @@ func (e *TokenExecutionEngine) ProcessMessage(
message *protobufs.Message,
) ([]*protobufs.Message, error) {
if bytes.Equal(address, e.GetSupportedApplications()[0].Address) {
any := &anypb.Any{}
if err := proto.Unmarshal(message.Payload, any); err != nil {
a := &anypb.Any{}
if err := proto.Unmarshal(message.Payload, a); err != nil {
return nil, errors.Wrap(err, "process message")
}
e.logger.Debug(
"processing execution message",
zap.String("type", any.TypeUrl),
zap.String("type", a.TypeUrl),
)
switch any.TypeUrl {
switch a.TypeUrl {
case protobufs.TokenRequestType:
if e.clock.IsInProverTrie(e.proverPublicKey) {
payload, err := proto.Marshal(any)
payload, err := proto.Marshal(a)
if err != nil {
return nil, errors.Wrap(err, "process message")
}
@ -1114,19 +1102,19 @@ func (e *TokenExecutionEngine) publishMessage(
filter []byte,
message proto.Message,
) error {
any := &anypb.Any{}
if err := any.MarshalFrom(message); err != nil {
a := &anypb.Any{}
if err := a.MarshalFrom(message); err != nil {
return errors.Wrap(err, "publish message")
}
any.TypeUrl = strings.Replace(
any.TypeUrl,
a.TypeUrl = strings.Replace(
a.TypeUrl,
"type.googleapis.com",
"types.quilibrium.com",
1,
)
payload, err := proto.Marshal(any)
payload, err := proto.Marshal(a)
if err != nil {
return errors.Wrap(err, "publish message")
}
@ -1378,8 +1366,14 @@ func (e *TokenExecutionEngine) AnnounceProverMerge() *protobufs.AnnounceProverRe
currentHead.FrameNumber < application.PROOF_FRAME_CUTOFF {
return nil
}
keys := [][]byte{}
ksigs := [][]byte{}
var helpers []protobufs.ED448SignHelper = []protobufs.ED448SignHelper{
{
PublicKey: e.pubSub.GetPublicKey(),
Sign: e.pubSub.SignMessage,
},
}
if len(e.engineConfig.MultisigProverEnrollmentPaths) != 0 &&
e.GetSeniority().Cmp(GetAggregatedSeniority(
[]string{peer.ID(e.pubSub.GetPeerID()).String()},
@ -1406,86 +1400,46 @@ func (e *TokenExecutionEngine) AnnounceProverMerge() *protobufs.AnnounceProverRe
panic(errors.Wrap(err, "error unmarshaling peerkey"))
}
keys = append(keys, pubBytes)
sig, err := privKey.Sign(e.pubSub.GetPublicKey())
if err != nil {
panic(errors.Wrap(err, "error unmarshaling peerkey"))
}
ksigs = append(ksigs, sig)
helpers = append(helpers, protobufs.ED448SignHelper{
PublicKey: pubBytes,
Sign: privKey.Sign,
})
}
}
keyjoin := []byte{}
for _, k := range keys {
keyjoin = append(keyjoin, k...)
}
mainsig, err := e.pubSub.SignMessage(keyjoin)
if err != nil {
announce := &protobufs.AnnounceProverRequest{}
if err := announce.SignED448(helpers); err != nil {
panic(err)
}
announce := &protobufs.AnnounceProverRequest{
PublicKeySignaturesEd448: []*protobufs.Ed448Signature{},
}
announce.PublicKeySignaturesEd448 = append(
announce.PublicKeySignaturesEd448,
&protobufs.Ed448Signature{
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: e.pubSub.GetPublicKey(),
},
Signature: mainsig,
},
)
for i := range keys {
announce.PublicKeySignaturesEd448 = append(
announce.PublicKeySignaturesEd448,
&protobufs.Ed448Signature{
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: keys[i],
},
Signature: ksigs[i],
},
)
if err := announce.Validate(); err != nil {
panic(err)
}
return announce
}
func (e *TokenExecutionEngine) AnnounceProverJoin() {
msg := []byte("join")
head := e.GetFrame()
if head == nil ||
head.FrameNumber < application.PROOF_FRAME_CUTOFF {
return
}
msg = binary.BigEndian.AppendUint64(msg, head.FrameNumber)
msg = append(msg, bytes.Repeat([]byte{0xff}, 32)...)
sig, err := e.pubSub.SignMessage(msg)
if err != nil {
join := &protobufs.AnnounceProverJoin{
Filter: bytes.Repeat([]byte{0xff}, 32),
FrameNumber: head.FrameNumber,
Announce: e.AnnounceProverMerge(),
}
if err := join.SignED448(e.pubSub.GetPublicKey(), e.pubSub.SignMessage); err != nil {
panic(err)
}
if err := join.Validate(); err != nil {
panic(err)
}
e.publishMessage(
append([]byte{0x00}, e.intrinsicFilter...),
&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Join{
Join: &protobufs.AnnounceProverJoin{
Filter: bytes.Repeat([]byte{0xff}, 32),
FrameNumber: head.FrameNumber,
PublicKeySignatureEd448: &protobufs.Ed448Signature{
Signature: sig,
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: e.pubSub.GetPublicKey(),
},
},
Announce: e.AnnounceProverMerge(),
},
},
Timestamp: gotime.Now().UnixMilli(),
},
join.TokenRequest(),
)
}

View File

@ -182,6 +182,11 @@ func (s *Ed448Signature) Verify(msg []byte) error {
return errors.Wrap(errors.New("invalid length for signature"), "verify")
}
return s.verifyUnsafe(msg)
}
// verifyUnsafe is used to verify a signature without checking the length of the public key and signature.
func (s *Ed448Signature) verifyUnsafe(msg []byte) error {
if !ed448.Verify(s.PublicKey.KeyValue, msg, s.Signature, "") {
return errors.Wrap(errors.New("invalid signature for public key"), "verify")
}

View File

@ -2,6 +2,7 @@ package protobufs
import (
"encoding/binary"
"time"
"github.com/iden3/go-iden3-crypto/poseidon"
pcrypto "github.com/libp2p/go-libp2p/core/crypto"
@ -22,14 +23,6 @@ func (t *TokenRequest) Priority() uint64 {
func (t *MintCoinRequest) RingAndParallelism(
ringCalc func(addr []byte) int,
) (int, uint32, error) {
payload := []byte("mint")
for _, p := range t.Proofs {
payload = append(payload, p...)
}
if err := t.Signature.Verify(payload); err != nil {
return -1, 0, errors.New("invalid")
}
pk, err := pcrypto.UnmarshalEd448PublicKey(
t.Signature.PublicKey.KeyValue,
)
@ -58,3 +51,93 @@ func (t *MintCoinRequest) RingAndParallelism(
return -1, 0, errors.New("invalid")
}
// TokenRequest returns the TokenRequest for the TransferCoinRequest.
func (t *TransferCoinRequest) TokenRequest() *TokenRequest {
return &TokenRequest{
Request: &TokenRequest_Transfer{
Transfer: t,
},
Timestamp: time.Now().UnixMilli(),
}
}
// TokenRequest returns the TokenRequest for the SplitCoinRequest.
func (t *SplitCoinRequest) TokenRequest() *TokenRequest {
return &TokenRequest{
Request: &TokenRequest_Split{
Split: t,
},
Timestamp: time.Now().UnixMilli(),
}
}
// TokenRequest returns the TokenRequest for the MergeCoinRequest.
func (t *MergeCoinRequest) TokenRequest() *TokenRequest {
return &TokenRequest{
Request: &TokenRequest_Merge{
Merge: t,
},
Timestamp: time.Now().UnixMilli(),
}
}
// TokenRequest returns the TokenRequest for the MintCoinRequest.
func (t *MintCoinRequest) TokenRequest() *TokenRequest {
return &TokenRequest{
Request: &TokenRequest_Mint{
Mint: t,
},
Timestamp: time.Now().UnixMilli(),
}
}
// TokenRequest returns the TokenRequest for the AnnounceProverRequest.
func (t *AnnounceProverRequest) TokenRequest() *TokenRequest {
return &TokenRequest{
Request: &TokenRequest_Announce{
Announce: t,
},
Timestamp: time.Now().UnixMilli(),
}
}
// TokenRequest returns the TokenRequest for the AnnounceProverJoin.
func (t *AnnounceProverJoin) TokenRequest() *TokenRequest {
return &TokenRequest{
Request: &TokenRequest_Join{
Join: t,
},
Timestamp: time.Now().UnixMilli(),
}
}
// TokenRequest returns the TokenRequest for the AnnounceProverLeave.
func (t *AnnounceProverLeave) TokenRequest() *TokenRequest {
return &TokenRequest{
Request: &TokenRequest_Leave{
Leave: t,
},
Timestamp: time.Now().UnixMilli(),
}
}
// TokenRequest returns the TokenRequest for the AnnounceProverPause.
func (t *AnnounceProverPause) TokenRequest() *TokenRequest {
return &TokenRequest{
Request: &TokenRequest_Pause{
Pause: t,
},
Timestamp: time.Now().UnixMilli(),
}
}
// TokenRequest returns the TokenRequest for the AnnounceProverResume.
func (t *AnnounceProverResume) TokenRequest() *TokenRequest {
return &TokenRequest{
Request: &TokenRequest_Resume{
Resume: t,
},
Timestamp: time.Now().UnixMilli(),
}
}

View File

@ -0,0 +1,700 @@
package protobufs
import (
"encoding/binary"
"github.com/pkg/errors"
)
type signatureMessage interface {
signatureMessage() []byte
}
var _ signatureMessage = (*TransferCoinRequest)(nil)
func (t *TransferCoinRequest) signatureMessage() []byte {
payload := []byte("transfer")
payload = append(payload, t.OfCoin.Address...)
payload = append(
payload,
t.ToAccount.GetImplicitAccount().Address...,
)
return payload
}
var _ signatureMessage = (*SplitCoinRequest)(nil)
func (t *SplitCoinRequest) signatureMessage() []byte {
payload := []byte("split")
payload = append(payload, t.OfCoin.Address...)
for _, a := range t.Amounts {
payload = append(payload, a...)
}
return payload
}
var _ signatureMessage = (*MergeCoinRequest)(nil)
func (t *MergeCoinRequest) signatureMessage() []byte {
payload := []byte("merge")
for _, c := range t.Coins {
payload = append(payload, c.Address...)
}
return payload
}
var _ signatureMessage = (*MintCoinRequest)(nil)
func (t *MintCoinRequest) signatureMessage() []byte {
payload := []byte("mint")
for _, p := range t.Proofs {
payload = append(payload, p...)
}
return payload
}
// NOTE: AnnounceProverRequest has a non-trivial signature payload.
var _ signatureMessage = (*AnnounceProverJoin)(nil)
func (t *AnnounceProverJoin) signatureMessage() []byte {
payload := []byte("join")
payload = binary.BigEndian.AppendUint64(payload, t.FrameNumber)
payload = append(payload, t.Filter...)
return payload
}
var _ signatureMessage = (*AnnounceProverLeave)(nil)
func (t *AnnounceProverLeave) signatureMessage() []byte {
payload := []byte("leave")
payload = binary.BigEndian.AppendUint64(payload, t.FrameNumber)
payload = append(payload, t.Filter...)
return payload
}
var _ signatureMessage = (*AnnounceProverPause)(nil)
func (t *AnnounceProverPause) signatureMessage() []byte {
payload := []byte("pause")
payload = binary.BigEndian.AppendUint64(payload, t.FrameNumber)
payload = append(payload, t.Filter...)
return payload
}
var _ signatureMessage = (*AnnounceProverResume)(nil)
func (t *AnnounceProverResume) signatureMessage() []byte {
payload := []byte("resume")
payload = binary.BigEndian.AppendUint64(payload, t.FrameNumber)
payload = append(payload, t.Filter...)
return payload
}
// SignedMessage is a message that has a signature.
type SignedMessage interface {
// ValidateSignature checks the signature of the message.
// The message contents are expected to be valid - validation
// of contents must precede validation of the signature.
ValidateSignature() error
}
var _ SignedMessage = (*TransferCoinRequest)(nil)
// ValidateSignature checks the signature of the transfer coin request.
func (t *TransferCoinRequest) ValidateSignature() error {
if err := t.Signature.verifyUnsafe(t.signatureMessage()); err != nil {
return errors.Wrap(err, "validate signature")
}
return nil
}
var _ SignedMessage = (*SplitCoinRequest)(nil)
// ValidateSignature checks the signature of the split coin request.
func (t *SplitCoinRequest) ValidateSignature() error {
if err := t.Signature.verifyUnsafe(t.signatureMessage()); err != nil {
return errors.Wrap(err, "validate signature")
}
return nil
}
var _ SignedMessage = (*MergeCoinRequest)(nil)
// ValidateSignature checks the signature of the merge coin request.
func (t *MergeCoinRequest) ValidateSignature() error {
if err := t.Signature.verifyUnsafe(t.signatureMessage()); err != nil {
return errors.Wrap(err, "validate signature")
}
return nil
}
var _ SignedMessage = (*MintCoinRequest)(nil)
// ValidateSignature checks the signature of the mint coin request.
func (t *MintCoinRequest) ValidateSignature() error {
if err := t.Signature.verifyUnsafe(t.signatureMessage()); err != nil {
return errors.Wrap(err, "validate signature")
}
return nil
}
var _ SignedMessage = (*AnnounceProverRequest)(nil)
// ValidateSignature checks the signature of the announce prover request.
func (t *AnnounceProverRequest) ValidateSignature() error {
payload := []byte{}
primary := t.PublicKeySignaturesEd448[0]
for _, p := range t.PublicKeySignaturesEd448[1:] {
payload = append(payload, p.PublicKey.KeyValue...)
if err := p.verifyUnsafe(primary.PublicKey.KeyValue); err != nil {
return errors.Wrap(err, "validate signature")
}
}
if err := primary.verifyUnsafe(payload); err != nil {
return errors.Wrap(err, "validate signature")
}
return nil
}
var _ SignedMessage = (*AnnounceProverJoin)(nil)
// ValidateSignature checks the signature of the announce prover join.
func (t *AnnounceProverJoin) ValidateSignature() error {
if err := t.PublicKeySignatureEd448.verifyUnsafe(t.signatureMessage()); err != nil {
return errors.Wrap(err, "validate signature")
}
return nil
}
var _ SignedMessage = (*AnnounceProverLeave)(nil)
// ValidateSignature checks the signature of the announce prover leave.
func (t *AnnounceProverLeave) ValidateSignature() error {
if err := t.PublicKeySignatureEd448.verifyUnsafe(t.signatureMessage()); err != nil {
return errors.Wrap(err, "validate signature")
}
return nil
}
var _ SignedMessage = (*AnnounceProverPause)(nil)
// ValidateSignature checks the signature of the announce prover pause.
func (t *AnnounceProverPause) ValidateSignature() error {
if err := t.PublicKeySignatureEd448.verifyUnsafe(t.signatureMessage()); err != nil {
return errors.Wrap(err, "validate signature")
}
return nil
}
var _ SignedMessage = (*AnnounceProverResume)(nil)
// ValidateSignature checks the signature of the announce prover resume.
func (t *AnnounceProverResume) ValidateSignature() error {
if err := t.PublicKeySignatureEd448.verifyUnsafe(t.signatureMessage()); err != nil {
return errors.Wrap(err, "validate signature")
}
return nil
}
// ValidatableMessage is a message that can be validated.
type ValidatableMessage interface {
// Validate checks the message contents.
// It will also verify signatures if the message is signed.
Validate() error
}
var _ ValidatableMessage = (*Ed448PublicKey)(nil)
// Validate checks the Ed448 public key.
func (e *Ed448PublicKey) Validate() error {
if e == nil {
return errors.New("nil Ed448 public key")
}
if len(e.KeyValue) != 57 {
return errors.New("invalid Ed448 public key")
}
return nil
}
var _ ValidatableMessage = (*Ed448Signature)(nil)
// Validate checks the Ed448 signature.
func (e *Ed448Signature) Validate() error {
if e == nil {
return errors.New("nil Ed448 signature")
}
if err := e.PublicKey.Validate(); err != nil {
return errors.Wrap(err, "public key")
}
if len(e.Signature) != 114 {
return errors.New("invalid Ed448 signature")
}
return nil
}
var _ ValidatableMessage = (*ImplicitAccount)(nil)
// Validate checks the implicit account.
func (i *ImplicitAccount) Validate() error {
if i == nil {
return errors.New("nil implicit account")
}
// TODO: Validate ImplicitType.
if len(i.Address) != 32 {
return errors.New("invalid implicit account")
}
// TODO: Validate Domain.
return nil
}
var _ ValidatableMessage = (*OriginatedAccountRef)(nil)
// Validate checks the originated account.
func (o *OriginatedAccountRef) Validate() error {
if o == nil {
return errors.New("nil originated account")
}
if len(o.Address) != 32 {
return errors.New("invalid originated account")
}
return nil
}
var _ ValidatableMessage = (*AccountRef)(nil)
// Validate checks the account reference.
func (a *AccountRef) Validate() error {
if a == nil {
return errors.New("nil account reference")
}
switch {
case a.GetImplicitAccount() != nil:
if err := a.GetImplicitAccount().Validate(); err != nil {
return errors.Wrap(err, "implicit account")
}
case a.GetOriginatedAccount() != nil:
if err := a.GetOriginatedAccount().Validate(); err != nil {
return errors.Wrap(err, "originated account")
}
default:
return errors.New("invalid account reference")
}
return nil
}
var _ ValidatableMessage = (*CoinRef)(nil)
// Validate checks the coin reference.
func (c *CoinRef) Validate() error {
if c == nil {
return errors.New("nil coin reference")
}
if len(c.Address) != 32 {
return errors.New("invalid coin reference")
}
return nil
}
var _ ValidatableMessage = (*AccountAllowanceRef)(nil)
// Validate checks the account allowance reference.
func (a *AccountAllowanceRef) Validate() error {
if a == nil {
return errors.New("nil account allowance reference")
}
if len(a.Address) != 32 {
return errors.New("invalid account allowance reference")
}
return nil
}
var _ ValidatableMessage = (*CoinAllowanceRef)(nil)
// Validate checks the coin allowance reference.
func (c *CoinAllowanceRef) Validate() error {
if c == nil {
return errors.New("nil coin allowance reference")
}
if len(c.Address) != 32 {
return errors.New("invalid coin allowance reference")
}
return nil
}
var _ ValidatableMessage = (*TokenRequest)(nil)
// Validate checks the token request.
func (t *TokenRequest) Validate() error {
if t == nil {
return errors.New("nil token request")
}
switch {
case t.GetTransfer() != nil:
return t.GetTransfer().Validate()
case t.GetSplit() != nil:
return t.GetSplit().Validate()
case t.GetMerge() != nil:
return t.GetMerge().Validate()
case t.GetMint() != nil:
return t.GetMint().Validate()
case t.GetAnnounce() != nil:
return t.GetAnnounce().Validate()
case t.GetJoin() != nil:
return t.GetJoin().Validate()
case t.GetLeave() != nil:
return t.GetLeave().Validate()
case t.GetPause() != nil:
return t.GetPause().Validate()
case t.GetResume() != nil:
return t.GetResume().Validate()
default:
return nil
}
}
var _ ValidatableMessage = (*TransferCoinRequest)(nil)
// Validate checks the transfer coin request.
func (t *TransferCoinRequest) Validate() error {
if t == nil {
return errors.New("nil transfer coin request")
}
if err := t.ToAccount.Validate(); err != nil {
return errors.Wrap(err, "to account")
}
// TODO: Validate RefundAccount.
if err := t.OfCoin.Validate(); err != nil {
return errors.Wrap(err, "of coin")
}
// TODO: Validate Expiry.
// TODO: Validate AccountAllowance.
// TODO: Validate CoinAllowance.
if err := t.Signature.Validate(); err != nil {
return errors.Wrap(err, "signature")
}
if err := t.ValidateSignature(); err != nil {
return errors.Wrap(err, "signature")
}
return nil
}
var _ ValidatableMessage = (*SplitCoinRequest)(nil)
// Validate checks the split coin request.
func (t *SplitCoinRequest) Validate() error {
if t == nil {
return errors.New("nil split coin request")
}
if err := t.OfCoin.Validate(); err != nil {
return errors.Wrap(err, "of coin")
}
if n := len(t.Amounts); n == 0 || n > 100 {
return errors.New("invalid amounts")
}
for _, a := range t.Amounts {
if n := len(a); n == 0 || n > 32 {
return errors.New("invalid amount")
}
}
// TODO: Validate AccountAllowance.
// TODO: Validate CoinAllowance.
if err := t.Signature.Validate(); err != nil {
return errors.Wrap(err, "signature")
}
if err := t.ValidateSignature(); err != nil {
return errors.Wrap(err, "signature")
}
return nil
}
var _ ValidatableMessage = (*MergeCoinRequest)(nil)
// Validate checks the merge coin request.
func (t *MergeCoinRequest) Validate() error {
if t == nil {
return errors.New("nil merge coin request")
}
if len(t.Coins) == 0 {
return errors.New("invalid coins")
}
for _, c := range t.Coins {
if err := c.Validate(); err != nil {
return errors.Wrap(err, "coin")
}
}
// TODO: Validate AccountAllowance.
// TODO: Validate CoinAllowance.
if err := t.Signature.Validate(); err != nil {
return errors.Wrap(err, "signature")
}
if err := t.ValidateSignature(); err != nil {
return errors.Wrap(err, "signature")
}
return nil
}
var _ ValidatableMessage = (*MintCoinRequest)(nil)
// Validate checks the mint coin request.
func (t *MintCoinRequest) Validate() error {
if t == nil {
return errors.New("nil mint coin request")
}
if len(t.Proofs) == 0 {
return errors.New("invalid proofs")
}
// TODO: Validate AccountAllowance.
if err := t.Signature.Validate(); err != nil {
return errors.Wrap(err, "signature")
}
if err := t.ValidateSignature(); err != nil {
return errors.Wrap(err, "signature")
}
return nil
}
var _ ValidatableMessage = (*AnnounceProverRequest)(nil)
// Validate checks the announce prover request.
func (t *AnnounceProverRequest) Validate() error {
if t == nil {
return errors.New("nil announce prover request")
}
if len(t.PublicKeySignaturesEd448) == 0 {
return errors.New("invalid public key signatures")
}
for _, p := range t.PublicKeySignaturesEd448 {
if err := p.Validate(); err != nil {
return errors.Wrap(err, "public key signature")
}
}
if err := t.ValidateSignature(); err != nil {
return errors.Wrap(err, "signature")
}
return nil
}
var _ ValidatableMessage = (*AnnounceProverJoin)(nil)
// Validate checks the announce prover join.
func (t *AnnounceProverJoin) Validate() error {
if t == nil {
return errors.New("nil announce prover join")
}
if len(t.Filter) != 32 {
return errors.New("invalid filter")
}
if announce := t.Announce; announce != nil {
if err := announce.Validate(); err != nil {
return errors.Wrap(err, "announce")
}
}
if err := t.PublicKeySignatureEd448.Validate(); err != nil {
return errors.Wrap(err, "public key signature")
}
if err := t.ValidateSignature(); err != nil {
return errors.Wrap(err, "signature")
}
return nil
}
var _ ValidatableMessage = (*AnnounceProverLeave)(nil)
// Validate checks the announce prover leave.
func (t *AnnounceProverLeave) Validate() error {
if t == nil {
return errors.New("nil announce prover leave")
}
if len(t.Filter) != 32 {
return errors.New("invalid filter")
}
if err := t.PublicKeySignatureEd448.Validate(); err != nil {
return errors.Wrap(err, "public key signature")
}
if err := t.ValidateSignature(); err != nil {
return errors.Wrap(err, "signature")
}
return nil
}
var _ ValidatableMessage = (*AnnounceProverPause)(nil)
// Validate checks the announce prover pause.
func (t *AnnounceProverPause) Validate() error {
if t == nil {
return errors.New("nil announce prover pause")
}
if len(t.Filter) != 32 {
return errors.New("invalid filter")
}
if err := t.PublicKeySignatureEd448.Validate(); err != nil {
return errors.Wrap(err, "public key signature")
}
if err := t.ValidateSignature(); err != nil {
return errors.Wrap(err, "signature")
}
return nil
}
var _ ValidatableMessage = (*AnnounceProverResume)(nil)
// Validate checks the announce prover resume.
func (t *AnnounceProverResume) Validate() error {
if t == nil {
return errors.New("nil announce prover resume")
}
if len(t.Filter) != 32 {
return errors.New("invalid filter")
}
if err := t.PublicKeySignatureEd448.Validate(); err != nil {
return errors.Wrap(err, "public key signature")
}
if err := t.ValidateSignature(); err != nil {
return errors.Wrap(err, "signature")
}
return nil
}
// SignableED448Message is a message that can be signed.
type SignableED448Message interface {
// SignED448 signs the message with the given key, modifying the message.
// The message contents are expected to be valid - message
// contents must be validated, or correctly constructed, before signing.
SignED448(publicKey []byte, sign func([]byte) ([]byte, error)) error
}
func newED448Signature(publicKey, signature []byte) *Ed448Signature {
return &Ed448Signature{
PublicKey: &Ed448PublicKey{
KeyValue: publicKey,
},
Signature: signature,
}
}
var _ SignableED448Message = (*TransferCoinRequest)(nil)
// SignED448 signs the transfer coin request with the given key.
func (t *TransferCoinRequest) SignED448(publicKey []byte, sign func([]byte) ([]byte, error)) error {
signature, err := sign(t.signatureMessage())
if err != nil {
return errors.Wrap(err, "sign")
}
t.Signature = newED448Signature(publicKey, signature)
return nil
}
var _ SignableED448Message = (*SplitCoinRequest)(nil)
// SignED448 signs the split coin request with the given key.
func (t *SplitCoinRequest) SignED448(publicKey []byte, sign func([]byte) ([]byte, error)) error {
signature, err := sign(t.signatureMessage())
if err != nil {
return errors.Wrap(err, "sign")
}
t.Signature = newED448Signature(publicKey, signature)
return nil
}
var _ SignableED448Message = (*MergeCoinRequest)(nil)
// SignED448 signs the merge coin request with the given key.
func (t *MergeCoinRequest) SignED448(publicKey []byte, sign func([]byte) ([]byte, error)) error {
signature, err := sign(t.signatureMessage())
if err != nil {
return errors.Wrap(err, "sign")
}
t.Signature = newED448Signature(publicKey, signature)
return nil
}
var _ SignableED448Message = (*MintCoinRequest)(nil)
// SignED448 signs the mint coin request with the given key.
func (t *MintCoinRequest) SignED448(publicKey []byte, sign func([]byte) ([]byte, error)) error {
signature, err := sign(t.signatureMessage())
if err != nil {
return errors.Wrap(err, "sign")
}
t.Signature = newED448Signature(publicKey, signature)
return nil
}
type ED448SignHelper struct {
PublicKey []byte
Sign func([]byte) ([]byte, error)
}
// SignED448 signs the announce prover request with the given keys.
func (t *AnnounceProverRequest) SignED448(helpers []ED448SignHelper) error {
if len(helpers) == 0 {
return errors.New("no keys")
}
payload := []byte{}
primary := helpers[0]
signatures := make([]*Ed448Signature, len(helpers))
for i, k := range helpers[1:] {
payload = append(payload, k.PublicKey...)
signature, err := k.Sign(primary.PublicKey)
if err != nil {
return errors.Wrap(err, "sign")
}
signatures[i+1] = newED448Signature(k.PublicKey, signature)
}
signature, err := primary.Sign(payload)
if err != nil {
return errors.Wrap(err, "sign")
}
signatures[0] = newED448Signature(primary.PublicKey, signature)
t.PublicKeySignaturesEd448 = signatures
return nil
}
var _ SignableED448Message = (*AnnounceProverJoin)(nil)
// SignED448 signs the announce prover join with the given key.
func (t *AnnounceProverJoin) SignED448(publicKey []byte, sign func([]byte) ([]byte, error)) error {
signature, err := sign(t.signatureMessage())
if err != nil {
return errors.Wrap(err, "sign")
}
t.PublicKeySignatureEd448 = newED448Signature(publicKey, signature)
return nil
}
var _ SignableED448Message = (*AnnounceProverLeave)(nil)
// SignED448 signs the announce prover leave with the given key.
func (t *AnnounceProverLeave) SignED448(publicKey []byte, sign func([]byte) ([]byte, error)) error {
signature, err := sign(t.signatureMessage())
if err != nil {
return errors.Wrap(err, "sign")
}
t.PublicKeySignatureEd448 = newED448Signature(publicKey, signature)
return nil
}
var _ SignableED448Message = (*AnnounceProverPause)(nil)
// SignED448 signs the announce prover pause with the given key.
func (t *AnnounceProverPause) SignED448(publicKey []byte, sign func([]byte) ([]byte, error)) error {
signature, err := sign(t.signatureMessage())
if err != nil {
return errors.Wrap(err, "sign")
}
t.PublicKeySignatureEd448 = newED448Signature(publicKey, signature)
return nil
}
var _ SignableED448Message = (*AnnounceProverResume)(nil)
// SignED448 signs the announce prover resume with the given key.
func (t *AnnounceProverResume) SignED448(publicKey []byte, sign func([]byte) ([]byte, error)) error {
signature, err := sign(t.signatureMessage())
if err != nil {
return errors.Wrap(err, "sign")
}
t.PublicKeySignatureEd448 = newED448Signature(publicKey, signature)
return nil
}

View File

@ -0,0 +1,5 @@
package protobufs
func SignatureMessageOf(m any) []byte {
return m.(signatureMessage).signatureMessage()
}

View File

@ -0,0 +1,914 @@
package protobufs_test
import (
"bytes"
"crypto/rand"
"testing"
"github.com/libp2p/go-libp2p/core/crypto"
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
)
func newPrivateKey() crypto.PrivKey {
privKey, _, err := crypto.GenerateEd448Key(rand.Reader)
if err != nil {
panic(err)
}
return privKey
}
func publicKeyBytesOf(privKey crypto.PrivKey) []byte {
b, err := privKey.GetPublic().Raw()
if err != nil {
panic(err)
}
return b
}
var (
primaryPrivateKey crypto.PrivKey = newPrivateKey()
primaryPublicKeyBytes []byte = publicKeyBytesOf(primaryPrivateKey)
secondaryPrivateKey crypto.PrivKey = newPrivateKey()
secondaryPublicKeyBytes []byte = publicKeyBytesOf(secondaryPrivateKey)
)
func metaAppend[T any](bs ...[]T) []T {
var result []T
for _, b := range bs {
result = append(result, b...)
}
return result
}
func TestTransferCoinRequestSignatureRoundtrip(t *testing.T) {
t.Parallel()
message := &protobufs.TransferCoinRequest{
OfCoin: &protobufs.CoinRef{
Address: bytes.Repeat([]byte{0x01}, 32),
},
ToAccount: &protobufs.AccountRef{
Account: &protobufs.AccountRef_ImplicitAccount{
ImplicitAccount: &protobufs.ImplicitAccount{
Address: bytes.Repeat([]byte{0x02}, 32),
},
},
},
Signature: &protobufs.Ed448Signature{
Signature: bytes.Repeat([]byte{0x03}, 114),
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: bytes.Repeat([]byte{0x04}, 57),
},
},
}
if !bytes.Equal(
protobufs.SignatureMessageOf(message),
metaAppend(
[]byte("transfer"),
bytes.Repeat([]byte{0x01}, 32),
bytes.Repeat([]byte{0x02}, 32),
),
) {
t.Fatal("unexpected signature message")
}
if err := message.ValidateSignature(); err == nil {
t.Fatal("expected error")
}
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
t.Fatal(err)
}
if !bytes.Equal(message.Signature.PublicKey.KeyValue, primaryPublicKeyBytes) {
t.Fatal("unexpected public key")
}
if err := message.ValidateSignature(); err != nil {
t.Fatal(err)
}
}
func TestSplitCoinRequestSignatureRoundtrip(t *testing.T) {
t.Parallel()
message := &protobufs.SplitCoinRequest{
OfCoin: &protobufs.CoinRef{
Address: bytes.Repeat([]byte{0x01}, 32),
},
Amounts: [][]byte{
bytes.Repeat([]byte{0x02}, 32),
bytes.Repeat([]byte{0x03}, 32),
},
Signature: &protobufs.Ed448Signature{
Signature: bytes.Repeat([]byte{0x04}, 114),
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: bytes.Repeat([]byte{0x05}, 57),
},
},
}
if !bytes.Equal(
protobufs.SignatureMessageOf(message),
metaAppend(
[]byte("split"),
bytes.Repeat([]byte{0x01}, 32),
bytes.Repeat([]byte{0x02}, 32),
bytes.Repeat([]byte{0x03}, 32),
),
) {
t.Fatal("unexpected signature message")
}
if err := message.ValidateSignature(); err == nil {
t.Fatal("expected error")
}
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
t.Fatal(err)
}
if !bytes.Equal(message.Signature.PublicKey.KeyValue, primaryPublicKeyBytes) {
t.Fatal("unexpected public key")
}
if err := message.ValidateSignature(); err != nil {
t.Fatal(err)
}
}
func TestMergeCoinRequestSignatureRoundtrip(t *testing.T) {
t.Parallel()
message := &protobufs.MergeCoinRequest{
Coins: []*protobufs.CoinRef{
{
Address: bytes.Repeat([]byte{0x01}, 32),
},
{
Address: bytes.Repeat([]byte{0x02}, 32),
},
},
Signature: &protobufs.Ed448Signature{
Signature: bytes.Repeat([]byte{0x03}, 114),
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: bytes.Repeat([]byte{0x04}, 57),
},
},
}
if !bytes.Equal(
protobufs.SignatureMessageOf(message),
metaAppend(
[]byte("merge"),
bytes.Repeat([]byte{0x01}, 32),
bytes.Repeat([]byte{0x02}, 32),
),
) {
t.Fatal("unexpected signature message")
}
if err := message.ValidateSignature(); err == nil {
t.Fatal("expected error")
}
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
t.Fatal(err)
}
if !bytes.Equal(message.Signature.PublicKey.KeyValue, primaryPublicKeyBytes) {
t.Fatal("unexpected public key")
}
if err := message.ValidateSignature(); err != nil {
t.Fatal(err)
}
}
func TestMintCoinRequestSignatureRoundtrip(t *testing.T) {
t.Parallel()
message := &protobufs.MintCoinRequest{
Proofs: [][]byte{
bytes.Repeat([]byte{0x01}, 32),
bytes.Repeat([]byte{0x02}, 32),
},
Signature: &protobufs.Ed448Signature{
Signature: bytes.Repeat([]byte{0x03}, 114),
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: bytes.Repeat([]byte{0x04}, 57),
},
},
}
if !bytes.Equal(
protobufs.SignatureMessageOf(message),
metaAppend(
[]byte("mint"),
bytes.Repeat([]byte{0x01}, 32),
bytes.Repeat([]byte{0x02}, 32),
),
) {
t.Fatal("unexpected signature message")
}
if err := message.ValidateSignature(); err == nil {
t.Fatal("expected error")
}
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
t.Fatal(err)
}
if !bytes.Equal(message.Signature.PublicKey.KeyValue, primaryPublicKeyBytes) {
t.Fatal("unexpected public key")
}
if err := message.ValidateSignature(); err != nil {
t.Fatal(err)
}
}
func TestAnnounceProverRequestSignatureRoundtrip(t *testing.T) {
t.Parallel()
message := &protobufs.AnnounceProverRequest{
PublicKeySignaturesEd448: []*protobufs.Ed448Signature{
{
Signature: bytes.Repeat([]byte{0x01}, 114),
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: bytes.Repeat([]byte{0x02}, 57),
},
},
{
Signature: bytes.Repeat([]byte{0x03}, 114),
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: bytes.Repeat([]byte{0x04}, 57),
},
},
},
}
if err := message.ValidateSignature(); err == nil {
t.Fatal("expected error")
}
if err := message.SignED448([]protobufs.ED448SignHelper{
{
PublicKey: primaryPublicKeyBytes,
Sign: primaryPrivateKey.Sign,
},
{
PublicKey: secondaryPublicKeyBytes,
Sign: secondaryPrivateKey.Sign,
},
}); err != nil {
t.Fatal(err)
}
if !bytes.Equal(message.PublicKeySignaturesEd448[0].PublicKey.KeyValue, primaryPublicKeyBytes) {
t.Fatal("unexpected public key")
}
if !bytes.Equal(message.PublicKeySignaturesEd448[1].PublicKey.KeyValue, secondaryPublicKeyBytes) {
t.Fatal("unexpected public key")
}
if err := message.ValidateSignature(); err != nil {
t.Fatal(err)
}
message = &protobufs.AnnounceProverRequest{
PublicKeySignaturesEd448: []*protobufs.Ed448Signature{
{
Signature: bytes.Repeat([]byte{0x01}, 114),
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: bytes.Repeat([]byte{0x02}, 57),
},
},
},
}
if err := message.ValidateSignature(); err == nil {
t.Fatal("expected error")
}
if err := message.SignED448([]protobufs.ED448SignHelper{
{
PublicKey: primaryPublicKeyBytes,
Sign: primaryPrivateKey.Sign,
},
}); err != nil {
t.Fatal(err)
}
if !bytes.Equal(message.PublicKeySignaturesEd448[0].PublicKey.KeyValue, primaryPublicKeyBytes) {
t.Fatal("unexpected public key")
}
if err := message.ValidateSignature(); err != nil {
t.Fatal(err)
}
}
func TestAnnounceProverJoinSignatureRoundtrip(t *testing.T) {
t.Parallel()
message := &protobufs.AnnounceProverJoin{
Filter: bytes.Repeat([]byte{0x01}, 32),
FrameNumber: 1,
PublicKeySignatureEd448: &protobufs.Ed448Signature{
Signature: bytes.Repeat([]byte{0x02}, 114),
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: bytes.Repeat([]byte{0x03}, 57),
},
},
}
if !bytes.Equal(
protobufs.SignatureMessageOf(message),
metaAppend(
[]byte("join"),
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
bytes.Repeat([]byte{0x01}, 32),
),
) {
t.Fatal("unexpected signature message")
}
if err := message.ValidateSignature(); err == nil {
t.Fatal("expected error")
}
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
t.Fatal(err)
}
if !bytes.Equal(message.PublicKeySignatureEd448.PublicKey.KeyValue, primaryPublicKeyBytes) {
t.Fatal("unexpected public key")
}
if err := message.ValidateSignature(); err != nil {
t.Fatal(err)
}
}
func TestAnnounceProverLeaveSignatureRoundtrip(t *testing.T) {
t.Parallel()
message := &protobufs.AnnounceProverLeave{
Filter: bytes.Repeat([]byte{0x01}, 32),
FrameNumber: 1,
PublicKeySignatureEd448: &protobufs.Ed448Signature{
Signature: bytes.Repeat([]byte{0x02}, 114),
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: bytes.Repeat([]byte{0x03}, 57),
},
},
}
if !bytes.Equal(
protobufs.SignatureMessageOf(message),
metaAppend(
[]byte("leave"),
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
bytes.Repeat([]byte{0x01}, 32),
),
) {
t.Fatal("unexpected signature message")
}
if err := message.ValidateSignature(); err == nil {
t.Fatal("expected error")
}
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
t.Fatal(err)
}
if !bytes.Equal(message.PublicKeySignatureEd448.PublicKey.KeyValue, primaryPublicKeyBytes) {
t.Fatal("unexpected public key")
}
if err := message.ValidateSignature(); err != nil {
t.Fatal(err)
}
}
func TestAnnounceProverPauseSignatureRoundtrip(t *testing.T) {
t.Parallel()
message := &protobufs.AnnounceProverPause{
Filter: bytes.Repeat([]byte{0x01}, 32),
FrameNumber: 1,
PublicKeySignatureEd448: &protobufs.Ed448Signature{
Signature: bytes.Repeat([]byte{0x02}, 114),
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: bytes.Repeat([]byte{0x03}, 57),
},
},
}
if !bytes.Equal(
protobufs.SignatureMessageOf(message),
metaAppend(
[]byte("pause"),
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
bytes.Repeat([]byte{0x01}, 32),
),
) {
t.Fatal("unexpected signature message")
}
if err := message.ValidateSignature(); err == nil {
t.Fatal("expected error")
}
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
t.Fatal(err)
}
if !bytes.Equal(message.PublicKeySignatureEd448.PublicKey.KeyValue, primaryPublicKeyBytes) {
t.Fatal("unexpected public key")
}
if err := message.ValidateSignature(); err != nil {
t.Fatal(err)
}
}
func TestAnnounceProverResumeSignatureRoundtrip(t *testing.T) {
t.Parallel()
message := &protobufs.AnnounceProverResume{
Filter: bytes.Repeat([]byte{0x01}, 32),
FrameNumber: 1,
PublicKeySignatureEd448: &protobufs.Ed448Signature{
Signature: bytes.Repeat([]byte{0x02}, 114),
PublicKey: &protobufs.Ed448PublicKey{
KeyValue: bytes.Repeat([]byte{0x03}, 57),
},
},
}
if !bytes.Equal(
protobufs.SignatureMessageOf(message),
metaAppend(
[]byte("resume"),
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
bytes.Repeat([]byte{0x01}, 32),
),
) {
t.Fatal("unexpected signature message")
}
if err := message.ValidateSignature(); err == nil {
t.Fatal("expected error")
}
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
t.Fatal(err)
}
if !bytes.Equal(message.PublicKeySignatureEd448.PublicKey.KeyValue, primaryPublicKeyBytes) {
t.Fatal("unexpected public key")
}
if err := message.ValidateSignature(); err != nil {
t.Fatal(err)
}
}
func TestEd448PublicKeyValidate(t *testing.T) {
t.Parallel()
if err := (*protobufs.Ed448PublicKey)(nil).Validate(); err == nil {
t.Fatal("expected error")
}
message := &protobufs.Ed448PublicKey{}
if err := message.Validate(); err == nil {
t.Fatal("expected error")
}
message.KeyValue = bytes.Repeat([]byte{0x01}, 57)
if err := message.Validate(); err != nil {
t.Fatal(err)
}
}
func TestEd448SignatureValidate(t *testing.T) {
t.Parallel()
if err := (*protobufs.Ed448Signature)(nil).Validate(); err == nil {
t.Fatal("expected error")
}
message := &protobufs.Ed448Signature{}
if err := message.Validate(); err == nil {
t.Fatal("expected error")
}
message.Signature = bytes.Repeat([]byte{0x01}, 114)
message.PublicKey = &protobufs.Ed448PublicKey{
KeyValue: bytes.Repeat([]byte{0x02}, 57),
}
if err := message.Validate(); err != nil {
t.Fatal(err)
}
}
func TestImplicitAccountValidate(t *testing.T) {
t.Parallel()
if err := (*protobufs.ImplicitAccount)(nil).Validate(); err == nil {
t.Fatal("expected error")
}
message := &protobufs.ImplicitAccount{}
if err := message.Validate(); err == nil {
t.Fatal("expected error")
}
message.Address = bytes.Repeat([]byte{0x01}, 32)
if err := message.Validate(); err != nil {
t.Fatal(err)
}
}
func TestOriginatedAccountRefValidate(t *testing.T) {
t.Parallel()
if err := (*protobufs.OriginatedAccountRef)(nil).Validate(); err == nil {
t.Fatal("expected error")
}
message := &protobufs.OriginatedAccountRef{}
if err := message.Validate(); err == nil {
t.Fatal("expected error")
}
message.Address = bytes.Repeat([]byte{0x01}, 32)
if err := message.Validate(); err != nil {
t.Fatal(err)
}
}
func TestAccountRefValidate(t *testing.T) {
t.Parallel()
message := &protobufs.AccountRef{}
if err := message.Validate(); err == nil {
t.Fatal("expected error")
}
message.Account = &protobufs.AccountRef_ImplicitAccount{
ImplicitAccount: &protobufs.ImplicitAccount{
Address: bytes.Repeat([]byte{0x01}, 32),
},
}
if err := message.Validate(); err != nil {
t.Fatal(err)
}
message.Account = &protobufs.AccountRef_OriginatedAccount{
OriginatedAccount: &protobufs.OriginatedAccountRef{
Address: bytes.Repeat([]byte{0x02}, 32),
},
}
if err := message.Validate(); err != nil {
t.Fatal(err)
}
}
func TestCoinRefValidate(t *testing.T) {
t.Parallel()
if err := (*protobufs.CoinRef)(nil).Validate(); err == nil {
t.Fatal("expected error")
}
message := &protobufs.CoinRef{}
if err := message.Validate(); err == nil {
t.Fatal("expected error")
}
message.Address = bytes.Repeat([]byte{0x01}, 32)
if err := message.Validate(); err != nil {
t.Fatal(err)
}
}
func TestAccountAllowanceRefValidate(t *testing.T) {
t.Parallel()
if err := (*protobufs.AccountAllowanceRef)(nil).Validate(); err == nil {
t.Fatal("expected error")
}
message := &protobufs.AccountAllowanceRef{}
if err := message.Validate(); err == nil {
t.Fatal("expected error")
}
message.Address = bytes.Repeat([]byte{0x01}, 32)
if err := message.Validate(); err != nil {
t.Fatal(err)
}
}
func TestCoinAllowanceRefValidate(t *testing.T) {
t.Parallel()
if err := (*protobufs.CoinAllowanceRef)(nil).Validate(); err == nil {
t.Fatal("expected error")
}
message := &protobufs.CoinAllowanceRef{}
if err := message.Validate(); err == nil {
t.Fatal("expected error")
}
message.Address = bytes.Repeat([]byte{0x01}, 32)
if err := message.Validate(); err != nil {
t.Fatal(err)
}
}
func TestTransferCoinRequestValidate(t *testing.T) {
t.Parallel()
if err := (*protobufs.TransferCoinRequest)(nil).Validate(); err == nil {
t.Fatal("expected error")
}
message := &protobufs.TransferCoinRequest{}
if err := message.Validate(); err == nil {
t.Fatal("expected error")
}
if err := (&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Transfer{
Transfer: message,
},
}).Validate(); err == nil {
t.Fatal("expected error")
}
message.OfCoin = &protobufs.CoinRef{
Address: bytes.Repeat([]byte{0x01}, 32),
}
message.ToAccount = &protobufs.AccountRef{
Account: &protobufs.AccountRef_ImplicitAccount{
ImplicitAccount: &protobufs.ImplicitAccount{
Address: bytes.Repeat([]byte{0x02}, 32),
},
},
}
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
t.Fatal(err)
}
if err := message.Validate(); err != nil {
t.Fatal(err)
}
if err := (&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Transfer{
Transfer: message,
},
}).Validate(); err != nil {
t.Fatal(err)
}
}
func TestSplitCoinRequestValidate(t *testing.T) {
t.Parallel()
if err := (*protobufs.SplitCoinRequest)(nil).Validate(); err == nil {
t.Fatal("expected error")
}
message := &protobufs.SplitCoinRequest{}
if err := message.Validate(); err == nil {
t.Fatal("expected error")
}
if err := (&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Split{
Split: message,
},
}).Validate(); err == nil {
t.Fatal("expected error")
}
message.OfCoin = &protobufs.CoinRef{
Address: bytes.Repeat([]byte{0x01}, 32),
}
message.Amounts = [][]byte{
bytes.Repeat([]byte{0x02}, 32),
bytes.Repeat([]byte{0x03}, 32),
}
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
t.Fatal(err)
}
if err := message.Validate(); err != nil {
t.Fatal(err)
}
if err := (&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Split{
Split: message,
},
}).Validate(); err != nil {
t.Fatal(err)
}
}
func TestMergeCoinRequestValidate(t *testing.T) {
t.Parallel()
if err := (*protobufs.MergeCoinRequest)(nil).Validate(); err == nil {
t.Fatal("expected error")
}
message := &protobufs.MergeCoinRequest{}
if err := message.Validate(); err == nil {
t.Fatal("expected error")
}
if err := (&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Merge{
Merge: message,
},
}).Validate(); err == nil {
t.Fatal("expected error")
}
message.Coins = []*protobufs.CoinRef{
{
Address: bytes.Repeat([]byte{0x01}, 32),
},
{
Address: bytes.Repeat([]byte{0x02}, 32),
},
}
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
t.Fatal(err)
}
if err := message.Validate(); err != nil {
t.Fatal(err)
}
if err := (&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Merge{
Merge: message,
},
}).Validate(); err != nil {
t.Fatal(err)
}
}
func TestMintCoinRequestValidate(t *testing.T) {
t.Parallel()
if err := (*protobufs.MintCoinRequest)(nil).Validate(); err == nil {
t.Fatal("expected error")
}
message := &protobufs.MintCoinRequest{}
if err := message.Validate(); err == nil {
t.Fatal("expected error")
}
if err := (&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Mint{
Mint: message,
},
}).Validate(); err == nil {
t.Fatal("expected error")
}
message.Proofs = [][]byte{
bytes.Repeat([]byte{0x01}, 32),
bytes.Repeat([]byte{0x02}, 32),
}
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
t.Fatal(err)
}
if err := message.Validate(); err != nil {
t.Fatal(err)
}
if err := (&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Mint{
Mint: message,
},
}).Validate(); err != nil {
t.Fatal(err)
}
}
func TestAnnounceProverRequestValidate(t *testing.T) {
t.Parallel()
if err := (*protobufs.AnnounceProverRequest)(nil).Validate(); err == nil {
t.Fatal("expected error")
}
message := &protobufs.AnnounceProverRequest{}
if err := message.Validate(); err == nil {
t.Fatal("expected error")
}
if err := (&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Announce{
Announce: message,
},
}).Validate(); err == nil {
t.Fatal("expected error")
}
if err := message.SignED448([]protobufs.ED448SignHelper{
{
PublicKey: primaryPublicKeyBytes,
Sign: primaryPrivateKey.Sign,
},
{
PublicKey: secondaryPublicKeyBytes,
Sign: secondaryPrivateKey.Sign,
},
}); err != nil {
t.Fatal(err)
}
if err := message.Validate(); err != nil {
t.Fatal(err)
}
if err := (&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Announce{
Announce: message,
},
}).Validate(); err != nil {
t.Fatal("expected error")
}
}
func TestAnnounceProverJoinValidate(t *testing.T) {
t.Parallel()
if err := (*protobufs.AnnounceProverJoin)(nil).Validate(); err == nil {
t.Fatal("expected error")
}
message := &protobufs.AnnounceProverJoin{}
if err := message.Validate(); err == nil {
t.Fatal("expected error")
}
if err := (&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Join{
Join: message,
},
}).Validate(); err == nil {
t.Fatal("expected error")
}
message.Filter = bytes.Repeat([]byte{0x01}, 32)
message.FrameNumber = 1
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
t.Fatal(err)
}
if err := message.Validate(); err != nil {
t.Fatal(err)
}
if err := (&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Join{
Join: message,
},
}).Validate(); err != nil {
t.Fatal(err)
}
announce := &protobufs.AnnounceProverRequest{}
message.Announce = announce
if err := message.Validate(); err == nil {
t.Fatal("expected error")
}
if err := (&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Join{
Join: message,
},
}).Validate(); err == nil {
t.Fatal("expected error")
}
if err := announce.SignED448([]protobufs.ED448SignHelper{
{
PublicKey: primaryPublicKeyBytes,
Sign: primaryPrivateKey.Sign,
},
{
PublicKey: secondaryPublicKeyBytes,
Sign: secondaryPrivateKey.Sign,
},
}); err != nil {
t.Fatal(err)
}
if err := message.Validate(); err != nil {
t.Fatal(err)
}
if err := (&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Join{
Join: message,
},
}).Validate(); err != nil {
t.Fatal(err)
}
}
func TestAnnounceProverLeaveValidate(t *testing.T) {
t.Parallel()
if err := (*protobufs.AnnounceProverLeave)(nil).Validate(); err == nil {
t.Fatal("expected error")
}
message := &protobufs.AnnounceProverLeave{}
if err := message.Validate(); err == nil {
t.Fatal("expected error")
}
if err := (&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Leave{
Leave: message,
},
}).Validate(); err == nil {
t.Fatal("expected error")
}
message.Filter = bytes.Repeat([]byte{0x01}, 32)
message.FrameNumber = 1
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
t.Fatal(err)
}
if err := message.Validate(); err != nil {
t.Fatal(err)
}
if err := (&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Leave{
Leave: message,
},
}).Validate(); err != nil {
t.Fatal(err)
}
}
func TestAnnounceProverPauseValidate(t *testing.T) {
t.Parallel()
if err := (*protobufs.AnnounceProverPause)(nil).Validate(); err == nil {
t.Fatal("expected error")
}
message := &protobufs.AnnounceProverPause{}
if err := message.Validate(); err == nil {
t.Fatal("expected error")
}
if err := (&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Pause{
Pause: message,
},
}).Validate(); err == nil {
t.Fatal("expected error")
}
message.Filter = bytes.Repeat([]byte{0x01}, 32)
message.FrameNumber = 1
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
t.Fatal(err)
}
if err := message.Validate(); err != nil {
t.Fatal(err)
}
if err := (&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Pause{
Pause: message,
},
}).Validate(); err != nil {
t.Fatal(err)
}
}
func TestAnnounceProverResumeValidate(t *testing.T) {
t.Parallel()
if err := (*protobufs.AnnounceProverResume)(nil).Validate(); err == nil {
t.Fatal("expected error")
}
message := &protobufs.AnnounceProverResume{}
if err := message.Validate(); err == nil {
t.Fatal("expected error")
}
if err := (&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Resume{
Resume: message,
},
}).Validate(); err == nil {
t.Fatal("expected error")
}
message.Filter = bytes.Repeat([]byte{0x01}, 32)
message.FrameNumber = 1
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
t.Fatal(err)
}
if err := message.Validate(); err != nil {
t.Fatal(err)
}
if err := (&protobufs.TokenRequest{
Request: &protobufs.TokenRequest_Resume{
Resume: message,
},
}).Validate(); err != nil {
t.Fatal(err)
}
}

View File

@ -221,20 +221,20 @@ func (r *RPCServer) SendMessage(
) (*protobufs.SendMessageResponse, error) {
req.Timestamp = time.Now().UnixMilli()
any := &anypb.Any{}
if err := any.MarshalFrom(req); err != nil {
a := &anypb.Any{}
if err := a.MarshalFrom(req); err != nil {
return nil, errors.Wrap(err, "publish message")
}
// annoying protobuf any hack
any.TypeUrl = strings.Replace(
any.TypeUrl,
a.TypeUrl = strings.Replace(
a.TypeUrl,
"type.googleapis.com",
"types.quilibrium.com",
1,
)
payload, err := proto.Marshal(any)
payload, err := proto.Marshal(a)
if err != nil {
return nil, errors.Wrap(err, "publish message")
}

View File

@ -31,9 +31,9 @@ func PackOutputIntoPayloadAndProof(
modulo int,
frame *protobufs.ClockFrame,
previousTree *mt.MerkleTree,
) (*mt.MerkleTree, []byte, [][]byte, error) {
) (*mt.MerkleTree, [][]byte, error) {
if modulo != len(outputs) {
return nil, nil, nil, errors.Wrap(
return nil, nil, errors.Wrap(
errors.New("mismatch of outputs and prover size"),
"pack output into payload and proof",
)
@ -50,14 +50,9 @@ func PackOutputIntoPayloadAndProof(
outputs,
)
if err != nil {
return nil, nil, nil, errors.Wrap(err, "pack output into payload and proof")
return nil, nil, errors.Wrap(err, "pack output into payload and proof")
}
payload := []byte("mint")
payload = append(payload, tree.Root...)
payload = binary.BigEndian.AppendUint32(payload, uint32(modulo))
payload = binary.BigEndian.AppendUint64(payload, frame.FrameNumber)
output := [][]byte{
tree.Root,
binary.BigEndian.AppendUint32([]byte{}, uint32(modulo)),
@ -68,19 +63,14 @@ func PackOutputIntoPayloadAndProof(
hash := sha3.Sum256(frame.Output)
pick := BytesToUnbiasedMod(hash, uint64(modulo))
if uint64(modulo) < pick {
return nil, nil, nil, errors.Wrap(
return nil, nil, errors.Wrap(
errors.New("proof size mismatch"),
"pack output into payload and proof",
)
}
for _, sib := range previousTree.Proofs[int(pick)].Siblings {
payload = append(payload, sib...)
output = append(output, sib)
}
payload = binary.BigEndian.AppendUint32(
payload,
previousTree.Proofs[int(pick)].Path,
)
output = append(
output,
binary.BigEndian.AppendUint32(
@ -88,10 +78,9 @@ func PackOutputIntoPayloadAndProof(
previousTree.Proofs[int(pick)].Path,
),
)
payload = append(payload, previousTree.Leaves[int(pick)]...)
output = append(output, previousTree.Leaves[int(pick)])
}
return tree, payload, output, nil
return tree, output, nil
}
func UnpackAndVerifyOutput(