Skip to content

Commit

Permalink
added opensearch integration to be used in /v1/tick-data, /v1/tx, /v1…
Browse files Browse the repository at this point in the history
…/bx endpoints. added balance in the /v1/identities/ response
  • Loading branch information
0xluk committed Jan 15, 2024
1 parent 348951e commit 2e0df53
Show file tree
Hide file tree
Showing 13 changed files with 316 additions and 37 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ jobs:
test-nocache:
strategy:
matrix:
go-version: [1.20.x, 1.21.x]
go-version: [1.21.x]
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
Expand Down
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ $ curl "localhost:8080/v1/identities/PKXGRCNOEEDLEGTLAZOSXMEYZIEDLGMSPNTJJJBHIBJ
{
"public_key": "4f27dc1b6a1a76d479833e5f1bed0d6d77c705a0290a632de94794dbee670dfa",
"tick": 10894487,
"balance": 10000,
"incoming_amount": 1479299940,
"outgoing_amount": 1479289940,
"number_of_incoming_transfers": 125981,
Expand All @@ -47,6 +48,37 @@ $ curl "localhost:8080/v1/identities/PKXGRCNOEEDLEGTLAZOSXMEYZIEDLGMSPNTJJJBHIBJ
}
```

## Getting tx by id:
```bash
$ curl "localhost:8080/v1/tx/qdnwqignkprgrbkdlbpsrprikjagdnzaafsbxngbtfczcfjnsvgelivfxoem"
{
"bxid": "bacab66e7cbbb950c8b80facef94c5f0bf478ee3ab8ac270f541b1aba71cb8a7",
"utime": "1704973083",
"epoch": "91",
"tick": "11963307",
"type": "0",
"src": "AMITKEPEADJMEBOKSXLFNNCQLQTCAAWIDNCKTDZGYEUCYCNOEEDJHMACPPTG",
"dest": "DCHWKUZLNYTDYBFZTELHWEDQDQCBBKTKYUITIKCDKACHDUBFYRHGDZSFQLBG",
"amount": "7357247517",
"extra": "",
"sig": "b6f330e9713047321de9ff3506078726a06119115ab27e8d805a9ebd2828a8189e96bd1a31d1a72702ba1ee5abebd130cf43e25ee68109f01c6f9cc42d100f00"
}
```

## Getting bx by id:
```bash
$ curl "localhost:8080/v1/bx/bacab66e7cbbb950c8b80facef94c5f0bf478ee3ab8ac270f541b1aba71cb8a7"
{
"utime": "1704973097",
"epoch": "91",
"tick": "11963307",
"type": "1",
"src": "AMITKEPEADJMEBOKSXLFNNCQLQTCAAWIDNCKTDZGYEUCYCNOEEDJHMACPPTG",
"dest": "DCHWKUZLNYTDYBFZTELHWEDQDQCBBKTKYUITIKCDKACHDUBFYRHGDZSFQLBG",
"amount": "7357247517"
}
```

## Getting latest tick info:
```bash
$ curl "localhost:8080/v1/tick-info"
Expand Down
18 changes: 12 additions & 6 deletions app/server/handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,34 @@ package handlers

import (
_ "github.com/qubic/qubic-http/app/server/docs"
mid2 "github.com/qubic/qubic-http/business/mid"
"github.com/qubic/qubic-http/business/mid"
"github.com/qubic/qubic-http/external/opensearch"
"github.com/qubic/qubic-http/foundation/nodes"
"github.com/qubic/qubic-http/foundation/web"
"log"
"net/http"
"os"
)

