Skip to content

Commit 9c6ebb4

Browse files
Add tongo.ParseTlbMessage() and change some funcs to accept tlb.Message
1 parent ac3b4ac commit 9c6ebb4

File tree

5 files changed

+109
-15
lines changed

5 files changed

+109
-15
lines changed

liteapi/utils.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ func VerifySendMessagePayload(payload []byte) error {
1313
return err
1414
}
1515

16+
// VerifySendMessage verifies that the given message is an external message ready to be sent to the blockchain.
17+
func VerifySendMessage(msg *tlb.Message) error {
18+
if msg.Info.SumType != "ExtInMsgInfo" {
19+
return fmt.Errorf("external message must begin with ext_in_msg_info$10")
20+
}
21+
return nil
22+
}
23+
1624
// ConvertSendMessagePayloadToMessage converts the given payload to a tlb.Message.
1725
// It also verifies that the message is an external message ready to be sent to the blockchain.
1826
func ConvertSendMessagePayloadToMessage(payload []byte) (*tlb.Message, error) {
@@ -31,8 +39,8 @@ func ConvertSendMessagePayloadToMessage(payload []byte) (*tlb.Message, error) {
3139
if err := tlb.Unmarshal(root, &msg); err != nil {
3240
return nil, fmt.Errorf("external message is not a tlb.Message")
3341
}
34-
if msg.Info.SumType != "ExtInMsgInfo" {
35-
return nil, fmt.Errorf("external message must begin with ext_in_msg_info$10")
42+
if err := VerifySendMessage(&msg); err != nil {
43+
return nil, err
3644
}
3745
return &msg, nil
3846
}

message.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package tongo
2+
3+
import (
4+
"encoding/base64"
5+
"encoding/hex"
6+
"fmt"
7+
8+
"github.com/tonkeeper/tongo/boc"
9+
"github.com/tonkeeper/tongo/tlb"
10+
"github.com/tonkeeper/tongo/ton"
11+
)
12+
13+
func decodeBoc(bocStr string) ([]byte, error) {
14+
bocData, err := base64.StdEncoding.DecodeString(bocStr)
15+
if err != nil {
16+
return hex.DecodeString(bocStr)
17+
}
18+
return bocData, nil
19+
}
20+
21+
// Message contains a tlb.Message, its boc representation and a Cell.
22+
type Message struct {
23+
Boc []byte
24+
TlbMsg *tlb.Message
25+
Cell *boc.Cell
26+
}
27+
28+
// ParseTlbMessage returns a Message unmarshalled from the given boc string.
29+
// The boc string can be either in base64 or hex format.
30+
func ParseTlbMessage(bocStr string) (*Message, error) {
31+
b, err := decodeBoc(bocStr)
32+
if err != nil {
33+
return nil, err
34+
}
35+
cells, err := boc.DeserializeBoc(b)
36+
if err != nil {
37+
return nil, err
38+
}
39+
if len(cells) != 1 {
40+
return nil, fmt.Errorf("invalid message boc")
41+
}
42+
var msg tlb.Message
43+
if err := tlb.Unmarshal(cells[0], &msg); err != nil {
44+
return nil, err
45+
}
46+
cells[0].ResetCounters()
47+
return &Message{Boc: b, TlbMsg: &msg, Cell: cells[0]}, nil
48+
}
49+
50+
func (m *Message) DestinationAccountID() (ton.AccountID, error) {
51+
var dest tlb.MsgAddress
52+
switch m.TlbMsg.Info.SumType {
53+
case "IntMsgInfo":
54+
dest = m.TlbMsg.Info.IntMsgInfo.Dest
55+
case "ExtInMsgInfo":
56+
dest = m.TlbMsg.Info.ExtInMsgInfo.Dest
57+
case "ExtOutMsgInfo":
58+
dest = m.TlbMsg.Info.ExtOutMsgInfo.Dest
59+
}
60+
accountID, err := ton.AccountIDFromTlb(dest)
61+
if err != nil {
62+
return ton.AccountID{}, err
63+
}
64+
if accountID == nil {
65+
return ton.AccountID{}, fmt.Errorf("failed to extract the destination address")
66+
}
67+
return ton.AccountID{}, nil
68+
}

wallet/messages.go

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ type RawMessage struct {
4444
Mode byte
4545
}
4646

47+
// ToTlbMessage converts a RawMessage to a tlb.Message.
48+
func (rm *RawMessage) ToTlbMessage() (*tlb.Message, error) {
49+
var msg tlb.Message
50+
if err := tlb.Unmarshal(rm.Message, &msg); err != nil {
51+
return nil, err
52+
}
53+
return &msg, nil
54+
}
55+
4756
type PayloadV1toV4 []RawMessage
4857
type PayloadHighload []RawMessage
4958

@@ -59,20 +68,16 @@ func (body *SignedMsgBody) Verify(publicKey ed25519.PublicKey) error {
5968
return fmt.Errorf("failed to verify msg signature")
6069
}
6170

62-
func extractSignedMsgBody(msg *boc.Cell) (*SignedMsgBody, error) {
63-
var m tlb.Message
64-
if err := tlb.Unmarshal(msg, &m); err != nil {
65-
return nil, err
66-
}
71+
func extractSignedMsgBody(msg *tlb.Message) (*SignedMsgBody, error) {
72+
bodyCell := boc.Cell(msg.Body.Value)
6773
msgBody := SignedMsgBody{}
68-
bodyCell := boc.Cell(m.Body.Value)
6974
if err := tlb.Unmarshal(&bodyCell, &msgBody); err != nil {
7075
return nil, err
7176
}
7277
return &msgBody, nil
7378
}
7479

75-
func DecodeMessageV4(msg *boc.Cell) (*MessageV4, error) {
80+
func DecodeMessageV4(msg *tlb.Message) (*MessageV4, error) {
7681
signedMsgBody, err := extractSignedMsgBody(msg)
7782
if err != nil {
7883
return nil, err
@@ -89,7 +94,7 @@ func decodeMessageV4(body *SignedMsgBody) (*MessageV4, error) {
8994
return &msgv4, nil
9095
}
9196

92-
func DecodeMessageV3(msg *boc.Cell) (*MessageV3, error) {
97+
func DecodeMessageV3(msg *tlb.Message) (*MessageV3, error) {
9398
signedMsgBody, err := extractSignedMsgBody(msg)
9499
if err != nil {
95100
return nil, err
@@ -106,7 +111,7 @@ func decodeMessageV3(body *SignedMsgBody) (*MessageV3, error) {
106111
return &msgv3, nil
107112
}
108113

109-
func DecodeHighloadV2Message(msg *boc.Cell) (*HighloadV2Message, error) {
114+
func DecodeHighloadV2Message(msg *tlb.Message) (*HighloadV2Message, error) {
110115
signedMsgBody, err := extractSignedMsgBody(msg)
111116
if err != nil {
112117
return nil, err
@@ -124,7 +129,10 @@ func decodeHighloadV2Message(body *SignedMsgBody) (*HighloadV2Message, error) {
124129
}
125130

126131
// ExtractRawMessages extracts a list of RawMessages from an external message.
127-
func ExtractRawMessages(ver Version, msg *boc.Cell) (PayloadV1toV4, error) {
132+
func ExtractRawMessages(ver Version, msg *tlb.Message) (PayloadV1toV4, error) {
133+
if msg == nil {
134+
return nil, fmt.Errorf("msg is nil")
135+
}
128136
switch ver {
129137
case V4R1, V4R2:
130138
v4, err := DecodeMessageV4(msg)
@@ -154,7 +162,10 @@ func ExtractRawMessages(ver Version, msg *boc.Cell) (PayloadV1toV4, error) {
154162
// was signed by the given public key of a wallet contract.
155163
// On success, it returns nil.
156164
// Otherwise, it returns an error.
157-
func VerifySignature(ver Version, msg *boc.Cell, publicKey ed25519.PublicKey) error {
165+
func VerifySignature(ver Version, msg *tlb.Message, publicKey ed25519.PublicKey) error {
166+
if msg == nil {
167+
return fmt.Errorf("msg is nil")
168+
}
158169
switch ver {
159170
case V3R1, V3R2, V4R1, V4R2, HighLoadV2R2:
160171
signedMsgBody, err := extractSignedMsgBody(msg)

wallet/messages_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,11 @@ func TestExtractRawMessages(t *testing.T) {
8181
if err != nil {
8282
t.Fatal(err)
8383
}
84-
rawMessages, err := ExtractRawMessages(tt.ver, c[0])
84+
var msg tlb.Message
85+
if err := tlb.Unmarshal(c[0], &msg); err != nil {
86+
t.Fatal(err)
87+
}
88+
rawMessages, err := ExtractRawMessages(tt.ver, &msg)
8589
if err != nil {
8690
t.Fatal(err)
8791
}

wallet/models.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,11 @@ func init() {
6868
// GetWalletVersion returns a wallet version by the given state of an account and an incoming message to the account.
6969
// An incoming message is needed in case when a wallet has not been initialized yet.
7070
// In this case, we take its code from the message's StateInit.
71-
func GetWalletVersion(state tlb.ShardAccount, msg tlb.Message) (Version, bool, error) {
71+
func GetWalletVersion(state tlb.ShardAccount, msg *tlb.Message) (Version, bool, error) {
7272
if state.Account.SumType == "AccountNone" || state.Account.Account.Storage.State.SumType == "AccountUninit" {
73+
if msg == nil {
74+
return 0, false, fmt.Errorf("account is not initialized")
75+
}
7376
if !msg.Init.Exists {
7477
return 0, false, fmt.Errorf("account is not initialized")
7578
}

0 commit comments

Comments
 (0)