diff --git a/core/block_validator.go b/core/block_validator.go index e3743680a..e4b96bd2b 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -94,9 +94,23 @@ func (v *BlockValidator) ValidateBody(block *types.WorkObject) error { if hash := types.CalcUncleHash(block.Uncles()); hash != header.UncleHash() { return fmt.Errorf("uncle root hash mismatch: have %x, want %x", hash, header.UncleHash()) } - if v.hc.ProcessingState() { - if hash := types.DeriveSha(block.Transactions(), trie.NewStackTrie(nil)); hash != header.TxHash() { - return fmt.Errorf("transaction root hash mismatch: have %x, want %x", hash, header.TxHash()) + if hash := types.DeriveSha(block.Transactions(), trie.NewStackTrie(nil)); hash != header.TxHash() { + return fmt.Errorf("transaction root hash mismatch: have %x, want %x", hash, header.TxHash()) + } + activeLocations := common.NewChainsAdded(v.hc.currentExpansionNumber) + for _, tx := range block.Transactions() { + if types.QiTxType == tx.Type() { + for _, txo := range tx.TxOut() { + found := false + for _, activeLoc := range activeLocations { + if common.IsInChainScope(txo.Address, activeLoc) { + found = true + } + } + if !found { + return fmt.Errorf("Qi TXO emitted to an inactive chain") + } + } } } // The header view should have the etxs populated diff --git a/core/tx_pool.go b/core/tx_pool.go index d2db17c5c..21c7ad582 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -1276,8 +1276,21 @@ func (pool *TxPool) addQiTxs(txs types.Transactions) []error { if etxPLimit < params.ETXPLimitMin { etxPLimit = params.ETXPLimitMin } + activeLocations := common.NewChainsAdded(pool.chain.CurrentBlock().ExpansionNumber()) transactionsWithoutErrors := make([]*types.TxWithMinerFee, 0, len(txs)) for _, tx := range txs { + // Reject TX if it emits an output to an inactive chain + for _, txo := range tx.TxOut() { + found := false + for _, activeLoc := range activeLocations { + if common.IsInChainScope(txo.Address, activeLoc) { + found = true + } + } + if !found { + errs = append(errs, fmt.Errorf("Qi TXO emitted to an inactive chain")) + } + } totalQitIn, err := ValidateQiTxInputs(tx, pool.chain, pool.db, currentBlock, pool.signer, pool.chainconfig.Location, *pool.chainconfig.ChainID) if err != nil {