Skip to content
This repository has been archived by the owner on Oct 21, 2024. It is now read-only.

feat(BUX-174): miner url wrapper added to responses from Query and Submit Transaction #20

Merged
merged 3 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions broadcast/base_response.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package broadcast

type BaseResponse struct {
// Miner is the URL of the miner that returned the response.
Miner string `json:"miner"`
}
22 changes: 10 additions & 12 deletions broadcast/fee_quotes.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,36 @@ package broadcast

// PolicyQuoteResponse is the response returned by the GetPolicyQuote method.
type PolicyQuoteResponse struct {
// Miner is the URL of the miner that returned the policy quote.
Miner string `json:"miner"`
BaseResponse
// Policy is a detailed policy of the miner.
Policy PolicyResponse `json:"policy"`
Policy PolicyResponse `json:"policy"`
// Timestamp is the timestamp of the policy quote response received.
Timestamp string `json:"timestamp"`
Timestamp string `json:"timestamp"`
}

// FeeQuote is the response returned by the GetFeeQuote method.
type FeeQuote struct {
// Miner is the URL of the miner that returned the fee quote.
Miner string `json:"miner"`
BaseResponse
// MiningFee is expressed by number of satoshis per number of bytes.
MiningFee MiningFeeResponse `json:"miningFee"`
// Timestamp is the timestamp of the fee quote response received.
Timestamp string `json:"timestamp"`
Timestamp string `json:"timestamp"`
}

type PolicyResponse struct {
// MaxScriptSizePolicy is the maximum number of bytes of the script in a single transaction.
MaxScriptSizePolicy int64 `json:"maxscriptsizepolicy"`
MaxScriptSizePolicy int64 `json:"maxscriptsizepolicy"`
// MaxTxSigOpsCountPolicy is the maximum allowed number of signature operations in a single transaction
MaxTxSigOpsCountPolicy int64 `json:"maxtxsigopscountspolicy"`
MaxTxSigOpsCountPolicy int64 `json:"maxtxsigopscountspolicy"`
// MaxTxSizePolicy is the maximum size in bytes of a single transaction.
MaxTxSizePolicy int64 `json:"maxtxsizepolicy"`
MaxTxSizePolicy int64 `json:"maxtxsizepolicy"`
// MiningFee is expressed by number of satoshis per number of bytes.
MiningFee MiningFeeResponse `json:"miningFee"`
MiningFee MiningFeeResponse `json:"miningFee"`
}

