Skip to content

Commit

Permalink
Guarantee the order of transactions in the block endpoint (coinbase#489)
Browse files Browse the repository at this point in the history
* feat: Guarantee the order of transactions in the block endpoint

This commit guarantees the order of transactions in the block endpoint. It does so by creating a map of fetched transactions and using that map to return the transactions in the original order they had in the block.

- Added a new struct `FetchedTransaction` to represent fetched transactions
- Updated `fetchChannelTransactions` to use the new `FetchedTransaction` struct
- Updated `UnsafeTransactions` to use the new `FetchedTransaction` struct and create a map of fetched transactions
- Modified the return statement in `UnsafeTransactions` to use the fetched transactions from the map

* chore: add timeout to mock server

This commit adds a timeout to the mock server to prevent it from hanging indefinitely. This is mainly to make salus security scans happy.

* chore: avoid memory leak in client

This commit fixes a memory leak in the client. The client was not reading the response body of the http request when closing the body, which could lead to a memory leak. This commit fixes this by reading the response body and discarding it.

This commit makes salus check pass.

* chore: make check-gen happy

* trigger github workflow
  • Loading branch information
wei-wang-cb committed Aug 23, 2023
1 parent f5e40aa commit c8a1eee
Show file tree
Hide file tree
Showing 12 changed files with 131 additions and 29 deletions.
11 changes: 9 additions & 2 deletions client/api_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package client
import (
_context "context"
"fmt"
"io"
_ioutil "io/ioutil"
_nethttp "net/http"

Expand Down Expand Up @@ -87,7 +88,10 @@ func (a *AccountAPIService) AccountBalance(
}

localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
defer localVarHTTPResponse.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, localVarHTTPResponse.Body)
_ = localVarHTTPResponse.Body.Close()
}()
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down Expand Up @@ -190,7 +194,10 @@ func (a *AccountAPIService) AccountCoins(
}

localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
defer localVarHTTPResponse.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, localVarHTTPResponse.Body)
_ = localVarHTTPResponse.Body.Close()
}()
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down
11 changes: 9 additions & 2 deletions client/api_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package client
import (
_context "context"
"fmt"
"io"
_ioutil "io/ioutil"
_nethttp "net/http"

Expand Down Expand Up @@ -84,7 +85,10 @@ func (a *BlockAPIService) Block(
}

localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
defer localVarHTTPResponse.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, localVarHTTPResponse.Body)
_ = localVarHTTPResponse.Body.Close()
}()
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down Expand Up @@ -190,7 +194,10 @@ func (a *BlockAPIService) BlockTransaction(
}

localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
defer localVarHTTPResponse.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, localVarHTTPResponse.Body)
_ = localVarHTTPResponse.Body.Close()
}()
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down
6 changes: 5 additions & 1 deletion client/api_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package client
import (
_context "context"
"fmt"
"io"
_ioutil "io/ioutil"
_nethttp "net/http"

Expand Down Expand Up @@ -87,7 +88,10 @@ func (a *CallAPIService) Call(
}

localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
defer localVarHTTPResponse.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, localVarHTTPResponse.Body)
_ = localVarHTTPResponse.Body.Close()
}()
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down
41 changes: 33 additions & 8 deletions client/api_construction.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package client
import (
_context "context"
"fmt"
"io"
_ioutil "io/ioutil"
_nethttp "net/http"

Expand Down Expand Up @@ -79,7 +80,10 @@ func (a *ConstructionAPIService) ConstructionCombine(
}

localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
defer localVarHTTPResponse.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, localVarHTTPResponse.Body)
_ = localVarHTTPResponse.Body.Close()
}()
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down Expand Up @@ -173,7 +177,10 @@ func (a *ConstructionAPIService) ConstructionDerive(
}

localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
defer localVarHTTPResponse.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, localVarHTTPResponse.Body)
_ = localVarHTTPResponse.Body.Close()
}()
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down Expand Up @@ -267,7 +274,10 @@ func (a *ConstructionAPIService) ConstructionHash(
}

localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
defer localVarHTTPResponse.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, localVarHTTPResponse.Body)
_ = localVarHTTPResponse.Body.Close()
}()
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down Expand Up @@ -368,7 +378,10 @@ func (a *ConstructionAPIService) ConstructionMetadata(
}

localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
defer localVarHTTPResponse.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, localVarHTTPResponse.Body)
_ = localVarHTTPResponse.Body.Close()
}()
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down Expand Up @@ -463,7 +476,10 @@ func (a *ConstructionAPIService) ConstructionParse(
}

localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
defer localVarHTTPResponse.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, localVarHTTPResponse.Body)
_ = localVarHTTPResponse.Body.Close()
}()
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down Expand Up @@ -563,7 +579,10 @@ func (a *ConstructionAPIService) ConstructionPayloads(
}

localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
defer localVarHTTPResponse.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, localVarHTTPResponse.Body)
_ = localVarHTTPResponse.Body.Close()
}()
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down Expand Up @@ -661,7 +680,10 @@ func (a *ConstructionAPIService) ConstructionPreprocess(
}

localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
defer localVarHTTPResponse.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, localVarHTTPResponse.Body)
_ = localVarHTTPResponse.Body.Close()
}()
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down Expand Up @@ -758,7 +780,10 @@ func (a *ConstructionAPIService) ConstructionSubmit(
}

localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
defer localVarHTTPResponse.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, localVarHTTPResponse.Body)
_ = localVarHTTPResponse.Body.Close()
}()
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down
6 changes: 5 additions & 1 deletion client/api_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package client
import (
_context "context"
"fmt"
"io"
_ioutil "io/ioutil"
_nethttp "net/http"

Expand Down Expand Up @@ -82,7 +83,10 @@ func (a *EventsAPIService) EventsBlocks(
}

localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
defer localVarHTTPResponse.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, localVarHTTPResponse.Body)
_ = localVarHTTPResponse.Body.Close()
}()
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down
11 changes: 9 additions & 2 deletions client/api_mempool.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package client
import (
_context "context"
"fmt"
"io"
_ioutil "io/ioutil"
_nethttp "net/http"

Expand Down Expand Up @@ -77,7 +78,10 @@ func (a *MempoolAPIService) Mempool(
}

localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
defer localVarHTTPResponse.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, localVarHTTPResponse.Body)
_ = localVarHTTPResponse.Body.Close()
}()
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down Expand Up @@ -176,7 +180,10 @@ func (a *MempoolAPIService) MempoolTransaction(
}

localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
defer localVarHTTPResponse.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, localVarHTTPResponse.Body)
_ = localVarHTTPResponse.Body.Close()
}()
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down
16 changes: 13 additions & 3 deletions client/api_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package client
import (
_context "context"
"fmt"
"io"
_ioutil "io/ioutil"
_nethttp "net/http"

Expand Down Expand Up @@ -77,7 +78,10 @@ func (a *NetworkAPIService) NetworkList(
}

localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
defer localVarHTTPResponse.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, localVarHTTPResponse.Body)
_ = localVarHTTPResponse.Body.Close()
}()
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down Expand Up @@ -173,7 +177,10 @@ func (a *NetworkAPIService) NetworkOptions(
}

localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
defer localVarHTTPResponse.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, localVarHTTPResponse.Body)
_ = localVarHTTPResponse.Body.Close()
}()
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down Expand Up @@ -267,7 +274,10 @@ func (a *NetworkAPIService) NetworkStatus(
}

localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
defer localVarHTTPResponse.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, localVarHTTPResponse.Body)
_ = localVarHTTPResponse.Body.Close()
}()
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down
6 changes: 5 additions & 1 deletion client/api_search.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package client
import (
_context "context"
"fmt"
"io"
_ioutil "io/ioutil"
_nethttp "net/http"

Expand Down Expand Up @@ -82,7 +83,10 @@ func (a *SearchAPIService) SearchTransactions(
}

localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
defer localVarHTTPResponse.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, localVarHTTPResponse.Body)
_ = localVarHTTPResponse.Body.Close()
}()
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
Expand Down
6 changes: 5 additions & 1 deletion constructor/worker/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"context"
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
Expand Down Expand Up @@ -871,7 +872,10 @@ func HTTPRequestWorker(rawInput string) (string, error) {
if err != nil {
return "", fmt.Errorf("failed to send request: %w", err)
}
defer resp.Body.Close()
defer func() {
_, _ = io.Copy(io.Discard, resp.Body)
_ = resp.Body.Close()
}()

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
Expand Down
12 changes: 11 additions & 1 deletion examples/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"fmt"
"log"
"net/http"
"time"

"github.com/coinbase/rosetta-sdk-go/asserter"
"github.com/coinbase/rosetta-sdk-go/examples/server/services"
Expand Down Expand Up @@ -76,5 +77,14 @@ func main() {
loggedRouter := server.LoggerMiddleware(router)
corsRouter := server.CorsMiddleware(loggedRouter)
log.Printf("Listening on port %d\n", serverPort)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", serverPort), corsRouter))

srv := &http.Server{
Addr: fmt.Sprintf(":%d", serverPort),
Handler: corsRouter,
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
IdleTimeout: 15 * time.Second,
}

log.Fatal(srv.ListenAndServe())
}
Loading

0 comments on commit c8a1eee

Please sign in to comment.