Skip to content

Commit

Permalink
Add tx package tests
Browse files Browse the repository at this point in the history
  • Loading branch information
MakisChristou authored and libotony committed Dec 19, 2023
1 parent 138d4f6 commit df2886c
Show file tree
Hide file tree
Showing 5 changed files with 343 additions and 0 deletions.
66 changes: 66 additions & 0 deletions tx/clause_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package tx

import (
"math/big"
"reflect"
"testing"

"github.com/stretchr/testify/assert"
"github.com/vechain/thor/thor"
)

func TestClauseTo(t *testing.T) {
var toAddress thor.Address
copy(toAddress[:], []byte{0xde, 0xad, 0xbe, 0xef})

clause := &Clause{
body: clauseBody{
To: &toAddress,
},
}

result := clause.To()

// The result should not be nil and should match the mock address
assert.NotNil(t, result)
assert.Equal(t, toAddress, *result)

// Test the case where 'To' is nil
clause.body.To = nil
result = clause.To()

// The result should be nil
assert.Nil(t, result)
}

func TestClauseValue(t *testing.T) {
expectedValue := big.NewInt(100) // Mock value

clause := &Clause{
body: clauseBody{
Value: expectedValue,
},
}

result := clause.Value()

// The result should not be nil and should match the mock value
assert.NotNil(t, result)
assert.Equal(t, 0, expectedValue.Cmp(result))
}

func TestClauseData(t *testing.T) {
expectedData := []byte{0x01, 0x02, 0x03} // Mock data

clause := &Clause{
body: clauseBody{
Data: expectedData,
},
}

result := clause.Data()

// The result should not be nil and should match the mock data
assert.NotNil(t, result)
assert.True(t, reflect.DeepEqual(expectedData, result))
}
42 changes: 42 additions & 0 deletions tx/receipt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,57 @@ package tx_test

import (
"fmt"
"math/big"
"testing"

"github.com/stretchr/testify/assert"
"github.com/vechain/thor/thor"
. "github.com/vechain/thor/tx"
)

func getMockReceipt() Receipt {
receipt := Receipt{
GasUsed: 1000,
GasPayer: thor.Address{},
Paid: big.NewInt(100),
Reward: big.NewInt(50),
Reverted: false,
Outputs: []*Output{},
}
return receipt
}

func TestReceipt(t *testing.T) {
var rs Receipts
fmt.Println(rs.RootHash())

var txs Transactions
fmt.Println(txs.RootHash())
}

func TestReceiptStructure(t *testing.T) {

receipt := getMockReceipt()

assert.Equal(t, uint64(1000), receipt.GasUsed)
assert.Equal(t, thor.Address{}, receipt.GasPayer)
assert.Equal(t, big.NewInt(100), receipt.Paid)
assert.Equal(t, big.NewInt(50), receipt.Reward)
assert.Equal(t, false, receipt.Reverted)
assert.Equal(t, []*Output{}, receipt.Outputs)

}

func TestEmptyRootHash(t *testing.T) {

receipt1 := getMockReceipt()
receipt2 := getMockReceipt()

receipts := Receipts{
&receipt1,
&receipt2,
}

rootHash := receipts.RootHash()
assert.NotEqual(t, thor.Bytes32{}, rootHash, "Root hash should not be empty")
}
156 changes: 156 additions & 0 deletions tx/transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,166 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
"github.com/stretchr/testify/assert"
"github.com/vechain/thor/metric"
"github.com/vechain/thor/thor"
"github.com/vechain/thor/tx"
)

