Skip to content

Commit 94dbc8d

Browse files
committed
fix: TON http server port mapping
1 parent 9bdb5d0 commit 94dbc8d

File tree

3 files changed

+74
-41
lines changed

3 files changed

+74
-41
lines changed

book/src/framework/components/blockchains/ton.md

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,23 +30,27 @@ More info on parameters can be found here <https://github.com/neodix42/mylocalto
3030

3131
## Network Configuration
3232

33-
The framework provides seamless access to the TON network configuration by embedding the config URL directly in the node URLs. The `ExternalHTTPUrl` and `InternalHTTPUrl` include the full path to `localhost.global.config.json`, which can be used directly with `liteclient.GetConfigFromUrl()` without additional URL formatting.
33+
The framework provides direct access to TON liteserver connections through pre-formatted liteserver URLs. The `ExternalHTTPUrl` and `InternalHTTPUrl` contain ready-to-use liteserver connection strings in the format `liteserver://publickey@host:port`, eliminating the need to fetch and parse separate configuration files.
3434

3535
## Default Ports
3636

37-
The TON implementation exposes essential services:
37+
The TON implementation exposes essential services through port mapping:
3838

39-
* TON Simple HTTP Server: Port 8000
40-
* TON Lite Server: Port derived from base port + 100
39+
* **TON Simple HTTP Server**: External dynamic port → Internal port 8000
40+
* **TON Lite Server**: External dynamic port → Internal dynamic port (base + 100 offset)
4141

42-
> Note: `tonutils-go` library is used for TON blockchain interactions, which requires a TON Lite Server connection. The framework embeds the config URL directly in the node URLs for convenient access to the global configuration file needed by `tonutils-go`.
42+
The framework automatically handles port mapping and provides ready-to-use liteserver connection URLs.
43+
44+
> Note: `tonutils-go` library is used for TON blockchain interactions, which requires a TON Lite Server connection. The framework provides direct liteserver:// URLs that can be used immediately without additional configuration parsing.
4345
4446
## Usage
4547