type MiningFeeResponse struct {
// Bytes is the number of bytes per which a number of satoshis is charged as transaction fee.
Bytes int64 `json:"bytes"`
Bytes int64 `json:"bytes"`
// Satoshis is the number of satoshis charged as transaction fee per the number of bytes.
Satoshis int64 `json:"satoshis"`
}
4 changes: 2 additions & 2 deletions broadcast/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ type TransactionSubmitter interface {

// TransactionsSubmitter is the interface that wraps the SubmitBatchTransactions method.
// It is the same as TransactionSubmitter but it takes a slice of transactions and tries to broadcast them to the P2P network.
// As a result it returns a slice of SubmitTxResponse objects.
// As a result it returns a SubmitBatchTxResponse, which includes a slice of SubmitTxResponse objects.
type TransactionsSubmitter interface {
SubmitBatchTransactions(ctx context.Context, tx []*Transaction, opts ...TransactionOptFunc) ([]*SubmitTxResponse, error)
SubmitBatchTransactions(ctx context.Context, tx []*Transaction, opts ...TransactionOptFunc) (*SubmitBatchTxResponse, error)
}

// Client is a grouping interface that represents the entire exposed functionality of the broadcast client.
Expand Down
6 changes: 3 additions & 3 deletions broadcast/internal/arc/arc_fee_quote.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ func (a *ArcClient) GetFeeQuote(ctx context.Context) ([]*broadcast.FeeQuote, err
}

feeQuote := &broadcast.FeeQuote{
Miner: a.apiURL,
MiningFee: policyQuotes[0].Policy.MiningFee,
Timestamp: policyQuotes[0].Timestamp,
BaseResponse: broadcast.BaseResponse{Miner: a.apiURL},
MiningFee: policyQuotes[0].Policy.MiningFee,
Timestamp: policyQuotes[0].Timestamp,
}

feeQuotes := []*broadcast.FeeQuote{feeQuote}
Expand Down
2 changes: 1 addition & 1 deletion broadcast/internal/arc/arc_fee_quote_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func TestFeeQuote(t *testing.T) {
},
expectedResult: []*broadcast.FeeQuote{
{
Miner: "http://example.com",
BaseResponse: broadcast.BaseResponse{Miner: "http://example.com"},
MiningFee: broadcast.MiningFeeResponse{
Bytes: 1000,
Satoshis: 1,
Expand Down
2 changes: 1 addition & 1 deletion broadcast/internal/arc/arc_policy_quote_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func TestPolicyQuote(t *testing.T) {
},
expectedResult: []*broadcast.PolicyQuoteResponse{
{
Miner: "http://example.com",
BaseResponse: broadcast.BaseResponse{Miner: "http://example.com"},
Policy: broadcast.PolicyResponse{
MaxScriptSizePolicy: 100000000,
MaxTxSigOpsCountPolicy: 4294967295,
Expand Down
2 changes: 2 additions & 0 deletions broadcast/internal/arc/arc_query_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ func queryTransaction(ctx context.Context, arc *ArcClient, txHash string) (*broa
return nil, err
}

model.Miner = arc.apiURL

return &model, nil
}

Expand Down
10 changes: 6 additions & 4 deletions broadcast/internal/arc/arc_query_tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import (
"net/http"
"testing"

"github.com/bitcoin-sv/go-broadcast-client/broadcast"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"

"github.com/bitcoin-sv/go-broadcast-client/broadcast"
)

func TestQueryTransaction(t *testing.T) {
Expand All @@ -34,9 +35,10 @@ func TestQueryTransaction(t *testing.T) {
`)),
},
expectedResult: &broadcast.QueryTxResponse{
BlockHash: "abc123",
TxStatus: broadcast.Confirmed,
TxID: "abc123",
BaseResponse: broadcast.BaseResponse{Miner: "http://example.com"},
BlockHash: "abc123",
TxStatus: broadcast.Confirmed,
TxID: "abc123",
},
},
{
Expand Down
28 changes: 19 additions & 9 deletions broadcast/internal/arc/arc_submit_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,15 @@ func (a *ArcClient) SubmitTransaction(ctx context.Context, tx *broadcast.Transac
return nil, err
}

return result, nil
response := &broadcast.SubmitTxResponse{
BaseResponse: broadcast.BaseResponse{Miner: a.apiURL},
SubmittedTx: result,
}

return response, nil
}

func (a *ArcClient) SubmitBatchTransactions(ctx context.Context, txs []*broadcast.Transaction, opts ...broadcast.TransactionOptFunc) ([]*broadcast.SubmitTxResponse, error) {
func (a *ArcClient) SubmitBatchTransactions(ctx context.Context, txs []*broadcast.Transaction, opts ...broadcast.TransactionOptFunc) (*broadcast.SubmitBatchTxResponse, error) {
if a == nil {
return nil, broadcast.ErrClientUndefined
}
Expand All @@ -62,10 +67,15 @@ func (a *ArcClient) SubmitBatchTransactions(ctx context.Context, txs []*broadcas
return nil, err
}

return result, nil
response := broadcast.SubmitBatchTxResponse{
BaseResponse: broadcast.BaseResponse{Miner: a.apiURL},
Transactions: result,
}

return &response, nil
}

func submitTransaction(ctx context.Context, arc *ArcClient, tx *broadcast.Transaction, opts *broadcast.TransactionOpts) (*broadcast.SubmitTxResponse, error) {
func submitTransaction(ctx context.Context, arc *ArcClient, tx *broadcast.Transaction, opts *broadcast.TransactionOpts) (*broadcast.SubmittedTx, error) {
url := arc.apiURL + arcSubmitTxRoute
data, err := createSubmitTxBody(tx)
if err != nil {
Expand All @@ -88,7 +98,7 @@ func submitTransaction(ctx context.Context, arc *ArcClient, tx *broadcast.Transa
return nil, arc_utils.HandleHttpError(err)
}

model := broadcast.SubmitTxResponse{}
model := broadcast.SubmittedTx{}
err = arc_utils.DecodeResponseBody(resp.Body, &model)
if err != nil {
return nil, err
Expand All @@ -97,7 +107,7 @@ func submitTransaction(ctx context.Context, arc *ArcClient, tx *broadcast.Transa
return &model, nil
}

func submitBatchTransactions(ctx context.Context, arc *ArcClient, txs []*broadcast.Transaction, opts *broadcast.TransactionOpts) ([]*broadcast.SubmitTxResponse, error) {
func submitBatchTransactions(ctx context.Context, arc *ArcClient, txs []*broadcast.Transaction, opts *broadcast.TransactionOpts) ([]*broadcast.SubmittedTx, error) {
url := arc.apiURL + arcSubmitBatchTxsRoute
data, err := createSubmitBatchTxsBody(txs)
if err != nil {
Expand All @@ -120,7 +130,7 @@ func submitBatchTransactions(ctx context.Context, arc *ArcClient, txs []*broadca
return nil, arc_utils.HandleHttpError(err)
}

var model []*broadcast.SubmitTxResponse
var model []*broadcast.SubmittedTx
err = arc_utils.DecodeResponseBody(resp.Body, &model)
if err != nil {
return nil, err
Expand Down Expand Up @@ -176,7 +186,7 @@ func appendSubmitTxHeaders(pld *httpclient.HTTPRequest, opts *broadcast.Transact
}
}

func validateBatchResponse(model []*broadcast.SubmitTxResponse) error {
func validateBatchResponse(model []*broadcast.SubmittedTx) error {
for _, tx := range model {
if err := validateSubmitTxResponse(tx); err != nil {
return err
Expand All @@ -186,7 +196,7 @@ func validateBatchResponse(model []*broadcast.SubmitTxResponse) error {
return nil
}

func validateSubmitTxResponse(model *broadcast.SubmitTxResponse) error {
func validateSubmitTxResponse(model *broadcast.SubmittedTx) error {
if model.TxStatus == "" {
return broadcast.ErrMissingStatus
}
Expand Down
31 changes: 23 additions & 8 deletions broadcast/internal/arc/arc_submit_tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import (
"net/http"
"testing"

"github.com/stretchr/testify/assert"

"github.com/bitcoin-sv/go-broadcast-client/broadcast"
"github.com/bitcoin-sv/go-broadcast-client/httpclient"
"github.com/stretchr/testify/assert"
)

func TestSubmitTransaction(t *testing.T) {
Expand All @@ -36,7 +37,8 @@ func TestSubmitTransaction(t *testing.T) {
`)),
},
expectedResult: &broadcast.SubmitTxResponse{
TxStatus: broadcast.Confirmed,
BaseResponse: broadcast.BaseResponse{Miner: "http://example.com"},
SubmittedTx: &broadcast.SubmittedTx{TxStatus: broadcast.Confirmed},
},
},
{
Expand Down Expand Up @@ -69,7 +71,12 @@ func TestSubmitTransaction(t *testing.T) {
mockHttpClient := new(MockHttpClient)

body, _ := createSubmitTxBody(tc.transaction)
expectedPayload := httpclient.NewPayload(httpclient.POST, "http://example.com"+arcSubmitTxRoute, "someToken", body)
expectedPayload := httpclient.NewPayload(
httpclient.POST,
"http://example.com"+arcSubmitTxRoute,
"someToken",
body,
)
appendSubmitTxHeaders(&expectedPayload, nil)

mockHttpClient.On("DoRequest", context.Background(), expectedPayload).
Expand Down Expand Up @@ -100,7 +107,7 @@ func TestSubmitBatchTransactions(t *testing.T) {
transactions []*broadcast.Transaction
httpResponse *http.Response
httpError error
expectedResult []*broadcast.SubmitTxResponse
expectedResult *broadcast.SubmitBatchTxResponse
expectedError error
}{
{
Expand All @@ -121,9 +128,12 @@ func TestSubmitBatchTransactions(t *testing.T) {
}
]`)),
},
expectedResult: []*broadcast.SubmitTxResponse{
{TxStatus: broadcast.Confirmed},
{TxStatus: broadcast.Confirmed},
expectedResult: &broadcast.SubmitBatchTxResponse{
BaseResponse: broadcast.BaseResponse{Miner: "http://example.com"},
Transactions: []*broadcast.SubmittedTx{
{TxStatus: broadcast.Confirmed},
{TxStatus: broadcast.Confirmed},
},
},
},
{
Expand Down Expand Up @@ -162,7 +172,12 @@ func TestSubmitBatchTransactions(t *testing.T) {
mockHttpClient := new(MockHttpClient)

body, _ := createSubmitBatchTxsBody(tc.transactions)
expectedPayload := httpclient.NewPayload(httpclient.POST, "http://example.com"+arcSubmitBatchTxsRoute, "someToken", body)
expectedPayload := httpclient.NewPayload(
httpclient.POST,
"http://example.com"+arcSubmitBatchTxsRoute,
"someToken",
body,
)
appendSubmitTxHeaders(&expectedPayload, nil)

mockHttpClient.On("DoRequest", context.Background(), expectedPayload).
Expand Down
4 changes: 2 additions & 2 deletions broadcast/internal/composite/broadcaster.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func (c *compositeBroadcaster) SubmitBatchTransactions(
ctx context.Context,
txs []*broadcast.Transaction,
opts ...broadcast.TransactionOptFunc,
) ([]*broadcast.SubmitTxResponse, error) {
) (*broadcast.SubmitBatchTxResponse, error) {
executionFuncs := make([]executionFunc, len(c.broadcasters))
for i, broadcaster := range c.broadcasters {
executionFuncs[i] = func(ctx context.Context) (Result, error) {
Expand All @@ -134,7 +134,7 @@ func (c *compositeBroadcaster) SubmitBatchTransactions(
}

// Convert result to []SubmitTxResponse
submitTxResponse, ok := result.([]*broadcast.SubmitTxResponse)
submitTxResponse, ok := result.(*broadcast.SubmitBatchTxResponse)
if !ok {
return nil, fmt.Errorf("unexpected result type: %T", result)
}
Expand Down
1 change: 1 addition & 0 deletions broadcast/query_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package broadcast

// QueryTxResponse is the response returned by the QueryTransaction method.
type QueryTxResponse struct {
BaseResponse
// BlockHash is the hash of the block where the transaction was included.
BlockHash string `json:"blockHash,omitempty"`
// BlockHeight is the height of the block where the transaction was included.
Expand Down
17 changes: 15 additions & 2 deletions broadcast/submit_tx.go
arkadiuszos4chain marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package broadcast

// SubmitTxResponse is the response returned by the SubmitTransaction method.
type SubmitTxResponse struct {
// SubmittedTx is the response returned by the miner from submitting transaction(s).
type SubmittedTx struct {
// BlockHash is the hash of the block where the transaction was included.
BlockHash string `json:"blockHash,omitempty"`
// BlockHeight is the height of the block where the transaction was included.
Expand All @@ -15,3 +15,16 @@ type SubmitTxResponse struct {
// TxStatus is the status of the transaction.
TxStatus TxStatus `json:"txStatus,omitempty"`
}

// SubmitTxResponse is the response returned by the SubmitTransaction method.
type SubmitTxResponse struct {
BaseResponse
*SubmittedTx
}

// SubmitTxResponse is the response returned by the SubmitBatchTransactions method.
type SubmitBatchTxResponse struct {
BaseResponse
// Transactions is a slice of responses returned from submitting the batch transactions.
Transactions []*SubmittedTx `json:"transactions"`
}
1 change: 1 addition & 0 deletions examples/query_transaction/query_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func main() {
log.Fatalf("error: %s", err.Error())
}

log.Printf("miner: %s", result.Miner)
log.Printf("hash: %s", result.BlockHash)
log.Printf("txID: %s", result.TxID)
log.Printf("status: %s", result.TxStatus)
Expand Down
3 changes: 2 additions & 1 deletion examples/submit_batch_transactions/submit_batch_txs.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ func main() {
log.Fatalf("error: %s", err.Error())
}

for i, tx := range result {
log.Printf("Miner that submitted batch txs: %s", result.Miner)
for i, tx := range result.Transactions {
log.Printf("tx[%d]: { hash: %s, status: %s }", i, tx.BlockHash, tx.TxStatus)
}

Expand Down
1 change: 1 addition & 0 deletions examples/submit_transaction/submit_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func main() {
log.Fatalf("error: %s", err.Error())
}

log.Printf("miner: %s", result.Miner)
log.Printf("hash: %s", result.BlockHash)
log.Printf("status: %s", result.TxStatus)
}