mirror of
https://github.com/QuilibriumNetwork/ceremonyclient.git
synced 2026-02-25 12:27:24 +08:00
Frame processing optimisations (#404)
* Make frame processing hashing parallel * Do not build address for new style proofs * Validate mint requests in parallel * Do not recompute byte form of address in mint * Remove unused output * Use single append * Cache verify challenge proof results
This commit is contained in:
parent
667b2aa2bc
commit
8a7aae3557
@ -76,8 +76,7 @@ var pubSubSet = wire.NewSet(
|
||||
|
||||
var engineSet = wire.NewSet(
|
||||
wire.FieldsOf(new(*config.Config), "Engine"),
|
||||
crypto.NewWesolowskiFrameProver,
|
||||
wire.Bind(new(crypto.FrameProver), new(*crypto.WesolowskiFrameProver)),
|
||||
crypto.NewCachedWesolowskiFrameProver,
|
||||
crypto.NewKZGInclusionProver,
|
||||
wire.Bind(new(crypto.InclusionProver), new(*crypto.KZGInclusionProver)),
|
||||
time.NewMasterTimeReel,
|
||||
|
||||
@ -45,14 +45,14 @@ func NewDebugNode(configConfig *config.Config, selfTestReport *protobufs.SelfTes
|
||||
fileKeyManager := keys.NewFileKeyManager(keyConfig, zapLogger)
|
||||
p2PConfig := configConfig.P2P
|
||||
blossomSub := p2p.NewBlossomSub(p2PConfig, zapLogger)
|
||||
wesolowskiFrameProver := crypto.NewWesolowskiFrameProver(zapLogger)
|
||||
frameProver := crypto.NewCachedWesolowskiFrameProver(zapLogger)
|
||||
kzgInclusionProver := crypto.NewKZGInclusionProver(zapLogger)
|
||||
engineConfig := configConfig.Engine
|
||||
masterTimeReel := time.NewMasterTimeReel(zapLogger, pebbleClockStore, engineConfig, wesolowskiFrameProver)
|
||||
masterTimeReel := time.NewMasterTimeReel(zapLogger, pebbleClockStore, engineConfig, frameProver)
|
||||
inMemoryPeerInfoManager := p2p.NewInMemoryPeerInfoManager(zapLogger)
|
||||
pebbleKeyStore := store.NewPebbleKeyStore(pebbleDB, zapLogger)
|
||||
tokenExecutionEngine := token.NewTokenExecutionEngine(zapLogger, configConfig, fileKeyManager, blossomSub, wesolowskiFrameProver, kzgInclusionProver, pebbleClockStore, pebbleDataProofStore, pebbleCoinStore, masterTimeReel, inMemoryPeerInfoManager, pebbleKeyStore, selfTestReport)
|
||||
masterClockConsensusEngine := master.NewMasterClockConsensusEngine(engineConfig, zapLogger, pebbleClockStore, fileKeyManager, blossomSub, kzgInclusionProver, wesolowskiFrameProver, masterTimeReel, inMemoryPeerInfoManager, selfTestReport)
|
||||
tokenExecutionEngine := token.NewTokenExecutionEngine(zapLogger, configConfig, fileKeyManager, blossomSub, frameProver, kzgInclusionProver, pebbleClockStore, pebbleDataProofStore, pebbleCoinStore, masterTimeReel, inMemoryPeerInfoManager, pebbleKeyStore, selfTestReport)
|
||||
masterClockConsensusEngine := master.NewMasterClockConsensusEngine(engineConfig, zapLogger, pebbleClockStore, fileKeyManager, blossomSub, kzgInclusionProver, frameProver, masterTimeReel, inMemoryPeerInfoManager, selfTestReport)
|
||||
node, err := newNode(zapLogger, pebbleDataProofStore, pebbleClockStore, pebbleCoinStore, fileKeyManager, blossomSub, tokenExecutionEngine, masterClockConsensusEngine, pebbleDB)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -71,14 +71,14 @@ func NewNode(configConfig *config.Config, selfTestReport *protobufs.SelfTestRepo
|
||||
fileKeyManager := keys.NewFileKeyManager(keyConfig, zapLogger)
|
||||
p2PConfig := configConfig.P2P
|
||||
blossomSub := p2p.NewBlossomSub(p2PConfig, zapLogger)
|
||||
wesolowskiFrameProver := crypto.NewWesolowskiFrameProver(zapLogger)
|
||||
frameProver := crypto.NewCachedWesolowskiFrameProver(zapLogger)
|
||||
kzgInclusionProver := crypto.NewKZGInclusionProver(zapLogger)
|
||||
engineConfig := configConfig.Engine
|
||||
masterTimeReel := time.NewMasterTimeReel(zapLogger, pebbleClockStore, engineConfig, wesolowskiFrameProver)
|
||||
masterTimeReel := time.NewMasterTimeReel(zapLogger, pebbleClockStore, engineConfig, frameProver)
|
||||
inMemoryPeerInfoManager := p2p.NewInMemoryPeerInfoManager(zapLogger)
|
||||
pebbleKeyStore := store.NewPebbleKeyStore(pebbleDB, zapLogger)
|
||||
tokenExecutionEngine := token.NewTokenExecutionEngine(zapLogger, configConfig, fileKeyManager, blossomSub, wesolowskiFrameProver, kzgInclusionProver, pebbleClockStore, pebbleDataProofStore, pebbleCoinStore, masterTimeReel, inMemoryPeerInfoManager, pebbleKeyStore, selfTestReport)
|
||||
masterClockConsensusEngine := master.NewMasterClockConsensusEngine(engineConfig, zapLogger, pebbleClockStore, fileKeyManager, blossomSub, kzgInclusionProver, wesolowskiFrameProver, masterTimeReel, inMemoryPeerInfoManager, selfTestReport)
|
||||
tokenExecutionEngine := token.NewTokenExecutionEngine(zapLogger, configConfig, fileKeyManager, blossomSub, frameProver, kzgInclusionProver, pebbleClockStore, pebbleDataProofStore, pebbleCoinStore, masterTimeReel, inMemoryPeerInfoManager, pebbleKeyStore, selfTestReport)
|
||||
masterClockConsensusEngine := master.NewMasterClockConsensusEngine(engineConfig, zapLogger, pebbleClockStore, fileKeyManager, blossomSub, kzgInclusionProver, frameProver, masterTimeReel, inMemoryPeerInfoManager, selfTestReport)
|
||||
node, err := newNode(zapLogger, pebbleDataProofStore, pebbleClockStore, pebbleCoinStore, fileKeyManager, blossomSub, tokenExecutionEngine, masterClockConsensusEngine, pebbleDB)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -136,7 +136,7 @@ var storeSet = wire.NewSet(wire.FieldsOf(new(*config.Config), "DB"), store.NewPe
|
||||
|
||||
var pubSubSet = wire.NewSet(wire.FieldsOf(new(*config.Config), "P2P"), p2p.NewInMemoryPeerInfoManager, p2p.NewBlossomSub, wire.Bind(new(p2p.PubSub), new(*p2p.BlossomSub)), wire.Bind(new(p2p.PeerInfoManager), new(*p2p.InMemoryPeerInfoManager)))
|
||||
|
||||
var engineSet = wire.NewSet(wire.FieldsOf(new(*config.Config), "Engine"), crypto.NewWesolowskiFrameProver, wire.Bind(new(crypto.FrameProver), new(*crypto.WesolowskiFrameProver)), crypto.NewKZGInclusionProver, wire.Bind(new(crypto.InclusionProver), new(*crypto.KZGInclusionProver)), time.NewMasterTimeReel, token.NewTokenExecutionEngine)
|
||||
var engineSet = wire.NewSet(wire.FieldsOf(new(*config.Config), "Engine"), crypto.NewCachedWesolowskiFrameProver, crypto.NewKZGInclusionProver, wire.Bind(new(crypto.InclusionProver), new(*crypto.KZGInclusionProver)), time.NewMasterTimeReel, token.NewTokenExecutionEngine)
|
||||
|
||||
var consensusSet = wire.NewSet(master.NewMasterClockConsensusEngine, wire.Bind(
|
||||
new(consensus.ConsensusEngine),
|
||||
|
||||
@ -81,6 +81,7 @@ func (e *DataClockConsensusEngine) prove(
|
||||
e.clockStore,
|
||||
e.pubSub,
|
||||
e.logger,
|
||||
e.frameProver,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "prove")
|
||||
|
||||
111
node/crypto/frame_prover_cache.go
Normal file
111
node/crypto/frame_prover_cache.go
Normal file
@ -0,0 +1,111 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/crypto/sha3"
|
||||
)
|
||||
|
||||
type frameProverCache struct {
|
||||
FrameProver
|
||||
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
|
||||
verifyChallengeProofCache sync.Map
|
||||
}
|
||||
|
||||
var (
|
||||
_ FrameProver = (*frameProverCache)(nil)
|
||||
_ io.Closer = (*frameProverCache)(nil)
|
||||
)
|
||||
|
||||
func (c *frameProverCache) gc(ctx context.Context, ttl time.Duration) {
|
||||
ticker := time.NewTicker(ttl / 2)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-ticker.C:
|
||||
c.verifyChallengeProofCache.Range(func(key, value interface{}) bool {
|
||||
if entry := value.(*frameProverVerifyChallengeProofCacheEntry); time.Since(entry.createdAt) > ttl {
|
||||
_ = c.verifyChallengeProofCache.CompareAndDelete(key, value)
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func NewCachedFrameProverWithTTL(prover FrameProver, ttl time.Duration) FrameProver {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
c := &frameProverCache{
|
||||
FrameProver: prover,
|
||||
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
}
|
||||
go c.gc(ctx, ttl)
|
||||
return c
|
||||
}
|
||||
|
||||
func NewCachedFrameProver(prover FrameProver) FrameProver {
|
||||
return NewCachedFrameProverWithTTL(prover, 5*time.Minute)
|
||||
}
|
||||
|
||||
func NewCachedWesolowskiFrameProver(logger *zap.Logger) FrameProver {
|
||||
return NewCachedFrameProver(NewWesolowskiFrameProver(logger))
|
||||
}
|
||||
|
||||
type frameProverVerifyChallengeProofCacheEntry struct {
|
||||
done chan struct{}
|
||||
result bool
|
||||
createdAt time.Time
|
||||
}
|
||||
|
||||
func (c *frameProverCache) verifyChallengeProofKey(
|
||||
challenge []byte,
|
||||
difficulty uint32,
|
||||
proof [516]byte,
|
||||
) [552]byte {
|
||||
h := sha3.Sum256(challenge)
|
||||
var key [32 + 4 + 516]byte
|
||||
copy(key[:32], h[:])
|
||||
binary.BigEndian.PutUint32(key[32:36], difficulty)
|
||||
copy(key[36:], proof[:])
|
||||
return key
|
||||
}
|
||||
|
||||
func (c *frameProverCache) VerifyChallengeProof(
|
||||
challenge []byte,
|
||||
difficulty uint32,
|
||||
proof []byte,
|
||||
) bool {
|
||||
if len(proof) != 516 {
|
||||
return false
|
||||
}
|
||||
key := c.verifyChallengeProofKey(challenge, difficulty, [516]byte(proof))
|
||||
entry := &frameProverVerifyChallengeProofCacheEntry{
|
||||
done: make(chan struct{}),
|
||||
createdAt: time.Now(),
|
||||
}
|
||||
defer close(entry.done)
|
||||
if entry, loaded := c.verifyChallengeProofCache.LoadOrStore(key, entry); loaded {
|
||||
entry := entry.(*frameProverVerifyChallengeProofCacheEntry)
|
||||
<-entry.done
|
||||
return entry.result
|
||||
}
|
||||
entry.result = c.FrameProver.VerifyChallengeProof(challenge, difficulty, proof)
|
||||
return entry.result
|
||||
}
|
||||
|
||||
func (c *frameProverCache) Close() error {
|
||||
c.cancel()
|
||||
return nil
|
||||
}
|
||||
85
node/crypto/frame_prover_cache_test.go
Normal file
85
node/crypto/frame_prover_cache_test.go
Normal file
@ -0,0 +1,85 @@
|
||||
package crypto_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/crypto"
|
||||
)
|
||||
|
||||
type mockFrameProver struct {
|
||||
crypto.FrameProver
|
||||
verifyChallengeProof func(challenge []byte, difficulty uint32, proof []byte) bool
|
||||
}
|
||||
|
||||
var _ crypto.FrameProver = (*mockFrameProver)(nil)
|
||||
|
||||
func (m *mockFrameProver) VerifyChallengeProof(challenge []byte, difficulty uint32, proof []byte) bool {
|
||||
return m.verifyChallengeProof(challenge, difficulty, proof)
|
||||
}
|
||||
|
||||
func TestCachedFrameProver(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
callCount := 0
|
||||
prover := &mockFrameProver{
|
||||
verifyChallengeProof: func(challenge []byte, difficulty uint32, proof []byte) bool {
|
||||
callCount++
|
||||
switch {
|
||||
case bytes.Equal(challenge, []byte{1, 2, 3}):
|
||||
assert.Equal(t, uint32(42), difficulty)
|
||||
assert.Equal(t, bytes.Repeat([]byte{0x42}, 516), proof)
|
||||
return true
|
||||
case bytes.Equal(challenge, []byte{1, 2, 4}):
|
||||
assert.Equal(t, uint32(43), difficulty)
|
||||
assert.Equal(t, bytes.Repeat([]byte{0x43}, 516), proof)
|
||||
return false
|
||||
default:
|
||||
t.Fatal("unexpected call")
|
||||
return false
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
cache := crypto.NewCachedFrameProverWithTTL(prover, 500*time.Millisecond)
|
||||
defer cache.(io.Closer).Close()
|
||||
|
||||
// Check that the proof size is checked.
|
||||
result := cache.VerifyChallengeProof([]byte{1, 2, 3}, 42, []byte{4, 5, 6})
|
||||
assert.Equal(t, 0, callCount)
|
||||
assert.False(t, result)
|
||||
|
||||
// Check that the result is cached.
|
||||
result = cache.VerifyChallengeProof([]byte{1, 2, 3}, 42, bytes.Repeat([]byte{0x42}, 516))
|
||||
assert.Equal(t, 1, callCount)
|
||||
assert.True(t, result)
|
||||
|
||||
result = cache.VerifyChallengeProof([]byte{1, 2, 3}, 42, bytes.Repeat([]byte{0x42}, 516))
|
||||
assert.Equal(t, 1, callCount)
|
||||
assert.True(t, result)
|
||||
|
||||
// Check that the result is cached in another key.
|
||||
result = cache.VerifyChallengeProof([]byte{1, 2, 4}, 43, bytes.Repeat([]byte{0x43}, 516))
|
||||
assert.Equal(t, 2, callCount)
|
||||
assert.False(t, result)
|
||||
|
||||
result = cache.VerifyChallengeProof([]byte{1, 2, 4}, 43, bytes.Repeat([]byte{0x43}, 516))
|
||||
assert.Equal(t, 2, callCount)
|
||||
assert.False(t, result)
|
||||
|
||||
// Wait for GC.
|
||||
time.Sleep(time.Second)
|
||||
|
||||
// Check that the result is not cached anymore.
|
||||
result = cache.VerifyChallengeProof([]byte{1, 2, 3}, 42, bytes.Repeat([]byte{0x42}, 516))
|
||||
assert.Equal(t, 3, callCount)
|
||||
assert.True(t, result)
|
||||
|
||||
// Check that the result is not cached anymore in another key.
|
||||
result = cache.VerifyChallengeProof([]byte{1, 2, 4}, 43, bytes.Repeat([]byte{0x43}, 516))
|
||||
assert.Equal(t, 4, callCount)
|
||||
assert.False(t, result)
|
||||
}
|
||||
@ -11,6 +11,7 @@ import (
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/config"
|
||||
qcrypto "source.quilibrium.com/quilibrium/monorepo/node/crypto"
|
||||
qruntime "source.quilibrium.com/quilibrium/monorepo/node/internal/runtime"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/p2p"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
|
||||
@ -37,6 +38,7 @@ type TokenApplication struct {
|
||||
PubSub p2p.PubSub
|
||||
Logger *zap.Logger
|
||||
Difficulty uint32
|
||||
FrameProver qcrypto.FrameProver
|
||||
}
|
||||
|
||||
func GetOutputsFromClockFrame(
|
||||
@ -86,6 +88,7 @@ func MaterializeApplicationFromFrame(
|
||||
clockStore store.ClockStore,
|
||||
pubSub p2p.PubSub,
|
||||
logger *zap.Logger,
|
||||
frameProver qcrypto.FrameProver,
|
||||
) (*TokenApplication, error) {
|
||||
_, tokenOutputs, err := GetOutputsFromClockFrame(frame)
|
||||
if err != nil {
|
||||
@ -103,6 +106,7 @@ func MaterializeApplicationFromFrame(
|
||||
Logger: logger,
|
||||
PubSub: pubSub,
|
||||
Difficulty: frame.Difficulty,
|
||||
FrameProver: frameProver,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -144,6 +148,32 @@ func (a *TokenApplication) ApplyTransitions(
|
||||
requests = transitions.Requests
|
||||
}
|
||||
|
||||
set := make([]*protobufs.TokenRequest, len(requests))
|
||||
fails := make([]*protobufs.TokenRequest, len(requests))
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
throttle := make(chan struct{}, qruntime.WorkerCount(0, false))
|
||||
|
||||
for i, transition := range requests {
|
||||
switch t := transition.Request.(type) {
|
||||
case *protobufs.TokenRequest_Mint:
|
||||
if t == nil {
|
||||
fails[i] = transition
|
||||
continue
|
||||
}
|
||||
throttle <- struct{}{}
|
||||
wg.Add(1)
|
||||
go func(i int, transition *protobufs.TokenRequest) {
|
||||
defer func() { <-throttle }()
|
||||
defer wg.Done()
|
||||
if err := t.Mint.Validate(); err != nil {
|
||||
fails[i] = transition
|
||||
}
|
||||
}(i, transition)
|
||||
}
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
parallelismMap := map[int]uint64{}
|
||||
if len(a.Tries) > 1 {
|
||||
for i := range a.Tries[1:] {
|
||||
@ -153,38 +183,30 @@ func (a *TokenApplication) ApplyTransitions(
|
||||
|
||||
seen := map[string]struct{}{}
|
||||
|
||||
set := make([]*protobufs.TokenRequest, len(requests))
|
||||
fails := make([]*protobufs.TokenRequest, len(set))
|
||||
outputsSet := make([][]*protobufs.TokenOutput, len(set))
|
||||
|
||||
for i, transition := range requests {
|
||||
i := i
|
||||
if fails[i] != nil {
|
||||
continue
|
||||
}
|
||||
switch t := transition.Request.(type) {
|
||||
case *protobufs.TokenRequest_Mint:
|
||||
if t == nil {
|
||||
fails[i] = transition
|
||||
continue
|
||||
}
|
||||
if err := t.Mint.Validate(); err != nil {
|
||||
fails[i] = transition
|
||||
continue
|
||||
}
|
||||
|
||||
addr, err := poseidon.HashBytes(
|
||||
t.Mint.Signature.PublicKey.KeyValue,
|
||||
)
|
||||
if err != nil {
|
||||
fails[i] = transition
|
||||
continue
|
||||
}
|
||||
|
||||
if len(t.Mint.Proofs) == 1 && a.Tries[0].Contains(
|
||||
addr.FillBytes(make([]byte, 32)),
|
||||
) && bytes.Equal(t.Mint.Signature.PublicKey.KeyValue, a.Beacon) {
|
||||
if _, ok := seen[string(t.Mint.Proofs[0][32:])]; !ok {
|
||||
set[i] = transition
|
||||
seen[string(t.Mint.Proofs[0][32:])] = struct{}{}
|
||||
if len(t.Mint.Proofs) == 1 {
|
||||
addr, err := poseidon.HashBytes(
|
||||
t.Mint.Signature.PublicKey.KeyValue,
|
||||
)
|
||||
if err != nil {
|
||||
fails[i] = transition
|
||||
continue
|
||||
}
|
||||
if a.Tries[0].Contains(addr.FillBytes(make([]byte, 32))) &&
|
||||
bytes.Equal(t.Mint.Signature.PublicKey.KeyValue, a.Beacon) {
|
||||
if _, ok := seen[string(t.Mint.Proofs[0][32:])]; !ok {
|
||||
set[i] = transition
|
||||
seen[string(t.Mint.Proofs[0][32:])] = struct{}{}
|
||||
continue
|
||||
}
|
||||
}
|
||||
fails[i] = transition
|
||||
continue
|
||||
} else if len(t.Mint.Proofs) >= 3 && currentFrameNumber > PROOF_FRAME_CUTOFF {
|
||||
frameNumber := binary.BigEndian.Uint64(t.Mint.Proofs[2])
|
||||
if frameNumber < currentFrameNumber-2 {
|
||||
@ -222,6 +244,7 @@ func (a *TokenApplication) ApplyTransitions(
|
||||
}
|
||||
}
|
||||
|
||||
outputsSet := make([][]*protobufs.TokenOutput, len(set))
|
||||
successes := make([]*protobufs.TokenRequest, len(set))
|
||||
for i, transition := range set {
|
||||
if transition == nil {
|
||||
@ -363,18 +386,15 @@ func (a *TokenApplication) ApplyTransitions(
|
||||
}
|
||||
}
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
throttle := make(chan struct{}, qruntime.WorkerCount(0, false))
|
||||
for i, transition := range set {
|
||||
if transition == nil {
|
||||
continue
|
||||
}
|
||||
i, transition := i, transition
|
||||
switch t := transition.Request.(type) {
|
||||
case *protobufs.TokenRequest_Mint:
|
||||
throttle <- struct{}{}
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
go func(i int, transition *protobufs.TokenRequest) {
|
||||
defer func() { <-throttle }()
|
||||
defer wg.Done()
|
||||
success, err := a.handleMint(
|
||||
@ -389,7 +409,7 @@ func (a *TokenApplication) ApplyTransitions(
|
||||
}
|
||||
outputsSet[i] = success
|
||||
successes[i] = transition
|
||||
}()
|
||||
}(i, transition)
|
||||
}
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
@ -12,7 +12,6 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/crypto/sha3"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/crypto"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/store"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/tries"
|
||||
@ -58,16 +57,17 @@ func (a *TokenApplication) handleMint(
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle mint")
|
||||
}
|
||||
addrBytes := addr.FillBytes(make([]byte, 32))
|
||||
|
||||
altAddr, err := poseidon.HashBytes([]byte(peerId))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle mint")
|
||||
}
|
||||
altAddrBytes := altAddr.FillBytes(make([]byte, 32))
|
||||
|
||||
// todo: set termination frame for this:
|
||||
if len(t.Proofs) == 1 && a.Tries[0].Contains(
|
||||
addr.FillBytes(make([]byte, 32)),
|
||||
) && bytes.Equal(t.Signature.PublicKey.KeyValue, a.Beacon) {
|
||||
if len(t.Proofs) == 1 && a.Tries[0].Contains(addrBytes) &&
|
||||
bytes.Equal(t.Signature.PublicKey.KeyValue, a.Beacon) {
|
||||
if len(t.Proofs[0]) != 64 {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle mint")
|
||||
}
|
||||
@ -126,14 +126,12 @@ func (a *TokenApplication) handleMint(
|
||||
)
|
||||
ring := -1
|
||||
for i, t := range a.Tries[1:] {
|
||||
if t.Contains(altAddr.FillBytes(make([]byte, 32))) {
|
||||
if t.Contains(altAddrBytes) {
|
||||
ring = i
|
||||
}
|
||||
}
|
||||
|
||||
_, prfs, err := a.CoinStore.GetPreCoinProofsForOwner(
|
||||
altAddr.FillBytes(make([]byte, 32)),
|
||||
)
|
||||
_, prfs, err := a.CoinStore.GetPreCoinProofsForOwner(altAddrBytes)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle mint")
|
||||
}
|
||||
@ -167,7 +165,7 @@ func (a *TokenApplication) handleMint(
|
||||
Account: &protobufs.AccountRef_ImplicitAccount{
|
||||
ImplicitAccount: &protobufs.ImplicitAccount{
|
||||
ImplicitType: 0,
|
||||
Address: altAddr.FillBytes(make([]byte, 32)),
|
||||
Address: altAddrBytes,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -195,7 +193,7 @@ func (a *TokenApplication) handleMint(
|
||||
Account: &protobufs.AccountRef_ImplicitAccount{
|
||||
ImplicitAccount: &protobufs.ImplicitAccount{
|
||||
ImplicitType: 0,
|
||||
Address: altAddr.FillBytes(make([]byte, 32)),
|
||||
Address: altAddrBytes,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -255,7 +253,7 @@ func (a *TokenApplication) handleMint(
|
||||
Account: &protobufs.AccountRef_ImplicitAccount{
|
||||
ImplicitAccount: &protobufs.ImplicitAccount{
|
||||
ImplicitType: 0,
|
||||
Address: altAddr.FillBytes(make([]byte, 32)),
|
||||
Address: altAddrBytes,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -293,7 +291,7 @@ func (a *TokenApplication) handleMint(
|
||||
Account: &protobufs.AccountRef_ImplicitAccount{
|
||||
ImplicitAccount: &protobufs.ImplicitAccount{
|
||||
ImplicitType: 0,
|
||||
Address: altAddr.FillBytes(make([]byte, 32)),
|
||||
Address: altAddrBytes,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -302,9 +300,8 @@ func (a *TokenApplication) handleMint(
|
||||
}}, nil
|
||||
}
|
||||
|
||||
wesoProver := crypto.NewWesolowskiFrameProver(a.Logger)
|
||||
if bytes.Equal(leaf, bytes.Repeat([]byte{0x00}, 516)) ||
|
||||
!wesoProver.VerifyChallengeProof(
|
||||
!a.FrameProver.VerifyChallengeProof(
|
||||
individualChallenge,
|
||||
frame.Difficulty,
|
||||
leaf,
|
||||
@ -339,6 +336,7 @@ func (a *TokenApplication) handleMint(
|
||||
}
|
||||
storage.Quo(storage, big.NewInt(int64(m)))
|
||||
storage.Mul(storage, big.NewInt(int64(parallelism)))
|
||||
storageBytes := storage.FillBytes(make([]byte, 32))
|
||||
|
||||
a.Logger.Debug(
|
||||
"issued reward",
|
||||
@ -356,14 +354,14 @@ func (a *TokenApplication) handleMint(
|
||||
append([]byte{}, newCommitment...),
|
||||
newFrameNumber,
|
||||
),
|
||||
Amount: storage.FillBytes(make([]byte, 32)),
|
||||
Amount: storageBytes,
|
||||
Proof: payload,
|
||||
Difficulty: a.Difficulty,
|
||||
Owner: &protobufs.AccountRef{
|
||||
Account: &protobufs.AccountRef_ImplicitAccount{
|
||||
ImplicitAccount: &protobufs.ImplicitAccount{
|
||||
ImplicitType: 0,
|
||||
Address: altAddr.FillBytes(make([]byte, 32)),
|
||||
Address: altAddrBytes,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -373,13 +371,13 @@ func (a *TokenApplication) handleMint(
|
||||
&protobufs.TokenOutput{
|
||||
Output: &protobufs.TokenOutput_Coin{
|
||||
Coin: &protobufs.Coin{
|
||||
Amount: storage.FillBytes(make([]byte, 32)),
|
||||
Amount: storageBytes,
|
||||
Intersection: make([]byte, 1024),
|
||||
Owner: &protobufs.AccountRef{
|
||||
Account: &protobufs.AccountRef_ImplicitAccount{
|
||||
ImplicitAccount: &protobufs.ImplicitAccount{
|
||||
ImplicitType: 0,
|
||||
Address: altAddr.FillBytes(make([]byte, 32)),
|
||||
Address: altAddrBytes,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -403,7 +401,7 @@ func (a *TokenApplication) handleMint(
|
||||
Account: &protobufs.AccountRef_ImplicitAccount{
|
||||
ImplicitAccount: &protobufs.ImplicitAccount{
|
||||
ImplicitType: 0,
|
||||
Address: altAddr.FillBytes(make([]byte, 32)),
|
||||
Address: altAddrBytes,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -421,7 +419,7 @@ func (a *TokenApplication) handleMint(
|
||||
Account: &protobufs.AccountRef_ImplicitAccount{
|
||||
ImplicitAccount: &protobufs.ImplicitAccount{
|
||||
ImplicitType: 0,
|
||||
Address: altAddr.FillBytes(make([]byte, 32)),
|
||||
Address: altAddrBytes,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -27,6 +27,7 @@ import (
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/execution"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/execution/intrinsics/token/application"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/internal/frametime"
|
||||
qruntime "source.quilibrium.com/quilibrium/monorepo/node/internal/runtime"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/keys"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/p2p"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
|
||||
@ -528,6 +529,7 @@ func (e *TokenExecutionEngine) ProcessFrame(
|
||||
e.clockStore,
|
||||
e.pubSub,
|
||||
e.logger,
|
||||
e.frameProver,
|
||||
)
|
||||
if err != nil {
|
||||
e.logger.Error(
|
||||
@ -547,10 +549,32 @@ func (e *TokenExecutionEngine) ProcessFrame(
|
||||
mapSnapshot := ToSerializedMap(e.peerSeniority)
|
||||
activeMap := NewFromMap(mapSnapshot)
|
||||
|
||||
outputAddresses := make([][]byte, len(app.TokenOutputs.Outputs))
|
||||
outputAddressErrors := make([]error, len(app.TokenOutputs.Outputs))
|
||||
wg := sync.WaitGroup{}
|
||||
throttle := make(chan struct{}, qruntime.WorkerCount(0, false))
|
||||
for i, output := range app.TokenOutputs.Outputs {
|
||||
throttle <- struct{}{}
|
||||
wg.Add(1)
|
||||
go func(i int, output *protobufs.TokenOutput) {
|
||||
defer func() { <-throttle }()
|
||||
defer wg.Done()
|
||||
switch o := output.Output.(type) {
|
||||
case *protobufs.TokenOutput_Coin:
|
||||
outputAddresses[i], outputAddressErrors[i] = GetAddressOfCoin(o.Coin, frame.FrameNumber, uint64(i))
|
||||
case *protobufs.TokenOutput_Proof:
|
||||
outputAddresses[i], outputAddressErrors[i] = GetAddressOfPreCoinProof(o.Proof)
|
||||
case *protobufs.TokenOutput_DeletedProof:
|
||||
outputAddresses[i], outputAddressErrors[i] = GetAddressOfPreCoinProof(o.DeletedProof)
|
||||
}
|
||||
}(i, output)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
for i, output := range app.TokenOutputs.Outputs {
|
||||
switch o := output.Output.(type) {
|
||||
case *protobufs.TokenOutput_Coin:
|
||||
address, err := GetAddressOfCoin(o.Coin, frame.FrameNumber, uint64(i))
|
||||
address, err := outputAddresses[i], outputAddressErrors[i]
|
||||
if err != nil {
|
||||
txn.Abort()
|
||||
return nil, errors.Wrap(err, "process frame")
|
||||
@ -581,7 +605,7 @@ func (e *TokenExecutionEngine) ProcessFrame(
|
||||
return nil, errors.Wrap(err, "process frame")
|
||||
}
|
||||
case *protobufs.TokenOutput_Proof:
|
||||
address, err := GetAddressOfPreCoinProof(o.Proof)
|
||||
address, err := outputAddresses[i], outputAddressErrors[i]
|
||||
if err != nil {
|
||||
txn.Abort()
|
||||
return nil, errors.Wrap(err, "process frame")
|
||||
@ -619,7 +643,7 @@ func (e *TokenExecutionEngine) ProcessFrame(
|
||||
}
|
||||
}
|
||||
case *protobufs.TokenOutput_DeletedProof:
|
||||
address, err := GetAddressOfPreCoinProof(o.DeletedProof)
|
||||
address, err := outputAddresses[i], outputAddressErrors[i]
|
||||
if err != nil {
|
||||
txn.Abort()
|
||||
return nil, errors.Wrap(err, "process frame")
|
||||
@ -1175,6 +1199,7 @@ func (e *TokenExecutionEngine) VerifyExecution(
|
||||
e.clockStore,
|
||||
e.pubSub,
|
||||
e.logger,
|
||||
e.frameProver,
|
||||
)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "verify execution")
|
||||
@ -1197,6 +1222,7 @@ func (e *TokenExecutionEngine) VerifyExecution(
|
||||
e.clockStore,
|
||||
e.pubSub,
|
||||
e.logger,
|
||||
e.frameProver,
|
||||
)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "verify execution")
|
||||
|
||||
@ -794,6 +794,7 @@ func processFrame(
|
||||
clockStore,
|
||||
nil,
|
||||
logger,
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
logger.Error(
|
||||
|
||||
@ -68,9 +68,7 @@ func PackOutputIntoPayloadAndProof(
|
||||
"pack output into payload and proof",
|
||||
)
|
||||
}
|
||||
for _, sib := range previousTree.Proofs[int(pick)].Siblings {
|
||||
output = append(output, sib)
|
||||
}
|
||||
output = append(output, previousTree.Proofs[int(pick)].Siblings...)
|
||||
output = append(
|
||||
output,
|
||||
binary.BigEndian.AppendUint32(
|
||||
@ -98,11 +96,6 @@ func UnpackAndVerifyOutput(
|
||||
modulo = binary.BigEndian.Uint32(output[1])
|
||||
frameNumber = binary.BigEndian.Uint64(output[2])
|
||||
|
||||
payload := []byte("mint")
|
||||
payload = append(payload, treeRoot...)
|
||||
payload = binary.BigEndian.AppendUint32(payload, modulo)
|
||||
payload = binary.BigEndian.AppendUint64(payload, frameNumber)
|
||||
|
||||
if len(output) > 3 {
|
||||
numSiblings := bits.Len64(uint64(modulo) - 1)
|
||||
if len(output) != 5+numSiblings {
|
||||
@ -113,16 +106,8 @@ func UnpackAndVerifyOutput(
|
||||
}
|
||||
|
||||
siblings := output[3 : 3+numSiblings]
|
||||
for _, sib := range siblings {
|
||||
payload = append(payload, sib...)
|
||||
}
|
||||
|
||||
pathBytes := output[3+numSiblings]
|
||||
path := binary.BigEndian.Uint32(pathBytes)
|
||||
payload = binary.BigEndian.AppendUint32(payload, path)
|
||||
|
||||
path := binary.BigEndian.Uint32(output[3+numSiblings])
|
||||
leaf := output[len(output)-1]
|
||||
payload = append(payload, leaf...)
|
||||
|
||||
verified, err = mt.Verify(
|
||||
NewProofLeaf(leaf),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user