Skip to content

Commit 15abe87

Browse files
committed
move types to special dir and print log and improve get chain info
1 parent 03b9219 commit 15abe87

15 files changed

+505
-424
lines changed

client.go

+13-1
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,23 @@ import (
77
"fmt"
88
"io"
99
"net/http"
10+
"time"
1011
)
1112

1213
type Client struct {
1314
endpoint string
1415
httpClient http.Client
16+
logger Logger
1517
}
1618

1719
func NewClient(endpoint string) *Client {
1820
return &Client{endpoint: endpoint}
1921
}
2022

23+
func NewClientWithLogger(endpoint string, logger Logger) *Client {
24+
return &Client{endpoint: endpoint, logger: logger}
25+
}
26+
2127
type QueryErrorLocation struct {
2228
Line int `json:"line"`
2329
Column int `json:"column"`
@@ -59,6 +65,10 @@ func (e QueryErrors) Error() string {
5965
}
6066

6167
func ExecuteQuery[DATA any](ctx context.Context, cli *Client, query string) (data DATA, err error) {
68+
if cli.logger != nil {
69+
cli.logger.Infof("execute query: %s", query)
70+
}
71+
start := time.Now()
6272
var reqBody bytes.Buffer
6373
if err = json.NewEncoder(&reqBody).Encode(map[string]any{"query": query}); err != nil {
6474
return data, fmt.Errorf("build request failed: %w", err)
@@ -83,7 +93,9 @@ func ExecuteQuery[DATA any](ctx context.Context, cli *Client, query string) (dat
8393
if err != nil {
8494
return data, fmt.Errorf("read response body failed: %w", err)
8595
}
86-
//fmt.Printf("!!! respBody(len:%d): %s\n", len(respBody), string(respBody))
96+
if cli.logger != nil {
97+
cli.logger.Infof("query result(len: %d, used: %s): %s", len(respBody), time.Since(start), string(respBody))
98+
}
8799

88100
var result struct {
89101
Data DATA `json:"data"`

client_block.go

+32-11
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,60 @@ package fuel
33
import (
44
"context"
55
"fmt"
6+
"github.com/sentioxyz/fuel-go/types"
67
"github.com/sentioxyz/fuel-go/util/query"
78
)
89

910
type GetBlockOption struct {
11+
OnlyIdAndHeight bool
1012
WithTransactions bool
1113
OnlyTransactionID bool
1214
}
1315

14-
func (c *Client) GetBlock(ctx context.Context, param QueryBlockParams, opt GetBlockOption) (*Block, error) {
15-
var ignoreChecker query.IgnoreChecker
16-
if opt.WithTransactions {
17-
if opt.OnlyTransactionID {
18-
ignoreChecker = query.IgnoreOtherField(Transaction{}, "Id")
16+
func (o GetBlockOption) BuildIgnoreChecker() query.IgnoreChecker {
17+
var checkers []query.IgnoreChecker
18+
if o.OnlyIdAndHeight {
19+
checkers = []query.IgnoreChecker{
20+
query.IgnoreOtherField(types.Block{}, "Id", "Header"),
21+
query.IgnoreOtherField(types.Header{}, "Id", "Height"),
22+
}
23+
} else if o.WithTransactions {
24+
if o.OnlyTransactionID {
25+
checkers = []query.IgnoreChecker{query.IgnoreOtherField(types.Transaction{}, "Id")}
1926
} else {
2027
// Otherwise it will create circular dependencies
21-
ignoreChecker = query.IgnoreObjects(SuccessStatus{}, FailureStatus{})
28+
checkers = []query.IgnoreChecker{query.IgnoreObjects(types.SuccessStatus{}, types.FailureStatus{})}
2229
}
2330
} else {
24-
ignoreChecker = query.IgnoreObjects(Transaction{})
31+
checkers = []query.IgnoreChecker{query.IgnoreObjects(types.Transaction{})}
2532
}
2633
// Contract.Bytecode is not needed
27-
ignoreChecker = query.MergeIgnores(ignoreChecker, query.IgnoreField(Contract{}, "Bytecode"))
34+
checkers = append(checkers, query.IgnoreField(types.Contract{}, "Bytecode"))
35+
return query.MergeIgnores(checkers...)
36+
}
37+
38+
func (c *Client) GetBlock(ctx context.Context, param types.QueryBlockParams, opt GetBlockOption) (*types.Block, error) {
2839
q := fmt.Sprintf("{ block(%s) { %s } }",
2940
query.Simple.GenParam(param),
30-
query.Simple.GenObjectQuery(Block{}, ignoreChecker),
41+
query.Simple.GenObjectQuery(types.Block{}, opt.BuildIgnoreChecker()),
3142
)
32-
//fmt.Printf("!!! query: %s\n", q)
3343
type resultType struct {
34-
Block *Block `json:"block"`
44+
Block *types.Block `json:"block"`
3545
}
3646
result, err := ExecuteQuery[resultType](ctx, c, q)
3747
if err != nil {
3848
return nil, err
3949
}
4050
return result.Block, nil
4151
}
52+
53+
func (c *Client) GetBlockHeader(ctx context.Context, param types.QueryBlockParams) (*types.Header, error) {
54+
block, err := c.GetBlock(ctx, param, GetBlockOption{})
55+
if err != nil {
56+
return nil, err
57+
}
58+
if block == nil {
59+
return nil, err
60+
}
61+
return &block.Header, nil
62+
}

client_block_test.go

+173-157
Large diffs are not rendered by default.

client_chain.go

+45-44
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,57 @@
11
package fuel
22

3-
import "context"
3+
import (
4+
"context"
5+
"fmt"
6+
"github.com/sentioxyz/fuel-go/types"
7+
"github.com/sentioxyz/fuel-go/util/query"
8+
)
49

5-
func (c *Client) GetLatestBlockHeight(ctx context.Context) (U32, error) {
6-
query := `
7-
{
8-
chain {
9-
latestBlock {
10-
header {
11-
height
12-
}
13-
}
14-
}
10+
type GetChainOption struct {
11+
Simple bool
12+
GetBlockOption
1513
}
16-
`
17-
type chainInfoResult struct {
18-
Chain ChainInfo `json:"chain"`
19-
}
20-
chainInfo, err := ExecuteQuery[chainInfoResult](ctx, c, query)
21-
if err != nil {
22-
return 0, err
14+
15+
func (o GetChainOption) BuildIgnoreChecker() query.IgnoreChecker {
16+
if o.Simple {
17+
return query.MergeIgnores(
18+
query.IgnoreOtherField(types.ChainInfo{}, "Name", "LatestBlock"),
19+
o.GetBlockOption.BuildIgnoreChecker(),
20+
)
2321
}
24-
return chainInfo.Chain.LatestBlock.Header.Height, nil
22+
return o.GetBlockOption.BuildIgnoreChecker()
2523
}
2624

27-
func (c *Client) GetLatestBlockHeader(ctx context.Context) (Header, error) {
28-
query := `
29-
{
30-
chain {
31-
latestBlock {
32-
header {
33-
id
34-
daHeight
35-
transactionsCount
36-
messageReceiptCount
37-
transactionsRoot
38-
messageReceiptRoot
39-
height
40-
prevRoot
41-
time
42-
applicationHash
43-
}
44-
}
45-
}
46-
}
47-
`
25+
func (c *Client) GetChain(ctx context.Context, opt GetChainOption) (types.ChainInfo, error) {
26+
q := fmt.Sprintf("{ chain { %s } }",
27+
query.Simple.GenObjectQuery(types.ChainInfo{}, opt.BuildIgnoreChecker()),
28+
)
4829
type resultType struct {
49-
Chain ChainInfo `json:"chain"`
30+
Chain types.ChainInfo `json:"chain"`
5031
}
51-
result, err := ExecuteQuery[resultType](ctx, c, query)
32+
result, err := ExecuteQuery[resultType](ctx, c, q)
5233
if err != nil {
53-
return Header{}, err
34+
return types.ChainInfo{}, err
5435
}
55-
return result.Chain.LatestBlock.Header, nil
36+
return result.Chain, nil
37+
}
38+
39+
func (c *Client) GetLatestBlockHeight(ctx context.Context) (types.U32, error) {
40+
info, err := c.GetChain(ctx, GetChainOption{
41+
Simple: true,
42+
GetBlockOption: GetBlockOption{
43+
OnlyIdAndHeight: true,
44+
},
45+
})
46+
return info.LatestBlock.Header.Height, err
47+
}
48+
49+
func (c *Client) GetLatestBlockHeader(ctx context.Context) (types.Header, error) {
50+
info, err := c.GetChain(ctx, GetChainOption{
51+
Simple: true,
52+
GetBlockOption: GetBlockOption{
53+
WithTransactions: false,
54+
},
55+
})
56+
return info.LatestBlock.Header, err
5657
}

client_chain_test.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,20 @@ import (
77
"testing"
88
)
99

10-
func Test_getLastestBlockHeight(t *testing.T) {
11-
cli := NewClient(testnetEndpoint)
10+
func Test_GetChain(t *testing.T) {
11+
cli := NewClientWithLogger(testnetEndpoint, SimpleStdoutLogger{})
12+
_, err := cli.GetChain(context.Background(), GetChainOption{Simple: true})
13+
assert.NoError(t, err)
14+
}
15+
16+
func Test_GetLatestBlockHeight(t *testing.T) {
17+
cli := NewClientWithLogger(testnetEndpoint, SimpleStdoutLogger{})
1218
h, err := cli.GetLatestBlockHeight(context.Background())
1319
assert.NoError(t, err)
1420
fmt.Printf("%d\n", h)
1521
}
1622

17-
func Test_getLastestBlockHeader(t *testing.T) {
23+
func Test_GetLatestBlockHeader(t *testing.T) {
1824
cli := NewClient(testnetEndpoint)
1925
h, err := cli.GetLatestBlockHeader(context.Background())
2026
assert.NoError(t, err)

client_test.go

+19-18
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package fuel
33
import (
44
"context"
55
"github.com/ethereum/go-ethereum/common"
6+
"github.com/sentioxyz/fuel-go/types"
67
"github.com/sentioxyz/fuel-go/util"
78
"github.com/sentioxyz/fuel-go/util/query"
89
"github.com/stretchr/testify/assert"
@@ -16,7 +17,7 @@ func Test_ExecuteQuery(t *testing.T) {
1617
cli := NewClient(testnetEndpoint)
1718

1819
type result struct {
19-
Block Block `json:"block"`
20+
Block types.Block `json:"block"`
2021
}
2122
{
2223
q := `
@@ -33,11 +34,11 @@ func Test_ExecuteQuery(t *testing.T) {
3334

3435
ti, _ := time.Parse(time.RFC3339, "2024-04-15T02:44:02Z")
3536
assert.NoError(t, err)
36-
assert.Equal(t, Block{
37-
Id: BlockId{Hash: common.HexToHash("0x5d7f48fc777144b21ea760525936db069329dee2ccce509550c1478c1c0b5b2c")},
38-
Header: Header{
37+
assert.Equal(t, types.Block{
38+
Id: types.BlockId{Hash: common.HexToHash("0x5d7f48fc777144b21ea760525936db069329dee2ccce509550c1478c1c0b5b2c")},
39+
Header: types.Header{
3940
Height: 9758550,
40-
Time: Tai64Timestamp{Time: ti},
41+
Time: types.Tai64Timestamp{Time: ti},
4142
},
4243
}, r.Block)
4344
}
@@ -62,7 +63,7 @@ func Test_ExecuteQuery(t *testing.T) {
6263
func Test_GenObjectQuery(t *testing.T) {
6364
assert.Equal(t,
6465
"id header { id daHeight transactionsCount messageReceiptCount transactionsRoot messageReceiptRoot height prevRoot time applicationHash } consensus { __typename ... on Genesis { chainConfigHash coinsRoot contractsRoot messagesRoot } ... on PoAConsensus { signature } } ",
65-
query.Simple.GenObjectQuery(Block{}, query.IgnoreObjects(Transaction{})),
66+
query.Simple.GenObjectQuery(types.Block{}, query.IgnoreObjects(types.Transaction{})),
6667
)
6768
assert.Equal(t, `id
6869
header {
@@ -90,40 +91,40 @@ consensus {
9091
}
9192
}
9293
`,
93-
query.Beauty.GenObjectQuery(Block{}, query.IgnoreObjects(Transaction{})),
94+
query.Beauty.GenObjectQuery(types.Block{}, query.IgnoreObjects(types.Transaction{})),
9495
)
9596

9697
assert.Equal(t,
9798
"id header { id daHeight transactionsCount messageReceiptCount transactionsRoot messageReceiptRoot height prevRoot time applicationHash } consensus { __typename ... on Genesis { chainConfigHash coinsRoot contractsRoot messagesRoot } ... on PoAConsensus { signature } } transactions { id inputAssetIds inputContracts { id bytecode salt } inputContract { utxoId balanceRoot stateRoot txPointer contract { id bytecode salt } } policies { gasPrice witnessLimit maturity maxFee } gasPrice scriptGasLimit maturity mintAmount mintAssetId txPointer isScript isCreate isMint inputs { __typename ... on InputCoin { utxoId owner amount assetId txPointer witnessIndex maturity predicateGasUsed predicate predicateData } ... on InputContract { utxoId balanceRoot stateRoot txPointer contract { id bytecode salt } } ... on InputMessage { sender recipient amount nonce witnessIndex predicateGasUsed data predicate predicateData } } outputs { __typename ... on CoinOutput { to amount assetId } ... on ContractOutput { inputIndex balanceRoot stateRoot } ... on ChangeOutput { to amount assetId } ... on VariableOutput { to amount assetId } ... on ContractCreated { contract { id bytecode salt } stateRoot } } outputContract { inputIndex balanceRoot stateRoot } witnesses receiptsRoot status { __typename ... on SubmittedStatus { time } ... on SqueezedOutStatus { reason } } receipts { contract { id bytecode salt } pc is to { id bytecode salt } toAddress amount assetId gas param1 param2 val ptr digest reason ra rb rc rd len receiptType result gasUsed data sender recipient nonce contractId subId } script scriptData bytecodeWitnessIndex bytecodeLength salt storageSlots rawPayload } ",
98-
query.Simple.GenObjectQuery(Block{}, query.IgnoreObjects(SuccessStatus{}, FailureStatus{})),
99+
query.Simple.GenObjectQuery(types.Block{}, query.IgnoreObjects(types.SuccessStatus{}, types.FailureStatus{})),
99100
)
100101
}
101102

102103
func Test_GenParam(t *testing.T) {
103104
assert.Equal(t,
104105
`id: "0x5d7f48fc777144b21ea760525936db069329dee2ccce509550c1478c1c0b5b2c" height: "1234" `,
105-
query.Simple.GenParam(QueryBlockParams{
106-
Id: &BlockId{Hash: common.HexToHash("0x5d7f48fc777144b21ea760525936db069329dee2ccce509550c1478c1c0b5b2c")},
107-
Height: util.GetPointer[U32](1234),
106+
query.Simple.GenParam(types.QueryBlockParams{
107+
Id: &types.BlockId{Hash: common.HexToHash("0x5d7f48fc777144b21ea760525936db069329dee2ccce509550c1478c1c0b5b2c")},
108+
Height: util.GetPointer[types.U32](1234),
108109
}),
109110
)
110111
assert.Equal(t,
111112
"id: \"0x5d7f48fc777144b21ea760525936db069329dee2ccce509550c1478c1c0b5b2c\"\nheight: \"1234\"\n",
112-
query.Beauty.GenParam(QueryBlockParams{
113-
Id: &BlockId{Hash: common.HexToHash("0x5d7f48fc777144b21ea760525936db069329dee2ccce509550c1478c1c0b5b2c")},
114-
Height: util.GetPointer[U32](1234),
113+
query.Beauty.GenParam(types.QueryBlockParams{
114+
Id: &types.BlockId{Hash: common.HexToHash("0x5d7f48fc777144b21ea760525936db069329dee2ccce509550c1478c1c0b5b2c")},
115+
Height: util.GetPointer[types.U32](1234),
115116
}),
116117
)
117118
assert.Equal(t,
118119
"height: \"1234\"\n",
119-
query.Beauty.GenParam(QueryBlockParams{
120-
Height: util.GetPointer[U32](1234),
120+
query.Beauty.GenParam(types.QueryBlockParams{
121+
Height: util.GetPointer[types.U32](1234),
121122
}),
122123
)
123124
assert.Equal(t,
124125
"id: \"0x5d7f48fc777144b21ea760525936db069329dee2ccce509550c1478c1c0b5b2c\"\n",
125-
query.Beauty.GenParam(QueryBlockParams{
126-
Id: &BlockId{Hash: common.HexToHash("0x5d7f48fc777144b21ea760525936db069329dee2ccce509550c1478c1c0b5b2c")},
126+
query.Beauty.GenParam(types.QueryBlockParams{
127+
Id: &types.BlockId{Hash: common.HexToHash("0x5d7f48fc777144b21ea760525936db069329dee2ccce509550c1478c1c0b5b2c")},
127128
}),
128129
)
129130
}

client_transaction.go

+11-11
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package fuel
33
import (
44
"context"
55
"fmt"
6+
"github.com/sentioxyz/fuel-go/types"
67
"github.com/sentioxyz/fuel-go/util/query"
78
)
89

@@ -13,28 +14,27 @@ type GetTransactionOption struct {
1314

1415
func (c *Client) GetTransaction(
1516
ctx context.Context,
16-
param QueryTransactionParams,
17+
param types.QueryTransactionParams,
1718
opt GetTransactionOption,
18-
) (*Transaction, error) {
19+
) (*types.Transaction, error) {
1920
ignoreCheckers := []query.IgnoreChecker{
20-
query.IgnoreField(Block{}, "Transactions"),
21-
query.IgnoreField(Contract{}, "Bytecode"),
22-
query.IgnoreField(SuccessStatus{}, "Receipts"),
23-
query.IgnoreField(FailureStatus{}, "Receipts"),
21+
query.IgnoreField(types.Block{}, "Transactions"),
22+
query.IgnoreField(types.Contract{}, "Bytecode"),
23+
query.IgnoreField(types.SuccessStatus{}, "Receipts"),
24+
query.IgnoreField(types.FailureStatus{}, "Receipts"),
2425
}
2526
if !opt.WithReceipts {
26-
ignoreCheckers = append(ignoreCheckers, query.IgnoreField(Transaction{}, "Receipts"))
27+
ignoreCheckers = append(ignoreCheckers, query.IgnoreField(types.Transaction{}, "Receipts"))
2728
}
2829
if !opt.WithStatus {
29-
ignoreCheckers = append(ignoreCheckers, query.IgnoreField(Transaction{}, "Status"))
30+
ignoreCheckers = append(ignoreCheckers, query.IgnoreField(types.Transaction{}, "Status"))
3031
}
3132
q := fmt.Sprintf("{ transaction(%s) { %s } }",
3233
query.Simple.GenParam(param),
33-
query.Simple.GenObjectQuery(Transaction{}, query.MergeIgnores(ignoreCheckers...)),
34+
query.Simple.GenObjectQuery(types.Transaction{}, query.MergeIgnores(ignoreCheckers...)),
3435
)
35-
//fmt.Printf("!!! query: %s\n", q)
3636
type resultType struct {
37-
Transaction *Transaction `json:"transaction"`
37+
Transaction *types.Transaction `json:"transaction"`
3838
}
3939
result, err := ExecuteQuery[resultType](ctx, c, q)
4040
if err != nil {

0 commit comments

Comments
 (0)