Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/block_view_lockups_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2353,7 +2353,7 @@ func TestLockupBlockConnectsAndDisconnects(t *testing.T) {
// Process the first block
err = testMeta.miner.BlockProducer.SignBlock(blk1)
require.NoError(t, err)
_, _, _, err = testMeta.chain.ProcessBlock(blk1, false)
_, _, _, err = testMeta.chain.ProcessBlock(blk1, nil, false)
require.NoError(t, err)

// Validate state update
Expand Down Expand Up @@ -2417,7 +2417,7 @@ func TestLockupBlockConnectsAndDisconnects(t *testing.T) {
// Process the second block
err = testMeta.miner.BlockProducer.SignBlock(blk2)
require.NoError(t, err)
_, _, _, err = testMeta.chain.ProcessBlock(blk2, false)
_, _, _, err = testMeta.chain.ProcessBlock(blk2, nil, false)
require.NoError(t, err)

// Validate state update
Expand Down
27 changes: 17 additions & 10 deletions lib/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -2214,13 +2214,17 @@ func (bc *Blockchain) ProcessHeader(blockHeader *MsgDeSoHeader, headerHash *Bloc
// If the header's height is after the PoS cut-over fork height, then we use the PoS header processing logic.
// Otherwise, fall back to the PoW logic.
if bc.params.IsPoSBlockHeight(blockHeader.Height) {
return bc.processHeaderPoS(blockHeader, verifySignatures)
return bc.processHeaderPoS(blockHeader, headerHash, verifySignatures)
}

return bc.processHeaderPoW(blockHeader, headerHash)
}

func (bc *Blockchain) ProcessBlock(desoBlock *MsgDeSoBlock, verifySignatures bool) (_isMainChain bool, _isOrphan bool, _missingBlockHashes []*BlockHash, _err error) {
func (bc *Blockchain) ProcessBlock(
desoBlock *MsgDeSoBlock,
hash *BlockHash, // hash is not required and will be computed if not provided, but speeds things up if provided.
verifySignatures bool,
) (_isMainChain bool, _isOrphan bool, _missingBlockHashes []*BlockHash, _err error) {
bc.ChainLock.Lock()
defer bc.ChainLock.Unlock()

Expand All @@ -2232,14 +2236,14 @@ func (bc *Blockchain) ProcessBlock(desoBlock *MsgDeSoBlock, verifySignatures boo
// If the block's height is after the PoS cut-over fork height, then we use the PoS block processing logic.
// Otherwise, fall back to the PoW logic.
if bc.params.IsPoSBlockHeight(desoBlock.Header.Height) {
return bc.processBlockPoS(desoBlock, 1, verifySignatures)
return bc.processBlockPoS(desoBlock, hash, 1, verifySignatures)
}

isMainChain, isOrphan, err := bc.processBlockPoW(desoBlock, verifySignatures)
isMainChain, isOrphan, err := bc.processBlockPoW(desoBlock, hash, verifySignatures)
return isMainChain, isOrphan, nil, err
}

func (bc *Blockchain) processBlockPoW(desoBlock *MsgDeSoBlock, verifySignatures bool) (_isMainChain bool, _isOrphan bool, err error) {
func (bc *Blockchain) processBlockPoW(desoBlock *MsgDeSoBlock, blockHash *BlockHash, verifySignatures bool) (_isMainChain bool, _isOrphan bool, err error) {
// Only accept the block if its height is below the PoS cutover height.
if !bc.params.IsPoWBlockHeight(desoBlock.Header.Height) {
return false, false, RuleErrorBlockHeightAfterProofOfStakeCutover
Expand All @@ -2253,10 +2257,13 @@ func (bc *Blockchain) processBlockPoW(desoBlock *MsgDeSoBlock, verifySignatures
if blockHeader == nil {
return false, false, fmt.Errorf("ProcessBlock: Block header was nil")
}
blockHash, err := blockHeader.Hash()
if err != nil {
return false, false, errors.Wrapf(err, "ProcessBlock: Problem computing block hash")
if blockHash == nil {
blockHash, err = blockHeader.Hash()
if err != nil {
return false, false, errors.Wrapf(err, "ProcessBlock: Problem computing block hash")
}
}

// If a trusted block producer public key is set, then we only accept blocks
// if they have been signed by one of these public keys.
if len(bc.trustedBlockProducerPublicKeys) > 0 {
Expand Down Expand Up @@ -2484,7 +2491,7 @@ func (bc *Blockchain) processBlockPoW(desoBlock *MsgDeSoBlock, verifySignatures
// This is needed for disconnects, otherwise GetBlock() will fail (e.g. when we reorg).
if err == nil {
err = bc.db.Update(func(txn *badger.Txn) error {
if err := PutBlockWithTxn(txn, nil, desoBlock, bc.eventManager); err != nil {
if err := PutBlockWithTxn(txn, nil, desoBlock, blockHash, bc.eventManager); err != nil {
return errors.Wrapf(err, "ProcessBlock: Problem putting block with txns")
}
return nil
Expand All @@ -2503,7 +2510,7 @@ func (bc *Blockchain) processBlockPoW(desoBlock *MsgDeSoBlock, verifySignatures
// set in PutBlockWithTxn. Block rewards are part of the state, and they should be identical to the ones
// we've fetched during Hypersync. Is there an edge-case where for some reason they're not identical? Or
// somehow ancestral records get corrupted?
if innerErr := PutBlockWithTxn(txn, bc.snapshot, desoBlock, bc.eventManager); innerErr != nil {
if innerErr := PutBlockWithTxn(txn, bc.snapshot, desoBlock, blockHash, bc.eventManager); innerErr != nil {
return errors.Wrapf(err, "ProcessBlock: Problem calling PutBlock")
}

Expand Down
16 changes: 8 additions & 8 deletions lib/blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ func TestBasicTransferReorg(t *testing.T) {
// Process all of the fork blocks on the original chain to make it
// experience a reorg.
for _, forkBlock := range forkBlocks {
_, _, _, err := chain1.ProcessBlock(forkBlock, true /*verifySignatures*/)
_, _, _, err := chain1.ProcessBlock(forkBlock, nil, true /*verifySignatures*/)
require.NoError(err)
}

Expand Down Expand Up @@ -661,7 +661,7 @@ func _shouldConnectBlock(blk *MsgDeSoBlock, t *testing.T, chain *Blockchain) {
blockHash, _ := blk.Hash()

verifySignatures := true
isMainChain, isOrphan, _, err := chain.ProcessBlock(blk, verifySignatures)
isMainChain, isOrphan, _, err := chain.ProcessBlock(blk, blockHash, verifySignatures)
require.NoError(err)
require.Falsef(isOrphan, "Block %v should not be an orphan", blockHash)
require.Truef(isMainChain, "Block %v should be on the main chain", blockHash)
Expand Down Expand Up @@ -826,7 +826,7 @@ func TestProcessBlockReorgBlocks(t *testing.T) {
// Block b1
fmt.Println("Connecting block b1")
require.Equal(uint64(3), GetUtxoNumEntries(db, chain.snapshot))
isMainChain, isOrphan, _, err := chain.ProcessBlock(blockB1, verifySignatures)
isMainChain, isOrphan, _, err := chain.ProcessBlock(blockB1, nil, verifySignatures)
require.NoError(err)
require.Falsef(isOrphan, "Block b1 should not be an orphan")
require.Falsef(isMainChain, "Block b1 should not be on the main chain")
Expand All @@ -842,7 +842,7 @@ func TestProcessBlockReorgBlocks(t *testing.T) {
// Block b2
fmt.Println("Connecting block b2")
require.Equal(uint64(3), GetUtxoNumEntries(db, chain.snapshot))
isMainChain, isOrphan, _, err := chain.ProcessBlock(blockB2, verifySignatures)
isMainChain, isOrphan, _, err := chain.ProcessBlock(blockB2, nil, verifySignatures)
require.NoError(err)
require.Falsef(isOrphan, "Block b2 should not be an orphan")
require.Falsef(isMainChain, "Block b2 should not be on the main chain")
Expand Down Expand Up @@ -1672,7 +1672,7 @@ func TestBadBlockSignature(t *testing.T) {

// A bad signature with the right public key should fail.
finalBlock1.BlockProducerInfo.PublicKey = senderPkBytes
_, _, _, err = chain.ProcessBlock(finalBlock1, true)
_, _, _, err = chain.ProcessBlock(finalBlock1, nil, true)
require.Error(err)
require.Contains(err.Error(), RuleErrorInvalidBlockProducerSIgnature)

Expand All @@ -1681,20 +1681,20 @@ func TestBadBlockSignature(t *testing.T) {
require.NoError(err)
finalBlock1.BlockProducerInfo.PublicKey = blockSignerPkBytes
finalBlock1.BlockProducerInfo.Signature = nil
_, _, _, err = chain.ProcessBlock(finalBlock1, true)
_, _, _, err = chain.ProcessBlock(finalBlock1, nil, true)
require.Error(err)
require.Contains(err.Error(), RuleErrorMissingBlockProducerSignature)

// If all the BlockProducerInfo is missing, things should fail
finalBlock1.BlockProducerInfo = nil
_, _, _, err = chain.ProcessBlock(finalBlock1, true)
_, _, _, err = chain.ProcessBlock(finalBlock1, nil, true)
require.Error(err)
require.Contains(err.Error(), RuleErrorMissingBlockProducerSignature)

// Now let's add blockSignerPK to the map of trusted keys and confirm that the block processes.
chain.trustedBlockProducerPublicKeys[MakePkMapKey(blockSignerPkBytes)] = true
finalBlock1.BlockProducerInfo = blockProducerInfoCopy
_, _, _, err = chain.ProcessBlock(finalBlock1, true)
_, _, _, err = chain.ProcessBlock(finalBlock1, nil, true)
require.NoError(err)

_, _ = finalBlock1, db
Expand Down
43 changes: 25 additions & 18 deletions lib/db_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -5044,14 +5044,13 @@ func GetBlock(blockHash *BlockHash, handle *badger.DB, snap *Snapshot) (*MsgDeSo
return blockRet, nil
}

func PutBlockHashToBlockWithTxn(txn *badger.Txn, snap *Snapshot, block *MsgDeSoBlock, eventManager *EventManager) error {
if block.Header == nil {
return fmt.Errorf("PutBlockHashToBlockWithTxn: Header was nil in block %v", block)
}
blockHash, err := block.Header.Hash()
if err != nil {
return errors.Wrap(err, "PutBlockHashToBlockWithTxn: Problem hashing header: ")
}
func PutBlockHashToBlockWithTxn(
txn *badger.Txn,
snap *Snapshot,
blockHash *BlockHash,
block *MsgDeSoBlock,
eventManager *EventManager,
) error {
blockKey := BlockHashToBlockKey(blockHash)
data, err := block.ToBytes(false)
if err != nil {
Expand All @@ -5070,12 +5069,14 @@ func PutBlockHashToBlockWithTxn(txn *badger.Txn, snap *Snapshot, block *MsgDeSoB
return nil
}

func PutBlockWithTxn(txn *badger.Txn, snap *Snapshot, desoBlock *MsgDeSoBlock, eventManager *EventManager) error {
blockHash, err := desoBlock.Header.Hash()
if err != nil {
return errors.Wrapf(err, "PutBlockWithTxn: Problem hashing header: ")
}
if err = PutBlockHashToBlockWithTxn(txn, snap, desoBlock, eventManager); err != nil {
func PutBlockWithTxn(
txn *badger.Txn,
snap *Snapshot,
desoBlock *MsgDeSoBlock,
blockHash *BlockHash,
eventManager *EventManager,
) error {
if err := PutBlockHashToBlockWithTxn(txn, snap, blockHash, desoBlock, eventManager); err != nil {
return errors.Wrap(err, "PutBlockWithTxn: Problem putting block hash to block")
}
blockRewardTxn := desoBlock.Txns[0]
Expand All @@ -5096,17 +5097,23 @@ func PutBlockWithTxn(txn *badger.Txn, snap *Snapshot, desoBlock *MsgDeSoBlock, e
pkMapKey := pkMapKeyIter

blockRewardKey := PublicKeyBlockHashToBlockRewardKey(pkMapKey[:], blockHash)
if err = DBSetWithTxn(txn, snap, blockRewardKey, EncodeUint64(blockReward), eventManager); err != nil {
if err := DBSetWithTxn(txn, snap, blockRewardKey, EncodeUint64(blockReward), eventManager); err != nil {
return err
}
}

return nil
}

func PutBlock(handle *badger.DB, snap *Snapshot, desoBlock *MsgDeSoBlock, eventManager *EventManager) error {
func PutBlock(
handle *badger.DB,
snap *Snapshot,
desoBlock *MsgDeSoBlock,
blockHash *BlockHash,
eventManager *EventManager,
) error {
err := handle.Update(func(txn *badger.Txn) error {
return PutBlockWithTxn(txn, snap, desoBlock, eventManager)
return PutBlockWithTxn(txn, snap, desoBlock, blockHash, eventManager)
})

return err
Expand Down Expand Up @@ -5324,7 +5331,7 @@ func InitDbWithDeSoGenesisBlock(params *DeSoParams, handle *badger.DB,
return errors.Wrapf(err, "InitDbWithGenesisBlock: Problem putting genesis block hash into db for block chain")
}
// Add the genesis block to the (hash -> block) index.
if err := PutBlockWithTxn(txn, snap, genesisBlock, eventManager); err != nil {
if err := PutBlockWithTxn(txn, snap, genesisBlock, blockHash, eventManager); err != nil {
return errors.Wrapf(err, "InitDbWithGenesisBlock: Problem putting genesis block into db")
}
// Add the genesis block to the (height, hash -> node info) index in the db.
Expand Down
4 changes: 2 additions & 2 deletions lib/load_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ func TestComputeMaxTPS(t *testing.T) {
_, _ = newParams, newDB
timeStart := time.Now()
for _, blockToConnect := range blocksMined {
_, _, _, err := newChain.ProcessBlock(blockToConnect, true /*verifySignatures*/)
_, _, _, err := newChain.ProcessBlock(blockToConnect, nil, true /*verifySignatures*/)
require.NoError(err)
}
elapsedSecs := (time.Since(timeStart)).Seconds()
Expand Down Expand Up @@ -236,7 +236,7 @@ func TestConnectBlocksLoadTest(t *testing.T) {
pprof.StartCPUProfile(ff)
timeStart := time.Now()
for _, blockToConnect := range blocksMined {
_, _, _, err := newChain.ProcessBlock(blockToConnect, false /*verifySignatures*/)
_, _, _, err := newChain.ProcessBlock(blockToConnect, nil, false /*verifySignatures*/)
require.NoError(err)
}
elapsedSecs := (time.Since(timeStart)).Seconds()
Expand Down
2 changes: 1 addition & 1 deletion lib/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ func (desoMiner *DeSoMiner) MineAndProcessSingleBlock(threadIndex uint32, mempoo
verifySignatures := true
// TODO(miner): Replace with a call to SubmitBlock.
isMainChain, isOrphan, _, err := desoMiner.BlockProducer.chain.ProcessBlock(
blockToMine, verifySignatures)
blockToMine, nil, verifySignatures)
glog.V(2).Infof("Called ProcessBlock: isMainChain=(%v), isOrphan=(%v), err=(%v)",
isMainChain, isOrphan, err)
if err != nil {
Expand Down
Loading