Skip to content

Commit

Permalink
Merge pull request #189 from xssnick/dev-v19
Browse files Browse the repository at this point in the history
FindTransaction & Offline LC & Dict Proof of no key & RLDP tunning
  • Loading branch information
xssnick authored May 8, 2024
2 parents db2bc98 + 3b5ac72 commit 1628740
Show file tree
Hide file tree
Showing 18 changed files with 448 additions and 103 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<img align="right" width="425px" src="https://github.com/xssnick/props/blob/master/logoimg.png?raw=true">

[![Based on TON][ton-svg]][ton]
![Coverage](https://img.shields.io/badge/Coverage-74.0%25-brightgreen)
![Coverage](https://img.shields.io/badge/Coverage-73.8%25-brightgreen)

Golang library for interacting with TON blockchain.

Expand Down
19 changes: 10 additions & 9 deletions adnl/rldp/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"crypto/ed25519"
"crypto/rand"
"encoding/hex"
"fmt"
"github.com/xssnick/tonutils-go/adnl"
"github.com/xssnick/tonutils-go/adnl/rldp/raptorq"
Expand Down Expand Up @@ -124,7 +123,7 @@ func (r *RLDP) handleMessage(msg *adnl.MessageCustom) error {
return fmt.Errorf("not supported fec type")
}

id := hex.EncodeToString(m.TransferID)
id := string(m.TransferID)
r.mx.RLock()
stream := r.recvStreams[id]
r.mx.RUnlock()
Expand Down Expand Up @@ -248,7 +247,7 @@ func (r *RLDP) handleMessage(msg *adnl.MessageCustom) error {
}()
}
case Answer:
qid := hex.EncodeToString(rVal.ID)
qid := string(rVal.ID)

r.mx.Lock()
req := r.activeRequests[qid]
Expand Down Expand Up @@ -298,7 +297,7 @@ func (r *RLDP) handleMessage(msg *adnl.MessageCustom) error {
}
}
case Complete: // receiver has fully received transfer, close our stream
id := hex.EncodeToString(m.TransferID)
id := string(m.TransferID)

r.mx.Lock()
t := r.activeTransfers[id]
Expand All @@ -312,7 +311,7 @@ func (r *RLDP) handleMessage(msg *adnl.MessageCustom) error {
}
case Confirm: // receiver has received some parts
// TODO: use confirmed seqno to limit sends
// id := hex.EncodeToString(m.TransferID)
// id := string(m.TransferID)
// r.mx.RLock()
// t := r.activeTransfers[id]
// r.mx.RUnlock()
Expand All @@ -329,7 +328,7 @@ func (r *RLDP) sendMessageParts(ctx context.Context, transferId, data []byte) er
return fmt.Errorf("failed to create raptorq object encoder: %w", err)
}

id := hex.EncodeToString(transferId)
id := string(transferId)

ch := make(chan bool, 1)
r.mx.Lock()
Expand All @@ -354,8 +353,10 @@ func (r *RLDP) sendMessageParts(ctx context.Context, transferId, data []byte) er
default:
}

