From fae4919d6c2016f769e1c01258e068b5d89c4b3c Mon Sep 17 00:00:00 2001 From: wizeguyy Date: Mon, 2 Dec 2024 12:30:23 -0600 Subject: [PATCH 1/2] Reject blocks which emit Qi UTXOs to inactive chains --- core/block_validator.go | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) 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 From be33e411b3592ad130fb52fbb4339b8a364ca996 Mon Sep 17 00:00:00 2001 From: wizeguyy Date: Wed, 4 Dec 2024 10:21:54 -0600 Subject: [PATCH 2/2] Reject transactions which emit Qi UTXOs to inactive chains --- core/tx_pool.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) 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 {