mirror of
https://github.com/QuilibriumNetwork/ceremonyclient.git
synced 2026-02-21 10:27:26 +08:00
Merge branch 'v2.0.6-p2' into develop-2.1-pre-milestone3
This commit is contained in:
commit
bd08966076
@ -157,7 +157,7 @@ var Signatories = []string{
|
||||
"9ab76d775487c85c8e5aa0c5b3f961772967899a14644651031ae5f98ac197bee3f8880492c4fdba268716fc4b7c38ffcac370b663ac10b600",
|
||||
"81d63a45f068629f568de812f18be5807bfe828a830097f09cf02330d6acd35e3607401df3fda08b03b68ea6e68afd506b23506b11e87a0f80",
|
||||
"6e2872f73c4868c4286bef7bfe2f5479a41c42f4e07505efa4883c7950c740252e0eea78eef10c584b19b1dcda01f7767d3135d07c33244100",
|
||||
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0ca6f5a9d7f86c1111be5edf31e26979918aa4fa3daae6de1120e05c2a09bdb8d2feeb084286a3347e06ced25530358cbc74c204d2a1753a00",
|
||||
}
|
||||
|
||||
var unlock *SignedGenesisUnlock
|
||||
|
||||
@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
func GetMinimumVersionCutoff() time.Time {
|
||||
return time.Date(2024, time.November, 24, 0, 0, 0, 0, time.UTC)
|
||||
return time.Date(2025, time.January, 13, 0, 0, 0, 0, time.UTC)
|
||||
}
|
||||
|
||||
// Gets the minimum patch version – This should only be set in a release series
|
||||
@ -43,7 +43,7 @@ func FormatVersion(version []byte) string {
|
||||
}
|
||||
|
||||
func GetPatchNumber() byte {
|
||||
return 0x01
|
||||
return 0x02
|
||||
}
|
||||
|
||||
func GetRCNumber() byte {
|
||||
|
||||
@ -10,9 +10,12 @@ import (
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/config"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/consensus/data/internal"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/internal/frametime"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/tries"
|
||||
|
||||
"github.com/iden3/go-iden3-crypto/poseidon"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/pkg/errors"
|
||||
mt "github.com/txaty/go-merkletree"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/protobuf/proto"
|
||||
@ -428,3 +431,146 @@ func (e *DataClockConsensusEngine) syncWithPeer(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (e *DataClockConsensusEngine) initiateProvers(
|
||||
latestFrame *protobufs.ClockFrame,
|
||||
) {
|
||||
if latestFrame.Timestamp > time.Now().UnixMilli()-60000 {
|
||||
if !e.IsInProverTrie(e.pubSub.GetPeerID()) {
|
||||
e.logger.Info("announcing prover join")
|
||||
for _, eng := range e.executionEngines {
|
||||
eng.AnnounceProverJoin()
|
||||
break
|
||||
}
|
||||
} else {
|
||||
if e.previousFrameProven != nil &&
|
||||
e.previousFrameProven.FrameNumber == latestFrame.FrameNumber {
|
||||
return
|
||||
}
|
||||
|
||||
h, err := poseidon.HashBytes(e.pubSub.GetPeerID())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
peerProvingKeyAddress := h.FillBytes(make([]byte, 32))
|
||||
|
||||
ring := -1
|
||||
if tries := e.GetFrameProverTries(); len(tries) > 1 {
|
||||
for i, tries := range tries[1:] {
|
||||
i := i
|
||||
if tries.Contains(peerProvingKeyAddress) {
|
||||
ring = i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
e.clientReconnectTest++
|
||||
if e.clientReconnectTest >= 10 {
|
||||
e.tryReconnectDataWorkerClients()
|
||||
e.clientReconnectTest = 0
|
||||
}
|
||||
|
||||
previousTreeRoot := []byte{}
|
||||
if e.previousTree != nil {
|
||||
previousTreeRoot = e.previousTree.Root
|
||||
}
|
||||
outputs := e.PerformTimeProof(latestFrame, previousTreeRoot, latestFrame.Difficulty, ring)
|
||||
if outputs == nil || len(outputs) < 3 {
|
||||
e.logger.Info("workers not yet available for proving")
|
||||
return
|
||||
}
|
||||
modulo := len(outputs)
|
||||
var proofTree *mt.MerkleTree
|
||||
var output [][]byte
|
||||
if latestFrame.FrameNumber >= application.PROOF_FRAME_COMBINE_CUTOFF {
|
||||
proofTree, output, err = tries.PackOutputIntoMultiPayloadAndProof(
|
||||
outputs,
|
||||
modulo,
|
||||
latestFrame,
|
||||
e.previousTree,
|
||||
)
|
||||
} else {
|
||||
proofTree, output, err = tries.PackOutputIntoPayloadAndProof(
|
||||
outputs,
|
||||
modulo,
|
||||
latestFrame,
|
||||
e.previousTree,
|
||||
)
|
||||
}
|
||||
if err != nil {
|
||||
e.logger.Error(
|
||||
"could not successfully pack proof, reattempting",
|
||||
zap.Error(err),
|
||||
)
|
||||
return
|
||||
}
|
||||
e.previousFrameProven = latestFrame
|
||||
e.previousTree = proofTree
|
||||
|
||||
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
|
||||
}
|
||||
if err := mint.Validate(); err != nil {
|
||||
e.logger.Error("mint validation failed", zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
e.logger.Info(
|
||||
"submitting data proof",
|
||||
zap.Int("ring", ring),
|
||||
zap.Int("active_workers", len(outputs)),
|
||||
zap.Uint64("frame_number", latestFrame.FrameNumber),
|
||||
zap.Duration("frame_age", frametime.Since(latestFrame)),
|
||||
)
|
||||
|
||||
if err := e.publishMessage(e.txFilter, mint.TokenRequest()); err != nil {
|
||||
e.logger.Error("could not publish mint", zap.Error(err))
|
||||
}
|
||||
|
||||
if e.config.Engine.AutoMergeCoins {
|
||||
_, addrs, _, err := e.coinStore.GetCoinsForOwner(
|
||||
peerProvingKeyAddress,
|
||||
)
|
||||
if err != nil {
|
||||
e.logger.Error(
|
||||
"received error while iterating coins",
|
||||
zap.Error(err),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if len(addrs) > 25 {
|
||||
refs := []*protobufs.CoinRef{}
|
||||
for _, addr := range addrs {
|
||||
refs = append(refs, &protobufs.CoinRef{
|
||||
Address: addr,
|
||||
})
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
if err := merge.Validate(); err != nil {
|
||||
e.logger.Error("merge validation failed", zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
if err := e.publishMessage(e.txFilter, merge.TokenRequest()); err != nil {
|
||||
e.logger.Warn("could not publish merge", zap.Error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,8 +4,6 @@ import (
|
||||
"bytes"
|
||||
"time"
|
||||
|
||||
"github.com/iden3/go-iden3-crypto/poseidon"
|
||||
mt "github.com/txaty/go-merkletree"
|
||||
"go.uber.org/zap"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/consensus"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/execution/intrinsics/token/application"
|
||||
@ -233,7 +231,7 @@ func (e *DataClockConsensusEngine) processFrame(
|
||||
latestFrame *protobufs.ClockFrame,
|
||||
dataFrame *protobufs.ClockFrame,
|
||||
) *protobufs.ClockFrame {
|
||||
|
||||
|
||||
e.logger.Info(
|
||||
"current frame head",
|
||||
zap.Uint64("frame_number", dataFrame.FrameNumber),
|
||||
@ -282,144 +280,6 @@ func (e *DataClockConsensusEngine) processFrame(
|
||||
|
||||
return nextFrame
|
||||
} else {
|
||||
if latestFrame.Timestamp > time.Now().UnixMilli()-120000 {
|
||||
if !e.IsInProverTrie(e.pubSub.GetPeerID()) {
|
||||
e.logger.Info("announcing prover join")
|
||||
for _, eng := range e.executionEngines {
|
||||
eng.AnnounceProverJoin()
|
||||
break
|
||||
}
|
||||
} else {
|
||||
if e.previousFrameProven != nil &&
|
||||
e.previousFrameProven.FrameNumber == latestFrame.FrameNumber {
|
||||
return latestFrame
|
||||
}
|
||||
|
||||
h, err := poseidon.HashBytes(e.pubSub.GetPeerID())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
peerProvingKeyAddress := h.FillBytes(make([]byte, 32))
|
||||
|
||||
ring := -1
|
||||
if tries := e.GetFrameProverTries(); len(tries) > 1 {
|
||||
for i, tries := range tries[1:] {
|
||||
i := i
|
||||
if tries.Contains(peerProvingKeyAddress) {
|
||||
ring = i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
e.clientReconnectTest++
|
||||
if e.clientReconnectTest >= 10 {
|
||||
e.tryReconnectDataWorkerClients()
|
||||
e.clientReconnectTest = 0
|
||||
}
|
||||
|
||||
previousTreeRoot := []byte{}
|
||||
if e.previousTree != nil {
|
||||
previousTreeRoot = e.previousTree.Root
|
||||
}
|
||||
outputs := e.PerformTimeProof(latestFrame, previousTreeRoot, latestFrame.Difficulty, ring)
|
||||
if outputs == nil || len(outputs) < 3 {
|
||||
e.logger.Info("workers not yet available for proving")
|
||||
return latestFrame
|
||||
}
|
||||
modulo := len(outputs)
|
||||
var proofTree *mt.MerkleTree
|
||||
var output [][]byte
|
||||
if latestFrame.FrameNumber >= application.PROOF_FRAME_COMBINE_CUTOFF {
|
||||
proofTree, output, err = tries.PackOutputIntoMultiPayloadAndProof(
|
||||
outputs,
|
||||
modulo,
|
||||
latestFrame,
|
||||
e.previousTree,
|
||||
)
|
||||
} else {
|
||||
proofTree, output, err = tries.PackOutputIntoPayloadAndProof(
|
||||
outputs,
|
||||
modulo,
|
||||
latestFrame,
|
||||
e.previousTree,
|
||||
)
|
||||
}
|
||||
if err != nil {
|
||||
e.logger.Error(
|
||||
"could not successfully pack proof, reattempting",
|
||||
zap.Error(err),
|
||||
)
|
||||
return latestFrame
|
||||
}
|
||||
e.previousFrameProven = latestFrame
|
||||
e.previousTree = proofTree
|
||||
|
||||
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(
|
||||
"submitting data proof",
|
||||
zap.Int("ring", ring),
|
||||
zap.Int("active_workers", len(outputs)),
|
||||
zap.Uint64("frame_number", latestFrame.FrameNumber),
|
||||
zap.Duration("frame_age", frametime.Since(latestFrame)),
|
||||
)
|
||||
|
||||
if err := e.publishMessage(e.txFilter, mint.TokenRequest()); err != nil {
|
||||
e.logger.Error("could not publish mint", zap.Error(err))
|
||||
}
|
||||
|
||||
if e.config.Engine.AutoMergeCoins {
|
||||
_, addrs, _, err := e.coinStore.GetCoinsForOwner(
|
||||
peerProvingKeyAddress,
|
||||
)
|
||||
if err != nil {
|
||||
e.logger.Error(
|
||||
"received error while iterating coins",
|
||||
zap.Error(err),
|
||||
)
|
||||
return latestFrame
|
||||
}
|
||||
|
||||
if len(addrs) > 25 {
|
||||
refs := []*protobufs.CoinRef{}
|
||||
for _, addr := range addrs {
|
||||
refs = append(refs, &protobufs.CoinRef{
|
||||
Address: addr,
|
||||
})
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
if err := e.publishMessage(e.txFilter, merge.TokenRequest()); err != nil {
|
||||
e.logger.Warn("could not publish merge", zap.Error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return latestFrame
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,6 +253,8 @@ func (e *DataClockConsensusEngine) handleClockFrame(
|
||||
}
|
||||
|
||||
if frame.FrameNumber > head.FrameNumber {
|
||||
go e.initiateProvers(frame)
|
||||
|
||||
if _, err := e.dataTimeReel.Insert(e.ctx, frame); err != nil {
|
||||
e.logger.Debug("could not insert frame", zap.Error(err))
|
||||
}
|
||||
|
||||
@ -109,7 +109,7 @@ func (p *prover) generateTransfer(coin []byte) *protobufs.TokenRequest {
|
||||
func (p *prover) generateSplit(addr []byte) *protobufs.TokenRequest {
|
||||
payload := []byte("split")
|
||||
payload = append(payload, addr...)
|
||||
bi1, _ := new(big.Int).SetString("2047999999999", 10)
|
||||
bi1, _ := new(big.Int).SetString("2048000000000", 10)
|
||||
bi2, _ := new(big.Int).SetString("2048000000000", 10)
|
||||
payload = append(payload, bi1.FillBytes(make([]byte, 32))...)
|
||||
payload = append(payload, bi2.FillBytes(make([]byte, 32))...)
|
||||
@ -174,6 +174,7 @@ func (p *prover) generateProof(
|
||||
proofTree *merkletree.MerkleTree,
|
||||
breakWesoProof bool,
|
||||
breakTreeProof bool,
|
||||
treeRecovery bool,
|
||||
) (*merkletree.MerkleTree, [][]byte, *protobufs.TokenRequest) {
|
||||
challenge := []byte{}
|
||||
challenge = append(challenge, []byte(p.peerId)...)
|
||||
@ -181,50 +182,32 @@ func (p *prover) generateProof(
|
||||
challenge,
|
||||
frame.FrameNumber,
|
||||
)
|
||||
individualChallenge := append([]byte{}, challenge...)
|
||||
individualChallenge = binary.BigEndian.AppendUint32(
|
||||
individualChallenge,
|
||||
uint32(0),
|
||||
)
|
||||
individualChallenge = append(individualChallenge, frame.Output...)
|
||||
if proofTree != nil {
|
||||
individualChallenge = append(individualChallenge, proofTree.Root...)
|
||||
}
|
||||
out1, _ := wprover.CalculateChallengeProof(individualChallenge, 10000)
|
||||
if breakWesoProof {
|
||||
out1[4] ^= 0xff
|
||||
}
|
||||
individualChallenge = append([]byte{}, challenge...)
|
||||
individualChallenge = binary.BigEndian.AppendUint32(
|
||||
individualChallenge,
|
||||
uint32(1),
|
||||
)
|
||||
individualChallenge = append(individualChallenge, frame.Output...)
|
||||
if proofTree != nil {
|
||||
individualChallenge = append(individualChallenge, proofTree.Root...)
|
||||
}
|
||||
out2, _ := wprover.CalculateChallengeProof(individualChallenge, 10000)
|
||||
if breakWesoProof {
|
||||
out2[4] ^= 0xff
|
||||
outs := []merkletree.DataBlock{}
|
||||
target := 8
|
||||
if treeRecovery {
|
||||
target = 4
|
||||
}
|
||||
for i := 0; i < target; i++ {
|
||||
individualChallenge := append([]byte{}, challenge...)
|
||||
individualChallenge = binary.BigEndian.AppendUint32(
|
||||
individualChallenge,
|
||||
uint32(i),
|
||||
)
|
||||
individualChallenge = append(individualChallenge, frame.Output...)
|
||||
if proofTree != nil {
|
||||
individualChallenge = append(individualChallenge, proofTree.Root...)
|
||||
}
|
||||
out, _ := wprover.CalculateChallengeProof(individualChallenge, 10000)
|
||||
if breakWesoProof {
|
||||
out[0] ^= 0xff
|
||||
}
|
||||
|
||||
individualChallenge = append([]byte{}, challenge...)
|
||||
individualChallenge = binary.BigEndian.AppendUint32(
|
||||
individualChallenge,
|
||||
uint32(2),
|
||||
)
|
||||
individualChallenge = append(individualChallenge, frame.Output...)
|
||||
if proofTree != nil {
|
||||
individualChallenge = append(individualChallenge, proofTree.Root...)
|
||||
}
|
||||
out3, _ := wprover.CalculateChallengeProof(individualChallenge, 10000)
|
||||
if breakWesoProof {
|
||||
out3[4] ^= 0xff
|
||||
outs = append(outs, tries.NewProofLeaf(out))
|
||||
}
|
||||
|
||||
proofTree, output, _ := tries.PackOutputIntoMultiPayloadAndProof(
|
||||
[]merkletree.DataBlock{tries.NewProofLeaf(out1), tries.NewProofLeaf(out2), tries.NewProofLeaf(out3)},
|
||||
3,
|
||||
outs,
|
||||
len(outs),
|
||||
frame,
|
||||
proofTree,
|
||||
)
|
||||
@ -237,7 +220,7 @@ func (p *prover) generateProof(
|
||||
}
|
||||
mint.SignED448([]byte(p.pubKey), p.privKey.Sign)
|
||||
|
||||
return proofTree, [][]byte{out1, out2}, &protobufs.TokenRequest{
|
||||
return proofTree, [][]byte{}, &protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Mint{
|
||||
Mint: mint,
|
||||
},
|
||||
@ -336,7 +319,7 @@ func TestHandleProverJoin(t *testing.T) {
|
||||
proofTrees := []*merkletree.MerkleTree{}
|
||||
reqs := []*protobufs.TokenRequest{}
|
||||
for _, prover := range provers {
|
||||
proofTree, _, req := prover.generateProof(frame2, wprover, nil, false, false)
|
||||
proofTree, _, req := prover.generateProof(frame2, wprover, nil, false, false, false)
|
||||
proofTrees = append(proofTrees, proofTree)
|
||||
reqs = append(reqs, req)
|
||||
}
|
||||
@ -386,7 +369,7 @@ func TestHandleProverJoin(t *testing.T) {
|
||||
txn.Commit()
|
||||
|
||||
for i, prover := range provers {
|
||||
proofTree, _, req := prover.generateProof(frame3, wprover, proofTrees[i], false, false)
|
||||
proofTree, _, req := prover.generateProof(frame3, wprover, proofTrees[i], false, false, true)
|
||||
proofTrees[i] = proofTree
|
||||
reqs[i] = req
|
||||
}
|
||||
@ -430,7 +413,7 @@ func TestHandleProverJoin(t *testing.T) {
|
||||
err = txn.Commit()
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, success.Requests, 1)
|
||||
assert.Len(t, app.TokenOutputs.Outputs, 3)
|
||||
assert.Len(t, app.TokenOutputs.Outputs, 2)
|
||||
|
||||
txn, _ = app.ClockStore.NewTransaction(false)
|
||||
frame4, _ := wprover.ProveDataClockFrame(frame3, [][]byte{}, []*protobufs.InclusionAggregateProof{}, bprivKey, time.Now().UnixMilli(), 10000)
|
||||
@ -440,7 +423,7 @@ func TestHandleProverJoin(t *testing.T) {
|
||||
txn.Commit()
|
||||
|
||||
for i, prover := range provers {
|
||||
proofTree, _, req := prover.generateProof(frame4, wprover, proofTrees[i], false, false)
|
||||
proofTree, _, req := prover.generateProof(frame4, wprover, proofTrees[i], false, false, true)
|
||||
proofTrees[i] = proofTree
|
||||
reqs[i] = req
|
||||
}
|
||||
|
||||
@ -59,12 +59,7 @@ func PackOutputIntoPayloadAndProof(
|
||||
binary.BigEndian.AppendUint64([]byte{}, frame.FrameNumber),
|
||||
}
|
||||
|
||||
if previousTree != nil {
|
||||
// don't let node produce invalid proofs that would otherwise fail
|
||||
if len(previousTree.Proofs) != modulo {
|
||||
return nil, nil, errors.Wrap(errors.New("invalid tree size"), "pack output into payload and proof")
|
||||
}
|
||||
|
||||
if previousTree != nil && len(previousTree.Proofs) == modulo {
|
||||
hash := sha3.Sum256(frame.Output)
|
||||
pick := BytesToUnbiasedMod(hash, uint64(modulo))
|
||||
if uint64(modulo) < pick {
|
||||
@ -119,12 +114,7 @@ func PackOutputIntoMultiPayloadAndProof(
|
||||
binary.BigEndian.AppendUint64([]byte{}, frame.FrameNumber),
|
||||
}
|
||||
|
||||
if previousTree != nil {
|
||||
// don't let node produce invalid proofs that would otherwise fail
|
||||
if len(previousTree.Proofs) != modulo {
|
||||
return nil, nil, errors.Wrap(errors.New("invalid tree size"), "pack output into payload and proof")
|
||||
}
|
||||
|
||||
if previousTree != nil && len(previousTree.Proofs) == modulo {
|
||||
hash := sha3.Sum256(append(append([]byte{}, frame.Output...), previousTree.Root...))
|
||||
pick := BytesToUnbiasedMod(hash, uint64(modulo))
|
||||
if uint64(modulo) < pick {
|
||||
|
||||
@ -298,3 +298,51 @@ func TestPackAndVerifyMultiOutput(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPackAndVerifyOutputFailover(t *testing.T) {
|
||||
outputs := make([]mt.DataBlock, 3)
|
||||
for i := range outputs {
|
||||
data := make([]byte, 32)
|
||||
binary.BigEndian.PutUint32(data, uint32(i))
|
||||
outputs[i] = tries.NewProofLeaf(data)
|
||||
}
|
||||
|
||||
frame := &protobufs.ClockFrame{
|
||||
FrameNumber: 1,
|
||||
Output: make([]byte, 516),
|
||||
}
|
||||
rand.Read(frame.Output)
|
||||
|
||||
var previousTree *mt.MerkleTree
|
||||
prevOutputs := make([]mt.DataBlock, 4)
|
||||
for i := range prevOutputs {
|
||||
data := make([]byte, 32)
|
||||
binary.BigEndian.PutUint32(data, uint32(i))
|
||||
prevOutputs[i] = tries.NewProofLeaf(data)
|
||||
}
|
||||
|
||||
var err error
|
||||
previousTree, err = mt.New(
|
||||
&mt.Config{
|
||||
HashFunc: func(data []byte) ([]byte, error) {
|
||||
hash := sha3.Sum256(data)
|
||||
return hash[:], nil
|
||||
},
|
||||
Mode: mt.ModeProofGen,
|
||||
DisableLeafHashing: true,
|
||||
},
|
||||
prevOutputs,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
tree, output, err := tries.PackOutputIntoMultiPayloadAndProof(
|
||||
outputs,
|
||||
3,
|
||||
frame,
|
||||
previousTree,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, tree)
|
||||
require.NotEmpty(t, output)
|
||||
require.Len(t, output, 3)
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MEMwBQYDK2VxAzoARQdib3Fk59jDBMB/+NLiPBE/4QiyIdLmBnL00HdQNFgV4rSz
|
||||
zD3000Zr8vZpw1wxcuBlEScGEqsA
|
||||
MEMwBQYDK2VxAzoAtt8OurbqIMwutxjbWHPAe7UM8jmha7Ywa74PJCgGZPmfcyxA
|
||||
SbjtoSJgZ+cP+4GViDTUhpQqEiEA
|
||||
-----END PUBLIC KEY-----
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MEMwBQYDK2VxAzoAT7JTc0Xka+PV+WNAwUQQB1AXAt1b+vbb9pQ7vvzsqPsrlOwK
|
||||
ihovSYUPvh0QJEiJpPQKv6ngyeAA
|
||||
MEMwBQYDK2VxAzoAPgh3ccNgmMstNxcR/YgtMJtMrrvQbe0wd6l1IxNE8CetMccG
|
||||
nna6UHBFHY61q/Kb/rNPzfm6kGSA
|
||||
-----END PUBLIC KEY-----
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MEMwBQYDK2VxAzoAVUevxxsCgh4vW/3TD74TdMOFOJje/yChtcxym46BZw+7udHp
|
||||
F/hdFT6ksmu/b5xUbcG2S5kWYI2A
|
||||
MEMwBQYDK2VxAzoAmrdtd1SHyFyOWqDFs/lhdylniZoUZEZRAxrl+YrBl77j+IgE
|
||||
ksT9uiaHFvxLfDj/ysNwtmOsELYA
|
||||
-----END PUBLIC KEY-----
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MEMwBQYDK2VxAzoAoRSwYfjTXj80l8jEPYO6a0r2eqezm3Q7Gwo18tZhELUFHdPY
|
||||
b2m1cSKjW2TmJLgYC+5jthUvzkKA
|
||||
MEMwBQYDK2VxAzoADKb1qdf4bBERvl7fMeJpeZGKpPo9qubeESDgXCoJvbjS/usI
|
||||
QoajNH4GztJVMDWMvHTCBNKhdToA
|
||||
-----END PUBLIC KEY-----
|
||||
|
||||
Loading…
Reference in New Issue
Block a user