func New(shutdown chan os.Signal, log *log.Logger, pool *nodes.Pool) http.Handler {
app := web.NewApp(shutdown, mid2.Logger(log), mid2.Errors(log), mid2.Metrics(), mid2.Panics(log))
func New(shutdown chan os.Signal, log *log.Logger, pool *nodes.Pool, osclient *opensearch.Client) http.Handler {
app := web.NewApp(shutdown, mid.Logger(log), mid.Errors(log), mid.Metrics(), mid.Panics(log))

ih := identitiesHandler{pool: pool}
app.Handle(http.MethodGet, "/v1/identities/:identity", ih.One)

th := tickHandler{pool: pool}
th := tickHandler{pool: pool, opensearchClient: osclient}
app.Handle(http.MethodGet, "/v1/tick-info", th.GetTickInfo)
app.Handle(http.MethodGet, "/v1/tick-transactions/:tick", th.GetTickTransactions)
app.Handle(http.MethodGet, "/v1/tick-data/:tick", th.GetTickData)
//app.Handle(http.MethodGet, "/v1/tick-data/:tick", th.GetTickData)

txH := txHandler{pool: pool}
app.Handle(http.MethodGet, "/v1/tick-data/:tick", th.GetTickDataV2)

txH := txHandler{pool: pool, opensearchClient: osclient}
app.Handle(http.MethodPost, "/v1/send-raw-tx", txH.SendRawTx)
app.Handle(http.MethodPost, "/v1/get-tx-status", txH.GetTxStatus)
app.Handle(http.MethodGet, "/v1/tx/:txID", txH.GetTx)
app.Handle(http.MethodGet, "/v1/bx/:bxID", txH.GetBx)


return app
}
18 changes: 18 additions & 0 deletions app/server/handlers/tick.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/0xluk/go-qubic/foundation/tcp"
"github.com/pkg/errors"
"github.com/qubic/qubic-http/business/data/tick"
"github.com/qubic/qubic-http/external/opensearch"
"github.com/qubic/qubic-http/foundation/nodes"
"github.com/qubic/qubic-http/foundation/web"
"net/http"
Expand All @@ -13,6 +14,7 @@ import (

type tickHandler struct {
pool *nodes.Pool
opensearchClient *opensearch.Client
}

func (h *tickHandler) GetTickInfo(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
Expand Down Expand Up @@ -70,3 +72,19 @@ func (h *tickHandler) GetTickData(ctx context.Context, w http.ResponseWriter, r

return web.Respond(ctx, w, res, http.StatusOK)
}

func (h *tickHandler) GetTickDataV2(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
params := web.Params(r)
tickNr := params["tick"]
tickNumber, err := strconv.ParseInt(tickNr, 10, 32)
if err != nil {
return web.RespondError(ctx, w, errors.Wrap(err, "parsing input"))
}

res, err := tick.GetTickDataV2(ctx, h.opensearchClient, uint32(tickNumber))
if err != nil {
return web.RespondError(ctx, w, errors.Wrap(err, "getting tick data"))
}

return web.Respond(ctx, w, res, http.StatusOK)
}
26 changes: 26 additions & 0 deletions app/server/handlers/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import (
"github.com/0xluk/go-qubic/foundation/tcp"
"github.com/pkg/errors"
"github.com/qubic/qubic-http/business/data/tx"
"github.com/qubic/qubic-http/external/opensearch"
"github.com/qubic/qubic-http/foundation/nodes"
"github.com/qubic/qubic-http/foundation/web"
"net/http"
)

type txHandler struct {
pool *nodes.Pool
opensearchClient *opensearch.Client
}

func (h *txHandler) SendRawTx(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
Expand Down Expand Up @@ -53,3 +55,27 @@ func (h *txHandler) GetTxStatus(ctx context.Context, w http.ResponseWriter, r *h

return web.Respond(ctx, w, output, http.StatusOK)
}

func (h *txHandler) GetTx(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
params := web.Params(r)
txID := params["txID"]
transaction, err := h.opensearchClient.GetTx(ctx, txID)
if err != nil {
return errors.Wrap(err, "getting tx by id")
}

return web.Respond(ctx, w, transaction, http.StatusOK)
}

func (h *txHandler) GetBx(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
params := web.Params(r)
bxID := params["bxID"]
bx, err := h.opensearchClient.GetBx(ctx, bxID)
if err != nil {
return errors.Wrap(err, "getting bx by id")
}

return web.Respond(ctx, w, bx, http.StatusOK)
}


9 changes: 7 additions & 2 deletions app/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"github.com/pkg/errors"
"github.com/qubic/qubic-http/app/server/handlers"
"github.com/qubic/qubic-http/external/opensearch"
"github.com/qubic/qubic-http/foundation/nodes"
"log"
"net/http"
Expand Down Expand Up @@ -34,9 +35,12 @@ func run(log *log.Logger) error {
ShutdownTimeout time.Duration `conf:"default:5s"`
}
Qubic struct {
NodeIps []string `conf:"default:167.235.118.235"`
NodeIps []string `conf:"default:62.2.219.174"`
NodePort string `conf:"default:21841"`
}
Opensearch struct {
Host string `conf:"default:http://93.190.139.223:9200"`
}
}

if err := conf.Parse(os.Args[1:], prefix, &cfg); err != nil {
Expand Down Expand Up @@ -70,12 +74,13 @@ func run(log *log.Logger) error {
return errors.Wrap(err, "creating qubic client")
}

osClient := opensearch.NewClient(cfg.Opensearch.Host)
shutdown := make(chan os.Signal, 1)
signal.Notify(shutdown, os.Interrupt, syscall.SIGTERM)

api := http.Server{
Addr: cfg.Web.Host,
Handler: handlers.New(shutdown, log, pool),
Handler: handlers.New(shutdown, log, pool, osClient),
ReadTimeout: cfg.Web.ReadTimeout,
WriteTimeout: cfg.Web.WriteTimeout,
}
Expand Down
1 change: 1 addition & 0 deletions business/data/identity/identity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func TestGetIdentityOutput_FromQubicModel(t *testing.T) {
expectedOutput := GetIdentityOutput{
PublicKey: hex.EncodeToString(qubicModel.Entity.PublicKey[:]),
Tick: qubicModel.Tick,
Balance: qubicModel.Entity.IncomingAmount - qubicModel.Entity.OutgoingAmount,
IncomingAmount: qubicModel.Entity.IncomingAmount,
OutgoingAmount: qubicModel.Entity.OutgoingAmount,
NumberOfIncomingTransfers: qubicModel.Entity.NumberOfIncomingTransfers,
Expand Down
2 changes: 2 additions & 0 deletions business/data/identity/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
type GetIdentityOutput struct {
PublicKey string `json:"public_key"`
Tick uint32 `json:"tick"`
Balance int64 `json:"balance"` // incoming_amount - outgoing_amount
IncomingAmount int64 `json:"incoming_amount"`
OutgoingAmount int64 `json:"outgoing_amount"`
NumberOfIncomingTransfers uint32 `json:"number_of_incoming_transfers"`
Expand All @@ -21,6 +22,7 @@ func (o *GetIdentityOutput) fromQubicModel(model identity.GetIdentityResponse) G
return GetIdentityOutput{
PublicKey: hex.EncodeToString(model.Entity.PublicKey[:]),
Tick: model.Tick,
Balance: model.Entity.IncomingAmount - model.Entity.OutgoingAmount,
IncomingAmount: model.Entity.IncomingAmount,
OutgoingAmount: model.Entity.OutgoingAmount,
NumberOfIncomingTransfers: model.Entity.NumberOfIncomingTransfers,
Expand Down
82 changes: 56 additions & 26 deletions business/data/tick/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,25 @@ package tick
import (
"encoding/hex"
"github.com/0xluk/go-qubic/data/tick"
"github.com/qubic/qubic-http/external/opensearch"
)

type GetTickDataOutput struct {
ComputorIndex uint16 `json:"computor_index"`
Epoch uint16 `json:"epoch"`
Tick uint32 `json:"tick"`
Millisecond uint16 `json:"millisecond"`
Second uint8 `json:"second"`
Minute uint8 `json:"minute"`
Hour uint8 `json:"hour"`
Day uint8 `json:"day"`
Month uint8 `json:"month"`
Year uint8 `json:"year"`
HexUnionData string `json:"hex_union_data"`
ComputorIndex uint16 `json:"computor_index"`
Epoch uint16 `json:"epoch"`
Tick uint32 `json:"tick"`
Millisecond uint16 `json:"millisecond"`
Second uint8 `json:"second"`
Minute uint8 `json:"minute"`
Hour uint8 `json:"hour"`
Day uint8 `json:"day"`
Month uint8 `json:"month"`
Year uint8 `json:"year"`
//HexUnionData string `json:"hex_union_data"`
HexTimelock string `json:"hex_timelock"`
TransactionDigests []string `json:"transaction_digests"`
ContractFees []int64 `json:"contract_fees"`
Signature string `json:"signature"`
//ContractFees []int64 `json:"contract_fees"`
Signature string `json:"signature"`
}

func (o *GetTickDataOutput) fromQubicModel(model tick.TickData) GetTickDataOutput {
Expand All @@ -32,21 +33,40 @@ func (o *GetTickDataOutput) fromQubicModel(model tick.TickData) GetTickDataOutpu
}

return GetTickDataOutput{
ComputorIndex: model.ComputorIndex,
Epoch: model.Epoch,
Tick: model.Tick,
Millisecond: model.Millisecond,
Second: model.Second,
Minute: model.Minute,
Hour: model.Hour,
Day: model.Day,
Month: model.Month,
Year: model.Year,
HexUnionData: hex.EncodeToString(model.UnionData[:]),
ComputorIndex: model.ComputorIndex,
Epoch: model.Epoch,
Tick: model.Tick,
Millisecond: model.Millisecond,
Second: model.Second,
Minute: model.Minute,
Hour: model.Hour,
Day: model.Day,
Month: model.Month,
Year: model.Year,
//HexUnionData: hex.EncodeToString(model.UnionData[:]),
HexTimelock: hex.EncodeToString(model.Timelock[:]),
TransactionDigests: byteArraysToHexStrings(model.TransactionDigests[:]),
ContractFees: contractFees,
Signature: hex.EncodeToString(model.Signature[:]),
//ContractFees: contractFees,
Signature: hex.EncodeToString(model.Signature[:]),
}
}

func (o *GetTickDataOutput) fromOpensearchModel(model opensearch.TickDataResponse) GetTickDataOutput {
timeArr := timeSliceTArr(model.Time)
return GetTickDataOutput{
ComputorIndex: uint16(model.Computor),
Epoch: uint16(model.Epoch),
Tick: model.Tick,
Millisecond: uint16(timeArr[0]),
Second: uint8(timeArr[1]),
Minute: uint8(timeArr[2]),
Hour: uint8(timeArr[3]),
Day: uint8(timeArr[4]),
Month: uint8(timeArr[5]),
Year: uint8(timeArr[6]),
HexTimelock: model.Timelock,
TransactionDigests: model.TransactionIDs,
Signature: model.Signature,
}
}

Expand Down Expand Up @@ -120,3 +140,13 @@ func byteArrayToString(arr [60]byte) string {

return string(arr[:])
}

func timeSliceTArr(slice []int) [7]int {
var arr [7]int

for i, t := range slice {
arr[i] = t
}

return arr
}
11 changes: 11 additions & 0 deletions business/data/tick/tick.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/0xluk/go-qubic"
"github.com/0xluk/go-qubic/foundation/tcp"
"github.com/pkg/errors"
"github.com/qubic/qubic-http/external/opensearch"
)

func GetTickData(ctx context.Context, qc *tcp.QubicConnection, tick uint32) (GetTickDataOutput, error) {
Expand All @@ -17,6 +18,16 @@ func GetTickData(ctx context.Context, qc *tcp.QubicConnection, tick uint32) (Get
return output.fromQubicModel(res), nil
}

func GetTickDataV2(ctx context.Context, osClient *opensearch.Client, tick uint32) (GetTickDataOutput, error) {
res, err := osClient.GetTickData(ctx, tick)
if err != nil {
return GetTickDataOutput{}, errors.Wrap(err, "getting tick data from opensearch")
}

var output GetTickDataOutput
return output.fromOpensearchModel(res), nil
}

func GetTickTxs(ctx context.Context, qc *tcp.QubicConnection, tick uint32) (GetTickTransactionsOutput, error) {
res, err := qubic.GetTickTransactions(ctx, qc, tick)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions business/data/tick/tick_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ func TestGetTickDataOutput_FromQubicModel(t *testing.T) {
Day: 15,
Month: 11,
Year: 22,
HexUnionData: hex.EncodeToString(union[:]),
//HexUnionData: hex.EncodeToString(union[:]),
HexTimelock: hex.EncodeToString(qubicModel.Timelock[:]),
TransactionDigests: byteArraysToHexStrings(qubicModel.TransactionDigests[:]),
ContractFees: []int64{100, 200, 300},
//ContractFees: []int64{100, 200, 300},
Signature: hex.EncodeToString(qubicModel.Signature[:]),
}

Expand Down
Loading

0 comments on commit 2e0df53

Please sign in to comment.