From 7bfb357cf88e6bfac8ce4fe06a21575e8c04464c Mon Sep 17 00:00:00 2001 From: "aleksej.paschenko" Date: Wed, 7 Feb 2024 14:42:45 +0300 Subject: [PATCH] Add liteclient.OverlayID --- liteclient/generated.go | 59 +++++++++++++++++++++++++++++++++-- liteclient/lite_api.tl | 1 + liteclient/overlay_id.go | 52 ++++++++++++++++++++++++++++++ liteclient/overlay_id_test.go | 55 ++++++++++++++++++++++++++++++++ 4 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 liteclient/overlay_id.go create mode 100644 liteclient/overlay_id_test.go diff --git a/liteclient/generated.go b/liteclient/generated.go index d17397be..c8c69ef7 100644 --- a/liteclient/generated.go +++ b/liteclient/generated.go @@ -1,6 +1,5 @@ package liteclient - -// Code autogenerated. DO NOT EDIT. +// Code autogenerated. DO NOT EDIT. import ( "bytes" @@ -205,6 +204,62 @@ func (t *TonNodeZeroStateIdExtC) UnmarshalTL(r io.Reader) error { return nil } +type TonNodeShardPublicOverlayIdC struct { + Workchain uint32 + Shard uint64 + ZeroStateFileHash tl.Int256 +} + +func (t TonNodeShardPublicOverlayIdC) MarshalTL() ([]byte, error) { + var ( + err error + b []byte + ) + buf := new(bytes.Buffer) + b, err = tl.Marshal(t.Workchain) + if err != nil { + return nil, err + } + _, err = buf.Write(b) + if err != nil { + return nil, err + } + b, err = tl.Marshal(t.Shard) + if err != nil { + return nil, err + } + _, err = buf.Write(b) + if err != nil { + return nil, err + } + b, err = tl.Marshal(t.ZeroStateFileHash) + if err != nil { + return nil, err + } + _, err = buf.Write(b) + if err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +func (t *TonNodeShardPublicOverlayIdC) UnmarshalTL(r io.Reader) error { + var err error + err = tl.Unmarshal(r, &t.Workchain) + if err != nil { + return err + } + err = tl.Unmarshal(r, &t.Shard) + if err != nil { + return err + } + err = tl.Unmarshal(r, &t.ZeroStateFileHash) + if err != nil { + return err + } + return nil +} + type AdnlMessage struct { tl.SumType AdnlMessageQuery struct { diff --git a/liteclient/lite_api.tl b/liteclient/lite_api.tl index 34814de1..581b2b70 100644 --- a/liteclient/lite_api.tl +++ b/liteclient/lite_api.tl @@ -18,6 +18,7 @@ tonNode.blockId#b7cdb167 workchain:int shard:long seqno:int = tonNode.BlockId; tonNode.blockIdExt#6752eb78 workchain:int shard:long seqno:int root_hash:int256 file_hash:int256 = tonNode.BlockIdExt; tonNode.zeroStateIdExt#1d7235ae workchain:int root_hash:int256 file_hash:int256 = tonNode.ZeroStateIdExt; +tonNode.shardPublicOverlayId#4d9ed329 workchain:int shard:long zero_state_file_hash:int256 = tonNode.ShardPublicOverlayId; adnl.message.query#b48bf97a query_id:int256 query:bytes = adnl.Message; adnl.message.answer#0fac8416 query_id:int256 answer:bytes = adnl.Message; diff --git a/liteclient/overlay_id.go b/liteclient/overlay_id.go new file mode 100644 index 00000000..4b6fc239 --- /dev/null +++ b/liteclient/overlay_id.go @@ -0,0 +1,52 @@ +package liteclient + +import ( + "crypto/sha256" + "encoding/binary" + + "github.com/tonkeeper/tongo/tl" + "github.com/tonkeeper/tongo/tlb" +) + +type OverlayID struct { + Workchain int32 + Shard int64 + ZeroStateFileHash tlb.Bits256 +} + +// FullID computes an ID of the overlay that is used to represent overlay in the TON overlay network. +func (o OverlayID) FullID() ([]byte, error) { + overlayID := TonNodeShardPublicOverlayIdC{ + Workchain: uint32(o.Workchain), + Shard: uint64(o.Shard), + ZeroStateFileHash: tl.Int256(o.ZeroStateFileHash), + } + m, err := overlayID.MarshalTL() + if err != nil { + return nil, err + } + var id [4]byte + binary.LittleEndian.PutUint32(id[:], uint32(1302254377)) + hasher := sha256.New() + hasher.Write(id[:]) + hasher.Write(m) + return hasher.Sum(nil), nil +} + +func (o OverlayID) ComputeShortID() (tl.Int256, error) { + m, err := o.FullID() + if err != nil { + return tl.Int256{}, err + } + var id [4]byte + binary.LittleEndian.PutUint32(id[:], uint32(884622795)) // pubkey_overlay + hasher := sha256.New() + hasher.Write(id[:]) + hasher.Write([]byte{32}) + hasher.Write(m) + hasher.Write([]byte{0, 0, 0}) + hash := hasher.Sum(nil) + var h tl.Int256 + copy(h[:], hash[:]) + return h, nil +} diff --git a/liteclient/overlay_id_test.go b/liteclient/overlay_id_test.go new file mode 100644 index 00000000..b119d46b --- /dev/null +++ b/liteclient/overlay_id_test.go @@ -0,0 +1,55 @@ +package liteclient + +import ( + "encoding/base64" + "encoding/hex" + "testing" + + "github.com/tonkeeper/tongo/tlb" +) + +func TestOverlayID_FullID(t *testing.T) { + bytes, err := base64.StdEncoding.DecodeString("XplPz01CXAps5qeSWUtxcyBfdAo5zVb1N979KLSKD24=") + if err != nil { + panic(err) + } + var zeroStateFileHash tlb.Bits256 + copy(zeroStateFileHash[:], bytes) + + tests := []struct { + name string + overlayID OverlayID + want string + }{ + { + name: "masterchain", + overlayID: OverlayID{ + Workchain: -1, + Shard: -9223372036854775808, + ZeroStateFileHash: zeroStateFileHash, + }, + want: "c684cd30e81e3ad7159bbef689daea0021dae2b90dd1a65d14fe8cc11f3523b1", + }, + { + name: "basechain", + overlayID: OverlayID{ + Workchain: 0, + Shard: -9223372036854775808, + ZeroStateFileHash: zeroStateFileHash, + }, + want: "9435c212dc0ec51dac686410e9ba98f4b6fc7d5f08aeb9164109178eb950ddec", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + shortID, err := tt.overlayID.FullID() + if err != nil { + t.Fatal(err) + } + hexStr := hex.EncodeToString(shortID) + if hexStr != tt.want { + t.Errorf("got %s, want %s", hexStr, tt.want) + } + }) + } +}