Skip to content

Commit

Permalink
Merge pull request #104 from xssnick/storage
Browse files Browse the repository at this point in the history
Storage
  • Loading branch information
xssnick authored Mar 3, 2023
2 parents bc389a9 + 1c4506e commit 33fd62d
Show file tree
Hide file tree
Showing 98 changed files with 5,341 additions and 1,998 deletions.
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
<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-72.4%25-brightgreen)
![Coverage](https://img.shields.io/badge/Coverage-73.3%25-brightgreen)

Golang library for interacting with TON blockchain.

This library is native golang implementation of ADNL and lite protocol. It works as connection pool and can be connected to multiple lite servers in the same time, balancing is done on lib side.

It is concurrent safe and can be used from multiple goroutines under high workloads.

All main TON protocols are implemented: ADNL, DHT, RLDP, Overlays, HTTP-RLDP, etc.

------

If you love this library and want to support its development you can donate any amount of coins to this ton address ☺️
Expand Down Expand Up @@ -211,7 +213,7 @@ if account.Data != nil { // Can be nil if account is not active
list, err := api.ListTransactions(context.Background(), addr, 15, account.LastTxLT, account.LastTxHash)
if err != nil {
// In some cases you can get error:
// lite server error, code 4294966896: cannot compute block with specified transaction: lt not in db
// lite server error, code XXX: cannot compute block with specified transaction: lt not in db
// it means that current lite server does not store older data, you can query one with full history
log.Printf("send err: %s", err.Error())
return
Expand Down Expand Up @@ -471,10 +473,14 @@ client.SetOnDisconnect(func(addr, serverKey string) {
* ✅ RLDP Client/Server
* ✅ TON Sites Client/Server
* ✅ DHT Client
* ✅ Merkle proofs
* ✅ TON Storage client
* ✅ Overlays
* ✅ TL Parser/Serializer
* ✅ TL-B Parser/Serializer
* DHT Server
* Payment channels
* Merkle proofs
* TON Storage
* Merkle proofs automatic validation

<!-- Badges -->
[ton-svg]: https://img.shields.io/badge/Based%20on-TON-blue
Expand Down
19 changes: 8 additions & 11 deletions adnl/adnl.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ func (a *ADNL) processPacket(packet *PacketContent, ch *Channel) (err error) {
seqno := uint64(*packet.Seqno)
a.lastReceiveAt = time.Now()

if ch == nil && packet.From != nil {
if ch == nil && packet.From != nil && a.peerKey == nil {
a.peerKey = packet.From.Key
}

Expand Down Expand Up @@ -211,12 +211,12 @@ func (a *ADNL) processMessage(message any, ch *Channel) error {
defer a.mx.Unlock()

if a.channel != nil {
if !bytes.Equal(a.channel.peerKey, ms.Key) {
return fmt.Errorf("another channel is already initialized")
if bytes.Equal(a.channel.peerKey, ms.Key) {
// already initialized on our side, but client missed confirmation,
// channel is already known, so more confirmations will be sent in the next packets
return nil
}
// already initialized on our side, but client missed confirmation,
// channel is already known, so more confirmations will be sent in the next packets
return nil
// looks like channel was lost on the other side, we will reinit it
}

_, key, err := ed25519.GenerateKey(nil)
Expand All @@ -235,16 +235,13 @@ func (a *ADNL) processMessage(message any, ch *Channel) error {
if err != nil {
return fmt.Errorf("failed to setup channel: %w", err)
}

if a.channel == nil {
a.channel = newChan
}
a.channel = newChan
case MessageConfirmChannel:
a.mx.Lock()
defer a.mx.Unlock()

if a.channel == nil || !bytes.Equal(a.channel.key.Public().(ed25519.PublicKey), ms.PeerKey) {
return fmt.Errorf("confirmation for unknown channel")
return fmt.Errorf("confirmation for unknown channel %s", hex.EncodeToString(ms.PeerKey))
}

if a.channel.ready {
Expand Down
54 changes: 45 additions & 9 deletions adnl/adnl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,16 @@ func TestADNL_ClientServer(t *testing.T) {

gotSrvCustom := make(chan any, 1)
gotCliCustom := make(chan any, 1)
gotCliCustom2 := make(chan any, 1)
gotSrvDiscon := make(chan any, 1)

s := NewServer(srvKey)
s.SetConnectionHandler(func(client Client) error {
s := NewGateway(srvKey)
err = s.StartServer("127.0.0.1:9055")
if err != nil {
t.Fatal(err)
}

s.SetConnectionHandler(func(client Peer) error {
client.SetQueryHandler(func(msg *MessageQuery) error {
switch m := msg.Data.(type) {
case MessagePing:
Expand Down Expand Up @@ -58,12 +64,6 @@ func TestADNL_ClientServer(t *testing.T) {
return nil
})

go func() {
if err = s.ListenAndServe("127.0.0.1:9055"); err != nil {
t.Fatal(err)
}
}()

time.Sleep(1 * time.Second)

cli, err := Connect(context.Background(), "127.0.0.1:9055", srvPub, nil)
Expand Down Expand Up @@ -125,7 +125,12 @@ func TestADNL_ClientServer(t *testing.T) {
})

t.Run("bad query", func(t *testing.T) {
cliBadQuery, err := Connect(context.Background(), "127.0.0.1:9055", srvPub, nil)
_, rndOur, err := ed25519.GenerateKey(nil)
if err != nil {
t.Fatal(err)
}

cliBadQuery, err := Connect(context.Background(), "127.0.0.1:9055", srvPub, rndOur)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -167,6 +172,37 @@ func TestADNL_ClientServer(t *testing.T) {
}
})

t.Run("custom msg channel reinited", func(t *testing.T) {
cli, err = Connect(context.Background(), "127.0.0.1:9055", srvPub, nil)
if err != nil {
t.Fatal(err)
}
cli.SetCustomMessageHandler(func(msg *MessageCustom) error {
gotCliCustom2 <- msg.Data
return nil
})

err = cli.SendCustomMessage(context.Background(), TestMsg{Data: make([]byte, 4)})
if err != nil {
t.Fatal(err)
}

select {
case <-gotSrvCustom:
case <-time.After(150 * time.Millisecond):
t.Fatal("custom not received from client")
}

select {
case m := <-gotCliCustom2:
if len(m.(TestMsg).Data) != 1280 {
t.Fatal("invalid custom from server")
}
case <-time.After(150 * time.Millisecond):
t.Fatal("custom not received from server")
}
})

// now we close connection
cli.Close()

Expand Down
4 changes: 2 additions & 2 deletions adnl/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,13 @@ func (c *Channel) setup(theirKey ed25519.PublicKey) (err error) {
return err
}

c.ready = true

h := c.adnl.onChannel
if h != nil {
h(c)
}

c.ready = true

return nil
}

Expand Down
20 changes: 16 additions & 4 deletions adnl/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"encoding/hex"
"fmt"
"net"
"sync"
"time"
)

Expand All @@ -15,13 +16,24 @@ var Dial = func(addr string, timeout time.Duration) (net.Conn, error) {
return net.DialTimeout("udp", addr, timeout)
}

var ourDefaultKey ed25519.PrivateKey
var defaultKeyMX sync.RWMutex

// Connect is DEPRECATED use Gateway
func Connect(ctx context.Context, addr string, peerKey ed25519.PublicKey, ourKey ed25519.PrivateKey) (_ *ADNL, err error) {
if ourKey == nil {
// new random key
_, ourKey, err = ed25519.GenerateKey(nil)
if err != nil {
return nil, err
// we generate key once and then use it for further connections
defaultKeyMX.Lock()
if ourDefaultKey == nil {
// new random key
_, ourDefaultKey, err = ed25519.GenerateKey(nil)
if err != nil {
defaultKeyMX.Unlock()
return nil, err
}
}
ourKey = ourDefaultKey
defaultKeyMX.Unlock()
}

a := initADNL(ourKey)
Expand Down
Loading

0 comments on commit 33fd62d

Please sign in to comment.