MCPcopy Index your code
hub / github.com/CovenantSQL/CovenantSQL / CheckAndPushNewBlock

Method CheckAndPushNewBlock

sqlchain/chain.go:932–1000  ·  view source on GitHub ↗

CheckAndPushNewBlock implements ChainRPCServer.CheckAndPushNewBlock.

(block *types.Block)

Source from the content-addressed store, hash-verified

930
931// CheckAndPushNewBlock implements ChainRPCServer.CheckAndPushNewBlock.
932func (c *Chain) CheckAndPushNewBlock(block *types.Block) (err error) {
933 height := c.rt.getHeightFromTime(block.Timestamp())
934 head := c.rt.getHead()
935 peers := c.rt.getPeers()
936 total := int32(len(peers.Servers))
937 next := func() int32 {
938 if total > 0 {
939 return (c.rt.getNextTurn() - 1) % total
940 }
941 return -1
942 }()
943 le := c.logEntryWithHeadState().WithFields(log.Fields{
944 "block": block.BlockHash().String(),
945 "producer": block.Producer(),
946 "blocktime": block.Timestamp().Format(time.RFC3339Nano),
947 "blockheight": height,
948 "blockparent": block.ParentHash().String(),
949 })
950 le.Debug("checking new block from other peer")
951
952 if head.Height == height && head.Head.IsEqual(block.BlockHash()) {
953 // Maybe already set by FetchBlock
954 return nil
955 } else if !block.ParentHash().IsEqual(&head.Head) {
956 err = ErrInvalidBlock
957 le.WithError(err).Error("invalid new block for the current chain")
958 return ErrInvalidBlock
959 }
960
961 // Verify block signatures
962 if err = block.Verify(); err != nil {
963 le.WithError(err).Error("failed to verify block")
964 return
965 }
966
967 // Short circuit the checking process if it's a self-produced block
968 if block.Producer() == c.rt.server {
969 return c.pushBlock(block)
970 }
971 // Check block producer
972 index, found := peers.Find(block.Producer())
973 if !found {
974 err = ErrUnknownProducer
975 le.WithError(err).Error("unknown producer of new block")
976 return ErrUnknownProducer
977 }
978
979 if index != next {
980 err = ErrInvalidProducer
981 le.WithFields(log.Fields{
982 "expected": next,
983 "actual": index,
984 }).WithError(err).Error("invalid producer of new block")
985 return
986 }
987
988 // TODO(leventeliu): check if too many periods are skipped or store block for future use.
989 // if height-c.rt.getHead().Height > X {

Callers 1

processBlocksMethod · 0.95

Calls 15

logEntryWithHeadStateMethod · 0.95
pushBlockMethod · 0.95
getHeightFromTimeMethod · 0.80
getPeersMethod · 0.80
getNextTurnMethod · 0.80
WithFieldsMethod · 0.80
DebugMethod · 0.80
ErrorMethod · 0.80
WithErrorMethod · 0.80
FindMethod · 0.80
VerifyMethod · 0.65

Tested by

no test coverage detected