Skip to content
This repository has been archived by the owner on Mar 16, 2022. It is now read-only.

Commit

Permalink
[Tezos] Implement block api from rpc (#1354)
Browse files Browse the repository at this point in the history
* implement block api from tezos rpc

* parse delegation operation
  • Loading branch information
hewigovens authored Jan 14, 2021
1 parent 37ed4f7 commit 3a772c4
Show file tree
Hide file tree
Showing 9 changed files with 1,464 additions and 38 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/getsentry/raven-go v0.2.0
github.com/gin-contrib/cors v1.3.1
github.com/gin-gonic/gin v1.6.3
github.com/itchyny/timefmt-go v0.1.1
github.com/mitchellh/mapstructure v1.4.1
github.com/mr-tron/base58 v1.2.0
github.com/opencontainers/runc v1.0.0-rc9 // indirect
Expand Down
11 changes: 4 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVa
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/cenkalti/backoff v1.1.0 h1:QnvVp8ikKCDWOsFheytRCoYWYPO/ObCTBGxT19Hc+yE=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 h1:uH66TXeswKn5PW5zdZ39xEwfS9an067BirqA+P4QaLI=
Expand Down Expand Up @@ -192,6 +191,8 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/itchyny/timefmt-go v0.1.1 h1:rLpnm9xxb39PEEVzO0n4IRp0q6/RmBc7Dy/rE4HrA0U=
github.com/itchyny/timefmt-go v0.1.1/go.mod h1:0osSSCQSASBJMsIZnhAaF1C2fCBTJZXrnj37mG8/c+A=
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
Expand Down Expand Up @@ -310,8 +311,7 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.4.0 h1:7ks8ZkOP5/ujthUsT07rNv+nkLXCQWKNHuwzOAesEks=
github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
Expand Down Expand Up @@ -399,6 +399,7 @@ github.com/streadway/amqp v1.0.0 h1:kuuDrUJFZL1QYL9hUNuCxNObNzB0bV/ZG5jV3RWAQgo=
github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
Expand All @@ -415,12 +416,8 @@ github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+t
github.com/swaggo/swag v1.7.0 h1:5bCA/MTLQoIqDXXyHfOpMeDvL9j68OY/udlK4pQoo4E=
github.com/swaggo/swag v1.7.0/go.mod h1:BdPIL73gvS9NBsdi7M1JOxLvlbfvNRaBP8m6WT6Aajo=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/trustwallet/golibs v0.0.31-0.20210111093217-efd7dac63bce h1:o+uU7PzPptwcW0z85S77B3dk5tIr1v7fd3cAFjdWbac=
github.com/trustwallet/golibs v0.0.31-0.20210111093217-efd7dac63bce/go.mod h1:VI0APImKAYxvJ8MnMD6aHSKvnArXUd3NgNEghX5P+K8=
github.com/trustwallet/golibs v0.0.31 h1:Ii5WqqN2TjTHAyXBYpvck7ImtqdNNITeO/zlqfd0E4o=
github.com/trustwallet/golibs v0.0.31/go.mod h1:VI0APImKAYxvJ8MnMD6aHSKvnArXUd3NgNEghX5P+K8=
github.com/trustwallet/golibs/network v0.0.0-20210107055554-eac147c5e524 h1:cHw4uer/5KexBPrK6Tx3viq/GRtTE22LtCBFPbQY7II=
github.com/trustwallet/golibs/network v0.0.0-20210107055554-eac147c5e524/go.mod h1:RMMyjp4qUcVhWidjE+XYzQgOtSXuhIKSB5pnLCA3WqY=
github.com/trustwallet/golibs/network v0.0.0-20210112030915-7e676f1ce53b h1:sAfeSYHLxCGW00mIv/+P8T03SiW0JP4OLAccuMAjz6M=
github.com/trustwallet/golibs/network v0.0.0-20210112030915-7e676f1ce53b/go.mod h1:RMMyjp4qUcVhWidjE+XYzQgOtSXuhIKSB5pnLCA3WqY=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
Expand Down
114 changes: 106 additions & 8 deletions platform/tezos/block.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,118 @@
package tezos

import "github.com/trustwallet/golibs/types"
import (
"encoding/json"
"errors"

"github.com/trustwallet/golibs/coin"
"github.com/trustwallet/golibs/types"

"github.com/itchyny/timefmt-go"
)

func (p *Platform) CurrentBlockNumber() (int64, error) {
return p.client.GetCurrentBlock()
return p.rpcClient.GetBlockHead()
}

func (p *Platform) GetBlockByNumber(num int64) (*types.Block, error) {
txTypes := []string{TxTypeTransaction, TxTypeDelegation}
srcTxs, err := p.client.GetBlockByNumber(num, txTypes)
block, err := p.rpcClient.GetBlockByNumber(num)
if err != nil {
return nil, err
}
txs := NormalizeTxs(srcTxs, "")
return &types.Block{
Number: num,
Txs: txs,
return NormalizeRpcBlock(block)
}

func NormalizeRpcBlock(block RpcBlock) (*types.Block, error) {
txs := []types.Tx{}

for _, ops := range block.Operations {
for _, op := range ops {
for _, content := range op.Contents {
if tx, err := mapTransaction(content); err == nil {
if normalized, err := NormalizeRpcTransaction(tx, block.Header); err == nil {
normalized.ID = op.Hash
txs = append(txs, normalized)
}
}
}
}
}

return &types.Block{Number: block.Header.Level, Txs: txs}, nil
}

func NormalizeRpcTransaction(tx RpcTransaction, header RpcBlockHeader) (types.Tx, error) {
coin := coin.Tezos()

var metadata interface{}
var to string
var txType types.TransactionType
switch tx.Kind {
case TxTypeTransaction:
to = tx.Destination
txType = types.TxTransfer
metadata = types.Transfer{
Value: types.Amount(tx.Amount),
Symbol: coin.Symbol,
Decimals: coin.Decimals,
}
case TxTypeDelegation:
var title types.KeyTitle
if len(tx.Delegate) == 0 {
title = types.AnyActionUndelegation
} else {
title = types.AnyActionDelegation
to = tx.Delegate
}
txType = types.TxAnyAction
metadata = types.AnyAction{
Coin: coin.ID,
Title: title,
Key: types.KeyStakeDelegate,
Name: coin.Name,
Symbol: coin.Symbol,
Decimals: coin.Decimals,
}
default:
return types.Tx{}, errors.New("not supported operation kind: " + tx.Kind)
}

date, err := timefmt.Parse(header.Timestamp, "%Y-%m-%dT%H:%M:%SZ")
if err != nil {
return types.Tx{}, err
}

var status types.Status
if tx.Metadata.OperationResult.Status == TxStatusApplied {
status = types.StatusCompleted
} else {
status = types.StatusError
}

return types.Tx{
Coin: coin.ID,
From: tx.Source,
To: to,
Fee: types.Amount(tx.Fee),
Date: date.Unix(),
Block: uint64(header.Level),
Status: status,
Type: txType,
Meta: metadata,
}, nil
}

func mapTransaction(content interface{}) (RpcTransaction, error) {
bytes, err := json.Marshal(content)
if err != nil {
return RpcTransaction{}, err
}

var tx RpcTransaction
err = json.Unmarshal(bytes, &tx)
if err != nil {
return RpcTransaction{}, err
}

return tx, nil
}
146 changes: 146 additions & 0 deletions platform/tezos/block_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package tezos

import (
"fmt"
"reflect"
"testing"

"github.com/trustwallet/golibs/mock"
"github.com/trustwallet/golibs/types"
)

func TestNormalizeRpcBlock(t *testing.T) {
type args struct {
filename string
}
tests := []struct {
name string
args args
want *types.Block
wantErr bool
}{
{
name: "Test normalize block 1292516",
args: args{
filename: "rpc_block_1292516.json",
},
want: &types.Block{
Number: 1292516,
Txs: []types.Tx{
{
ID: "oo25sEdAT3YDb83WNdMSxRv4E6V2Rt6Jc8msgTio7R4FBnAiFmj",
Coin: 1729,
From: "tz1SiPXX4MYGNJNDsRc7n8hkvUqFzg8xqF9m",
To: "tz1LGrjCS3Jj3YZyRx3mHMmEXRJVQeVnoYYi",
Fee: "2940",
Date: 1610065014,
Block: 1292516,
Status: "completed",
Sequence: 0,
Type: "transfer",
Memo: "",
Meta: types.Transfer{
Value: "5278500000",
Symbol: "XTZ",
Decimals: 6,
},
},
{
ID: "ooPykS2pw28FveDV3FojeXmThtuCATDJdn93iFjrRxFaEytait2",
Coin: 1729,
From: "tz1MKCMt9dQDccykzripUGk5439BwEWthqx5",
To: "tz1S1Aew75hMrPUymqenKfHo8FspppXKpW7h",
Fee: "9008",
Date: 1610065014,
Block: 1292516,
Status: "completed",
Sequence: 0,
Type: "any_action",
Memo: "",
Meta: types.AnyAction{
Coin: 1729,
Title: "Delegation",
Key: "stake_delegate",
Name: "Tezos",
Symbol: "XTZ",
Decimals: 6,
},
},
{
ID: "ooFFpMbVAJMkxNYFqxERDumptXS2kSEJQqTwoovVPinayJehB8f",
Coin: 1729,
From: "tz1YbzpfsfRtSiYJWcvpWEDHPNe3kkqEvY56",
To: "tz1L1c5YoQMaciYGB8gpzWoHbscBmtsTsknF",
Fee: "30000",
Date: 1610065014,
Block: 1292516,
Status: "completed",
Sequence: 0,
Type: "transfer",
Memo: "",
Meta: types.Transfer{
Value: "290691675",
Symbol: "XTZ",
Decimals: 6,
},
},
{
ID: "opLbuEsuf9NmzgikvAG4sVaS7NJedzXHcz53iQPon6QurLP8Ztv",
Coin: 1729,
From: "tz1XbmS2Z3ya36JDqo1P1y3VU8t4RU2LJW6J",
To: "",
Fee: "2500",
Date: 1610065014,
Block: 1292516,
Status: "completed",
Sequence: 0,
Type: "any_action",
Memo: "",
Meta: types.AnyAction{
Coin: 1729,
Title: "Undelegation",
Key: "stake_delegate",
Name: "Tezos",
Symbol: "XTZ",
Decimals: 6,
},
},
{
ID: "opNgBb87Cnpjr29Uc4CRuXpWgTfhPx2h76S5txrPJELa5XYiidZ",
Coin: 1729,
From: "tz1c5wM9826YcUNQ8a17z9eUYpKQ3oW3zfmJ",
To: "KT19kgnqC5VWoxktLRdRUERbyUPku9YioE8W",
Fee: "824",
Date: 1610065014,
Block: 1292516,
Status: "completed",
Sequence: 0,
Type: "transfer",
Memo: "",
Meta: types.Transfer{
Value: "0",
Symbol: "XTZ",
Decimals: 6,
},
},
},
},
wantErr: false,
},
}
for _, tt := range tests {
var block RpcBlock
_ = mock.JsonModelFromFilePath("mocks/"+tt.args.filename, &block)
t.Run(tt.name, func(t *testing.T) {
got, err := NormalizeRpcBlock(block)
fmt.Println(got)
if (err != nil) != tt.wantErr {
t.Errorf("NormalizeRpcBlock() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("NormalizeRpcBlock() = %v, \nwant %v", got, tt.want)
}
})
}
}
19 changes: 0 additions & 19 deletions platform/tezos/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,3 @@ func (c *Client) GetTxsOfAddress(address string, txType []string) (txs ExplorerA
})
return
}

// Get last indexed block by explorer
func (c *Client) GetCurrentBlock() (int64, error) {
var status Status
err := c.Get(&status, "status", nil)
return status.Indexed, err
}

func (c *Client) GetBlockByNumber(num int64, txType []string) ([]Transaction, error) {
var blockOps []Transaction
path := fmt.Sprintf("block/%d/operations", num)
types := strings.Join(txType, ",")

err := c.Get(&blockOps, path, url.Values{
"limit": {"5000"}, // https://github.com/blockwatch-cc/tzindex/issues/17#issuecomment-604967761
"type": {types},
})
return blockOps, err
}
Loading

0 comments on commit 3a772c4

Please sign in to comment.