Skip to content

Commit 3ce8cf2

Browse files
author
Alexander Plevako
committed
Refactoring
* refactor http transport call method, use mutex in requestID generation * replace pkg/errors with errors and fmt package * make CreateSignedTransaction public
1 parent 2e4a2a7 commit 3ce8cf2

File tree

5 files changed

+67
-37
lines changed

5 files changed

+67
-37
lines changed

client.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,15 @@ func (client *Client) Close() error {
6464
}
6565

6666
func (client *Client) BroadcastTransactionSynchronous(ctx context.Context, chainID []byte, operations []types.Operation, keys ...*key.PrivateKey) (*network_broadcast.BroadcastResponse, error) {
67-
stx, err := client.createSignedTransaction(ctx, chainID, operations, keys...)
67+
stx, err := client.CreateSignedTransaction(ctx, chainID, operations, keys...)
6868
if err != nil {
6969
return nil, err
7070
}
7171
return client.NetworkBroadcast.BroadcastTransactionSynchronous(ctx, stx.Transaction)
7272
}
7373

7474
func (client *Client) BroadcastTransaction(ctx context.Context, chainID []byte, operations []types.Operation, keys ...*key.PrivateKey) (string, error) {
75-
stx, err := client.createSignedTransaction(ctx, chainID, operations, keys...)
75+
stx, err := client.CreateSignedTransaction(ctx, chainID, operations, keys...)
7676
if err != nil {
7777
return "", err
7878
}
@@ -82,7 +82,7 @@ func (client *Client) BroadcastTransaction(ctx context.Context, chainID []byte,
8282
return hex.EncodeToString(id), client.NetworkBroadcast.BroadcastTransaction(ctx, stx.Transaction)
8383
}
8484

85-
func (client *Client) createSignedTransaction(ctx context.Context, chainID []byte, operations []types.Operation, keys ...*key.PrivateKey) (*sign.SignedTransaction, error) {
85+
func (client *Client) CreateSignedTransaction(ctx context.Context, chainID []byte, operations []types.Operation, keys ...*key.PrivateKey) (*sign.SignedTransaction, error) {
8686
props, err := client.Chain.GetChainProperties(ctx)
8787
if err != nil {
8888
return nil, fmt.Errorf("get chainID properties: %w", err)

sign/transactions.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import (
44
"bytes"
55
"encoding/binary"
66
"encoding/hex"
7-
8-
"github.com/pkg/errors"
7+
"errors"
8+
"fmt"
99
)
1010

1111
func RefBlockNum(blockNumber uint32) uint16 {
@@ -16,20 +16,20 @@ func RefBlockPrefix(blockID string) (uint32, error) {
1616
// Block ID is hex-encoded.
1717
rawBlockID, err := hex.DecodeString(blockID)
1818
if err != nil {
19-
return 0, errors.Wrapf(err, "network_broadcast: failed to decode block ID: %v", blockID)
19+
return 0, fmt.Errorf("failed to decode block ID: %w", err)
2020
}
2121

2222
// Raw prefix = raw block ID [4:8].
2323
// Make sure we don't trigger a slice bounds out of range panic.
2424
if len(rawBlockID) < 8 {
25-
return 0, errors.Errorf("network_broadcast: invalid block ID: %v", blockID)
25+
return 0, errors.New("invalid blockID")
2626
}
2727
rawPrefix := rawBlockID[4:8]
2828

2929
// Decode the prefix.
3030
var prefix uint32
3131
if err := binary.Read(bytes.NewReader(rawPrefix), binary.LittleEndian, &prefix); err != nil {
32-
return 0, errors.Wrapf(err, "network_broadcast: failed to read block prefix: %v", rawPrefix)
32+
return 0, fmt.Errorf("failed to read block prefix: %w", err)
3333
}
3434

3535
// Done, return the prefix.

transport/generator.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package transport
2+
3+
import "sync"
4+
5+
type SequenceGenerator struct {
6+
requestID uint64
7+
mtx sync.Mutex
8+
}
9+
10+
func NewSequenceGenerator(initial uint64) *SequenceGenerator {
11+
return &SequenceGenerator{
12+
requestID: initial,
13+
mtx: sync.Mutex{},
14+
}
15+
}
16+
17+
func (r *SequenceGenerator) Generate() uint64 {
18+
r.mtx.Lock()
19+
defer r.mtx.Unlock()
20+
21+
r.requestID++
22+
23+
return r.requestID
24+
}

transport/http/transport.go

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,29 @@ import (
55
"context"
66
"encoding/json"
77
"fmt"
8+
"io"
89
"io/ioutil"
9-
"math"
1010
"net/http"
11-
"sync"
1211
"time"
1312

14-
"github.com/pkg/errors"
1513
"github.com/scorum/scorum-go/transport"
1614
)
1715

16+
type requestIDGenerator interface {
17+
Generate() uint64
18+
}
19+
1820
type Transport struct {
1921
Url string
2022
client *http.Client
2123

22-
requestID uint64
23-
reqMutex sync.Mutex
24+
requestID requestIDGenerator
2425
}
2526

2627
func NewTransport(url string, options ...func(*Transport)) *Transport {
2728
t := Transport{
28-
Url: url,
29+
Url: url,
30+
requestID: transport.NewSequenceGenerator(0),
2931
}
3032

3133
for _, o := range options {
@@ -48,59 +50,45 @@ func WithHttpClient(client *http.Client) func(*Transport) {
4850
}
4951

5052
func (caller *Transport) Call(ctx context.Context, api string, method string, args []interface{}, reply interface{}) error {
51-
caller.reqMutex.Lock()
52-
defer caller.reqMutex.Unlock()
53-
54-
// increase request id
55-
if caller.requestID == math.MaxUint64 {
56-
caller.requestID = 0
57-
}
58-
caller.requestID++
59-
6053
request := transport.RPCRequest{
6154
Method: "call",
62-
ID: caller.requestID,
55+
ID: caller.requestID.Generate(),
6356
Params: []interface{}{api, method, args},
6457
}
6558

6659
reqBody, err := json.Marshal(request)
6760
if err != nil {
68-
return err
61+
return fmt.Errorf("json marshall: %w", err)
6962
}
7063

7164
req, err := http.NewRequestWithContext(ctx, "POST", caller.Url, bytes.NewBuffer(reqBody))
7265
if err != nil {
73-
return err
66+
return fmt.Errorf("http new request: %w", err)
7467
}
7568
req.Header.Set("Content-Type", "application/json")
7669

7770
resp, err := caller.client.Do(req)
7871
if err != nil {
79-
return err
72+
return fmt.Errorf("http client do: %w", err)
8073
}
8174
defer resp.Body.Close()
8275

8376
if resp.StatusCode != http.StatusOK {
8477
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
8578
}
8679

87-
respBody, err := ioutil.ReadAll(resp.Body)
88-
if err != nil {
89-
return errors.Wrap(err, "failed to read body")
90-
}
91-
9280
var rpcResponse transport.RPCResponse
93-
if err = json.Unmarshal(respBody, &rpcResponse); err != nil {
94-
return errors.Wrapf(err, "failed to unmarshal response: %+v", string(respBody))
81+
if err := decodeJSON(resp.Body, &rpcResponse); err != nil {
82+
return fmt.Errorf("failed decode rpc response: %w", err)
9583
}
9684

9785
if rpcResponse.Error != nil {
9886
return rpcResponse.Error
9987
}
10088

10189
if rpcResponse.Result != nil {
102-
if err := json.Unmarshal(*rpcResponse.Result, reply); err != nil {
103-
return errors.Wrapf(err, "failed to unmarshal rpc result: %+v", string(*rpcResponse.Result))
90+
if err := decodeJSON(bytes.NewReader(*rpcResponse.Result), reply); err != nil {
91+
return fmt.Errorf("failed decode rpc result: %w", err)
10492
}
10593
}
10694

@@ -114,3 +102,21 @@ func (caller *Transport) SetCallback(api string, method string, notice func(args
114102
func (caller *Transport) Close() error {
115103
return nil
116104
}
105+
106+
func decodeJSON(reader io.Reader, out interface{}) error {
107+
buf := new(bytes.Buffer)
108+
tr := io.TeeReader(reader, buf)
109+
110+
data, err := ioutil.ReadAll(tr)
111+
if err != nil {
112+
return fmt.Errorf("failed to read body: %w", err)
113+
}
114+
if !json.Valid(data) {
115+
return fmt.Errorf("invalid json: %q", buf.String())
116+
}
117+
118+
if err := json.NewDecoder(buf).Decode(out); err != nil {
119+
return fmt.Errorf("failed to decode json: %w", err)
120+
}
121+
return nil
122+
}

types/game.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package types
22

33
import (
44
"encoding/json"
5-
"github.com/pkg/errors"
5+
"errors"
66
"reflect"
77
)
88

0 commit comments

Comments
 (0)