func GetMockTx() tx.Transaction {
to, _ := thor.ParseAddress("0x7567d83b7b8d80addcb281a71d54fc7b3364ffed")
trx := new(tx.Builder).ChainTag(1).
BlockRef(tx.BlockRef{0, 0, 0, 0, 0xaa, 0xbb, 0xcc, 0xdd}).
Expiration(32).
Clause(tx.NewClause(&to).WithValue(big.NewInt(10000)).WithData([]byte{0, 0, 0, 0x60, 0x60, 0x60})).
Clause(tx.NewClause(&to).WithValue(big.NewInt(20000)).WithData([]byte{0, 0, 0, 0x60, 0x60, 0x60})).
GasPriceCoef(128).
Gas(21000).
DependsOn(nil).
Nonce(12345678).Build()

return *trx
}

func TestIsExpired(t *testing.T) {
tx := GetMockTx()
res := tx.IsExpired(10)
assert.Equal(t, res, false)
}

func TestHash(t *testing.T) {
tx := GetMockTx()
res := tx.Hash()
assert.Equal(t, res, thor.Bytes32(thor.Bytes32{0x4b, 0xff, 0x70, 0x1, 0xfe, 0xc4, 0x2, 0x84, 0xd9, 0x3b, 0x4c, 0x45, 0x61, 0x7d, 0xc7, 0x41, 0xb9, 0xa8, 0x8e, 0xd5, 0x9d, 0xf, 0x1, 0xa3, 0x76, 0x39, 0x4c, 0x7b, 0xfe, 0xa6, 0xed, 0x24}))

}

func TestDependsOn(t *testing.T) {
tx := GetMockTx()
res := tx.DependsOn()
var expected *thor.Bytes32 = nil
assert.Equal(t, expected, res)
}

func TestTestFeatures(t *testing.T) {
txx := GetMockTx()
supportedFeatures := tx.Features(1)
res := txx.TestFeatures(supportedFeatures)
assert.Equal(t, res, nil)

}

func TestToString(t *testing.T) {
tx := GetMockTx() // Ensure this mock transaction has all the necessary fields populated

// Construct the expected string representation of the transaction
// This should match the format used in the String() method of the Transaction struct
// and should reflect the actual state of the mock transaction
expectedString := "\n\tTx(0x0000000000000000000000000000000000000000000000000000000000000000, 87 B)\n\tOrigin: N/A\n\tClauses: [\n\t\t(To:\t0x7567d83b7b8d80addcb281a71d54fc7b3364ffed\n\t\t Value:\t10000\n\t\t Data:\t0x000000606060) \n\t\t(To:\t0x7567d83b7b8d80addcb281a71d54fc7b3364ffed\n\t\t Value:\t20000\n\t\t Data:\t0x000000606060)]\n\tGasPriceCoef: 128\n\tGas: 21000\n\tChainTag: 1\n\tBlockRef: 0-aabbccdd\n\tExpiration: 32\n\tDependsOn: nil\n\tNonce: 12345678\n\tUnprovedWork: 0\n\tDelegator: N/A\n\tSignature: 0x\n"

res := tx.String()

// Use assert.Equal to compare the actual result with the expected string
assert.Equal(t, expectedString, res)
}

func TestTxSize(t *testing.T) {

tx := GetMockTx()

size := tx.Size()
assert.Equal(t, size, metric.StorageSize(87))
}

func TestProvedWork(t *testing.T) {
// Mock the transaction
tx := GetMockTx()

// Define a head block number
headBlockNum := uint32(20)

// Mock getBlockID function
getBlockID := func(num uint32) (thor.Bytes32, error) {
return thor.Bytes32{}, nil
}

// Call ProvedWork
provedWork, err := tx.ProvedWork(headBlockNum, getBlockID)

// Check for errors
assert.NoError(t, err)

expectedProvedWork := big.NewInt(0)
assert.Equal(t, expectedProvedWork, provedWork)
}

func TestChainTag(t *testing.T) {
tx := GetMockTx()
res := tx.ChainTag()
assert.Equal(t, res, uint8(0x1))
}

func TestNonce(t *testing.T) {
tx := GetMockTx()
res := tx.Nonce()
assert.Equal(t, res, uint64(0xbc614e))
}

