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

Commit

Permalink
feat(BUX-162): moves headers opts out of tx struct (#14)
Browse files Browse the repository at this point in the history
* feat: moves headers opts out of tx struct

* fix: moves .With methods to exposed broadcast packages
  • Loading branch information
wregulski authored Aug 17, 2023
1 parent 0c9262d commit f06b5db
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 34 deletions.
4 changes: 2 additions & 2 deletions broadcast/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ type TransactionQuerier interface {
// Transaction object needs RawTx to be set. All other fields are optional and used to append headers related to status callbacks.
// As a result it returns a SubmitTxResponse object.
type TransactionSubmitter interface {
SubmitTransaction(ctx context.Context, tx *Transaction) (*SubmitTxResponse, error)
SubmitTransaction(ctx context.Context, tx *Transaction, opts ...TransactionOptFunc) (*SubmitTxResponse, error)
}

// 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.
type TransactionsSubmitter interface {
SubmitBatchTransactions(ctx context.Context, tx []*Transaction) ([]*SubmitTxResponse, error)
SubmitBatchTransactions(ctx context.Context, tx []*Transaction, opts ...TransactionOptFunc) ([]*SubmitTxResponse, error)
}

// Client is a grouping interface that represents the entire exposed functionality of the broadcast client.
Expand Down
44 changes: 29 additions & 15 deletions broadcast/internal/arc/arc_submit_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,17 @@ type SubmitTxRequest struct {

var ErrSubmitTxMarshal = errors.New("error while marshalling submit tx body")

func (a *ArcClient) SubmitTransaction(ctx context.Context, tx *broadcast.Transaction) (*broadcast.SubmitTxResponse, error) {
func (a *ArcClient) SubmitTransaction(ctx context.Context, tx *broadcast.Transaction, opts ...broadcast.TransactionOptFunc) (*broadcast.SubmitTxResponse, error) {
if a == nil {
return nil, broadcast.ErrClientUndefined
}

result, err := submitTransaction(ctx, a, tx)
options := &broadcast.TransactionOpts{}
for _, opt := range opts {
opt(options)
}

result, err := submitTransaction(ctx, a, tx, options)
if err != nil {
return nil, err
}
Expand All @@ -34,7 +39,7 @@ func (a *ArcClient) SubmitTransaction(ctx context.Context, tx *broadcast.Transac
return result, nil
}

func (a *ArcClient) SubmitBatchTransactions(ctx context.Context, txs []*broadcast.Transaction) ([]*broadcast.SubmitTxResponse, error) {
func (a *ArcClient) SubmitBatchTransactions(ctx context.Context, txs []*broadcast.Transaction, opts ...broadcast.TransactionOptFunc) ([]*broadcast.SubmitTxResponse, error) {
if a == nil {
return nil, broadcast.ErrClientUndefined
}
Expand All @@ -43,7 +48,12 @@ func (a *ArcClient) SubmitBatchTransactions(ctx context.Context, txs []*broadcas
return nil, errors.New("invalid request, no transactions to submit")
}

result, err := submitBatchTransactions(ctx, a, txs)
options := &broadcast.TransactionOpts{}
for _, opt := range opts {
opt(options)
}

result, err := submitBatchTransactions(ctx, a, txs, options)
if err != nil {
return nil, err
}
Expand All @@ -55,7 +65,7 @@ func (a *ArcClient) SubmitBatchTransactions(ctx context.Context, txs []*broadcas
return result, nil
}

func submitTransaction(ctx context.Context, arc *ArcClient, tx *broadcast.Transaction) (*broadcast.SubmitTxResponse, error) {
func submitTransaction(ctx context.Context, arc *ArcClient, tx *broadcast.Transaction, opts *broadcast.TransactionOpts) (*broadcast.SubmitTxResponse, error) {
url := arc.apiURL + arcSubmitTxRoute
data, err := createSubmitTxBody(tx)
if err != nil {
Expand All @@ -68,7 +78,7 @@ func submitTransaction(ctx context.Context, arc *ArcClient, tx *broadcast.Transa
arc.token,
data,
)
appendSubmitTxHeaders(&pld, tx)
appendSubmitTxHeaders(&pld, opts)

resp, err := arc.HTTPClient.DoRequest(
ctx,
Expand All @@ -87,7 +97,7 @@ func submitTransaction(ctx context.Context, arc *ArcClient, tx *broadcast.Transa
return &model, nil
}

func submitBatchTransactions(ctx context.Context, arc *ArcClient, txs []*broadcast.Transaction) ([]*broadcast.SubmitTxResponse, error) {
func submitBatchTransactions(ctx context.Context, arc *ArcClient, txs []*broadcast.Transaction, opts *broadcast.TransactionOpts) ([]*broadcast.SubmitTxResponse, error) {
url := arc.apiURL + arcSubmitBatchTxsRoute
data, err := createSubmitBatchTxsBody(txs)
if err != nil {
Expand All @@ -100,7 +110,7 @@ func submitBatchTransactions(ctx context.Context, arc *ArcClient, txs []*broadca
arc.token,
data,
)
appendSubmitTxHeaders(&pld, txs[0])
appendSubmitTxHeaders(&pld, opts)

resp, err := arc.HTTPClient.DoRequest(
ctx,
Expand Down Expand Up @@ -144,20 +154,24 @@ func createSubmitBatchTxsBody(txs []*broadcast.Transaction) ([]byte, error) {
return data, nil
}

func appendSubmitTxHeaders(pld *httpclient.HTTPRequest, tx *broadcast.Transaction) {
if tx.MerkleProof {
func appendSubmitTxHeaders(pld *httpclient.HTTPRequest, opts *broadcast.TransactionOpts) {
if opts == nil {
return
}

if opts.MerkleProof {
pld.AddHeader("X-MerkleProof", "true")
}

if tx.CallBackURL != "" {
pld.AddHeader("X-CallbackUrl", tx.CallBackURL)
if opts.CallbackURL != "" {
pld.AddHeader("X-CallbackUrl", opts.CallbackURL)
}

if tx.CallBackToken != "" {
pld.AddHeader("X-CallbackToken", tx.CallBackToken)
if opts.CallbackToken != "" {
pld.AddHeader("X-CallbackToken", opts.CallbackToken)
}

if statusCode, ok := broadcast.MapTxStatusToInt(tx.WaitForStatus); ok {
if statusCode, ok := broadcast.MapTxStatusToInt(opts.WaitForStatus); ok {
pld.AddHeader("X-WaitForStatus", strconv.Itoa(statusCode))
}
}
Expand Down
4 changes: 2 additions & 2 deletions broadcast/internal/arc/arc_submit_tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func TestSubmitTransaction(t *testing.T) {

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

mockHttpClient.On("DoRequest", context.Background(), expectedPayload).
Return(tc.httpResponse, tc.httpError).Once()
Expand Down Expand Up @@ -163,7 +163,7 @@ func TestSubmitBatchTransactions(t *testing.T) {

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

mockHttpClient.On("DoRequest", context.Background(), expectedPayload).
Return(tc.httpResponse, tc.httpError).Once()
Expand Down
2 changes: 2 additions & 0 deletions broadcast/internal/composite/broadcaster.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ func (c *compositeBroadcaster) QueryTransaction(
func (c *compositeBroadcaster) SubmitTransaction(
ctx context.Context,
tx *broadcast.Transaction,
opts ...broadcast.TransactionOptFunc,
) (*broadcast.SubmitTxResponse, error) {
executionFuncs := make([]executionFunc, len(c.broadcasters))
for i, broadcaster := range c.broadcasters {
Expand All @@ -118,6 +119,7 @@ func (c *compositeBroadcaster) SubmitTransaction(
func (c *compositeBroadcaster) SubmitBatchTransactions(
ctx context.Context,
txs []*broadcast.Transaction,
opts ...broadcast.TransactionOptFunc,
) ([]*broadcast.SubmitTxResponse, error) {
executionFuncs := make([]executionFunc, len(c.broadcasters))
for i, broadcaster := range c.broadcasters {
Expand Down
52 changes: 37 additions & 15 deletions broadcast/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,42 @@ package broadcast

// Transaction is the body contents in the "submit transaction" request
type Transaction struct {
// CallbackEncryption is the encryption method used for the callback (to set in the callback header).
CallBackEncryption string `json:"callBackEncryption,omitempty"`
// CallbackToken is the token used for the callback (to set in the callback header).
CallBackToken string `json:"callBackToken,omitempty"`
// CallbackURL is the URL used for the callback (to set in the callback header).
CallBackURL string `json:"callBackUrl,omitempty"`
// DsCheck is the double spend check flag.
DsCheck bool `json:"dsCheck,omitempty"`
// MerkleFormat is the requested merkle format (to set in the merkle format header).
MerkleFormat string `json:"merkleFormat,omitempty"`
// MerkleProof is the merkle proof flag - if merkle proof should be included in the response (to set in the merkle proof header).
MerkleProof bool `json:"merkleProof,omitempty"`
// RawTx is the raw transaction string -> required.
// RawTx is the raw transaction hex string.
RawTx string `json:"rawtx"`
// WaitForStatus is the status to wait for with the callback (to set in the wait for status header).
WaitForStatus TxStatus `json:"waitForStatus,omitempty"`
}

// TransactionOptFunc defines an optional arguments that can be passed to the SubmitTransaction method.
type TransactionOptFunc func(o *TransactionOpts)

// TransactionOpts is a struct that holds optional arguments that can be passed to the SubmitTransaction method.
type TransactionOpts struct {
// CallbackURL is the URL that will be called when the transaction status changes.
CallbackURL string
// CallbackToken is the token that will be sent in the callback request.
CallbackToken string
// MerkleProof is a flag that indicates if the merkle proof should be returned in the submit transaction response.
MerkleProof bool
// WaitForStatus is the status that the callback request will wait for.
WaitForStatus TxStatus
}

func WithCallback(callbackURL string, callbackToken ...string) TransactionOptFunc {
return func(o *TransactionOpts) {
o.CallbackToken = callbackURL
if len(callbackToken) > 0 {
o.CallbackToken = callbackToken[0]
}
}
}

func WithMerkleProof() TransactionOptFunc {
return func(o *TransactionOpts) {
o.MerkleProof = true
}
}

func WithWaitForStatus(status TxStatus) TransactionOptFunc {
return func(o *TransactionOpts) {
o.WaitForStatus = status
}
}

0 comments on commit f06b5db

Please sign in to comment.