Skip to content

Commit

Permalink
feat: new unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
oxf71 committed Nov 21, 2023
1 parent a840057 commit 9aafe3d
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 0 deletions.
17 changes: 17 additions & 0 deletions bitcoin/indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"

"github.com/btcsuite/btcd/btcjson"
"github.com/btcsuite/btcd/txscript"
"github.com/evmos/ethermint/types"

Expand Down Expand Up @@ -100,6 +101,7 @@ func (b *Indexer) parseTx(txHash chainhash.Hash) (parsedResult []*types.BitcoinT

// parseFromAddress from vin parse from address
// return all possible values parsed from address
// TODO: at present, it is assumed that it is a single from, and multiple from needs to be tested later
func (b *Indexer) parseFromAddress(txResult *btcutil.Tx) (fromAddress []string, err error) {
for _, vin := range txResult.MsgTx().TxIn {
// get prev tx hash
Expand All @@ -126,6 +128,11 @@ func (b *Indexer) parseFromAddress(txResult *btcutil.Tx) (fromAddress []string,
return
}

// parseAddress from pkscript parse address
func (b *Indexer) ParseAddress(pkScript []byte) (string, error) {
return b.parseAddress(pkScript)
}

// parseAddress from pkscript parse address
func (b *Indexer) parseAddress(pkScript []byte) (string, error) {
pk, err := txscript.ParsePkScript(pkScript)
Expand All @@ -140,3 +147,13 @@ func (b *Indexer) parseAddress(pkScript []byte) (string, error) {
}
return pkAddress.EncodeAddress(), nil
}

// LatestBlock get latest block height in the longest block chain.
func (b *Indexer) LatestBlock() (int64, error) {
return b.client.GetBlockCount()
}

// BlockChainInfo get block chain info
func (b *Indexer) BlockChainInfo() (*btcjson.GetBlockChainInfoResult, error) {
return b.client.GetBlockChainInfo()
}
149 changes: 149 additions & 0 deletions bitcoin/indexer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package bitcoin

import (
"testing"

"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/rpcclient"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/stretchr/testify/require"
)

func TestNewBitcoinIndexer(t *testing.T) {
testCases := []struct {
name string
listendAddress string
errMsg string
}{
{
"success",
"tb1qukxc3sy3s3k5n5z9cxt3xyywgcjmp2tzudlz2n",
"",
},
{
"success: segwit",
"3HctoF43JZCjAQrad1MqGtn5EsF57f5CCN",
"",
},
{
"success: legacy",
"1CpnsCEQ3Q4d15rLkrANnfd9GtYNHJRsYb",
"",
},
{
"success: segwit(bech32)",
"bc1qj2hkaplmmka9lqjj4p23t2z2lrd4vv8fjqa36g",
"",
},
{
"fail: format fail",
"tb1qukxc3sy3s3k5n5z9cxt3xyywgcjmp2tzudlz2n1",
"decode listen address err:decoded address is of unknown format",
},
{
"fail: address null",
"",
"decode listen address err:decoded address is of unknown format",
},
{
"fail: check sum",
"1CpnsCEQ3Q4d15rLkrANnfd9GtYNHJRsYy",
"decode listen address err:checksum mismatch",
},
}

for _, tc := range testCases {
_, err := NewBitcoinIndexer(mockRpcClient(t),
&chaincfg.MainNetParams, // chainParams Do not affect the address
tc.listendAddress)
if err != nil {
require.EqualError(t, err, tc.errMsg)
}
}
}

func TestParseAddress(t *testing.T) {
testCases := []struct {
name string
pkScriptHex string
parsedAddress string
pkAddress string
chainParams *chaincfg.Params
errMsg string
}{
{
"success",
"0x51207099e4b23427fc40ba4777bbf52cfd0b7444d69a3e21ef281270723f54c0c14b",
"tb1pwzv7fv35yl7ypwj8w7al2t8apd6yf4568cs772qjwper74xqc99sk8x7tk",
"tb1pwzv7fv35yl7ypwj8w7al2t8apd6yf4568cs772qjwper74xqc99sk8x7tk",
&chaincfg.SigNetParams,
"",
},
{
"success: main net",
"0x5120916e7f2636a8754793a5257198d9bef0d6afbea8d09cc2a36b5901869d6b0ad5",
"bc1pj9h87f3k4p650ya9y4ce3kd77rt2l04g6zwv9gmttyqcd8ttpt2sva77pe",
"bc1pj9h87f3k4p650ya9y4ce3kd77rt2l04g6zwv9gmttyqcd8ttpt2sva77pe",
&chaincfg.MainNetParams,
"",
},
{
"success: sim net",
"0x5120916e7f2636a8754793a5257198d9bef0d6afbea8d09cc2a36b5901869d6b0ad5",
"sb1pj9h87f3k4p650ya9y4ce3kd77rt2l04g6zwv9gmttyqcd8ttpt2suyzkzn",
"sb1pj9h87f3k4p650ya9y4ce3kd77rt2l04g6zwv9gmttyqcd8ttpt2suyzkzn",
&chaincfg.SimNetParams,
"",
},
{
"fail: unsupported script type",
"0x51207099e4b23427fc40ba4777bbf52cfd0b7444d69a3e21ef281270723f54c0c1",
"1CpnsCEQ3Q4d15rLkrANnfd9GtYNHJRsYb",
"tb1pwzv7fv35yl7ypwj8w7al2t8apd6yf4568cs772qjwper74xqc99sk8x7tk",
&chaincfg.SigNetParams,
"parse pkscript err:unsupported script type",
},
{
"fail: empty pk",
"0x",
"1CpnsCEQ3Q4d15rLkrANnfd9GtYNHJRsYb",
"tb1pwzv7fv35yl7ypwj8w7al2t8apd6yf4568cs772qjwper74xqc99sk8x7tk",
&chaincfg.SigNetParams,
"parse pkscript err:unsupported script type",
},
}

for _, tc := range testCases {
pkScript, err := hexutil.Decode(tc.pkScriptHex)
require.NoError(t, err)
tmpAddress, err := mockBitcoinIndexer(t, tc.chainParams).ParseAddress(pkScript)
if err != nil {
require.EqualError(t, err, tc.errMsg)
continue
}
if tmpAddress != tc.parsedAddress && tmpAddress != tc.pkAddress {
t.Errorf("test:%s expected %s, got %s", tc.name, tc.parsedAddress, tmpAddress)
}
}
}

func mockRpcClient(t *testing.T) *rpcclient.Client {
connCfg := &rpcclient.ConnConfig{
Host: "127.0.0.1:38332",
User: "user",
Pass: "password",
HTTPPostMode: true,
DisableTLS: true,
}
client, err := rpcclient.New(connCfg, nil)
require.NoError(t, err)
return client
}

func mockBitcoinIndexer(t *testing.T, chainParams *chaincfg.Params) *Indexer {
indexer, err := NewBitcoinIndexer(mockRpcClient(t),
chainParams,
"tb1qukxc3sy3s3k5n5z9cxt3xyywgcjmp2tzudlz2n")
require.NoError(t, err)
return indexer
}
2 changes: 2 additions & 0 deletions types/bitcoin_indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ package types
type BITCOINTxIndexer interface {
// ParseBlock parse bitcoin block tx
ParseBlock(int64) ([]*BitcoinTxParseResult, error)
// LatestBlock get latest block height in the longest block chain.
LatestBlock() (int64, error)
}

0 comments on commit 9aafe3d

Please sign in to comment.