if symbolsSent > enc.BaseSymbolsNum()+enc.BaseSymbolsNum()/2 { //+enc.BaseSymbolsNum()/2
x := symbolsSent - (enc.BaseSymbolsNum() + enc.BaseSymbolsNum()/2)
fastSymbols := enc.BaseSymbolsNum() + enc.BaseSymbolsNum()/5 // send 120% packets fast

if symbolsSent > fastSymbols {
x := (symbolsSent - fastSymbols) / 2

select {
case <-ctx.Done():
Expand Down Expand Up @@ -415,7 +416,7 @@ func (r *RLDP) DoQuery(ctx context.Context, maxAnswerSize int64, query, result t
Data: query,
}

queryID := hex.EncodeToString(q.ID)
queryID := string(q.ID)

res := make(chan any, 2)

Expand Down
7 changes: 3 additions & 4 deletions adnl/rldp/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"context"
"crypto/ed25519"
"crypto/rand"
"encoding/hex"
"errors"
"github.com/xssnick/tonutils-go/adnl"
"github.com/xssnick/tonutils-go/adnl/rldp/raptorq"
Expand Down Expand Up @@ -227,7 +226,7 @@ func TestRLDP_handleMessage(t *testing.T) {
return nil
}
} else if test.tstSubName == "answer case" {
queryId := hex.EncodeToString(tQuery.ID)
queryId := string(tQuery.ID)
tChan := make(chan any, 2)
cli.activeRequests[queryId] = tChan
}
Expand Down Expand Up @@ -279,7 +278,7 @@ func TestRLDP_handleMessage(t *testing.T) {
if err != nil {
t.Fatal("failed to execute handleMessage func, err: ", err)
}
if cli.recvStreams[hex.EncodeToString(tId)].lastCompleteAt.IsZero() {
if cli.recvStreams[string(tId)].lastCompleteAt.IsZero() {
t.Error("got lastCompleteAt == nil, want != nil")
}
})
Expand All @@ -296,7 +295,7 @@ func TestRLDP_handleMessage(t *testing.T) {
cli := NewClient(tAdnl)

tChan := make(chan bool, 1)
cli.activeTransfers[hex.EncodeToString(tId)] = tChan
cli.activeTransfers[string(tId)] = tChan

err := cli.handleMessage(msgComplete)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion example/vanity_fast/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func generateWallets(caseSensitive bool, suffix string, counter *uint64) {
binary.BigEndian.PutUint32(subwalletIDBytes, i)
getHashV3HashFromKey(hash, subwalletIDBytes, v3DataCell, v3StateInit, hashDst)

addr := address.NewAddress(0, 0, hashDst)
addr := address.NewAddress(0, 0, hashDst).Bounce(false)
addr.StringToBytes(addrTo, addrFrom)

if equalityFunc(suffix, string(addrTo[strCmpOffset:])) {
Expand Down
1 change: 1 addition & 0 deletions example/wallet-cold-alike/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
)

func main() {
// for completely offline mode you could use liteclient.NewOfflineClient() instead
client := liteclient.NewConnectionPool()

// connect to mainnet lite server
Expand Down
13 changes: 13 additions & 0 deletions liteclient/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,19 @@ func Test_Conn(t *testing.T) {
doReq(nil)
}

func Test_Offline(t *testing.T) {
client := NewOfflineClient()

doReq := func(expErr error) {
var resp tl.Serializable
err := client.QueryLiteserver(context.Background(), GetMasterchainInf{}, &resp)
if err != ErrOfflineMode {
t.Fatal("err", err)
}
}
doReq(nil)
}

func Test_ConnSticky(t *testing.T) {
client := NewConnectionPool()

Expand Down
31 changes: 31 additions & 0 deletions liteclient/offline.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package liteclient

import (
"context"
"fmt"
"github.com/xssnick/tonutils-go/tl"
)

var ErrOfflineMode = fmt.Errorf("offline mode is used")

type OfflineClient struct{}

func NewOfflineClient() OfflineClient {
return OfflineClient{}
}

func (o OfflineClient) QueryLiteserver(ctx context.Context, payload tl.Serializable, result tl.Serializable) error {
return ErrOfflineMode
}

func (o OfflineClient) StickyContext(ctx context.Context) context.Context {
return nil
}

func (o OfflineClient) StickyContextNextNode(ctx context.Context) (context.Context, error) {
return ctx, nil
}

func (o OfflineClient) StickyNodeID(ctx context.Context) uint32 {
return 0
}
19 changes: 17 additions & 2 deletions tlb/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,15 +235,30 @@ type Transaction struct {
}

func (t *Transaction) Dump() string {
res := fmt.Sprintf("LT: %d\n\nInput:\nType %s\nFrom %s\nPayload:\n%s\n\nOutputs:\n", t.LT, t.IO.In.MsgType, t.IO.In.Msg.SenderAddr(), t.IO.In.Msg.Payload().Dump())
var in string
if t.IO.In != nil {
var pl = "EMPTY"
if p := t.IO.In.Msg.Payload(); p != nil {
pl = p.Dump()
}
in = fmt.Sprintf("\nInput:\nType %s\nFrom %s\nPayload:\n%s\n", t.IO.In.MsgType, t.IO.In.Msg.SenderAddr(), pl)
}
res := fmt.Sprintf("LT: %d\n%s\nOutputs:\n", t.LT, in)
if t.IO.Out != nil {
list, err := t.IO.Out.ToSlice()
if err != nil {
return res + "\nOUT MESSAGES NOT PARSED DUE TO ERR: " + err.Error()
}

for _, m := range list {
res += m.AsInternal().Dump()
switch m.MsgType {
case MsgTypeInternal:
res += m.AsInternal().Dump()
case MsgTypeExternalOut:
res += "[EXT OUT] " + m.AsExternalOut().Body.Dump()
default:
res += "[UNKNOWN]"
}
}
}
return res
Expand Down
3 changes: 2 additions & 1 deletion ton/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (

func init() {
tl.Register(LSError{}, "liteServer.error code:int message:string = liteServer.Error")

}

type ProofCheckPolicy int
Expand Down Expand Up @@ -74,6 +73,8 @@ type APIClientWrapped interface {
WithTimeout(timeout time.Duration) APIClientWrapped
SetTrustedBlock(block *BlockIDExt)
SetTrustedBlockFromConfig(cfg *liteclient.GlobalConfig)
FindLastTransactionByInMsgHash(ctx context.Context, addr *address.Address, msgHash []byte, maxTxNumToScan ...int) (*tlb.Transaction, error)
FindLastTransactionByOutMsgHash(ctx context.Context, addr *address.Address, msgHash []byte, maxTxNumToScan ...int) (*tlb.Transaction, error)
}

type APIClient struct {
Expand Down
71 changes: 71 additions & 0 deletions ton/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -753,3 +753,74 @@ func TestAPIClient_WithRetry(t *testing.T) {
t.Fatal("expected deadline exceeded error but", err)
}
}

func TestAPIClient_FindLastTransactionByInMsgHash(t *testing.T) {
addr := address.MustParseAddr("Ef8zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM0vF")

block, err := api.CurrentMasterchainInfo(context.Background())
if err != nil {
t.Fatal(err)
}

acc, err := api.GetAccount(context.Background(), block, addr)
if err != nil {
t.Fatal(err)
}

list, err := api.ListTransactions(context.Background(), addr, 20, acc.LastTxLT, acc.LastTxHash)
if err != nil {
t.Fatal(err)
}

tx := list[len(list)-1]

// find tx hash
tx, err = api.FindLastTransactionByInMsgHash(context.Background(), addr, tx.IO.In.Msg.Payload().Hash(), 30)
if err != nil {
t.Fatal("cannot find tx:", err.Error())
}
t.Logf("tx hash: %s %s", hex.EncodeToString(tx.Hash), hex.EncodeToString(acc.LastTxHash))
}

func TestAPIClient_FindLastTransactionByOutMsgHash(t *testing.T) {
addr := address.MustParseAddr("UQCZ-7akCw_dvl_Q5xyriWqCXdWubIPbuN7aDQlzX45pa01R")

block, err := api.CurrentMasterchainInfo(context.Background())
if err != nil {
t.Fatal(err)
}

acc, err := api.GetAccount(context.Background(), block, addr)
if err != nil {
t.Fatal(err)
}

list, err := api.ListTransactions(context.Background(), addr, 20, acc.LastTxLT, acc.LastTxHash)
if err != nil {
t.Fatal(err)
}

var hash []byte
for i := len(list) - 1; i >= 0; i-- {
ls, err := list[i].IO.Out.ToSlice()
if err != nil {
continue
}

if len(ls) == 0 {
continue
}
hash = ls[0].Msg.Payload().Hash()
}

if hash == nil {
t.Fatal("no outs")
}

// find tx hash
tx, err := api.FindLastTransactionByOutMsgHash(context.Background(), addr, hash, 30)
if err != nil {
t.Fatal("cannot find tx:", err.Error())
}
t.Logf("tx hash: %s %s", hex.EncodeToString(tx.Hash), hex.EncodeToString(acc.LastTxHash))
}
8 changes: 8 additions & 0 deletions ton/retrier.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ func (w *retryClient) QueryLiteserver(ctx context.Context, payload tl.Serializab

continue
}
if errors.Is(err, context.DeadlineExceeded) {
err := ctx.Err()
if err != nil {
return err
}

continue
}

return err
}
Expand Down
Loading

0 comments on commit 1628740

Please sign in to comment.