func TestOverallGasPrice(t *testing.T) {
// Mock or create a Transaction with necessary fields initialized
tx := GetMockTx()

// Define test cases
testCases := []struct {
name string
baseGasPrice *big.Int
provedWork *big.Int
expectedOutput *big.Int
}{
{
name: "Case 1: No proved work",
baseGasPrice: big.NewInt(1000),
provedWork: big.NewInt(0),
expectedOutput: big.NewInt(1501),
},
{
name: "Case 1: Negative proved work",
baseGasPrice: big.NewInt(1000),
provedWork: big.NewInt(-100),
expectedOutput: big.NewInt(1501),
},
}

// Run test cases
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// Call OverallGasPrice
result := tx.OverallGasPrice(tc.baseGasPrice, tc.provedWork)

// Check the value of the result
if result.Cmp(tc.expectedOutput) != 0 {
t.Errorf("%s: expected %v, got %v", tc.name, tc.expectedOutput, result)
}
})
}
}

func TestEvaluateWork(t *testing.T) {
origin := thor.BytesToAddress([]byte("origin"))
tx := GetMockTx()

// Returns a function
evaluate := tx.EvaluateWork(origin)

// Test with a range of nonce values
for nonce := uint64(0); nonce < 10; nonce++ {
work := evaluate(nonce)

// Basic Assertions
assert.NotNil(t, work)
assert.True(t, work.Cmp(big.NewInt(0)) > 0, "Work should be positive")
}
}

func TestTx(t *testing.T) {
to, _ := thor.ParseAddress("0x7567d83b7b8d80addcb281a71d54fc7b3364ffed")
trx := new(tx.Builder).ChainTag(1).
Expand Down
28 changes: 28 additions & 0 deletions tx/transactions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package tx_test

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/vechain/thor/thor"
"github.com/vechain/thor/tx"
)

func MockTransactions(n int) tx.Transactions {
txs := make(tx.Transactions, n)
for i := range txs {
mockTx := GetMockTx()
txs[i] = &mockTx
}
return txs
}

func TestRootHash(t *testing.T) {
// Test empty transactions slice
emptyTxs := tx.Transactions{}
emptyRoot := emptyTxs.RootHash()
assert.Equal(t, emptyTxs.RootHash(), emptyRoot)

nonEmptyTxs := MockTransactions(2)
assert.Equal(t, nonEmptyTxs.RootHash(), thor.Bytes32{0x30, 0x9a, 0xd5, 0x4b, 0x28, 0x76, 0x65, 0x52, 0x66, 0x89, 0x7b, 0x19, 0x22, 0x24, 0x63, 0xd8, 0x27, 0xc8, 0x2a, 0xd6, 0x20, 0x17, 0x7a, 0xcf, 0x9a, 0xfa, 0xc, 0xce, 0xff, 0x12, 0x24, 0x48})
}
51 changes: 51 additions & 0 deletions tx/work_eval_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package tx

import (
"math"
"math/big"
"testing"

"github.com/stretchr/testify/assert"
)

func TestWorkToGas(t *testing.T) {
// Test cases
testCases := []struct {
name string
work *big.Int
blockNum uint32
expected uint64
}{
{
name: "Basic conversion",
work: big.NewInt(10000),
blockNum: 100,
expected: 10,
},
{
name: "Zero work",
work: big.NewInt(0),
blockNum: 100,
expected: 0,
},
{
name: "Large work value",
work: big.NewInt(math.MaxInt64),
blockNum: 100,
expected: 0x20c49ba5e353f7,
},
{
name: "Large work value and blockNum",
work: big.NewInt(math.MaxInt64),
blockNum: 12345679,
expected: 0x52fc533083329,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
result := workToGas(tc.work, tc.blockNum)
assert.Equal(t, tc.expected, result, "Expected and actual gas should match")
})
}
}

0 comments on commit df2886c

Please sign in to comment.