Skip to content

Commit

Permalink
Group test blocks using t.Run() (#423)
Browse files Browse the repository at this point in the history
* Group test blocks using t.Run()

* Adding test case for AddInputsAndChangeToTransactionWithSubsidy

- Calling AddInputsAndChangeToTransactionWithSubsidy with txnInputs.
- Expected to fail.
  • Loading branch information
hackintoshrao authored Dec 5, 2022
1 parent 83b3153 commit a96b03f
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 40 deletions.
86 changes: 59 additions & 27 deletions lib/block_view_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ import (
"bytes"
"encoding/hex"
"fmt"
_ "net/http/pprof"
"reflect"
"sort"
"testing"

"github.com/btcsuite/btcd/btcec"
"github.com/decred/dcrd/lru"
"github.com/dgraph-io/badger/v3"
embeddedpostgres "github.com/fergusstrange/embedded-postgres"
"github.com/golang/glog"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
_ "net/http/pprof"
"reflect"
"sort"
"testing"
)

func _strToPk(t *testing.T, pkStr string) []byte {
Expand Down Expand Up @@ -1172,9 +1173,35 @@ func TestBasicTransfer(t *testing.T) {
recipientPkBytes, _, err := Base58CheckDecode(recipientPkString)
require.NoError(err)

// A basic transfer with input value set should fail during AddInputsAndChangeToTransaction
t.Run("txn_with_inputs_should_fail", func(t *testing.T) {
txn := &MsgDeSoTxn{
// The inputs will be set below.
TxInputs: []*DeSoInput{&DeSoInput{
TxID: BlockHash{},
}},
TxOutputs: []*DeSoOutput{
{
PublicKey: recipientPkBytes,
AmountNanos: 1,
},
},
PublicKey: senderPkBytes,
TxnMeta: &BasicTransferMetadata{},
}

_, _, _, _, err :=
chain.AddInputsAndChangeToTransaction(txn, 10, nil)
require.Error(err)

require.Contains(err.Error(), fmt.Sprintf("_computeInputsForTxn: Transaction passed in "+
"txArg should not have any inputs set but found the found %d inputs",
len(txn.TxInputs)))
})

// A basic transfer whose input public keys differ from the
// transaction-level public key should fail.
{
t.Run("txn_public_txb_keys_differ", func(t *testing.T) {
txn := &MsgDeSoTxn{
// The inputs will be set below.
TxInputs: []*DeSoInput{},
Expand Down Expand Up @@ -1208,10 +1235,10 @@ func TestBasicTransfer(t *testing.T) {
true /*verifySignatures*/, false /*ignoreUtxos*/)
require.Error(err)
require.Contains(err.Error(), RuleErrorInputWithPublicKeyDifferentFromTxnPublicKey)
}
})

// Just a basic transfer with a bad signature.
{
t.Run("txn_basic_bad_signature", func(t *testing.T) {
txn := &MsgDeSoTxn{
// The inputs will be set below.
TxInputs: []*DeSoInput{},
Expand Down Expand Up @@ -1242,10 +1269,10 @@ func TestBasicTransfer(t *testing.T) {
true /*verifySignature*/, false /*ignoreUtxos*/)
require.Error(err)
require.Contains(err.Error(), RuleErrorInvalidTransactionSignature)
}
})

// A block reward with a bad signature should fail.
{
t.Run("txn_block_reward_bad_sign", func(t *testing.T) {
txn := &MsgDeSoTxn{
// The inputs will be set below.
TxInputs: []*DeSoInput{},
Expand All @@ -1269,11 +1296,11 @@ func TestBasicTransfer(t *testing.T) {
true /*verifySignature*/, false /*ignoreUtxos*/)
require.Error(err)
require.Contains(err.Error(), RuleErrorBlockRewardTxnNotAllowedToHaveSignature)
}
})

// A block reward with an input, even if it's signed legitimately,
// should fail.
{
t.Run("txn_reward_with_input", func(t *testing.T) {
txn := &MsgDeSoTxn{
// The inputs will be set below.
TxInputs: []*DeSoInput{},
Expand Down Expand Up @@ -1304,14 +1331,16 @@ func TestBasicTransfer(t *testing.T) {
true /*verifySignature*/, false /*ignoreUtxos*/)
require.Error(err)
require.Contains(err.Error(), RuleErrorBlockRewardTxnNotAllowedToHaveInputs)
}
})

// A block with too much block reward should fail.
allowedBlockReward := CalcBlockRewardNanos(chain.blockTip().Height)
assert.Equal(int64(allowedBlockReward), int64(1*NanosPerUnit))
blockToMine, _, _, err := miner._getBlockToMine(0 /*threadIndex*/)
require.NoError(err)
{

// A block with too much block reward should fail.

t.Run("txn_block_too_much_reward", func(t *testing.T) {
blockToMine.Txns[0].TxOutputs[0].AmountNanos = allowedBlockReward + 1
// One iteration should be sufficient to find us a good block.
_, bestNonce, err := FindLowestHash(blockToMine.Header, 10000)
Expand All @@ -1324,10 +1353,10 @@ func TestBasicTransfer(t *testing.T) {
_, err = utxoView.ConnectBlock(blockToMine, txHashes, true /*verifySignatures*/, nil, 0)
require.Error(err)
require.Contains(err.Error(), RuleErrorBlockRewardExceedsMaxAllowed)
}
})

// A block with less than the max block reward should be OK.
{
t.Run("txn_block_less_max_reward", func(t *testing.T) {
blockToMine.Txns[0].TxOutputs[0].AmountNanos = allowedBlockReward - 1
// One iteration should be sufficient to find us a good block.
_, bestNonce, err := FindLowestHash(blockToMine.Header, 10000)
Expand All @@ -1339,19 +1368,21 @@ func TestBasicTransfer(t *testing.T) {
utxoView, _ := NewUtxoView(db, params, postgres, chain.snapshot)
_, err = utxoView.ConnectBlock(blockToMine, txHashes, true /*verifySignatures*/, nil, 0)
require.NoError(err)
}
})
}

// TestBasicTransferSignatures thoroughly tests all possible ways to sign a DeSo transaction.
// There are three available signature schemas that are accepted by the DeSo blockchain:
//
// (1) Transaction signed by user's main public key
// (2) Transaction signed by user's derived key with "DerivedPublicKey" passed in ExtraData
// (3) Transaction signed by user's derived key using DESO-DER signature standard.
// (3) Transaction signed by user's derived key using DESO-DER signature standard.
//
// We will try all these schemas while running three main tests scenarios:
// - try signing and processing a basicTransfer
// - try signing and processing a authorizeDerivedKey
// - try signing and processing a authorizeDerivedKey followed by a basicTransfer
// - try signing and processing a basicTransfer
// - try signing and processing a authorizeDerivedKey
// - try signing and processing a authorizeDerivedKey followed by a basicTransfer
//
// We use basicTransfer as a placeholder for a normal DeSo transaction (alternatively, we could have used a post,
// follow, nft, etc transaction). For each scenario we try signing the transaction with either user's main public
// key, a derived key, or a random key. Basically, we try every possible context in which a transaction can be signed.
Expand Down Expand Up @@ -1559,7 +1590,7 @@ func TestBasicTransferSignatures(t *testing.T) {
}

// First scenario, just signing a basic transfer.
{
t.Run("sign_basic_transfer", func(t *testing.T) {
var allTxns []*MsgDeSoTxn
// Try signing the basic transfer with the owner's private key.
testSenderVector := [3]RuleError{
Expand Down Expand Up @@ -1590,10 +1621,11 @@ func TestBasicTransferSignatures(t *testing.T) {
)...)

mineBlockAndVerifySignatures(allTxns)
}
})

// Second scenario, authorize derived key transaction.
{

t.Run("sign_autorize_derive_key_txn", func(t *testing.T) {
var allTxns []*MsgDeSoTxn
transactionSpendingLimit := &TransactionSpendingLimit{
GlobalDESOLimit: 100,
Expand Down Expand Up @@ -1644,10 +1676,10 @@ func TestBasicTransferSignatures(t *testing.T) {
)...)

mineBlockAndVerifySignatures(allTxns)
}
})

// Third scenario, there exists an authorize derived key entry and we're signing a basic transfer.
{
t.Run("sign_derived_key_basic_transfer", func(t *testing.T) {
var allTxns []*MsgDeSoTxn
transactionSpendingLimit := &TransactionSpendingLimit{
GlobalDESOLimit: 100,
Expand Down Expand Up @@ -1708,5 +1740,5 @@ func TestBasicTransferSignatures(t *testing.T) {
)...)

mineBlockAndVerifySignatures(allTxns)
}
})
}
27 changes: 14 additions & 13 deletions lib/block_view_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ package lib
import (
"bytes"
"encoding/hex"
"github.com/brianvoe/gofakeit"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"reflect"
"testing"
"time"

"github.com/brianvoe/gofakeit"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

// Initialize empty DeSoEncoders and check if they are encoded properly.
Expand Down Expand Up @@ -267,7 +268,7 @@ func TestUtxoEntryEncodeDecode(t *testing.T) {
burnTxn2 := bitcoinExchangeTxns[1]

// Applying the full transaction with its merkle proof should work.
{
t.Run("utxo_entry_full_txn", func(t *testing.T) {
mempoolTxs, err := mempool.processTransaction(
burnTxn1, true /*allowUnconnectedTxn*/, true /*rateLimit*/, 0 /*peerID*/, true /*verifySignatures*/)
require.NoError(err)
Expand All @@ -277,15 +278,15 @@ func TestUtxoEntryEncodeDecode(t *testing.T) {
require.Equal(
mempoolTxRet.Tx.TxnMeta.(*BitcoinExchangeMetadata),
burnTxn1.TxnMeta.(*BitcoinExchangeMetadata))
}
})

// According to the mempool, the balance of the user whose public key created
// the Bitcoin burn transaction should now have some DeSo.
pkBytes1, _ := hex.DecodeString(BitcoinTestnetPub1)
pkBytes3, _ := hex.DecodeString(BitcoinTestnetPub3)

// The mempool should be able to process a burn transaction directly.
{
t.Run("utxo_entry_burn_txn", func(t *testing.T) {
mempoolTxsAdded, err := mempool.processTransaction(
burnTxn2, true /*allowUnconnectedTxn*/, true /*rateLimit*/, 0, /*peerID*/
true /*verifySignatures*/)
Expand All @@ -296,23 +297,23 @@ func TestUtxoEntryEncodeDecode(t *testing.T) {
require.Equal(
mempoolTxRet.Tx.TxnMeta.(*BitcoinExchangeMetadata),
burnTxn2.TxnMeta.(*BitcoinExchangeMetadata))
}
})

// According to the mempool, the balances should have updated.
{
t.Run("utxo_entry_update_mempool_bal", func(t *testing.T) {
utxoEntries, err := chain.GetSpendableUtxosForPublicKey(pkBytes3, mempool, nil)
require.NoError(err)

require.Equal(1, len(utxoEntries))
assert.Equal(int64(3372255472), int64(utxoEntries[0].AmountNanos))
}
})

// If the mempool is not consulted, the balances should be zero.
{
t.Run("utxo_entry_mempool_bal_zero", func(t *testing.T) {
utxoEntries, err := chain.GetSpendableUtxosForPublicKey(pkBytes3, nil, nil)
require.NoError(err)
require.Equal(0, len(utxoEntries))
}
})

// Make the moneyPkString the paramUpdater so they can update the exchange rate.
rateUpdateIndex := 4
Expand All @@ -322,7 +323,7 @@ func TestUtxoEntryEncodeDecode(t *testing.T) {
// Applying all the txns to the UtxoView should work. Include a rate update
// in the middle.
utxoOpsList := [][]*UtxoOperation{}
{
t.Run("utxo_entry_update_txn", func(t *testing.T) {
utxoView, err := NewUtxoView(db, paramsCopy, nil, chain.snapshot)
require.NoError(err)

Expand Down Expand Up @@ -382,5 +383,5 @@ func TestUtxoEntryEncodeDecode(t *testing.T) {

// Flushing the UtxoView should work.
require.NoError(utxoView.FlushToDb(0))
}
})
}

0 comments on commit a96b03f

Please sign in to comment.