kaspad/testing/integration/tx_relay_test.go
Svarog 8ccf381fc7 [NOD-1532] csm unit tests (#1059)
* Revert "[NOD-1500] Delete integration tests"

This reverts commit fcb57a206690a884fa6afb69d5d493282954a8bf.

* [NOD-1518] hashserialization -> consenusserialization

* [NOD-1518] Fix add genesis to virtual

* [NOD-1518] Fix a bug in SerializeCoinbasePayload.

* [NOD-1518] Fix a loop error and make pastMedianTime behave correctly everywhere on genesis.

* [NOD-1518] Fix another bug and an infinite loop.

* [NOD-1518] Fix uninitialized slice.

* [NOD-1518] Fix bad should-commit checks and another infinite loop.

* [NOD-1518] Fix nil serialization.

* [NOD-1518] Rename blockHash to currentBlockHash.

* [NOD-1518] Move the check whether stagedVirtualUTXOSet != nil to the top of commitVirtualUTXODiff.

* [NOD-1518] Simplify utxoDiffStore.Commit.

* [NOD-1518] Unextract resolveBlockStatusAndCheckFinality.

* [NOD-1518] Move no-transactions logic into CalculateIDMerkleRoot.

* [NOD-1518] Remove redundant is-staged check.

* [NOD-1518] Fix merge errors.

* [NOD-1518] Don't write anything if utxoDiffChild is nil.

* [NOD-1518] Stage virtualAcceptanceData and virtualMultiset.

* [NOD-1518] Fix bugs in getBlockTemplate and submitBlock.

* [NOD-1518] Fix bad validation order in validateHeaderInContext.

* [NOD-1518] Fix bug in Next().

* [NOD-1518] Fix nil dereference of subnetworks in AddressCache.

* [NOD-1518] Fix multisetStore.Get returning a pointer to a multiset that is changed in place.

* [NOD-1518] Break on genesis in countSubtrees.

* [NOD-1518] Fix createBlockLocator.

* [NOD-1518] Fix MsgTxToDomainTransaction.

* [NOD-1518] Set MaxTxVersion to 1.

* [NOD-1518] Fix missing error handling, bug in MsgTxToDomainTransaction, and bad subnetwork equality check.

* [NOD-1518] Fix bug in hasUTXOByOutpointFromStagedVirtualUTXODiff.

* [NOD-1518] Remove irrelevant comments.

* [NOD-1518] Generate transactions with sufficient fee in tx_relay_test.

* [NOD-1518] Fix broken RPC handlers.

* [NOD-1518] Fix merge errors.

* [NOD-1518] Fix bad exists check in restorePastUTXO and missing genesis check in CalculatePastUTXOAndAcceptanceData.

* [NOD-1518] Add a comment.

* [NOD-1518] Use a regular mutex instead of a read-write mutex in consensus to avoid dealing with sneaky not-actually-read functions.

* [NOD-1518] Fix a deadlock in GetVirtualSelectedParent.

* [NOD-1518] Fix missing handler registration for CmdHeader.

* [NOD-1518] Fix processHeader calling OnNewBlock and LogBlock. Also fix conversion errors in IBDRootUTXOSetAndBlock.

* [NOD-1518] Fix bad Command() in MsgIBDRootUTXOSetAndBlock.

* [NOD-1518] Fix bad SyncStateMissingUTXOSet logic in resolveSyncState.

* [NOD-1518] Rename mode to syncState.

* [NOD-1518] Fix headers-only blocks coming in after the consensus thinks it's synced.

* [NOD-1518] Fix selectedChildIterator.Next not ignoring virtual, infinite loop in HashSet.Length().

* [NOD-1518] Fix not-properly wrapped IBD blocks.

* [NOD-1532] Add TestMultiset

* [NOD-1518] Fix bad conversion in RequestIBDBlocks.

* [NOD-1518] Fix bad string for CmdRequestHeaders.

* [NOD-1518] Fix bad string for CmdDoneHeaders.

* [NOD-1518] Fix bad Command() for MsgIBDRootNotFound.

* [NOD-1532] Add TestPastUTXOMultiset

* [NOD-1518] Fix bad areHeaderTipsSyncedMaxTimeDifference value.

* [NOD-1532] Added TestDoubleSpends

* [NOD-1518] Add missing string for CmdRequestIBDBlocks.

* [NOD-1518] Fix bad check for SyncStateMissingBlockBodies.

* [NOD-1518] Fix bad timeout durations in tests.

* [NOD-1518] Fix IBD blocks not calling OnNewBlock.

* [NOD-1518] Change when IBD finishes.

* [NOD-1518] Properly clone utxoDiffChild.

* [NOD-1532] Update hashes of blocks

* [NOD-1532] Fix genesis blocks and a few more bugs

* [NOD-1532] Bugfix: incorrect key passed to dbTx.Put

* [NOD-1532] Make sure there's no nil payloads

* [NOD-1532] Fix AddBlockToVirtual

* [NOD-1532] Update tips and virtualDiffParents properly

* [NOD-1532] Allow nil payload

* [NOD-1532] Check for actual error and not just some RuleError

* [NOD-1532] Get rid of SimpleCoinbaseData and make OpTrueScript P2SH

* [NOD-1532] If coinbaseData is nil - fill in with generic coinbaseData

Co-authored-by: Ori Newman <orinewman1@gmail.com>
Co-authored-by: stasatdaglabs <stas@daglabs.com>
2020-11-17 16:00:16 +02:00

127 lines
4.0 KiB
Go

package integration
import (
"encoding/hex"
"strings"
"testing"
"time"
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
"github.com/kaspanet/go-secp256k1"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
"github.com/kaspanet/kaspad/util"
)
func TestTxRelay(t *testing.T) {
payer, mediator, payee, teardown := standardSetup(t)
defer teardown()
// Connect nodes in chain: payer <--> mediator <--> payee
// So that payee doesn't directly get transactions from payer
connect(t, payer, mediator)
connect(t, mediator, payee)
payeeBlockAddedChan := make(chan *appmessage.MsgBlockHeader)
setOnBlockAddedHandler(t, payee, func(notification *appmessage.BlockAddedNotificationMessage) {
payeeBlockAddedChan <- &notification.Block.Header
})
// skip the first block because it's paying to genesis script
mineNextBlock(t, payer)
waitForPayeeToReceiveBlock(t, payeeBlockAddedChan)
// use the second block to get money to pay with
secondBlock := mineNextBlock(t, payer)
waitForPayeeToReceiveBlock(t, payeeBlockAddedChan)
// Mine BlockCoinbaseMaturity more blocks for our money to mature
for i := uint64(0); i < payer.config.ActiveNetParams.BlockCoinbaseMaturity; i++ {
mineNextBlock(t, payer)
waitForPayeeToReceiveBlock(t, payeeBlockAddedChan)
}
tx := generateTx(t, secondBlock.Transactions[transactionhelper.CoinbaseTransactionIndex], payer, payee)
response, err := payer.rpcClient.SubmitTransaction(tx)
if err != nil {
t.Fatalf("Error submitting transaction: %+v", err)
}
txID := response.TxID
txAddedToMempoolChan := make(chan struct{})
spawn("TestTxRelay-WaitForTransactionPropagation", func() {
ticker := time.NewTicker(10 * time.Millisecond)
defer ticker.Stop()
for range ticker.C {
_, err := payee.rpcClient.GetMempoolEntry(txID)
if err != nil {
if strings.Contains(err.Error(), "transaction is not in the pool") {
continue
}
t.Fatalf("Error getting mempool entry: %+v", err)
}
close(txAddedToMempoolChan)
return
}
})
select {
case <-txAddedToMempoolChan:
case <-time.After(defaultTimeout):
t.Fatalf("Timeout waiting for transaction to be accepted into mempool")
}
}
func waitForPayeeToReceiveBlock(t *testing.T, payeeBlockAddedChan chan *appmessage.MsgBlockHeader) {
select {
case <-payeeBlockAddedChan:
case <-time.After(defaultTimeout):
t.Fatalf("Timeout waiting for block added")
}
}
func generateTx(t *testing.T, firstBlockCoinbase *externalapi.DomainTransaction, payer, payee *appHarness) *appmessage.MsgTx {
txIns := make([]*appmessage.TxIn, 1)
txIns[0] = appmessage.NewTxIn(appmessage.NewOutpoint(consensusserialization.TransactionID(firstBlockCoinbase), 0), []byte{})
payeeAddress, err := util.DecodeAddress(payee.miningAddress, util.Bech32PrefixKaspaSim)
if err != nil {
t.Fatalf("Error decoding payeeAddress: %+v", err)
}
toScript, err := txscript.PayToAddrScript(payeeAddress)
if err != nil {
t.Fatalf("Error generating script: %+v", err)
}
txOuts := []*appmessage.TxOut{appmessage.NewTxOut(firstBlockCoinbase.Outputs[0].Value-1000, toScript)}
fromScript := firstBlockCoinbase.Outputs[0].ScriptPublicKey
tx := appmessage.NewNativeMsgTx(constants.TransactionVersion, txIns, txOuts)
privateKeyBytes, err := hex.DecodeString(payer.miningAddressPrivateKey)
if err != nil {
t.Fatalf("Error decoding private key: %+v", err)
}
privateKey, err := secp256k1.DeserializePrivateKeyFromSlice(privateKeyBytes)
if err != nil {
t.Fatalf("Error deserializing private key: %+v", err)
}
signatureScript, err := txscript.SignatureScript(appmessage.MsgTxToDomainTransaction(tx), 0,
fromScript, txscript.SigHashAll, privateKey, true)
if err != nil {
t.Fatalf("Error signing transaction: %+v", err)
}
tx.TxIn[0].SignatureScript = signatureScript
return tx
}