77 "crypto/rand"
88 "encoding/binary"
99 "encoding/hex"
10+ "fmt"
1011 "io"
1112 "math/big"
1213 "sync"
@@ -15,9 +16,12 @@ import (
1516 "github.com/iden3/go-iden3-crypto/poseidon"
1617 "github.com/libp2p/go-libp2p/core/peer"
1718 "github.com/mr-tron/base58"
19+ "github.com/multiformats/go-multiaddr"
20+ mn "github.com/multiformats/go-multiaddr/net"
1821 "github.com/pkg/errors"
1922 "go.uber.org/zap"
2023 "google.golang.org/grpc"
24+ "google.golang.org/grpc/credentials/insecure"
2125 "source.quilibrium.com/quilibrium/monorepo/node/config"
2226 "source.quilibrium.com/quilibrium/monorepo/node/consensus"
2327 qtime "source.quilibrium.com/quilibrium/monorepo/node/consensus/time"
@@ -68,6 +72,7 @@ type MasterClockConsensusEngine struct {
6872 verifyTestCh chan verifyChallenge
6973 currentReceivingSyncPeers int
7074 currentReceivingSyncPeersMx sync.Mutex
75+ engineConfig * config.EngineConfig
7176}
7277
7378var _ consensus.ConsensusEngine = (* MasterClockConsensusEngine )(nil )
@@ -131,6 +136,7 @@ func NewMasterClockConsensusEngine(
131136 frameValidationCh : make (chan * protobufs.ClockFrame ),
132137 bandwidthTestCh : make (chan []byte ),
133138 verifyTestCh : make (chan verifyChallenge ),
139+ engineConfig : engineConfig ,
134140 }
135141
136142 e .addPeerManifestReport (e .pubSub .GetPeerID (), report )
@@ -241,6 +247,16 @@ func (e *MasterClockConsensusEngine) Start() <-chan error {
241247 time .Sleep (30 * time .Second )
242248 difficultyMetric := int64 (100000 )
243249 skew := (difficultyMetric * 12 ) / 10
250+ parallelism := e .report .Cores - 1
251+
252+ if parallelism < 3 {
253+ panic ("invalid system configuration, minimum system configuration must be four cores" )
254+ }
255+
256+ clients , err := e .createParallelDataClients (int (parallelism ))
257+ if err != nil {
258+ panic (err )
259+ }
244260
245261 for {
246262 head , err := e .masterTimeReel .Head ()
@@ -250,23 +266,49 @@ func (e *MasterClockConsensusEngine) Start() <-chan error {
250266
251267 e .report .MasterHeadFrame = head .FrameNumber
252268 e .report .DifficultyMetric = difficultyMetric
253- parallelism := e .report .Cores - 1
254269
255270 challenge := binary .BigEndian .AppendUint64 (
256271 []byte {},
257272 e .report .MasterHeadFrame ,
258273 )
259274 challenge = append (challenge , e .pubSub .GetPeerID ()... )
260275
261- ts , proofs , nextDifficultyMetric , err :=
262- e .frameProver .CalculateChallengeProof (
263- challenge ,
264- parallelism ,
265- skew ,
266- )
267- if err != nil {
268- panic (err )
276+ proofs := make ([][]byte , parallelism )
277+ nextMetrics := make ([]int64 , parallelism )
278+
279+ wg := sync.WaitGroup {}
280+ wg .Add (int (parallelism ))
281+
282+ ts := time .Now ().UnixMilli ()
283+ for i := uint32 (0 ); i < parallelism ; i ++ {
284+ i := i
285+ go func () {
286+ resp , err :=
287+ clients [i ].CalculateChallengeProof (
288+ context .Background (),
289+ & protobufs.ChallengeProofRequest {
290+ Challenge : challenge ,
291+ Core : i ,
292+ Skew : skew ,
293+ NowMs : ts ,
294+ },
295+ )
296+ if err != nil {
297+ panic (err )
298+ }
299+
300+ proofs [i ], nextMetrics [i ] = resp .Output , resp .NextSkew
301+ wg .Done ()
302+ }()
269303 }
304+ wg .Wait ()
305+ nextDifficultySum := uint64 (0 )
306+ for i := 0 ; i < int (parallelism ); i ++ {
307+ nextDifficultySum += uint64 (nextMetrics [i ])
308+ }
309+
310+ nextDifficultyMetric := int64 (nextDifficultySum / uint64 (parallelism ))
311+
270312 e .logger .Info (
271313 "recalibrating difficulty metric" ,
272314 zap .Int64 ("previous_difficulty_metric" , difficultyMetric ),
@@ -336,6 +378,64 @@ func (e *MasterClockConsensusEngine) Start() <-chan error {
336378 return errChan
337379}
338380
381+ func (e * MasterClockConsensusEngine ) createParallelDataClients (
382+ paralellism int ,
383+ ) ([]protobufs.DataIPCServiceClient , error ) {
384+ e .logger .Info (
385+ "connecting to data worker processes" ,
386+ zap .Int ("parallelism" , paralellism ),
387+ )
388+
389+ if e .engineConfig .DataWorkerBaseListenMultiaddr == "" {
390+ e .engineConfig .DataWorkerBaseListenMultiaddr = "/ip4/127.0.0.1/tcp/%d"
391+ }
392+
393+ if e .engineConfig .DataWorkerBaseListenPort == 0 {
394+ e .engineConfig .DataWorkerBaseListenPort = 40000
395+ }
396+
397+ clients := make ([]protobufs.DataIPCServiceClient , paralellism )
398+
399+ for i := 0 ; i < paralellism ; i ++ {
400+ ma , err := multiaddr .NewMultiaddr (
401+ fmt .Sprintf (
402+ e .engineConfig .DataWorkerBaseListenMultiaddr ,
403+ int (e .engineConfig .DataWorkerBaseListenPort )+ i ,
404+ ),
405+ )
406+ if err != nil {
407+ panic (err )
408+ }
409+
410+ _ , addr , err := mn .DialArgs (ma )
411+ if err != nil {
412+ panic (err )
413+ }
414+
415+ conn , err := grpc .Dial (
416+ addr ,
417+ grpc .WithTransportCredentials (
418+ insecure .NewCredentials (),
419+ ),
420+ grpc .WithDefaultCallOptions (
421+ grpc .MaxCallSendMsgSize (10 * 1024 * 1024 ),
422+ grpc .MaxCallRecvMsgSize (10 * 1024 * 1024 ),
423+ ),
424+ )
425+ if err != nil {
426+ panic (err )
427+ }
428+
429+ clients [i ] = protobufs .NewDataIPCServiceClient (conn )
430+ }
431+
432+ e .logger .Info (
433+ "connected to data worker processes" ,
434+ zap .Int ("parallelism" , paralellism ),
435+ )
436+ return clients , nil
437+ }
438+
339439func (e * MasterClockConsensusEngine ) PerformValidation (
340440 ctx context.Context ,
341441 msg * protobufs.ValidationMessage ,
0 commit comments