mirror of
https://github.com/QuilibriumNetwork/ceremonyclient.git
synced 2026-02-21 10:27:26 +08:00
v2.0.3-p0
This commit is contained in:
parent
05f1bf94fe
commit
77c036b94b
@ -202,6 +202,7 @@ func (e *DataClockConsensusEngine) prove(
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "prove")
|
||||
}
|
||||
|
||||
e.lastProven = previousFrame.FrameNumber
|
||||
e.logger.Info(
|
||||
"returning new proven frame",
|
||||
@ -233,12 +234,6 @@ func (e *DataClockConsensusEngine) GetMostAheadPeer(
|
||||
max := frameNumber
|
||||
var peer []byte = nil
|
||||
e.peerMapMx.RLock()
|
||||
beaconInfo, ok := e.peerMap[string(e.beaconPeerId)]
|
||||
if !ok {
|
||||
e.peerMapMx.RUnlock()
|
||||
return nil, 0, p2p.ErrNoPeersAvailable
|
||||
}
|
||||
|
||||
for _, v := range e.peerMap {
|
||||
e.logger.Debug(
|
||||
"checking peer info",
|
||||
@ -248,7 +243,7 @@ func (e *DataClockConsensusEngine) GetMostAheadPeer(
|
||||
zap.Binary("version", v.version),
|
||||
)
|
||||
_, ok := e.uncooperativePeersMap[string(v.peerId)]
|
||||
if v.maxFrame <= beaconInfo.maxFrame && v.maxFrame > max &&
|
||||
if v.maxFrame > max &&
|
||||
v.timestamp > config.GetMinimumVersionCutoff().UnixMilli() &&
|
||||
bytes.Compare(v.version, config.GetMinimumVersion()) >= 0 && !ok {
|
||||
peer = v.peerId
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto"
|
||||
"encoding/binary"
|
||||
@ -11,8 +10,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/iden3/go-iden3-crypto/poseidon"
|
||||
pcrypto "github.com/libp2p/go-libp2p/core/crypto"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/p2p/discovery/backoff"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
mn "github.com/multiformats/go-multiaddr/net"
|
||||
@ -98,7 +95,6 @@ type DataClockConsensusEngine struct {
|
||||
currentReceivingSyncPeersMx sync.Mutex
|
||||
currentReceivingSyncPeers int
|
||||
announcedJoin int
|
||||
beaconPeerId []byte
|
||||
|
||||
frameChan chan *protobufs.ClockFrame
|
||||
executionEngines map[string]execution.ExecutionEngine
|
||||
@ -198,17 +194,6 @@ func NewDataClockConsensusEngine(
|
||||
panic(errors.New("peer info manager is nil"))
|
||||
}
|
||||
|
||||
genesis := config.GetGenesis()
|
||||
beaconPubKey, err := pcrypto.UnmarshalEd448PublicKey(genesis.Beacon)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
beaconPeerId, err := peer.IDFromPublicKey(beaconPubKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
minimumPeersRequired := cfg.Engine.MinimumPeersRequired
|
||||
if minimumPeersRequired == 0 {
|
||||
minimumPeersRequired = 3
|
||||
@ -256,7 +241,6 @@ func NewDataClockConsensusEngine(
|
||||
infoMessageProcessorCh: make(chan *pb.Message),
|
||||
config: cfg,
|
||||
preMidnightMint: map[string]struct{}{},
|
||||
beaconPeerId: []byte(beaconPeerId),
|
||||
}
|
||||
|
||||
logger.Info("constructing consensus engine")
|
||||
@ -396,20 +380,6 @@ func (e *DataClockConsensusEngine) Start() <-chan error {
|
||||
continue
|
||||
}
|
||||
|
||||
e.peerMapMx.RLock()
|
||||
beaconInfo, ok := e.peerMap[string(e.beaconPeerId)]
|
||||
if !ok {
|
||||
e.peerMapMx.RUnlock()
|
||||
time.Sleep(120 * time.Second)
|
||||
continue
|
||||
}
|
||||
e.peerMapMx.RUnlock()
|
||||
|
||||
if nextFrame.FrameNumber < beaconInfo.maxFrame-100 {
|
||||
time.Sleep(120 * time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
frame = nextFrame
|
||||
|
||||
timestamp := time.Now().UnixMilli()
|
||||
@ -1135,29 +1105,3 @@ func (e *DataClockConsensusEngine) createParallelDataClientsFromBaseMultiaddr(
|
||||
)
|
||||
return clients, nil
|
||||
}
|
||||
|
||||
func (e *DataClockConsensusEngine) announceProverJoin() {
|
||||
msg := []byte("join")
|
||||
head, _ := e.dataTimeReel.Head()
|
||||
msg = binary.BigEndian.AppendUint64(msg, head.FrameNumber)
|
||||
msg = append(msg, bytes.Repeat([]byte{0xff}, 32)...)
|
||||
sig, err := e.pubSub.SignMessage(msg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
e.publishMessage(e.txFilter, &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(),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@ -83,8 +83,7 @@ func (e *DataClockConsensusEngine) processFrame(
|
||||
}
|
||||
}
|
||||
|
||||
if latestFrame != nil &&
|
||||
dataFrame.FrameNumber > latestFrame.FrameNumber {
|
||||
if latestFrame != nil && dataFrame.FrameNumber > latestFrame.FrameNumber {
|
||||
latestFrame = dataFrame
|
||||
}
|
||||
|
||||
@ -131,7 +130,11 @@ func (e *DataClockConsensusEngine) processFrame(
|
||||
if !e.IsInProverTrie(e.pubSub.GetPeerID()) &&
|
||||
dataFrame.Timestamp > time.Now().UnixMilli()-30000 {
|
||||
e.logger.Info("announcing prover join")
|
||||
e.announceProverJoin()
|
||||
for _, eng := range e.executionEngines {
|
||||
eng.AnnounceProverMerge()
|
||||
eng.AnnounceProverJoin()
|
||||
break
|
||||
}
|
||||
}
|
||||
return latestFrame
|
||||
}
|
||||
|
||||
@ -19,4 +19,6 @@ type ExecutionEngine interface {
|
||||
GetFrame() *protobufs.ClockFrame
|
||||
GetSeniority() *big.Int
|
||||
GetRingPosition() int
|
||||
AnnounceProverMerge()
|
||||
AnnounceProverJoin()
|
||||
}
|
||||
|
||||
@ -139,6 +139,41 @@ func (a *TokenApplication) ApplyTransitions(
|
||||
requests = transitions.Requests
|
||||
}
|
||||
|
||||
parallelismMap := map[int]uint64{}
|
||||
for i := range a.Tries[1:] {
|
||||
parallelismMap[i] = 0
|
||||
}
|
||||
|
||||
seen := map[string]struct{}{}
|
||||
|
||||
for _, transition := range requests {
|
||||
switch t := transition.Request.(type) {
|
||||
case *protobufs.TokenRequest_Mint:
|
||||
ring, parallelism, err := t.Mint.RingAndParallelism(
|
||||
func(addr []byte) int {
|
||||
if _, ok := seen[string(addr)]; ok {
|
||||
return -1
|
||||
}
|
||||
|
||||
ring := -1
|
||||
for i, t := range a.Tries[1:] {
|
||||
if t.Contains(addr) {
|
||||
ring = i
|
||||
seen[string(addr)] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
return ring
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
parallelismMap[ring] = parallelismMap[ring] + uint64(parallelism)
|
||||
}
|
||||
}
|
||||
|
||||
for _, transition := range requests {
|
||||
req:
|
||||
switch t := transition.Request.(type) {
|
||||
@ -319,7 +354,13 @@ func (a *TokenApplication) ApplyTransitions(
|
||||
transition,
|
||||
)
|
||||
case *protobufs.TokenRequest_Mint:
|
||||
success, err := a.handleMint(currentFrameNumber, lockMap, t.Mint, frame)
|
||||
success, err := a.handleMint(
|
||||
currentFrameNumber,
|
||||
lockMap,
|
||||
t.Mint,
|
||||
frame,
|
||||
parallelismMap,
|
||||
)
|
||||
if err != nil {
|
||||
if !skipFailures {
|
||||
return nil, nil, nil, errors.Wrap(
|
||||
|
||||
@ -18,11 +18,14 @@ import (
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/tries"
|
||||
)
|
||||
|
||||
const PROOF_FRAME_CUTOFF = 46500
|
||||
|
||||
func (a *TokenApplication) handleMint(
|
||||
currentFrameNumber uint64,
|
||||
lockMap map[string]struct{},
|
||||
t *protobufs.MintCoinRequest,
|
||||
frame *protobufs.ClockFrame,
|
||||
parallelismMap map[int]uint64,
|
||||
) ([]*protobufs.TokenOutput, error) {
|
||||
if t == nil || t.Proofs == nil || t.Signature == nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle mint")
|
||||
@ -119,7 +122,7 @@ func (a *TokenApplication) handleMint(
|
||||
},
|
||||
}
|
||||
return outputs, nil
|
||||
} else if len(t.Proofs) > 0 && currentFrameNumber > 0 {
|
||||
} else if len(t.Proofs) > 0 && currentFrameNumber > PROOF_FRAME_CUTOFF {
|
||||
a.Logger.Debug(
|
||||
"got mint from peer",
|
||||
zap.String("peer_id", base58.Encode([]byte(peerId))),
|
||||
@ -134,7 +137,6 @@ func (a *TokenApplication) handleMint(
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle mint")
|
||||
}
|
||||
ring := -1
|
||||
proverSet := int64((len(a.Tries) - 1) * 1024)
|
||||
for i, t := range a.Tries[1:] {
|
||||
if t.Contains(altAddr.FillBytes(make([]byte, 32))) {
|
||||
ring = i
|
||||
@ -232,8 +234,12 @@ func (a *TokenApplication) handleMint(
|
||||
)
|
||||
}
|
||||
|
||||
// Current frame - 2 is because the current frame is the newly created frame,
|
||||
// and the provers are submitting proofs on the frame preceding the one they
|
||||
// last saw. This enforces liveness and creates a punishment for being
|
||||
// late.
|
||||
if (previousFrame != nil && newFrameNumber <= previousFrame.FrameNumber) ||
|
||||
newFrameNumber < currentFrameNumber-10 {
|
||||
newFrameNumber < currentFrameNumber-2 {
|
||||
previousFrameNumber := uint64(0)
|
||||
if previousFrame != nil {
|
||||
previousFrameNumber = previousFrame.FrameNumber
|
||||
@ -349,15 +355,9 @@ func (a *TokenApplication) handleMint(
|
||||
)
|
||||
}
|
||||
if verified && delete != nil && len(t.Proofs) > 3 {
|
||||
ringFactor := big.NewInt(2)
|
||||
ringFactor.Exp(ringFactor, big.NewInt(int64(ring)), nil)
|
||||
|
||||
// const for testnet
|
||||
storage := big.NewInt(int64(256 * parallelism))
|
||||
unitFactor := big.NewInt(8000000000)
|
||||
storage.Mul(storage, unitFactor)
|
||||
storage.Quo(storage, big.NewInt(proverSet))
|
||||
storage.Quo(storage, ringFactor)
|
||||
storage := PomwBasis(1, ring, currentFrameNumber)
|
||||
storage.Quo(storage, big.NewInt(int64(parallelismMap[ring])))
|
||||
storage.Mul(storage, big.NewInt(int64(parallelism)))
|
||||
|
||||
a.Logger.Debug(
|
||||
"issued reward",
|
||||
@ -458,3 +458,52 @@ func (a *TokenApplication) handleMint(
|
||||
)
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle mint")
|
||||
}
|
||||
|
||||
func PomwBasis(generation uint64, ring int, currentFrameNumber uint64) *big.Int {
|
||||
prec := uint(53)
|
||||
|
||||
one := new(big.Float).SetPrec(prec).SetInt64(1)
|
||||
divisor := new(big.Float).SetPrec(prec).SetInt64(1048576)
|
||||
|
||||
normalized := new(big.Float).SetPrec(prec)
|
||||
// A simple hack for estimating state growth in terms of frames, based on
|
||||
// linear relationship of state growth:
|
||||
normalized.SetInt64(int64((737280 + currentFrameNumber) / 184320))
|
||||
normalized.Quo(normalized, divisor)
|
||||
|
||||
// 1/2^n
|
||||
exp := new(big.Float).SetPrec(prec).SetInt64(1)
|
||||
if generation > 0 {
|
||||
powerOfTwo := new(big.Float).SetPrec(prec).SetInt64(2)
|
||||
powerOfTwo.SetInt64(1)
|
||||
for i := uint64(0); i < generation; i++ {
|
||||
powerOfTwo.Mul(powerOfTwo, big.NewFloat(2))
|
||||
}
|
||||
exp.Quo(one, powerOfTwo)
|
||||
}
|
||||
|
||||
// (d/1048576)^(1/2^n)
|
||||
result := new(big.Float).Copy(normalized)
|
||||
if generation > 0 {
|
||||
for i := uint64(0); i < generation; i++ {
|
||||
result.Sqrt(result)
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate 1/result
|
||||
result.Quo(one, result)
|
||||
|
||||
// Divide by 2^s
|
||||
if ring > 0 {
|
||||
divisor := new(big.Float).SetPrec(prec).SetInt64(1)
|
||||
for i := 0; i < ring; i++ {
|
||||
divisor.Mul(divisor, big.NewFloat(2))
|
||||
}
|
||||
result.Quo(result, divisor)
|
||||
}
|
||||
|
||||
result.Mul(result, new(big.Float).SetPrec(prec).SetInt64(8000000000))
|
||||
|
||||
out, _ := result.Int(new(big.Int))
|
||||
return out
|
||||
}
|
||||
|
||||
@ -16,7 +16,8 @@ func (a *TokenApplication) handleAnnounce(
|
||||
var primary *protobufs.Ed448Signature
|
||||
payload := []byte{}
|
||||
|
||||
if t == nil || t.PublicKeySignaturesEd448 == nil {
|
||||
if t == nil || t.PublicKeySignaturesEd448 == nil ||
|
||||
len(t.PublicKeySignaturesEd448) == 0 {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle announce")
|
||||
}
|
||||
for i, p := range t.PublicKeySignaturesEd448 {
|
||||
@ -44,11 +45,18 @@ func (a *TokenApplication) handleAnnounce(
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle announce")
|
||||
}
|
||||
|
||||
for _, p := range t.PublicKeySignaturesEd448 {
|
||||
for _, p := range t.PublicKeySignaturesEd448[1:] {
|
||||
lockMap[string(p.PublicKey.KeyValue)] = struct{}{}
|
||||
}
|
||||
|
||||
outputs := []*protobufs.TokenOutput{}
|
||||
if currentFrameNumber >= PROOF_FRAME_CUTOFF {
|
||||
outputs = append(outputs, &protobufs.TokenOutput{
|
||||
Output: &protobufs.TokenOutput_Announce{
|
||||
Announce: t,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return outputs, nil
|
||||
}
|
||||
|
||||
@ -46,6 +46,10 @@ func (a *TokenApplication) handleDataAnnounceProverJoin(
|
||||
[]*protobufs.TokenOutput,
|
||||
error,
|
||||
) {
|
||||
if currentFrameNumber < PROOF_FRAME_CUTOFF {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle join")
|
||||
}
|
||||
|
||||
payload := []byte("join")
|
||||
|
||||
if t == nil || t.PublicKeySignatureEd448 == nil {
|
||||
|
||||
@ -176,12 +176,13 @@ func TestHandleProverJoin(t *testing.T) {
|
||||
fmt.Printf("%x\n", individualChallenge)
|
||||
out2, _ := wprover.CalculateChallengeProof(individualChallenge, 10000)
|
||||
|
||||
proofTree, payload, output := tries.PackOutputIntoPayloadAndProof(
|
||||
proofTree, payload, output, err := tries.PackOutputIntoPayloadAndProof(
|
||||
[]merkletree.DataBlock{tries.NewProofLeaf(out1), tries.NewProofLeaf(out2)},
|
||||
2,
|
||||
frame2,
|
||||
nil,
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
|
||||
sig, _ = privKey.Sign(payload)
|
||||
app, success, _, err = app.ApplyTransitions(2, &protobufs.TokenRequests{
|
||||
@ -240,12 +241,13 @@ 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 = tries.PackOutputIntoPayloadAndProof(
|
||||
proofTree, payload, output, err = tries.PackOutputIntoPayloadAndProof(
|
||||
[]merkletree.DataBlock{tries.NewProofLeaf(out1), tries.NewProofLeaf(out2)},
|
||||
2,
|
||||
frame3,
|
||||
proofTree,
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
|
||||
sig, _ = privKey.Sign(payload)
|
||||
app, success, _, err = app.ApplyTransitions(3, &protobufs.TokenRequests{
|
||||
|
||||
@ -15,6 +15,10 @@ func (a *TokenApplication) handleDataAnnounceProverLeave(
|
||||
[]*protobufs.TokenOutput,
|
||||
error,
|
||||
) {
|
||||
if currentFrameNumber < PROOF_FRAME_CUTOFF {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle leave")
|
||||
}
|
||||
|
||||
payload := []byte("leave")
|
||||
|
||||
if t == nil || t.PublicKeySignatureEd448 == nil {
|
||||
|
||||
@ -15,6 +15,10 @@ func (a *TokenApplication) handleDataAnnounceProverPause(
|
||||
[]*protobufs.TokenOutput,
|
||||
error,
|
||||
) {
|
||||
if currentFrameNumber < PROOF_FRAME_CUTOFF {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle pause")
|
||||
}
|
||||
|
||||
payload := []byte("pause")
|
||||
|
||||
if t == nil || t.PublicKeySignatureEd448 == nil {
|
||||
|
||||
@ -15,6 +15,10 @@ func (a *TokenApplication) handleDataAnnounceProverResume(
|
||||
[]*protobufs.TokenOutput,
|
||||
error,
|
||||
) {
|
||||
if currentFrameNumber < PROOF_FRAME_CUTOFF {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle resume")
|
||||
}
|
||||
|
||||
payload := []byte("resume")
|
||||
|
||||
if t == nil || t.PublicKeySignatureEd448 == nil {
|
||||
|
||||
@ -7,6 +7,7 @@ import (
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
gotime "time"
|
||||
@ -32,17 +33,24 @@ import (
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/tries"
|
||||
)
|
||||
|
||||
type peerSeniorityItem struct {
|
||||
type PeerSeniorityItem struct {
|
||||
seniority uint64
|
||||
addr string
|
||||
}
|
||||
|
||||
type peerSeniority map[string]peerSeniorityItem
|
||||
func NewPeerSeniorityItem(seniority uint64, addr string) PeerSeniorityItem {
|
||||
return PeerSeniorityItem{
|
||||
seniority: seniority,
|
||||
addr: addr,
|
||||
}
|
||||
}
|
||||
|
||||
func newFromMap(m map[string]uint64) *peerSeniority {
|
||||
s := &peerSeniority{}
|
||||
type PeerSeniority map[string]PeerSeniorityItem
|
||||
|
||||
func newFromMap(m map[string]uint64) *PeerSeniority {
|
||||
s := &PeerSeniority{}
|
||||
for k, v := range m {
|
||||
(*s)[k] = peerSeniorityItem{
|
||||
(*s)[k] = PeerSeniorityItem{
|
||||
seniority: v,
|
||||
addr: k,
|
||||
}
|
||||
@ -50,7 +58,7 @@ func newFromMap(m map[string]uint64) *peerSeniority {
|
||||
return s
|
||||
}
|
||||
|
||||
func toSerializedMap(m *peerSeniority) map[string]uint64 {
|
||||
func toSerializedMap(m *PeerSeniority) map[string]uint64 {
|
||||
s := map[string]uint64{}
|
||||
for k, v := range *m {
|
||||
s[k] = v.seniority
|
||||
@ -58,7 +66,7 @@ func toSerializedMap(m *peerSeniority) map[string]uint64 {
|
||||
return s
|
||||
}
|
||||
|
||||
func (p peerSeniorityItem) Priority() *big.Int {
|
||||
func (p PeerSeniorityItem) Priority() *big.Int {
|
||||
return big.NewInt(int64(p.seniority))
|
||||
}
|
||||
|
||||
@ -82,7 +90,7 @@ type TokenExecutionEngine struct {
|
||||
alreadyPublishedShare bool
|
||||
intrinsicFilter []byte
|
||||
frameProver qcrypto.FrameProver
|
||||
peerSeniority *peerSeniority
|
||||
peerSeniority *PeerSeniority
|
||||
}
|
||||
|
||||
func NewTokenExecutionEngine(
|
||||
@ -116,7 +124,6 @@ func NewTokenExecutionEngine(
|
||||
var inclusionProof *qcrypto.InclusionAggregateProof
|
||||
var proverKeys [][]byte
|
||||
var peerSeniority map[string]uint64
|
||||
genesisCreated := false
|
||||
|
||||
if err != nil && errors.Is(err, store.ErrNotFound) {
|
||||
origin, inclusionProof, proverKeys, peerSeniority = CreateGenesisState(
|
||||
@ -133,7 +140,6 @@ func NewTokenExecutionEngine(
|
||||
); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
genesisCreated = true
|
||||
} else if err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
@ -155,7 +161,6 @@ func NewTokenExecutionEngine(
|
||||
coinStore,
|
||||
uint(cfg.P2P.Network),
|
||||
)
|
||||
genesisCreated = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,8 +170,29 @@ func NewTokenExecutionEngine(
|
||||
panic(err)
|
||||
}
|
||||
if peerSeniority == nil {
|
||||
RebuildPeerSeniority(clockStore)
|
||||
peerSeniority, err = RebuildPeerSeniority(uint(cfg.P2P.Network))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
txn, err := clockStore.NewTransaction()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = clockStore.PutPeerSeniorityMap(txn, intrinsicFilter, peerSeniority)
|
||||
if err != nil {
|
||||
txn.Abort()
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err = txn.Commit(); err != nil {
|
||||
txn.Abort()
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LoadAggregatedSeniorityMap()
|
||||
}
|
||||
|
||||
e := &TokenExecutionEngine{
|
||||
@ -251,126 +277,26 @@ func NewTokenExecutionEngine(
|
||||
e.proverPublicKey = publicKeyBytes
|
||||
e.provingKeyAddress = provingKeyAddress
|
||||
|
||||
if genesisCreated {
|
||||
go func() {
|
||||
keys := [][]byte{}
|
||||
ksigs := [][]byte{}
|
||||
if len(e.engineConfig.MultisigProverEnrollmentPaths) != 0 {
|
||||
for _, conf := range e.engineConfig.MultisigProverEnrollmentPaths {
|
||||
extraConf, err := config.LoadConfig(conf, "", false)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
peerPrivKey, err := hex.DecodeString(extraConf.P2P.PeerPrivKey)
|
||||
if err != nil {
|
||||
panic(errors.Wrap(err, "error unmarshaling peerkey"))
|
||||
}
|
||||
|
||||
privKey, err := pcrypto.UnmarshalEd448PrivateKey(peerPrivKey)
|
||||
if err != nil {
|
||||
panic(errors.Wrap(err, "error unmarshaling peerkey"))
|
||||
}
|
||||
|
||||
pub := privKey.GetPublic()
|
||||
pubBytes, err := pub.Raw()
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
keyjoin := []byte{}
|
||||
for _, k := range keys {
|
||||
keyjoin = append(keyjoin, k...)
|
||||
}
|
||||
|
||||
mainsig, err := e.pubSub.SignMessage(keyjoin)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
announce := &protobufs.TokenRequest_Announce{
|
||||
Announce: &protobufs.AnnounceProverRequest{
|
||||
PublicKeySignaturesEd448: []*protobufs.Ed448Signature{},
|
||||
},
|
||||
}
|
||||
|
||||
announce.Announce.PublicKeySignaturesEd448 = append(
|
||||
announce.Announce.PublicKeySignaturesEd448,
|
||||
&protobufs.Ed448Signature{
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: e.pubSub.GetPublicKey(),
|
||||
},
|
||||
Signature: mainsig,
|
||||
},
|
||||
)
|
||||
|
||||
for i := range keys {
|
||||
announce.Announce.PublicKeySignaturesEd448 = append(
|
||||
announce.Announce.PublicKeySignaturesEd448,
|
||||
&protobufs.Ed448Signature{
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: keys[i],
|
||||
},
|
||||
Signature: ksigs[i],
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
req := &protobufs.TokenRequest{
|
||||
Request: announce,
|
||||
}
|
||||
|
||||
// need to wait for peering
|
||||
gotime.Sleep(30 * gotime.Second)
|
||||
e.publishMessage(append([]byte{0x00}, intrinsicFilter...), req)
|
||||
}()
|
||||
} else {
|
||||
go func() {
|
||||
f, tries, err := e.clockStore.GetLatestDataClockFrame(e.intrinsicFilter)
|
||||
fn, err := coinStore.GetLatestFrameProcessed()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return
|
||||
}
|
||||
|
||||
if f.FrameNumber != fn && fn == 0 {
|
||||
txn, err := coinStore.NewTransaction()
|
||||
shouldResume := false
|
||||
for _, trie := range tries[1:] {
|
||||
altAddr, err := poseidon.HashBytes(e.pubSub.GetPeerID())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
break
|
||||
}
|
||||
|
||||
err = coinStore.SetLatestFrameProcessed(txn, f.FrameNumber)
|
||||
if err != nil {
|
||||
txn.Abort()
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err = txn.Commit(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else if f.FrameNumber-fn == 1 && f.FrameNumber > fn {
|
||||
txn, err := coinStore.NewTransaction()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
e.logger.Info(
|
||||
"replaying last data frame",
|
||||
zap.Uint64("frame_number", f.FrameNumber),
|
||||
)
|
||||
e.ProcessFrame(txn, f, tries)
|
||||
if err = txn.Commit(); err != nil {
|
||||
panic(err)
|
||||
if trie.Contains(altAddr.FillBytes(make([]byte, 32))) {
|
||||
shouldResume = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
if shouldResume {
|
||||
msg := []byte("resume")
|
||||
msg = binary.BigEndian.AppendUint64(msg, f.FrameNumber)
|
||||
msg = append(msg, e.intrinsicFilter...)
|
||||
@ -380,7 +306,17 @@ func NewTokenExecutionEngine(
|
||||
}
|
||||
|
||||
// need to wait for peering
|
||||
gotime.Sleep(30 * gotime.Second)
|
||||
for {
|
||||
gotime.Sleep(30 * gotime.Second)
|
||||
peerMap := e.pubSub.GetBitmaskPeers()
|
||||
if peers, ok := peerMap[string(
|
||||
append([]byte{0x00}, e.intrinsicFilter...),
|
||||
)]; ok {
|
||||
if len(peers) >= 3 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
e.publishMessage(
|
||||
append([]byte{0x00}, e.intrinsicFilter...),
|
||||
&protobufs.TokenRequest{
|
||||
@ -399,7 +335,7 @@ func NewTokenExecutionEngine(
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return e
|
||||
}
|
||||
@ -591,17 +527,23 @@ func (e *TokenExecutionEngine) ProcessFrame(
|
||||
txn.Abort()
|
||||
return nil, errors.Wrap(err, "process frame")
|
||||
}
|
||||
// testnet:
|
||||
if len(o.Proof.Amount) == 32 &&
|
||||
!bytes.Equal(o.Proof.Amount, make([]byte, 32)) {
|
||||
!bytes.Equal(o.Proof.Amount, make([]byte, 32)) &&
|
||||
o.Proof.Commitment != nil {
|
||||
addr := string(o.Proof.Owner.GetImplicitAccount().Address)
|
||||
for _, t := range app.Tries {
|
||||
if t.Contains([]byte(addr)) {
|
||||
t.Add([]byte(addr), frame.FrameNumber)
|
||||
break
|
||||
}
|
||||
}
|
||||
if _, ok := (*e.peerSeniority)[addr]; !ok {
|
||||
(*e.peerSeniority)[addr] = peerSeniorityItem{
|
||||
(*e.peerSeniority)[addr] = PeerSeniorityItem{
|
||||
seniority: 10,
|
||||
addr: addr,
|
||||
}
|
||||
} else {
|
||||
(*e.peerSeniority)[addr] = peerSeniorityItem{
|
||||
(*e.peerSeniority)[addr] = PeerSeniorityItem{
|
||||
seniority: (*e.peerSeniority)[addr].seniority + 10,
|
||||
addr: addr,
|
||||
}
|
||||
@ -622,6 +564,96 @@ func (e *TokenExecutionEngine) ProcessFrame(
|
||||
txn.Abort()
|
||||
return nil, errors.Wrap(err, "process frame")
|
||||
}
|
||||
case *protobufs.TokenOutput_Announce:
|
||||
peerIds := []string{}
|
||||
for _, sig := range o.Announce.PublicKeySignaturesEd448 {
|
||||
peerId, err := e.getPeerIdFromSignature(sig)
|
||||
if err != nil {
|
||||
txn.Abort()
|
||||
return nil, errors.Wrap(err, "process frame")
|
||||
}
|
||||
|
||||
peerIds = append(peerIds, peerId.String())
|
||||
}
|
||||
|
||||
mergeable := true
|
||||
for i, peerId := range peerIds {
|
||||
addr, err := e.getAddressFromSignature(
|
||||
o.Announce.PublicKeySignaturesEd448[i],
|
||||
)
|
||||
if err != nil {
|
||||
txn.Abort()
|
||||
return nil, errors.Wrap(err, "process frame")
|
||||
}
|
||||
|
||||
sen, ok := (*e.peerSeniority)[string(addr)]
|
||||
if !ok {
|
||||
e.logger.Debug(
|
||||
"peer announced with no seniority",
|
||||
zap.String("peer_id", peerId),
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
peer := new(big.Int).SetUint64(sen.seniority)
|
||||
if peer.Cmp(e.GetAggregatedSeniority([]string{peerId})) != 0 {
|
||||
e.logger.Debug(
|
||||
"peer announced but is already different seniority",
|
||||
zap.String("peer_id", peerIds[0]),
|
||||
)
|
||||
mergeable = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if mergeable {
|
||||
addr, err := e.getAddressFromSignature(
|
||||
o.Announce.PublicKeySignaturesEd448[0],
|
||||
)
|
||||
if err != nil {
|
||||
txn.Abort()
|
||||
return nil, errors.Wrap(err, "process frame")
|
||||
}
|
||||
|
||||
additional := uint64(0)
|
||||
_, prfs, err := e.coinStore.GetPreCoinProofsForOwner(addr)
|
||||
if err != nil && !errors.Is(err, store.ErrNotFound) {
|
||||
txn.Abort()
|
||||
return nil, errors.Wrap(err, "process frame")
|
||||
}
|
||||
|
||||
for _, pr := range prfs {
|
||||
if pr.IndexProof == nil && pr.Difficulty == 0 && pr.Commitment == nil {
|
||||
// approximate average per interval:
|
||||
add := new(big.Int).SetBytes(pr.Amount)
|
||||
add.Quo(add, big.NewInt(58800000))
|
||||
if add.Cmp(big.NewInt(4000000)) > 0 {
|
||||
add = big.NewInt(4000000)
|
||||
}
|
||||
additional = add.Uint64()
|
||||
}
|
||||
}
|
||||
|
||||
(*e.peerSeniority)[string(addr)] = PeerSeniorityItem{
|
||||
seniority: e.GetAggregatedSeniority(peerIds).Uint64() + additional,
|
||||
addr: string(addr),
|
||||
}
|
||||
|
||||
for _, sig := range o.Announce.PublicKeySignaturesEd448[1:] {
|
||||
addr, err := e.getAddressFromSignature(
|
||||
sig,
|
||||
)
|
||||
if err != nil {
|
||||
txn.Abort()
|
||||
return nil, errors.Wrap(err, "process frame")
|
||||
}
|
||||
|
||||
(*e.peerSeniority)[string(addr)] = PeerSeniorityItem{
|
||||
seniority: 0,
|
||||
addr: string(addr),
|
||||
}
|
||||
}
|
||||
}
|
||||
case *protobufs.TokenOutput_Join:
|
||||
addr, err := e.getAddressFromSignature(o.Join.PublicKeySignatureEd448)
|
||||
if err != nil {
|
||||
@ -629,12 +661,12 @@ func (e *TokenExecutionEngine) ProcessFrame(
|
||||
return nil, errors.Wrap(err, "process frame")
|
||||
}
|
||||
if _, ok := (*e.peerSeniority)[string(addr)]; !ok {
|
||||
(*e.peerSeniority)[string(addr)] = peerSeniorityItem{
|
||||
(*e.peerSeniority)[string(addr)] = PeerSeniorityItem{
|
||||
seniority: 20,
|
||||
addr: string(addr),
|
||||
}
|
||||
} else {
|
||||
(*e.peerSeniority)[string(addr)] = peerSeniorityItem{
|
||||
(*e.peerSeniority)[string(addr)] = PeerSeniorityItem{
|
||||
seniority: (*e.peerSeniority)[string(addr)].seniority + 20,
|
||||
addr: string(addr),
|
||||
}
|
||||
@ -662,19 +694,28 @@ func (e *TokenExecutionEngine) ProcessFrame(
|
||||
case *protobufs.TokenOutput_Penalty:
|
||||
addr := string(o.Penalty.Account.GetImplicitAccount().Address)
|
||||
if _, ok := (*e.peerSeniority)[addr]; !ok {
|
||||
(*e.peerSeniority)[addr] = peerSeniorityItem{
|
||||
(*e.peerSeniority)[addr] = PeerSeniorityItem{
|
||||
seniority: 0,
|
||||
addr: addr,
|
||||
}
|
||||
proverTrieLeaveRequests = append(proverTrieLeaveRequests, []byte(addr))
|
||||
} else {
|
||||
if (*e.peerSeniority)[addr].seniority > o.Penalty.Quantity {
|
||||
(*e.peerSeniority)[addr] = peerSeniorityItem{
|
||||
for _, t := range app.Tries {
|
||||
if t.Contains([]byte(addr)) {
|
||||
_, latest, _ := t.Get([]byte(addr))
|
||||
if frame.FrameNumber-latest > 100 {
|
||||
proverTrieLeaveRequests = append(proverTrieLeaveRequests, []byte(addr))
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
(*e.peerSeniority)[addr] = PeerSeniorityItem{
|
||||
seniority: (*e.peerSeniority)[addr].seniority - o.Penalty.Quantity,
|
||||
addr: addr,
|
||||
}
|
||||
} else {
|
||||
(*e.peerSeniority)[addr] = peerSeniorityItem{
|
||||
(*e.peerSeniority)[addr] = PeerSeniorityItem{
|
||||
seniority: 0,
|
||||
addr: addr,
|
||||
}
|
||||
@ -684,11 +725,11 @@ func (e *TokenExecutionEngine) ProcessFrame(
|
||||
}
|
||||
}
|
||||
|
||||
joinAddrs := tries.NewMinHeap[peerSeniorityItem]()
|
||||
leaveAddrs := tries.NewMinHeap[peerSeniorityItem]()
|
||||
joinAddrs := tries.NewMinHeap[PeerSeniorityItem]()
|
||||
leaveAddrs := tries.NewMinHeap[PeerSeniorityItem]()
|
||||
for _, addr := range proverTrieJoinRequests {
|
||||
if _, ok := (*e.peerSeniority)[string(addr)]; !ok {
|
||||
joinAddrs.Push(peerSeniorityItem{
|
||||
joinAddrs.Push(PeerSeniorityItem{
|
||||
addr: string(addr),
|
||||
seniority: 0,
|
||||
})
|
||||
@ -698,7 +739,7 @@ func (e *TokenExecutionEngine) ProcessFrame(
|
||||
}
|
||||
for _, addr := range proverTrieLeaveRequests {
|
||||
if _, ok := (*e.peerSeniority)[string(addr)]; !ok {
|
||||
leaveAddrs.Push(peerSeniorityItem{
|
||||
leaveAddrs.Push(PeerSeniorityItem{
|
||||
addr: string(addr),
|
||||
seniority: 0,
|
||||
})
|
||||
@ -707,36 +748,14 @@ func (e *TokenExecutionEngine) ProcessFrame(
|
||||
}
|
||||
}
|
||||
|
||||
joinReqs := make([]peerSeniorityItem, len(joinAddrs.All()))
|
||||
joinReqs := make([]PeerSeniorityItem, len(joinAddrs.All()))
|
||||
copy(joinReqs, joinAddrs.All())
|
||||
slices.Reverse(joinReqs)
|
||||
leaveReqs := make([]peerSeniorityItem, len(leaveAddrs.All()))
|
||||
leaveReqs := make([]PeerSeniorityItem, len(leaveAddrs.All()))
|
||||
copy(leaveReqs, leaveAddrs.All())
|
||||
slices.Reverse(leaveReqs)
|
||||
|
||||
for _, addr := range joinReqs {
|
||||
rings := len(app.Tries)
|
||||
last := app.Tries[rings-1]
|
||||
set := last.FindNearestAndApproximateNeighbors(make([]byte, 32))
|
||||
if len(set) == 1024 || rings == 1 {
|
||||
app.Tries = append(
|
||||
app.Tries,
|
||||
&tries.RollingFrecencyCritbitTrie{},
|
||||
)
|
||||
last = app.Tries[rings]
|
||||
}
|
||||
if !last.Contains([]byte(addr.addr)) {
|
||||
last.Add([]byte(addr.addr), frame.FrameNumber)
|
||||
}
|
||||
}
|
||||
for _, addr := range leaveReqs {
|
||||
for _, t := range app.Tries {
|
||||
if t.Contains([]byte(addr.addr)) {
|
||||
t.Remove([]byte(addr.addr))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
ProcessJoinsAndLeaves(joinReqs, leaveReqs, app, e.peerSeniority, frame)
|
||||
|
||||
err = e.clockStore.PutPeerSeniorityMap(
|
||||
txn,
|
||||
@ -757,6 +776,57 @@ func (e *TokenExecutionEngine) ProcessFrame(
|
||||
return app.Tries, nil
|
||||
}
|
||||
|
||||
func ProcessJoinsAndLeaves(
|
||||
joinReqs []PeerSeniorityItem,
|
||||
leaveReqs []PeerSeniorityItem,
|
||||
app *application.TokenApplication,
|
||||
seniority *PeerSeniority,
|
||||
frame *protobufs.ClockFrame,
|
||||
) {
|
||||
for _, addr := range joinReqs {
|
||||
rings := len(app.Tries)
|
||||
last := app.Tries[rings-1]
|
||||
set := last.FindNearestAndApproximateNeighbors(make([]byte, 32))
|
||||
if len(set) == 2048 || rings == 1 {
|
||||
app.Tries = append(
|
||||
app.Tries,
|
||||
&tries.RollingFrecencyCritbitTrie{},
|
||||
)
|
||||
last = app.Tries[rings]
|
||||
}
|
||||
if !last.Contains([]byte(addr.addr)) {
|
||||
last.Add([]byte(addr.addr), frame.FrameNumber)
|
||||
}
|
||||
}
|
||||
for _, addr := range leaveReqs {
|
||||
for _, t := range app.Tries[1:] {
|
||||
if t.Contains([]byte(addr.addr)) {
|
||||
t.Remove([]byte(addr.addr))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(app.Tries) > 2 {
|
||||
for i, t := range app.Tries[2:] {
|
||||
setSize := len(app.Tries[1+i].FindNearestAndApproximateNeighbors(make([]byte, 32)))
|
||||
if setSize < 2048 {
|
||||
nextSet := t.FindNearestAndApproximateNeighbors(make([]byte, 32))
|
||||
eligibilityOrder := tries.NewMinHeap[PeerSeniorityItem]()
|
||||
for _, n := range nextSet {
|
||||
eligibilityOrder.Push((*seniority)[string(n.External.Key)])
|
||||
}
|
||||
process := eligibilityOrder.All()
|
||||
slices.Reverse(process)
|
||||
for s := 0; s+setSize < 2048; s++ {
|
||||
app.Tries[1+i].Add([]byte(process[s].addr), frame.FrameNumber)
|
||||
app.Tries[2+i].Remove([]byte(process[s].addr))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (e *TokenExecutionEngine) publishMessage(
|
||||
filter []byte,
|
||||
message proto.Message,
|
||||
@ -913,6 +983,235 @@ func (e *TokenExecutionEngine) GetSeniority() *big.Int {
|
||||
return sen.Priority()
|
||||
}
|
||||
|
||||
func (e *TokenExecutionEngine) GetAggregatedSeniority(peerIds []string) *big.Int {
|
||||
highestFirst := uint64(0)
|
||||
highestSecond := uint64(0)
|
||||
highestThird := uint64(0)
|
||||
highestFourth := uint64(0)
|
||||
|
||||
for _, f := range firstRetro {
|
||||
found := false
|
||||
for _, p := range peerIds {
|
||||
if p != f.PeerId {
|
||||
continue
|
||||
}
|
||||
found = true
|
||||
}
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
// these don't have decimals so we can shortcut
|
||||
max := 157208
|
||||
actual, err := strconv.Atoi(f.Reward)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
s := uint64(10 * 6 * 60 * 24 * 92 / (max / actual))
|
||||
if s > uint64(highestFirst) {
|
||||
highestFirst = s
|
||||
}
|
||||
}
|
||||
|
||||
for _, f := range secondRetro {
|
||||
found := false
|
||||
for _, p := range peerIds {
|
||||
if p != f.PeerId {
|
||||
continue
|
||||
}
|
||||
found = true
|
||||
}
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
|
||||
amt := uint64(0)
|
||||
if f.JanPresence {
|
||||
amt += (10 * 6 * 60 * 24 * 31)
|
||||
}
|
||||
|
||||
if f.FebPresence {
|
||||
amt += (10 * 6 * 60 * 24 * 29)
|
||||
}
|
||||
|
||||
if f.MarPresence {
|
||||
amt += (10 * 6 * 60 * 24 * 31)
|
||||
}
|
||||
|
||||
if f.AprPresence {
|
||||
amt += (10 * 6 * 60 * 24 * 30)
|
||||
}
|
||||
|
||||
if f.MayPresence {
|
||||
amt += (10 * 6 * 60 * 24 * 31)
|
||||
}
|
||||
|
||||
if amt > uint64(highestSecond) {
|
||||
highestSecond = amt
|
||||
}
|
||||
}
|
||||
|
||||
for _, f := range thirdRetro {
|
||||
found := false
|
||||
for _, p := range peerIds {
|
||||
if p != f.PeerId {
|
||||
continue
|
||||
}
|
||||
found = true
|
||||
}
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
|
||||
s := uint64(10 * 6 * 60 * 24 * 30)
|
||||
if s > uint64(highestThird) {
|
||||
highestThird = s
|
||||
}
|
||||
}
|
||||
|
||||
for _, f := range fourthRetro {
|
||||
found := false
|
||||
for _, p := range peerIds {
|
||||
if p != f.PeerId {
|
||||
continue
|
||||
}
|
||||
found = true
|
||||
}
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
|
||||
s := uint64(10 * 6 * 60 * 24 * 31)
|
||||
if s > uint64(highestFourth) {
|
||||
highestFourth = s
|
||||
}
|
||||
}
|
||||
return new(big.Int).SetUint64(
|
||||
highestFirst + highestSecond + highestThird + highestFourth,
|
||||
)
|
||||
}
|
||||
|
||||
func (e *TokenExecutionEngine) AnnounceProverMerge() {
|
||||
currentHead := e.GetFrame()
|
||||
if currentHead == nil ||
|
||||
currentHead.FrameNumber < application.PROOF_FRAME_CUTOFF {
|
||||
return
|
||||
}
|
||||
keys := [][]byte{}
|
||||
ksigs := [][]byte{}
|
||||
if len(e.engineConfig.MultisigProverEnrollmentPaths) != 0 &&
|
||||
e.GetSeniority().Cmp(e.GetAggregatedSeniority(
|
||||
[]string{peer.ID(e.pubSub.GetPeerID()).String()},
|
||||
)) == 0 {
|
||||
for _, conf := range e.engineConfig.MultisigProverEnrollmentPaths {
|
||||
extraConf, err := config.LoadConfig(conf, "", false)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
peerPrivKey, err := hex.DecodeString(extraConf.P2P.PeerPrivKey)
|
||||
if err != nil {
|
||||
panic(errors.Wrap(err, "error unmarshaling peerkey"))
|
||||
}
|
||||
|
||||
privKey, err := pcrypto.UnmarshalEd448PrivateKey(peerPrivKey)
|
||||
if err != nil {
|
||||
panic(errors.Wrap(err, "error unmarshaling peerkey"))
|
||||
}
|
||||
|
||||
pub := privKey.GetPublic()
|
||||
pubBytes, err := pub.Raw()
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
keyjoin := []byte{}
|
||||
for _, k := range keys {
|
||||
keyjoin = append(keyjoin, k...)
|
||||
}
|
||||
|
||||
mainsig, err := e.pubSub.SignMessage(keyjoin)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
announce := &protobufs.TokenRequest_Announce{
|
||||
Announce: &protobufs.AnnounceProverRequest{
|
||||
PublicKeySignaturesEd448: []*protobufs.Ed448Signature{},
|
||||
},
|
||||
}
|
||||
|
||||
announce.Announce.PublicKeySignaturesEd448 = append(
|
||||
announce.Announce.PublicKeySignaturesEd448,
|
||||
&protobufs.Ed448Signature{
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: e.pubSub.GetPublicKey(),
|
||||
},
|
||||
Signature: mainsig,
|
||||
},
|
||||
)
|
||||
|
||||
for i := range keys {
|
||||
announce.Announce.PublicKeySignaturesEd448 = append(
|
||||
announce.Announce.PublicKeySignaturesEd448,
|
||||
&protobufs.Ed448Signature{
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: keys[i],
|
||||
},
|
||||
Signature: ksigs[i],
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
req := &protobufs.TokenRequest{
|
||||
Request: announce,
|
||||
}
|
||||
|
||||
e.publishMessage(append([]byte{0x00}, e.intrinsicFilter...), req)
|
||||
}
|
||||
|
||||
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 {
|
||||
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(),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (e *TokenExecutionEngine) GetRingPosition() int {
|
||||
altAddr, err := poseidon.HashBytes(e.pubSub.GetPeerID())
|
||||
if err != nil {
|
||||
@ -933,6 +1232,28 @@ func (e *TokenExecutionEngine) GetRingPosition() int {
|
||||
return -1
|
||||
}
|
||||
|
||||
func (e *TokenExecutionEngine) getPeerIdFromSignature(
|
||||
sig *protobufs.Ed448Signature,
|
||||
) (peer.ID, error) {
|
||||
if sig.PublicKey == nil || sig.PublicKey.KeyValue == nil {
|
||||
return "", errors.New("invalid data")
|
||||
}
|
||||
|
||||
pk, err := pcrypto.UnmarshalEd448PublicKey(
|
||||
sig.PublicKey.KeyValue,
|
||||
)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "get address from signature")
|
||||
}
|
||||
|
||||
peerId, err := peer.IDFromPublicKey(pk)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "get address from signature")
|
||||
}
|
||||
|
||||
return peerId, nil
|
||||
}
|
||||
|
||||
func (e *TokenExecutionEngine) getAddressFromSignature(
|
||||
sig *protobufs.Ed448Signature,
|
||||
) ([]byte, error) {
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
package token_test
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/execution/intrinsics/token"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/execution/intrinsics/token/application"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/tries"
|
||||
)
|
||||
|
||||
func TestProcessJoinsAndLeaves(t *testing.T) {
|
||||
set := [][]byte{}
|
||||
for i := 0; i < 6000; i++ {
|
||||
b := make([]byte, 32)
|
||||
rand.Read(b)
|
||||
set = append(set, b)
|
||||
}
|
||||
|
||||
joins := []token.PeerSeniorityItem{}
|
||||
seniority := &token.PeerSeniority{}
|
||||
for i, s := range set {
|
||||
joins = append(joins, token.NewPeerSeniorityItem(uint64(i), string(s)))
|
||||
(*seniority)[string(s)] = token.NewPeerSeniorityItem(uint64(i), string(s))
|
||||
}
|
||||
tr := []*tries.RollingFrecencyCritbitTrie{
|
||||
&tries.RollingFrecencyCritbitTrie{},
|
||||
&tries.RollingFrecencyCritbitTrie{},
|
||||
}
|
||||
app := &application.TokenApplication{
|
||||
Tries: tr,
|
||||
}
|
||||
token.ProcessJoinsAndLeaves(joins, []token.PeerSeniorityItem{}, app, seniority, &protobufs.ClockFrame{FrameNumber: 20})
|
||||
|
||||
assert.Equal(t, len(app.Tries), 4)
|
||||
assert.Equal(t, len(app.Tries[1].FindNearestAndApproximateNeighbors(make([]byte, 32))), 2048)
|
||||
assert.Equal(t, len(app.Tries[2].FindNearestAndApproximateNeighbors(make([]byte, 32))), 2048)
|
||||
assert.Equal(t, len(app.Tries[3].FindNearestAndApproximateNeighbors(make([]byte, 32))), 1904)
|
||||
|
||||
leaves := []token.PeerSeniorityItem{}
|
||||
leaves = append(leaves, joins[30])
|
||||
leaves = append(leaves, joins[2047])
|
||||
leaves = append(leaves, joins[4095])
|
||||
token.ProcessJoinsAndLeaves([]token.PeerSeniorityItem{}, leaves, app, seniority, &protobufs.ClockFrame{FrameNumber: 20})
|
||||
|
||||
assert.Equal(t, len(app.Tries), 4)
|
||||
assert.Equal(t, len(app.Tries[1].FindNearestAndApproximateNeighbors(make([]byte, 32))), 2048)
|
||||
assert.Equal(t, len(app.Tries[2].FindNearestAndApproximateNeighbors(make([]byte, 32))), 2048)
|
||||
assert.Equal(t, len(app.Tries[3].FindNearestAndApproximateNeighbors(make([]byte, 32))), 1901)
|
||||
}
|
||||
@ -75,25 +75,140 @@ var thirdRetroJsonBinary []byte
|
||||
//go:embed fourth_retro.json
|
||||
var fourthRetroJsonBinary []byte
|
||||
|
||||
func RebuildPeerSeniority(clockStore store.ClockStore) {
|
||||
// testnet:
|
||||
txn, err := clockStore.NewTransaction()
|
||||
var firstRetro []*FirstRetroJson
|
||||
var secondRetro []*SecondRetroJson
|
||||
var thirdRetro []*ThirdRetroJson
|
||||
var fourthRetro []*FourthRetroJson
|
||||
|
||||
func LoadAggregatedSeniorityMap() {
|
||||
firstRetro = []*FirstRetroJson{}
|
||||
secondRetro = []*SecondRetroJson{}
|
||||
thirdRetro = []*ThirdRetroJson{}
|
||||
fourthRetro = []*FourthRetroJson{}
|
||||
|
||||
err := json.Unmarshal(firstRetroJsonBinary, &firstRetro)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = clockStore.PutPeerSeniorityMap(
|
||||
txn,
|
||||
p2p.GetBloomFilter(application.TOKEN_ADDRESS, 256, 3),
|
||||
map[string]uint64{},
|
||||
)
|
||||
err = json.Unmarshal(secondRetroJsonBinary, &secondRetro)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err = txn.Commit(); err != nil {
|
||||
err = json.Unmarshal(thirdRetroJsonBinary, &thirdRetro)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(fourthRetroJsonBinary, &fourthRetro)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func RebuildPeerSeniority(network uint) (map[string]uint64, error) {
|
||||
if network != 0 {
|
||||
return map[string]uint64{}, nil
|
||||
}
|
||||
|
||||
firstRetro = []*FirstRetroJson{}
|
||||
secondRetro = []*SecondRetroJson{}
|
||||
thirdRetro = []*ThirdRetroJson{}
|
||||
fourthRetro = []*FourthRetroJson{}
|
||||
|
||||
err := json.Unmarshal(firstRetroJsonBinary, &firstRetro)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(secondRetroJsonBinary, &secondRetro)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(thirdRetroJsonBinary, &thirdRetro)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(fourthRetroJsonBinary, &fourthRetro)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
peerSeniority := map[string]uint64{}
|
||||
for _, f := range firstRetro {
|
||||
// these don't have decimals so we can shortcut
|
||||
max := 157208
|
||||
actual, err := strconv.Atoi(f.Reward)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p := []byte(f.PeerId)
|
||||
addr, _ := poseidon.HashBytes(p)
|
||||
|
||||
peerSeniority[string(
|
||||
addr.FillBytes(make([]byte, 32)),
|
||||
)] = uint64(10 * 6 * 60 * 24 * 92 / (max / actual))
|
||||
}
|
||||
|
||||
for _, f := range secondRetro {
|
||||
p := []byte(f.PeerId)
|
||||
addr, _ := poseidon.HashBytes(p)
|
||||
addrBytes := string(addr.FillBytes(make([]byte, 32)))
|
||||
|
||||
if _, ok := peerSeniority[addrBytes]; !ok {
|
||||
peerSeniority[addrBytes] = 0
|
||||
}
|
||||
|
||||
if f.JanPresence {
|
||||
peerSeniority[addrBytes] = peerSeniority[addrBytes] + (10 * 6 * 60 * 24 * 31)
|
||||
}
|
||||
|
||||
if f.FebPresence {
|
||||
peerSeniority[addrBytes] = peerSeniority[addrBytes] + (10 * 6 * 60 * 24 * 29)
|
||||
}
|
||||
|
||||
if f.MarPresence {
|
||||
peerSeniority[addrBytes] = peerSeniority[addrBytes] + (10 * 6 * 60 * 24 * 31)
|
||||
}
|
||||
|
||||
if f.AprPresence {
|
||||
peerSeniority[addrBytes] = peerSeniority[addrBytes] + (10 * 6 * 60 * 24 * 30)
|
||||
}
|
||||
|
||||
if f.MayPresence {
|
||||
peerSeniority[addrBytes] = peerSeniority[addrBytes] + (10 * 6 * 60 * 24 * 31)
|
||||
}
|
||||
}
|
||||
|
||||
for _, f := range thirdRetro {
|
||||
p := []byte(f.PeerId)
|
||||
addr, _ := poseidon.HashBytes(p)
|
||||
addrBytes := string(addr.FillBytes(make([]byte, 32)))
|
||||
|
||||
if _, ok := peerSeniority[addrBytes]; !ok {
|
||||
peerSeniority[addrBytes] = 0
|
||||
}
|
||||
|
||||
peerSeniority[addrBytes] = peerSeniority[addrBytes] + (10 * 6 * 60 * 24 * 30)
|
||||
}
|
||||
|
||||
for _, f := range fourthRetro {
|
||||
p := []byte(f.PeerId)
|
||||
addr, _ := poseidon.HashBytes(p)
|
||||
addrBytes := string(addr.FillBytes(make([]byte, 32)))
|
||||
|
||||
if _, ok := peerSeniority[addrBytes]; !ok {
|
||||
peerSeniority[addrBytes] = 0
|
||||
}
|
||||
|
||||
peerSeniority[addrBytes] = peerSeniority[addrBytes] + (10 * 6 * 60 * 24 * 31)
|
||||
}
|
||||
|
||||
return peerSeniority, nil
|
||||
}
|
||||
|
||||
// Creates a genesis state for the intrinsic
|
||||
@ -147,10 +262,10 @@ func CreateGenesisState(
|
||||
if network == 0 {
|
||||
bridged := []*BridgedPeerJson{}
|
||||
vouchers := []string{}
|
||||
firstRetro := []*FirstRetroJson{}
|
||||
secondRetro := []*SecondRetroJson{}
|
||||
thirdRetro := []*ThirdRetroJson{}
|
||||
fourthRetro := []*FourthRetroJson{}
|
||||
firstRetro = []*FirstRetroJson{}
|
||||
secondRetro = []*SecondRetroJson{}
|
||||
thirdRetro = []*ThirdRetroJson{}
|
||||
fourthRetro = []*FourthRetroJson{}
|
||||
|
||||
err = json.Unmarshal(bridgedPeersJsonBinary, &bridged)
|
||||
if err != nil {
|
||||
@ -200,6 +315,9 @@ func CreateGenesisState(
|
||||
peerSeniority := map[string]uint64{}
|
||||
logger.Info("encoding first retro state")
|
||||
for _, f := range firstRetro {
|
||||
p := []byte(f.PeerId)
|
||||
addr, _ := poseidon.HashBytes(p)
|
||||
addrBytes := string(addr.FillBytes(make([]byte, 32)))
|
||||
if _, ok := bridgedAddrs[f.PeerId]; !ok {
|
||||
peerIdTotals[f.PeerId], err = decimal.NewFromString(f.Reward)
|
||||
if err != nil {
|
||||
@ -214,7 +332,7 @@ func CreateGenesisState(
|
||||
panic(err)
|
||||
}
|
||||
|
||||
peerSeniority[f.PeerId] = uint64(10 * 6 * 60 * 24 * 92 / (max / actual))
|
||||
peerSeniority[addrBytes] = uint64(10 * 6 * 60 * 24 * 92 / (max / actual))
|
||||
}
|
||||
|
||||
logger.Info("encoding voucher state")
|
||||
@ -226,6 +344,10 @@ func CreateGenesisState(
|
||||
|
||||
logger.Info("encoding second retro state")
|
||||
for _, f := range secondRetro {
|
||||
p := []byte(f.PeerId)
|
||||
addr, _ := poseidon.HashBytes(p)
|
||||
addrBytes := string(addr.FillBytes(make([]byte, 32)))
|
||||
|
||||
if _, ok := bridgedAddrs[f.PeerId]; !ok {
|
||||
existing, ok := peerIdTotals[f.PeerId]
|
||||
|
||||
@ -241,33 +363,37 @@ func CreateGenesisState(
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := peerSeniority[f.PeerId]; !ok {
|
||||
peerSeniority[f.PeerId] = 0
|
||||
if _, ok := peerSeniority[addrBytes]; !ok {
|
||||
peerSeniority[addrBytes] = 0
|
||||
}
|
||||
|
||||
if f.JanPresence {
|
||||
peerSeniority[f.PeerId] = peerSeniority[f.PeerId] + (10 * 6 * 60 * 24 * 31)
|
||||
peerSeniority[addrBytes] = peerSeniority[addrBytes] + (10 * 6 * 60 * 24 * 31)
|
||||
}
|
||||
|
||||
if f.FebPresence {
|
||||
peerSeniority[f.PeerId] = peerSeniority[f.PeerId] + (10 * 6 * 60 * 24 * 29)
|
||||
peerSeniority[addrBytes] = peerSeniority[addrBytes] + (10 * 6 * 60 * 24 * 29)
|
||||
}
|
||||
|
||||
if f.MarPresence {
|
||||
peerSeniority[f.PeerId] = peerSeniority[f.PeerId] + (10 * 6 * 60 * 24 * 31)
|
||||
peerSeniority[addrBytes] = peerSeniority[addrBytes] + (10 * 6 * 60 * 24 * 31)
|
||||
}
|
||||
|
||||
if f.AprPresence {
|
||||
peerSeniority[f.PeerId] = peerSeniority[f.PeerId] + (10 * 6 * 60 * 24 * 30)
|
||||
peerSeniority[addrBytes] = peerSeniority[addrBytes] + (10 * 6 * 60 * 24 * 30)
|
||||
}
|
||||
|
||||
if f.MayPresence {
|
||||
peerSeniority[f.PeerId] = peerSeniority[f.PeerId] + (10 * 6 * 60 * 24 * 31)
|
||||
peerSeniority[addrBytes] = peerSeniority[addrBytes] + (10 * 6 * 60 * 24 * 31)
|
||||
}
|
||||
}
|
||||
|
||||
logger.Info("encoding third retro state")
|
||||
for _, f := range thirdRetro {
|
||||
p := []byte(f.PeerId)
|
||||
addr, _ := poseidon.HashBytes(p)
|
||||
addrBytes := string(addr.FillBytes(make([]byte, 32)))
|
||||
|
||||
existing, ok := peerIdTotals[f.PeerId]
|
||||
|
||||
amount, err := decimal.NewFromString(f.Reward)
|
||||
@ -281,15 +407,19 @@ func CreateGenesisState(
|
||||
peerIdTotals[f.PeerId] = existing.Add(amount)
|
||||
}
|
||||
|
||||
if _, ok := peerSeniority[f.PeerId]; !ok {
|
||||
peerSeniority[f.PeerId] = 0
|
||||
if _, ok := peerSeniority[addrBytes]; !ok {
|
||||
peerSeniority[addrBytes] = 0
|
||||
}
|
||||
|
||||
peerSeniority[f.PeerId] = peerSeniority[f.PeerId] + (10 * 6 * 60 * 24 * 30)
|
||||
peerSeniority[addrBytes] = peerSeniority[addrBytes] + (10 * 6 * 60 * 24 * 30)
|
||||
}
|
||||
|
||||
logger.Info("encoding fourth retro state")
|
||||
for _, f := range fourthRetro {
|
||||
p := []byte(f.PeerId)
|
||||
addr, _ := poseidon.HashBytes(p)
|
||||
addrBytes := string(addr.FillBytes(make([]byte, 32)))
|
||||
|
||||
existing, ok := peerIdTotals[f.PeerId]
|
||||
|
||||
amount, err := decimal.NewFromString(f.Reward)
|
||||
@ -303,11 +433,11 @@ func CreateGenesisState(
|
||||
peerIdTotals[f.PeerId] = existing.Add(amount)
|
||||
}
|
||||
|
||||
if _, ok := peerSeniority[f.PeerId]; !ok {
|
||||
peerSeniority[f.PeerId] = 0
|
||||
if _, ok := peerSeniority[addrBytes]; !ok {
|
||||
peerSeniority[addrBytes] = 0
|
||||
}
|
||||
|
||||
peerSeniority[f.PeerId] = peerSeniority[f.PeerId] + (10 * 6 * 60 * 24 * 31)
|
||||
peerSeniority[addrBytes] = peerSeniority[addrBytes] + (10 * 6 * 60 * 24 * 31)
|
||||
}
|
||||
|
||||
genesisState := &protobufs.TokenOutputs{
|
||||
|
||||
@ -1,6 +1,14 @@
|
||||
package protobufs
|
||||
|
||||
import "math/big"
|
||||
import (
|
||||
"encoding/binary"
|
||||
"math/big"
|
||||
|
||||
"github.com/iden3/go-iden3-crypto/poseidon"
|
||||
pcrypto "github.com/libp2p/go-libp2p/core/crypto"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (t *TokenRequest) Priority() *big.Int {
|
||||
switch p := t.Request.(type) {
|
||||
@ -11,3 +19,42 @@ func (t *TokenRequest) Priority() *big.Int {
|
||||
}
|
||||
return big.NewInt(0)
|
||||
}
|
||||
|
||||
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,
|
||||
)
|
||||
if err != nil {
|
||||
return -1, 0, errors.New("invalid")
|
||||
}
|
||||
|
||||
peerId, err := peer.IDFromPublicKey(pk)
|
||||
if err != nil {
|
||||
return -1, 0, errors.New("invalid")
|
||||
}
|
||||
|
||||
altAddr, err := poseidon.HashBytes([]byte(peerId))
|
||||
if err != nil {
|
||||
return -1, 0, errors.New("invalid")
|
||||
}
|
||||
|
||||
ring := ringCalc(altAddr.FillBytes(make([]byte, 32)))
|
||||
if ring == -1 {
|
||||
return -1, 0, errors.New("invalid")
|
||||
}
|
||||
|
||||
if t.Proofs != nil && len(t.Proofs) >= 3 && len(t.Proofs[1]) == 4 {
|
||||
return ring, binary.BigEndian.Uint32(t.Proofs[1]), nil
|
||||
}
|
||||
|
||||
return -1, 0, errors.New("invalid")
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ type CoinStore interface {
|
||||
)
|
||||
GetCoinByAddress(txn Transaction, address []byte) (*protobufs.Coin, error)
|
||||
GetPreCoinProofByAddress(address []byte) (*protobufs.PreCoinProof, error)
|
||||
RangePreCoinProofs() (Iterator, error)
|
||||
PutCoin(
|
||||
txn Transaction,
|
||||
frameNumber uint64,
|
||||
@ -251,6 +252,18 @@ func (p *PebbleCoinStore) GetPreCoinProofByAddress(address []byte) (
|
||||
return proof, nil
|
||||
}
|
||||
|
||||
func (p *PebbleCoinStore) RangePreCoinProofs() (Iterator, error) {
|
||||
iter, err := p.db.NewIter(
|
||||
proofKey(bytes.Repeat([]byte{0x00}, 32)),
|
||||
proofKey(bytes.Repeat([]byte{0xff}, 32)),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "range pre coin proofs")
|
||||
}
|
||||
|
||||
return iter, nil
|
||||
}
|
||||
|
||||
func (p *PebbleCoinStore) PutCoin(
|
||||
txn Transaction,
|
||||
frameNumber uint64,
|
||||
|
||||
@ -89,12 +89,13 @@ func TestPackAndVerifyOutput(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
tree, payload, output := tries.PackOutputIntoPayloadAndProof(
|
||||
tree, payload, output, err := tries.PackOutputIntoPayloadAndProof(
|
||||
outputs,
|
||||
tc.modulo,
|
||||
frame,
|
||||
previousTree,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, tree)
|
||||
require.NotEmpty(t, payload)
|
||||
require.NotEmpty(t, output)
|
||||
|
||||
@ -134,7 +134,7 @@ func (t *RollingFrecencyCritbitTrie) FindNearestAndApproximateNeighbors(
|
||||
|
||||
var traverse func(p *Node, address []byte) bool
|
||||
traverse = func(p *Node, address []byte) bool {
|
||||
if len(ret) > 1024 {
|
||||
if len(ret) > 2048 {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user