Skip to content

Commit

Permalink
Merge pull request #255 from xssnick/dev-v19
Browse files Browse the repository at this point in the history
v1.10.0
  • Loading branch information
xssnick authored Sep 16, 2024
2 parents 9db1a13 + ed8b367 commit d4afeb1
Show file tree
Hide file tree
Showing 29 changed files with 641 additions and 205 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

[![Based on TON][ton-svg]][ton]
[![Telegram Channel][tgc-svg]][tg-channel]
![Coverage](https://img.shields.io/badge/Coverage-73.8%25-brightgreen)
![Coverage](https://img.shields.io/badge/Coverage-73.5%25-brightgreen)

Golang library for interacting with TON blockchain.

Expand Down
29 changes: 23 additions & 6 deletions adnl/adnl.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,24 @@ func (c *Channel) process(buf []byte) error {

func (a *ADNL) processPacket(packet *PacketContent, ch *Channel) (err error) {
a.mx.Lock()

if packet.DstReinitDate != nil && *packet.DstReinitDate > 0 && *packet.DstReinitDate < a.reinitTime {
if packet.ReinitDate != nil {
a.dstReinit = *packet.ReinitDate
}
a.mx.Unlock()

buf, err := a.buildRequest(ch, MessageNop{})
if err != nil {
return fmt.Errorf("failed to create packet: %w", err)
}
if err = a.send(context.Background(), buf); err != nil {
return fmt.Errorf("failed to send ping reinit: %w", err)
}

return nil
}

seqno := uint64(*packet.Seqno)
a.lastReceiveAt = time.Now()

Expand All @@ -161,17 +179,14 @@ func (a *ADNL) processPacket(packet *PacketContent, ch *Channel) (err error) {
a.confirmSeqno = seqno
}

if packet.ReinitDate != nil && *packet.ReinitDate > a.dstReinit {
if (packet.ReinitDate != nil && *packet.ReinitDate > a.dstReinit) &&
(packet.DstReinitDate != nil && *packet.DstReinitDate == a.reinitTime) {
// reset their seqno even if it is lower,
// because other side could lose counter
a.confirmSeqno = seqno
a.loss = 0

// a.dstReinit = *packet.ReinitDate
// a.seqno = 0
// a.channel = nil
// a.confirmSeqno = 0
// a.reinitTime = a.dstReinit
a.dstReinit = *packet.ReinitDate
}

if packet.RecvPriorityAddrListVersion != nil {
Expand Down Expand Up @@ -329,6 +344,8 @@ func (a *ADNL) processMessage(message any, ch *Channel) error {
return fmt.Errorf("failed to handle custom message: %w", err)
}
}
case MessageNop:
return nil
default:
return fmt.Errorf("skipped unprocessable message of type %s", reflect.TypeOf(message).String())
}
Expand Down
21 changes: 10 additions & 11 deletions adnl/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ func (g *Gateway) listen(rootId []byte) {
g.mx.RUnlock()

if proc == nil {
Logger("no processor for ADNL packet from", hex.EncodeToString(id))
Logger("no processor for ADNL packet from", addr.String(), hex.EncodeToString(id))
continue
}

Expand Down Expand Up @@ -384,18 +384,17 @@ func (g *Gateway) registerClient(addr net.Addr, key ed25519.PublicKey, id string
closer: ch.adnl.Close,
}
g.mx.Unlock()
})

if oldId == "" { // connection = first channel initialisation
connHandler := g.connHandler
if connHandler != nil {
err := connHandler(peer)
if err != nil {
// close connection if connection handler reports an error
ch.adnl.Close()
}
connHandler := g.connHandler
if connHandler != nil {
go func() {
if err := connHandler(peer); err != nil {
// close connection if connection handler reports an error
a.Close()
}
}
})
}()
}

return peer, nil
}
Expand Down
4 changes: 2 additions & 2 deletions adnl/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,9 @@ func parsePacket(data []byte) (_ *PacketContent, err error) {
data = data[4:]
packet.ReinitDate = &reinit

reinit = int32(binary.LittleEndian.Uint32(data))
dstReinit := int32(binary.LittleEndian.Uint32(data))
data = data[4:]
packet.DstReinitDate = &reinit
packet.DstReinitDate = &dstReinit
}

if flags&_FlagSignature != 0 {
Expand Down
5 changes: 4 additions & 1 deletion adnl/rldp/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,9 @@ func (r *RLDP) sendMessageParts(ctx context.Context, transferId, data []byte) er

if symbolsSent > fastSymbols {
x := (symbolsSent - fastSymbols) / 2
if x > 70 { // 7 ms max delay
x = 70
}

select {
case <-ctx.Done():
Expand All @@ -365,7 +368,7 @@ func (r *RLDP) sendMessageParts(ctx context.Context, transferId, data []byte) er
case <-ch:
// we got complete from receiver, finish sending
return nil
case <-time.After(time.Duration(x) * _PacketWaitTime):
case <-time.After(time.Duration(x) * (time.Millisecond / 10)):
// send additional FEC recovery parts until complete
}
}
Expand Down
18 changes: 15 additions & 3 deletions adnl/rldp/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,10 +377,14 @@ func TestRDLP_sendMessageParts(t *testing.T) {
}

decoded, receivData, err := tDecoder.Decode()
if err != nil || decoded != true {
if err != nil {
t.Fatal("failed to decode received test data, err: ", err)
}

if decoded != true {
return nil
}

if !bytes.Equal(data, receivData) {
t.Fatal("bad data received in 'sendCustomMessage'")
}
Expand Down Expand Up @@ -479,10 +483,14 @@ func TestRLDP_DoQuery(t *testing.T) {
}

decoded, receivData, err := tDecoder.Decode()
if err != nil || decoded != true {
if err != nil {
t.Fatal("failed to decode received test data, err: ", err)
}

if decoded != true {
return nil
}

var checkReq Query
_, err = tl.Parse(&checkReq, receivData, true)
if err != nil {
Expand Down Expand Up @@ -568,10 +576,14 @@ func TestRLDP_SendAnswer(t *testing.T) {
}

decoded, receivData, err := tDecoder.Decode()
if err != nil || decoded != true {
if err != nil {
t.Fatal("failed to decode received test data, err: ", err)
}

if decoded != true {
return nil
}

var checkAnswer Answer
_, err = tl.Parse(&checkAnswer, receivData, true)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions adnl/rldp/http/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func (t *Transport) connectRLDP(ctx context.Context, key ed25519.PublicKey, addr
}

rCap := GetCapabilities{
Capabilities: CapabilityRLDP2,
Capabilities: 0,
}

var caps Capabilities
Expand All @@ -126,7 +126,7 @@ func (t *Transport) connectRLDP(ctx context.Context, key ed25519.PublicKey, addr
switch query.Data.(type) {
case GetCapabilities:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
err := a.Answer(ctx, query.ID, &Capabilities{Value: CapabilityRLDP2})
err := a.Answer(ctx, query.ID, &Capabilities{Value: 0})
cancel()
if err != nil {
return fmt.Errorf("failed to send capabilities answer: %w", err)
Expand Down Expand Up @@ -284,7 +284,7 @@ func (t *Transport) RoundTrip(request *http.Request) (_ *http.Response, err erro
req := Request{
ID: qid,
Method: request.Method,
URL: request.URL.String(),
URL: request.URL.RequestURI(),
Version: "HTTP/1.1",
Headers: []Header{
{
Expand Down
11 changes: 8 additions & 3 deletions adnl/rldp/http/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ func (s *Server) ListenAndServe(listenAddr string) error {
switch query.Data.(type) {
case GetCapabilities:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
err := client.Answer(ctx, query.ID, &Capabilities{Value: CapabilityRLDP2})
err := client.Answer(ctx, query.ID, &Capabilities{Value: 0}) // CapabilityRLDP2
cancel()
if err != nil {
return fmt.Errorf("failed to send capabilities answer: %w", err)
Expand Down Expand Up @@ -236,11 +236,15 @@ func (s *Server) handle(client RLDP, adnlId, addr string) func(transferId []byte
if err != nil {
return fmt.Errorf("failed to parse url `%s`: %w", uri, err)
}
uri.Scheme = "http"

contentLen := int64(-1)
headers := http.Header{}
for _, header := range req.Headers {
if header.Name == "Content-Length" {
name := http.CanonicalHeaderKey(header.Name)
if name == "Host" {
uri.Host = header.Value
} else if name == "Content-Length" {
contentLen, err = strconv.ParseInt(header.Value, 10, 64)
if err != nil {
return fmt.Errorf("failed to parse content len `%s`: %w", header.Value, err)
Expand All @@ -250,7 +254,8 @@ func (s *Server) handle(client RLDP, adnlId, addr string) func(transferId []byte
return fmt.Errorf("failed to parse content len: should be >= 0")
}
}
headers[header.Name] = append(headers[header.Name], header.Value)

headers[name] = append(headers[name], header.Value)
}
headers.Set("X-Adnl-Ip", netAddr.IP.String())
headers.Set("X-Adnl-Id", adnlId)
Expand Down
4 changes: 2 additions & 2 deletions example/nft-info/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func main() {
case *nft.ContentOffchain:
fmt.Println(" content offchain :", content.URI)
case *nft.ContentOnchain:
fmt.Println(" content onchain :", content.Name)
fmt.Println(" content onchain :", content.GetAttribute("name"))
}
fmt.Println(" owner :", collectionData.OwnerAddress.String())
fmt.Println(" minted items num :", collectionData.NextItemIndex)
Expand All @@ -69,7 +69,7 @@ func main() {
fmt.Println(" full content :", nftContent.(*nft.ContentOffchain).URI)
}
case *nft.ContentOnchain:
fmt.Println(" content name :", content.Name)
fmt.Println(" content name :", content.GetAttribute("name"))
}
} else {
fmt.Println(" empty content")
Expand Down
12 changes: 12 additions & 0 deletions tlb/coins.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,15 @@ func (g *Coins) UnmarshalJSON(data []byte) error {

return nil
}

func (g *Coins) Compare(coins *Coins) int {
if g.decimals != coins.decimals {
panic("invalid comparsion")
}

return g.Nano().Cmp(coins.Nano())
}

func (g *Coins) Decimals() int {
return g.decimals
}
6 changes: 6 additions & 0 deletions tlb/state-init.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package tlb

import (
"github.com/xssnick/tonutils-go/address"
"github.com/xssnick/tonutils-go/tvm/cell"
)

Expand All @@ -16,3 +17,8 @@ type StateInit struct {
Data *cell.Cell `tlb:"maybe ^"`
Lib *cell.Dictionary `tlb:"dict 256"`
}

func (s StateInit) CalcAddress(workchain int) *address.Address {
c, _ := ToCell(s)
return address.NewAddress(0, byte(workchain), c.Hash())
}
49 changes: 49 additions & 0 deletions tlb/state-init_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package tlb

import (
"github.com/xssnick/tonutils-go/tvm/cell"
"testing"
)

func TestStateInit_CalcAddress(t *testing.T) {
tests := []struct {
name string
stateInit StateInit
workchain int
want string
}{
{
name: "Base",
stateInit: StateInit{
Code: cell.BeginCell().MustStoreUInt(0, 8).EndCell(),
Data: cell.BeginCell().MustStoreUInt(0, 8).EndCell(),
},
workchain: 0,
want: "EQBPQF6r6-pUObVWu6RO05YwoHQRnjM95tRLAL_s2A6n0pvq",
},
{
name: "Empty",
stateInit: StateInit{},
workchain: 0,
want: "EQA_B407fiLIlE5VYZCaI2rki0in6kLyjdhhwitvZNfpe7eY",
},
{
name: "Master",
stateInit: StateInit{
Code: cell.BeginCell().MustStoreUInt(123, 8).EndCell(),
Data: cell.BeginCell().MustStoreUInt(456, 16).EndCell(),
},
workchain: -1,
want: "Ef_jHHi5wLtyTaS56iIEPUc9mJuoD2keQPxZX87rl2FcVDZ1",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := tt.stateInit.CalcAddress(tt.workchain)
if got.String() != tt.want {
t.Errorf("StateInit.CalcAddress() = %v, want %v", got, tt.want)
}
})
}
}
1 change: 1 addition & 0 deletions ton/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ type APIClientWrapped interface {
GetMasterchainInfo(ctx context.Context) (*BlockIDExt, error)
GetAccount(ctx context.Context, block *BlockIDExt, addr *address.Address) (*tlb.Account, error)
SendExternalMessage(ctx context.Context, msg *tlb.ExternalMessage) error
SendExternalMessageWaitTransaction(ctx context.Context, msg *tlb.ExternalMessage) (*tlb.Transaction, *BlockIDExt, []byte, error)
RunGetMethod(ctx context.Context, blockInfo *BlockIDExt, addr *address.Address, method string, params ...interface{}) (*ExecutionResult, error)
ListTransactions(ctx context.Context, addr *address.Address, num uint32, lt uint64, txHash []byte) ([]*tlb.Transaction, error)
GetTransaction(ctx context.Context, block *BlockIDExt, addr *address.Address, lt uint64) (*tlb.Transaction, error)
Expand Down
3 changes: 2 additions & 1 deletion ton/getstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ func (c *APIClient) GetAccount(ctx context.Context, block *BlockIDExt, addr *add
}

var shardHash []byte
if c.proofCheckPolicy != ProofCheckPolicyUnsafe && addr.Workchain() != address.MasterchainID {
if c.proofCheckPolicy != ProofCheckPolicyUnsafe && addr.Workchain() != address.MasterchainID &&
block.Workchain == address.MasterchainID {
if len(t.ShardProof) == 0 {
return nil, ErrNoProof
}
Expand Down
Loading

0 comments on commit d4afeb1

Please sign in to comment.