produceBlock prepares, signs and advises the pending block to the other peers.
(now time.Time)
| 466 | |
| 467 | // produceBlock prepares, signs and advises the pending block to the other peers. |
| 468 | func (c *Chain) produceBlock(now time.Time) (err error) { |
| 469 | var ( |
| 470 | frs []*types.Request |
| 471 | qts []*x.QueryTracker |
| 472 | ) |
| 473 | if frs, qts, err = c.st.CommitEx(); err != nil { |
| 474 | err = errors.Wrap(err, "failed to fetch query list from db state") |
| 475 | return |
| 476 | } |
| 477 | if len(frs) == 0 && len(qts) == 0 { |
| 478 | c.logEntryWithHeadState().Debug("no query found in current period, skip block producing") |
| 479 | return |
| 480 | } |
| 481 | var block = &types.Block{ |
| 482 | SignedHeader: types.SignedHeader{ |
| 483 | Header: types.Header{ |
| 484 | Version: 0x01000000, |
| 485 | Producer: c.rt.getServer(), |
| 486 | GenesisHash: c.rt.genesisHash, |
| 487 | ParentHash: c.rt.getHead().Head, |
| 488 | // MerkleRoot: will be set by BPBlock.PackAndSignBlock(PrivateKey) |
| 489 | Timestamp: now, |
| 490 | }, |
| 491 | }, |
| 492 | FailedReqs: frs, |
| 493 | QueryTxs: make([]*types.QueryAsTx, len(qts)), |
| 494 | Acks: c.ai.acks(c.rt.getHeightFromTime(now)), |
| 495 | } |
| 496 | for i, v := range qts { |
| 497 | // TODO(leventeliu): maybe block waiting at a ready channel instead? |
| 498 | for !v.Ready() { |
| 499 | time.Sleep(c.rt.period / 10) |
| 500 | if c.rt.ctx.Err() != nil { |
| 501 | err = c.rt.ctx.Err() |
| 502 | return |
| 503 | } |
| 504 | } |
| 505 | block.QueryTxs[i] = &types.QueryAsTx{ |
| 506 | // TODO(leventeliu): add acks for billing. |
| 507 | Request: v.Req, |
| 508 | Response: &v.Resp.Header, |
| 509 | } |
| 510 | } |
| 511 | // Sign block |
| 512 | if err = block.PackAndSignBlock(c.pk); err != nil { |
| 513 | return |
| 514 | } |
| 515 | // Send to pending list |
| 516 | le := c.logEntryWithHeadState().WithFields(log.Fields{ |
| 517 | "using_timestamp": now.Format(time.RFC3339Nano), |
| 518 | "block_hash": block.BlockHash().String(), |
| 519 | }) |
| 520 | select { |
| 521 | case c.blocks <- block: |
| 522 | case <-c.rt.ctx.Done(): |
| 523 | err = c.rt.ctx.Err() |
| 524 | le.WithError(err).Info("abort block producing") |
| 525 | return |
no test coverage detected