Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
chris124567 committed Oct 12, 2024
1 parent c3676cc commit e06ff6a
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 1 deletion.
20 changes: 20 additions & 0 deletions internal/testutil/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,26 @@ func MineBlock(state consensus.State, txns []types.Transaction, minerAddr types.
return b
}

// MineV2Block mines sets the metadata fields of the block along with the
// transactions and then generates a valid nonce for the block.
func MineV2Block(state consensus.State, txns []types.V2Transaction, minerAddr types.Address) types.Block {
b := types.Block{
ParentID: state.Index.ID,
Timestamp: types.CurrentTimestamp(),
MinerPayouts: []types.SiacoinOutput{{Address: minerAddr, Value: state.BlockReward()}},

V2: &types.V2BlockData{
Transactions: txns,
Height: state.Index.Height + 1,
},
}
b.V2.Commitment = state.Commitment(state.TransactionsCommitment(b.Transactions, b.V2Transactions()), b.MinerPayouts[0].Address)
for b.ID().CmpWork(state.ChildTarget) < 0 {
b.Nonce += state.NonceFactor()
}
return b
}

// SignTransactionWithContracts signs a transaction using the specified private
// keys, including contract revisions.
func SignTransactionWithContracts(cs consensus.State, pk, renterPK, hostPK types.PrivateKey, txn *types.Transaction) {
Expand Down
32 changes: 32 additions & 0 deletions internal/testutil/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ func CheckTransaction(t *testing.T, expectTxn types.Transaction, gotTxn explorer
Equal(t, "siacoin outputs", len(expectTxn.SiacoinOutputs), len(gotTxn.SiacoinOutputs))
Equal(t, "siafund inputs", len(expectTxn.SiafundInputs), len(gotTxn.SiafundInputs))
Equal(t, "siafund outputs", len(expectTxn.SiafundOutputs), len(gotTxn.SiafundOutputs))
Equal(t, "arbitrary data", len(expectTxn.ArbitraryData), len(gotTxn.ArbitraryData))
Equal(t, "miner fees", len(expectTxn.MinerFees), len(gotTxn.MinerFees))
Equal(t, "signatures", len(expectTxn.Signatures), len(gotTxn.Signatures))

for i := range expectTxn.SiacoinInputs {
expectSci := expectTxn.SiacoinInputs[i]
Expand Down Expand Up @@ -100,6 +103,35 @@ func CheckTransaction(t *testing.T, expectTxn types.Transaction, gotTxn explorer
}
}

// CheckV2Transaction checks the inputs and outputs of the retrieved transaction
// with the source transaction.
func CheckV2Transaction(t *testing.T, expectTxn types.V2Transaction, gotTxn explorer.V2Transaction) {
t.Helper()

Equal(t, "arbitrary data", len(expectTxn.ArbitraryData), len(gotTxn.ArbitraryData))

for i := range expectTxn.ArbitraryData {
Equal(t, "arbitrary data value", expectTxn.ArbitraryData[i], gotTxn.ArbitraryData[i])
}
}

// CheckV2ChainIndices checks that the chain indices that a v2 transaction was
// in from the explorer match the expected chain indices.
func CheckV2ChainIndices(t *testing.T, db explorer.Store, txnID types.TransactionID, expected []types.ChainIndex) {
t.Helper()

indices, err := db.V2TransactionChainIndices(txnID, 0, 100)
switch {
case err != nil:
t.Fatal(err)
case len(indices) != len(expected):
t.Fatalf("expected %d indices, got %d", len(expected), len(indices))
}
for i := range indices {
Equal(t, "index", expected[i], indices[i])
}
}

// CheckFC checks the retrieved file contract with the source file contract in
// addition to checking the resolved and valid fields.
func CheckFC(t *testing.T, revision, resolved, valid bool, expected types.FileContract, got explorer.FileContract) {
Expand Down
2 changes: 1 addition & 1 deletion persist/sqlite/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -1077,7 +1077,7 @@ func (ut *updateTx) ApplyIndex(state explorer.UpdateState) error {

if err := addTransactionFields(ut.tx, state.Block.Transactions, scDBIds, sfDBIds, fcDBIds, txnDBIds); err != nil {
return fmt.Errorf("ApplyIndex: failed to add transaction fields: %w", err)
} else if err := addV2TransactionFields(ut.tx, state.Block.V2Transactions(), scDBIds, sfDBIds, fcDBIds, txnDBIds); err != nil {
} else if err := addV2TransactionFields(ut.tx, state.Block.V2Transactions(), scDBIds, sfDBIds, fcDBIds, v2TxnDBIds); err != nil {
return fmt.Errorf("ApplyIndex: failed to add v2 transaction fields: %w", err)
} else if err := updateBalances(ut.tx, state.Metrics.Index.Height, state.SpentSiacoinElements, state.NewSiacoinElements, state.SpentSiafundElements, state.NewSiafundElements); err != nil {
return fmt.Errorf("ApplyIndex: failed to update balances: %w", err)
Expand Down
108 changes: 108 additions & 0 deletions persist/sqlite/v2consensus_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package sqlite_test

import (
"path/filepath"
"testing"

"go.sia.tech/core/types"
"go.sia.tech/coreutils"
"go.sia.tech/coreutils/chain"
ctestutil "go.sia.tech/coreutils/testutil"
"go.sia.tech/explored/internal/testutil"
"go.sia.tech/explored/persist/sqlite"
"go.uber.org/zap/zaptest"
)

func TestV2ArbitraryData(t *testing.T) {
log := zaptest.NewLogger(t)
dir := t.TempDir()
db, err := sqlite.OpenDatabase(filepath.Join(dir, "explored.sqlite3"), log.Named("sqlite3"))
if err != nil {
t.Fatal(err)
}
defer db.Close()

bdb, err := coreutils.OpenBoltChainDB(filepath.Join(dir, "consensus.db"))
if err != nil {
t.Fatal(err)
}
defer bdb.Close()

network, genesisBlock := ctestutil.V2Network()
network.HardforkV2.AllowHeight = 1
network.HardforkV2.RequireHeight = 2

store, genesisState, err := chain.NewDBStore(bdb, network, genesisBlock)
if err != nil {
t.Fatal(err)
}

cm := chain.NewManager(store, genesisState)

txn1 := types.V2Transaction{
ArbitraryData: []byte("hello"),
}

txn2 := types.V2Transaction{
ArbitraryData: []byte("world"),
}

if err := cm.AddBlocks([]types.Block{testutil.MineV2Block(cm.TipState(), []types.V2Transaction{txn1, txn2}, types.VoidAddress)}); err != nil {
t.Fatal(err)
}
syncDB(t, db, cm)
prev := cm.Tip()

{
b, err := db.Block(cm.Tip().ID)
if err != nil {
t.Fatal(err)
}
testutil.Equal(t, "v2 height", b.V2.Height, 1)
testutil.CheckV2Transaction(t, txn1, b.V2.Transactions[0])
testutil.CheckV2Transaction(t, txn2, b.V2.Transactions[1])
}

{
dbTxns, err := db.V2Transactions([]types.TransactionID{txn1.ID(), txn2.ID()})
if err != nil {
t.Fatal(err)
}
testutil.CheckV2Transaction(t, txn1, dbTxns[0])
testutil.CheckV2Transaction(t, txn2, dbTxns[1])
}

txn3 := types.V2Transaction{
ArbitraryData: []byte("12345"),
}

if err := cm.AddBlocks([]types.Block{testutil.MineV2Block(cm.TipState(), []types.V2Transaction{txn1, txn2, txn3}, types.VoidAddress)}); err != nil {
t.Fatal(err)
}
syncDB(t, db, cm)

{
b, err := db.Block(cm.Tip().ID)
if err != nil {
t.Fatal(err)
}
testutil.Equal(t, "v2 height", b.V2.Height, 2)
testutil.CheckV2Transaction(t, txn1, b.V2.Transactions[0])
testutil.CheckV2Transaction(t, txn2, b.V2.Transactions[1])
testutil.CheckV2Transaction(t, txn3, b.V2.Transactions[2])
}

{
dbTxns, err := db.V2Transactions([]types.TransactionID{txn1.ID(), txn2.ID(), txn3.ID()})
if err != nil {
t.Fatal(err)
}
testutil.CheckV2Transaction(t, txn1, dbTxns[0])
testutil.CheckV2Transaction(t, txn2, dbTxns[1])
testutil.CheckV2Transaction(t, txn3, dbTxns[2])
}

testutil.CheckV2ChainIndices(t, db, txn1.ID(), []types.ChainIndex{cm.Tip(), prev})
testutil.CheckV2ChainIndices(t, db, txn2.ID(), []types.ChainIndex{cm.Tip(), prev})
testutil.CheckV2ChainIndices(t, db, txn3.ID(), []types.ChainIndex{cm.Tip()})
}

0 comments on commit e06ff6a

Please sign in to comment.