// blockParts: Must be parts of the block // seenValidation: The +2/3 precommits that were seen which committed at height. // If all the nodes restart after committing a block, // we need this to reload the precommits to catch-up nodes to the // most recent height. Otherwise they'd stall at H-1. func (bs *BlockStore) SaveBlock(block *types.Block, blockParts *types.PartSet, seenValidation *types.Validation) { height := block.Height if height != bs.height+1 { PanicSanity(Fmt("BlockStore can only save contiguous blocks. Wanted %v, got %v", bs.height+1, height)) } if !blockParts.IsComplete() { PanicSanity(Fmt("BlockStore can only save complete block part sets")) } // Save block meta meta := types.NewBlockMeta(block, blockParts) metaBytes := wire.BinaryBytes(meta) bs.db.Set(calcBlockMetaKey(height), metaBytes) // Save block parts for i := 0; i < blockParts.Total(); i++ { bs.saveBlockPart(height, i, blockParts.GetPart(i)) } // Save block validation (duplicate and separate from the Block) blockValidationBytes := wire.BinaryBytes(block.LastValidation) bs.db.Set(calcBlockValidationKey(height-1), blockValidationBytes) // Save seen validation (seen +2/3 precommits for block) seenValidationBytes := wire.BinaryBytes(seenValidation) bs.db.Set(calcSeenValidationKey(height), seenValidationBytes) // Save new BlockStoreStateJSON descriptor BlockStoreStateJSON{Height: height}.Save(bs.db) // Done! bs.height = height }