Skip to content

Commit

Permalink
added live test for intx sender address parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
ws4charlie committed Mar 29, 2024
1 parent a341da9 commit f2755af
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -348,3 +348,76 @@ func LiveTestAvgFeeRateTestnetMempoolSpace(t *testing.T) {

compareAvgFeeRate(t, client, startBlock, endBlock, true)
}

// Remove prefix "Live" to run this live test
func LiveTestGetSenderByVin(t *testing.T) {
// setup Bitcoin client
chainID := int64(8332)
client, err := getRPCClient(chainID)
require.NoError(t, err)

// net params
net, err := common.GetBTCChainParams(chainID)
require.NoError(t, err)
testnet := false
if chainID == common.BtcTestNetChain().ChainId {
testnet = true
}

// calculates block range to test
startBlock, err := client.GetBlockCount()
require.NoError(t, err)
endBlock := startBlock - 5000

// loop through mempool.space blocks in descending order
BLOCKLOOP:
for bn := startBlock; bn >= endBlock; {
// get block hash
blkHash, err := client.GetBlockHash(int64(bn))
if err != nil {
fmt.Printf("error GetBlockHash for block %d: %s\n", bn, err)
time.Sleep(3 * time.Second)
continue
}

// get mempool.space txs for the block
mempoolTxs, err := testutils.GetBlockTxs(context.Background(), blkHash.String(), testnet)
if err != nil {
fmt.Printf("error GetBlockTxs %d: %s\n", bn, err)
time.Sleep(10 * time.Second)
continue
}

// loop through each tx in the block
for i, mptx := range mempoolTxs {
// sample 10 txs per block
if i >= 10 {
break
}
for _, mpvin := range mptx.Vin {
// skip coinbase tx
if mpvin.IsCoinbase {
continue
}
// get sender address for each vin
vin := btcjson.Vin{
Txid: mpvin.TxID,
Vout: mpvin.Vout,
}
senderAddr, err := GetSenderAddressByVin(client, vin, net)
if err != nil {
fmt.Printf("error GetSenderAddressByVin for block %d, tx %s vout %d: %s\n", bn, vin.Txid, vin.Vout, err)
time.Sleep(3 * time.Second)
continue BLOCKLOOP // retry the block
}
if senderAddr != mpvin.Prevout.ScriptpubkeyAddress {
panic(fmt.Sprintf("block %d, tx %s, vout %d: want %s, got %s\n", bn, vin.Txid, vin.Vout, mpvin.Prevout.ScriptpubkeyAddress, senderAddr))
} else {
fmt.Printf("block: %d sender address type: %s\n", bn, mpvin.Prevout.ScriptpubkeyType)
}
}
}
bn--
time.Sleep(500 * time.Millisecond)
}
}
55 changes: 52 additions & 3 deletions zetaclient/testutils/mempool_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import (
)

const (
APIURLBlocks = "https://mempool.space/api/v1/blocks"
APIUrlBlocksTestnet = "https://mempool.space/testnet/api/v1/blocks"
APIURLBlocks = "https://mempool.space/api/v1/blocks"
APIURLBlockTxs = "https://mempool.space/api/block/%s/txs"
APIURLBlocksTestnet = "https://mempool.space/testnet/api/v1/blocks"
APIURLBlockTxsTestnet = "https://mempool.space/testnet/api/block/%s/txs"
)

type MempoolBlock struct {
Expand All @@ -30,6 +32,39 @@ type MempoolBlock struct {
Extras BlockExtra `json:"extras"`
}

type Vin struct {
TxID string `json:"txid"`
Vout uint32 `json:"vout"`
Prevout struct {
Scriptpubkey string `json:"scriptpubkey"`
ScriptpubkeyAsm string `json:"scriptpubkey_asm"`
ScriptpubkeyType string `json:"scriptpubkey_type"`
ScriptpubkeyAddress string `json:"scriptpubkey_address"`
Value int64 `json:"value"`
} `json:"prevout"`
Scriptsig string `json:"scriptsig"`
IsCoinbase bool `json:"is_coinbase"`
Sequence uint32 `json:"sequence"`
}

type Vout struct {
Scriptpubkey string `json:"scriptpubkey"`
ScriptpubkeyAsm string `json:"scriptpubkey_asm"`
ScriptpubkeyType string `json:"scriptpubkey_type"`
Value int64 `json:"value"`
}

type MempoolTx struct {
TxID string `json:"txid"`
Version int `json:"version"`
LockTime int `json:"locktime"`
Vin []Vin `json:"vin"`
Vout []Vout `json:"vout"`
Size int `json:"size"`
Weight int `json:"weight"`
Fee int `json:"fee"`
}

type BlockExtra struct {
TotalFees int `json:"totalFees"`
MedianFee float64 `json:"medianFee"`
Expand Down Expand Up @@ -91,14 +126,28 @@ func Get(ctx context.Context, path string, v interface{}) error {
return json.NewDecoder(r.Body).Decode(v)
}

// GetBlocks returns return 15 mempool.space blocks [n-14, n] per request
func GetBlocks(ctx context.Context, n int, testnet bool) ([]MempoolBlock, error) {
path := fmt.Sprintf("%s/%d", APIURLBlocks, n)
if testnet {
path = fmt.Sprintf("%s/%d", APIUrlBlocksTestnet, n)
path = fmt.Sprintf("%s/%d", APIURLBlocksTestnet, n)
}
blocks := make([]MempoolBlock, 0)
if err := Get(ctx, path, &blocks); err != nil {
return nil, err
}
return blocks, nil
}

// GetBlockTxs a list of transactions in the block (up to 25 transactions beginning at index 0)
func GetBlockTxs(ctx context.Context, blockHash string, testnet bool) ([]MempoolTx, error) {
path := fmt.Sprintf(APIURLBlockTxs, blockHash)
if testnet {
path = fmt.Sprintf(APIURLBlockTxsTestnet, blockHash)
}
txs := make([]MempoolTx, 0)
if err := Get(ctx, path, &txs); err != nil {
return nil, err
}
return txs, nil
}

0 comments on commit f2755af

Please sign in to comment.