4648
```go
4749
package examples
4850

4951
import (
52+
"context"
53+
"fmt"
5054
"strings"
5155
"testing"
5256

@@ -63,6 +67,34 @@ type CfgTon struct {
6367
BlockchainA *blockchain.Input `toml:"blockchain_a" validate:"required"`
6468
}
6569

70+
// getConnectionPoolFromLiteserverURL parses a liteserver:// URL and creates a connection pool
71+
func getConnectionPoolFromLiteserverURL(ctx context.Context, liteserverURL string) (*liteclient.ConnectionPool, error) {
72+
// Parse the liteserver URL, expected format: liteserver://publickey@host:port
73+
if !strings.HasPrefix(liteserverURL, "liteserver://") {
74+
return nil, fmt.Errorf("invalid liteserver URL format: expected liteserver:// prefix")
75+
}
76+
77+
// Remove the liteserver:// prefix
78+
urlPart := strings.TrimPrefix(liteserverURL, "liteserver://")
79+
80+
// Split by @ to separate publickey and host:port
81+
parts := strings.Split(urlPart, "@")
82+
if len(parts) != 2 {
83+
return nil, fmt.Errorf("invalid liteserver URL format: expected publickey@host:port")
84+
}
85+
86+
publicKey := parts[0]
87+
hostPort := parts[1]
88+
89+
connectionPool := liteclient.NewConnectionPool()
90+
err := connectionPool.AddConnection(ctx, hostPort, publicKey)
91+
if err != nil {
92+
return nil, fmt.Errorf("failed to add liteserver connection: %w", err)
93+
}
94+
95+
return connectionPool, nil
96+
}
97+
6698
func TestTonSmoke(t *testing.T) {
6799
in, err := framework.Load[CfgTon](t)
68100
require.NoError(t, err)
@@ -75,19 +107,14 @@ func TestTonSmoke(t *testing.T) {
75107
var client ton.APIClientWrapped
76108

77109
t.Run("setup:connect", func(t *testing.T) {
78-
// Create a connection pool
79-
connectionPool := liteclient.NewConnectionPool()
80-
81-
// Get the network configuration directly from the embedded config URL
82-
// The ExternalHTTPUrl already includes the full path to localhost.global.config.json
83-
cfg, cferr := liteclient.GetConfigFromUrl(t.Context(), bc.Nodes[0].ExternalHTTPUrl)
84-
require.NoError(t, cferr, "Failed to get config from URL")
85-
86-
// Add connections from the config
87-
caerr := connectionPool.AddConnectionsFromConfig(t.Context(), cfg)
88-
require.NoError(t, caerr, "Failed to add connections from config")
89-
90-
// Create an API client with retry functionality
110+
// bc.Nodes[0].ExternalHTTPUrl now contains: "liteserver://publickey@host:port"
111+
liteserverURL := bc.Nodes[0].ExternalHTTPUrl
112+
113+
// Create connection pool from liteserver URL
114+
connectionPool, err := getConnectionPoolFromLiteserverURL(t.Context(), liteserverURL)
115+
require.NoError(t, err, "Failed to create connection pool from liteserver URL")
116+
117+
// Create API client
91118
client = ton.NewAPIClient(connectionPool).WithRetry()
92119

93120
t.Run("setup:faucet", func(t *testing.T) {

framework/components/blockchain/ton.go

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ import (
1818
)
1919

2020
const (
21-
DefaultTonSimpleServerPort = "8000"
2221
// NOTE: Prefunded high-load wallet from MyLocalTon pre-funded wallet, that can send up to 254 messages per 1 external message
2322
// https://docs.ton.org/v3/documentation/smart-contracts/contracts-specs/highload-wallet#highload-wallet-v2
2423
DefaultTonHlWalletAddress = "-1:5ee77ced0b7ae6ef88ab3f4350d8872c64667ffbe76073455215d3cdfab3294b"
2524
DefaultTonHlWalletMnemonic = "twenty unfair stay entry during please water april fabric morning length lumber style tomorrow melody similar forum width ride render void rather custom coin"
26-
27-
liteServerPortOffset = 100 // internal, arbitrary offset for lite server port
25+
// internals
26+
defaultTonHTTPServerPort = "8000"
27+
defaultLiteServerPort = "40000"
28+
defaultLiteServerPublicKey = "E7XwFSQzNkcRepUC23J2nRpASXpnsEKmyyHYV4u/FZY="
29+
liteServerPortOffset = 100 // arbitrary offset for lite server port
2830
)
2931

3032
// TON config structures (e.g.: ton-blockchain.github.io/testnet-global.config.json)
@@ -84,19 +86,16 @@ func fetchTonConfig(configURL string) ([]string, error) {
8486
}
8587

8688
type portMapping struct {
87-
SimpleServer string
88-
LiteServer string
89-
DHTServer string
90-
Console string
91-
ValidatorUDP string
89+
HTTPServer string
90+
LiteServer string
9291
}
9392

9493
func defaultTon(in *Input) {
9594
if in.Image == "" {
9695
in.Image = "ghcr.io/neodix42/mylocalton-docker:latest"
9796
}
9897
if in.Port == "" {
99-
in.Port = DefaultTonSimpleServerPort
98+
in.Port = defaultTonHTTPServerPort
10099
}
101100
}
102101

@@ -109,8 +108,8 @@ func newTon(in *Input) (*Output, error) {
109108
}
110109

111110
ports := &portMapping{
112-
SimpleServer: in.Port,
113-
LiteServer: strconv.Itoa(base + liteServerPortOffset),
111+
HTTPServer: in.Port,
112+
LiteServer: strconv.Itoa(base + liteServerPortOffset),
114113
}
115114

116115
ctx := context.Background()
@@ -125,12 +124,14 @@ func newTon(in *Input) (*Output, error) {
125124
networkName := network.Name
126125

127126
baseEnv := map[string]string{
128-
"GENESIS": "true",
129-
"NAME": "genesis",
130-
"LITE_PORT": ports.LiteServer,
131-
"CUSTOM_PARAMETERS": "--state-ttl 315360000 --archive-ttl 315360000",
127+
"GENESIS": "true",
128+
"NAME": "genesis",
129+
132130
"EMBEDDED_FILE_HTTP_SERVER": "true",
133-
"EMBEDDED_FILE_HTTP_SERVER_PORT": in.Port,
131+
"EMBEDDED_FILE_HTTP_SERVER_PORT": defaultTonHTTPServerPort,
132+
"LITE_PORT": defaultLiteServerPort,
133+
134+
"CUSTOM_PARAMETERS": "--state-ttl 315360000 --archive-ttl 315360000",
134135
}
135136

136137
// merge with additional environment variables from input
@@ -146,8 +147,8 @@ func newTon(in *Input) (*Output, error) {
146147
AlwaysPullImage: in.PullImage,
147148
Name: framework.DefaultTCName("ton-genesis"),
148149
ExposedPorts: []string{
149-
fmt.Sprintf("%s:%s/tcp", ports.SimpleServer, DefaultTonSimpleServerPort),
150-
fmt.Sprintf("%s:%s/tcp", ports.LiteServer, ports.LiteServer),
150+
fmt.Sprintf("%s:%s/tcp", ports.HTTPServer, defaultTonHTTPServerPort),
151+
fmt.Sprintf("%s:%s/tcp", ports.LiteServer, defaultLiteServerPort),
151152
"40003/udp",
152153
"40002/tcp",
153154
"40001/udp",
@@ -158,8 +159,8 @@ func newTon(in *Input) (*Output, error) {
158159
Env: finalEnv,
159160
WaitingFor: wait.ForExec([]string{
160161
"/usr/local/bin/lite-client",
161-
"-a", fmt.Sprintf("127.0.0.1:%s", ports.LiteServer),
162-
"-b", "E7XwFSQzNkcRepUC23J2nRpASXpnsEKmyyHYV4u/FZY=",
162+
"-a", fmt.Sprintf("127.0.0.1:%s", defaultLiteServerPort),
163+
"-b", defaultLiteServerPublicKey,
163164
"-t", "3", "-c", "last",
164165
}).WithStartupTimeout(2 * time.Minute),
165166
Mounts: testcontainers.ContainerMounts{
@@ -185,6 +186,11 @@ func newTon(in *Input) (*Output, error) {
185186
return nil, err
186187
}
187188

189+
host, err := c.Host(ctx)
190+
if err != nil {
191+
return nil, err
192+
}
193+
188194
name, err := c.Name(ctx)
189195
if err != nil {
190196
return nil, err
@@ -211,8 +217,8 @@ func newTon(in *Input) (*Output, error) {
211217
Container: c,
212218
Nodes: []*Node{{
213219
// URLs now contain liteserver://publickey@host:port
214-
ExternalHTTPUrl: liteServerURLs[0],
215-
InternalHTTPUrl: liteServerURLs[0],
220+
ExternalHTTPUrl: fmt.Sprintf("liteserver://%s@%s:%s", defaultLiteServerPublicKey, host, ports.LiteServer),
221+
InternalHTTPUrl: fmt.Sprintf("liteserver://%s@%s:%s", defaultLiteServerPublicKey, name, ports.LiteServer),
216222
}},
217223
}, nil
218224
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[blockchain_a]
22
type = "ton"
33
image = "ghcr.io/neodix42/mylocalton-docker:v3.7"
4-
port = "8000"
4+
port = "9000"
55

66
[blockchain_a.custom_env]

0 commit comments

Comments
 (0)