diff --git a/domain/consensus/processes/blockbuilder/test_block_builder.go b/domain/consensus/processes/blockbuilder/test_block_builder.go index 31eeea624..697672d60 100644 --- a/domain/consensus/processes/blockbuilder/test_block_builder.go +++ b/domain/consensus/processes/blockbuilder/test_block_builder.go @@ -28,6 +28,18 @@ func NewTestBlockBuilder(baseBlockBuilder model.BlockBuilder, testConsensus test } } +func cleanBlockPrefilledFields(block *externalapi.DomainBlock) { + for _, tx := range block.Transactions { + tx.Fee = 0 + tx.Mass = 0 + tx.ID = nil + + for _, input := range tx.Inputs { + input.UTXOEntry = nil + } + } +} + // BuildBlockWithParents builds a block with provided parents, coinbaseData and transactions, // and returns the block together with its past UTXO-diff from the virtual. func (bb *testBlockBuilder) BuildBlockWithParents(parentHashes []*externalapi.DomainHash, @@ -37,7 +49,16 @@ func (bb *testBlockBuilder) BuildBlockWithParents(parentHashes []*externalapi.Do onEnd := logger.LogAndMeasureExecutionTime(log, "BuildBlockWithParents") defer onEnd() - return bb.buildBlockWithParents(parentHashes, coinbaseData, transactions) + block, diff, err := bb.buildBlockWithParents(parentHashes, coinbaseData, transactions) + if err != nil { + return nil, nil, err + } + + // It's invalid to insert a block with prefilled fields to consensus, so we + // clean them before returning the block. + cleanBlockPrefilledFields(block) + + return block, diff, nil } func (bb *testBlockBuilder) buildHeaderWithParents(parentHashes []*externalapi.DomainHash, diff --git a/domain/consensus/processes/blockvalidator/block_body_in_isolation.go b/domain/consensus/processes/blockvalidator/block_body_in_isolation.go index aa0f6d45c..4c3cf18d2 100644 --- a/domain/consensus/processes/blockvalidator/block_body_in_isolation.go +++ b/domain/consensus/processes/blockvalidator/block_body_in_isolation.go @@ -23,6 +23,11 @@ func (v *blockValidator) ValidateBodyInIsolation(blockHash *externalapi.DomainHa return err } + err = v.checkNoPrefilledFields(block) + if err != nil { + return err + } + err = v.checkBlockSize(block) if err != nil { return err @@ -224,3 +229,28 @@ func (v *blockValidator) checkBlockSize(block *externalapi.DomainBlock) error { return nil } + +func (v *blockValidator) checkNoPrefilledFields(block *externalapi.DomainBlock) error { + for _, tx := range block.Transactions { + if tx.Fee != 0 { + return errors.Errorf("transaction %s has a prefilled fee", consensushashing.TransactionID(tx)) + } + + if tx.Mass != 0 { + return errors.Errorf("transaction %s has a prefilled mass", consensushashing.TransactionID(tx)) + } + + if tx.ID != nil { + return errors.Errorf("transaction %s has a prefilled ID", consensushashing.TransactionID(tx)) + } + + for i, input := range tx.Inputs { + if input.UTXOEntry != nil { + return errors.Errorf("input %d in transaction %s has a prefilled UTXO entry", + i, consensushashing.TransactionID(tx)) + } + } + } + + return nil +} diff --git a/domain/consensus/test_consensus.go b/domain/consensus/test_consensus.go index 8c4d002c6..c6e1809f6 100644 --- a/domain/consensus/test_consensus.go +++ b/domain/consensus/test_consensus.go @@ -30,7 +30,12 @@ func (tc *testConsensus) BuildBlockWithParents(parentHashes []*externalapi.Domai tc.lock.Lock() defer tc.lock.Unlock() - return tc.testBlockBuilder.BuildBlockWithParents(parentHashes, coinbaseData, transactions) + block, diff, err := tc.testBlockBuilder.BuildBlockWithParents(parentHashes, coinbaseData, transactions) + if err != nil { + return nil, nil, err + } + + return block, diff, nil } func (tc *testConsensus) AddBlock(parentHashes []*externalapi.DomainHash, coinbaseData *externalapi.DomainCoinbaseData,