Skip to content

Commit

Permalink
Decode ext in msg for highload wallet v3r1
Browse files Browse the repository at this point in the history
  • Loading branch information
aleksej-paschenko committed Apr 12, 2024
1 parent b1c716c commit f9feb54
Show file tree
Hide file tree
Showing 7 changed files with 302 additions and 8 deletions.
132 changes: 131 additions & 1 deletion abi/generated_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1062,6 +1062,136 @@ func TestDecodeExternalIn(t *testing.T) {
wantOpName string
wantValue func() any
}{
{
name: "highload wallet v3 - jetton transfer",
interfaces: []ContractInterface{WalletHighloadV3R1},
wantOpName: "HighloadWalletSignedV3",
boc: "te6ccgECBAEAAQwAAcWIAdJ6F/XoVT62daLt612xzAWuJPA9cAk+F5bifcMnw3uuBJ4krVRznuQJVWa7b5YZXZbyhQ9ypfRice+gJkPTVJGL6qLnQi57P4N9vIIvjbTxPvBBeSn5Vdk4jbhh2DI5iDQBASUAAAABA//61AAAAADMMooIAB9EAgFoYgBch4rJB2cPeC7H+qWhc5NL4Tn35ZEO/PqhjjJtLxbjISC+vCAAAAAAAAAAAAAAAAAAAQMArg+KfqUAAAAAAAAAADD0JAgA2ZpktQsYby0n9cV5VWOFINBjScIU2HdondFsK3lDpEEAGzNMlqFjDeWk/rivKqxwpBoMaThCmw7tE7othW8odIgII8NGAA==",
wantValue: func() any {
b := HighloadWalletSignedV3ExtInMsgBody{
Signature: tlb.Bits512{},
Msg: HighloadV3MsgInner{
SubwalletId: 1,
SendMode: 3,
MessageToSend: MessageRelaxed{
SumType: "MessageInternal",
MessageInternal: struct {
IhrDisabled bool
Bounce bool
Bounced bool
Src tlb.MsgAddress
Dest tlb.MsgAddress
Value tlb.CurrencyCollection
IhrFee tlb.Grams
FwdFee tlb.Grams
CreatedLt uint64
CreatedAt uint32
Init *tlb.EitherRef[tlb.StateInit] `tlb:"maybe"`
Body tlb.EitherRef[InMsgBody]
}{
IhrDisabled: true,
Bounce: true,
Src: tlb.MsgAddress{SumType: "AddrNone"},
Dest: mustToMsgAddress("0:b90f15920ece1ef05d8ff54b42e72697c273efcb221df9f5431c64da5e2dc642"),
Value: tlb.CurrencyCollection{
Grams: tlb.Grams(400000000),
},
IhrFee: 0,
FwdFee: 0,
CreatedLt: 0,
CreatedAt: 0,
Init: nil,
Body: tlb.EitherRef[InMsgBody]{
IsRight: true,
Value: InMsgBody{
SumType: "JettonTransfer",
OpCode: pointer(uint32(260734629)),
Value: JettonTransferMsgBody{
QueryId: 0,
Amount: mustToVarUInteger16("1000000"),
Destination: pointer(ton.MustParseAccountID("0:6ccd325a858c379693fae2bcaab1c2906831a4e10a6c3bb44ee8b615bca1d220")).ToMsgAddress(),
ResponseDestination: pointer(ton.MustParseAccountID("0:6ccd325a858c379693fae2bcaab1c2906831a4e10a6c3bb44ee8b615bca1d220")).ToMsgAddress(),
CustomPayload: nil,
ForwardTonAmount: mustToVarUInteger16("300000000"),
ForwardPayload: tlb.EitherRef[JettonPayload]{
IsRight: false,
},
},
},
},
},
},
QueryId: HighloadV3QueryId{
Shift: 8191,
BitNumber: 362,
},
CreatedAt: 1712932100,
Timeout: 1000,
},
}
sig, _ := hex.DecodeString("8801d27a17f5e8553eb675a2edeb5db1cc05ae24f03d70093e1796e27dc327c37bae049e24ad54739ee4095566bb6f96195d96f2850f72a5f46271efa02643d3")
copy(b.Signature[:], sig)
return b
},
},
{
name: "highload wallet v3 - ton transfer",
interfaces: []ContractInterface{WalletHighloadV3R1},
wantOpName: "HighloadWalletSignedV3",
boc: "b5ee9c720101030100b10001c588004a3c91f996eb4f3f3799bde7f22005b44a622abcd3ab5ef4b793bf996422542c02b30423be3ecfd979bb1d41e0e8bf5154e58af1e3dea23e35edfd837919c34bb530f91a7c3ae7adc9aac317a5a630b2c52a82bf889a83a9a4a48471247bacd874010125000010ad0300219600000000cc27b04c0070840200664200126de9fd8617ede66d3dd8eb09d01259144017ca508a603776919e6a83ed24581cc4b40000000000000000000000000000",
wantValue: func() any {
b := HighloadWalletSignedV3ExtInMsgBody{
Signature: tlb.Bits512{},
Msg: HighloadV3MsgInner{
SubwalletId: 4269,
SendMode: 3,
MessageToSend: MessageRelaxed{
SumType: "MessageInternal",
MessageInternal: struct {
IhrDisabled bool
Bounce bool
Bounced bool
Src tlb.MsgAddress
Dest tlb.MsgAddress
Value tlb.CurrencyCollection
IhrFee tlb.Grams
FwdFee tlb.Grams
CreatedLt uint64
CreatedAt uint32
Init *tlb.EitherRef[tlb.StateInit] `tlb:"maybe"`
Body tlb.EitherRef[InMsgBody]
}{
IhrDisabled: true,
Src: tlb.MsgAddress{
SumType: "AddrNone",
},
Dest: mustToMsgAddress("0:24dbd3fb0c2fdbccda7bb1d613a024b228802f94a114c06eed233cd507da48b0"),
Value: tlb.CurrencyCollection{
Grams: tlb.Grams(10000000),
},
IhrFee: 0,
FwdFee: 0,
CreatedLt: 0,
CreatedAt: 0,
Init: nil,
Body: tlb.EitherRef[InMsgBody]{
IsRight: false,
},
},
},
QueryId: HighloadV3QueryId{
Shift: 4,
BitNumber: 203,
},
CreatedAt: 1712576550,
Timeout: 3600,
},
}
sig, _ := hex.DecodeString("88004a3c91f996eb4f3f3799bde7f22005b44a622abcd3ab5ef4b793bf996422542c02b30423be3ecfd979bb1d41e0e8bf5154e58af1e3dea23e35edfd837919")
copy(b.Signature[:], sig)
return b
},
},
{
name: "wallet v4",
interfaces: []ContractInterface{WalletV4R2},
Expand Down Expand Up @@ -1210,7 +1340,7 @@ func TestDecodeExternalIn(t *testing.T) {
t.Fatalf("MessageDecoder() error: %v", err)
}
if *opName != tt.wantOpName {
t.Fatalf("got opname: %v, want: %v", opName, tt.wantOpName)
t.Fatalf("got opname: %v, want: %v", *opName, tt.wantOpName)
}
b, err := json.Marshal(value)
if err != nil {
Expand Down
72 changes: 72 additions & 0 deletions abi/get_methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ var KnownGetMethodsDecoder = map[string][]func(tlb.VmStack) (string, any, error)
"get_editor": {DecodeGetEditorResult},
"get_full_domain": {DecodeGetFullDomainResult},
"get_jetton_data": {DecodeGetJettonDataResult},
"get_last_clean_time": {DecodeGetLastCleanTimeResult},
"get_last_fill_up_time": {DecodeGetLastFillUpTimeResult},
"get_locker_bill_data": {DecodeGetLockerBillDataResult},
"get_locker_data": {DecodeGetLockerDataResult},
Expand Down Expand Up @@ -61,6 +62,7 @@ var KnownGetMethodsDecoder = map[string][]func(tlb.VmStack) (string, any, error)
"get_telemint_auction_config": {DecodeGetTelemintAuctionConfigResult},
"get_telemint_auction_state": {DecodeGetTelemintAuctionStateResult},
"get_telemint_token_name": {DecodeGetTelemintTokenNameResult},
"get_timeout": {DecodeGetTimeoutResult},
"get_torrent_hash": {DecodeGetTorrentHashResult},
"get_validator_controller_data": {DecodeGetValidatorControllerDataResult},
"get_wallet_address": {DecodeGetWalletAddressResult},
Expand All @@ -86,6 +88,7 @@ var KnownSimpleGetMethods = map[int][]func(ctx context.Context, executor Executo
78748: {GetPublicKey},
80035: {GetLpData},
80697: {GetAuctionInfo},
80822: {GetLastCleanTime},
81467: {GetSubwalletId},
81490: {GetNextProofInfo},
81689: {GetPoolData},
Expand All @@ -110,6 +113,7 @@ var KnownSimpleGetMethods = map[int][]func(ctx context.Context, executor Executo
103232: {GetValidatorControllerData},
104122: {GetLpMiningData},
104346: {GetStorageParams},
105070: {GetTimeout},
106029: {GetJettonData},
107305: {GetLockupData},
107307: {GetMultisigData},
Expand Down Expand Up @@ -146,6 +150,7 @@ var resultTypes = []interface{}{
&GetEditorResult{},
&GetFullDomainResult{},
&GetJettonDataResult{},
&GetLastCleanTimeResult{},
&GetLastFillUpTimeResult{},
&GetLockerBillDataResult{},
&GetLockerDataResult{},
Expand Down Expand Up @@ -185,6 +190,7 @@ var resultTypes = []interface{}{
&GetTelemintAuctionConfigResult{},
&GetTelemintAuctionStateResult{},
&GetTelemintTokenNameResult{},
&GetTimeoutResult{},
&GetTorrentHashResult{},
&GetValidatorControllerDataResult{},
&GetWalletAddressResult{},
Expand Down Expand Up @@ -724,6 +730,39 @@ func DecodeGetJettonDataResult(stack tlb.VmStack) (resultType string, resultAny
return "GetJettonDataResult", result, err
}

type GetLastCleanTimeResult struct {
Timestamp uint64
}

func GetLastCleanTime(ctx context.Context, executor Executor, reqAccountID ton.AccountID) (string, any, error) {
stack := tlb.VmStack{}

// MethodID = 80822 for "get_last_clean_time" method
errCode, stack, err := executor.RunSmcMethodByID(ctx, reqAccountID, 80822, stack)
if err != nil {
return "", nil, err
}
if errCode != 0 && errCode != 1 {
return "", nil, fmt.Errorf("method execution failed with code: %v", errCode)
}
for _, f := range []func(tlb.VmStack) (string, any, error){DecodeGetLastCleanTimeResult} {
s, r, err := f(stack)
if err == nil {
return s, r, nil
}
}
return "", nil, fmt.Errorf("can not decode outputs")
}

func DecodeGetLastCleanTimeResult(stack tlb.VmStack) (resultType string, resultAny any, err error) {
if len(stack) < 1 || (stack[0].SumType != "VmStkTinyInt" && stack[0].SumType != "VmStkInt") {
return "", nil, fmt.Errorf("invalid stack format")
}
var result GetLastCleanTimeResult
err = stack.Unmarshal(&result)
return "GetLastCleanTimeResult", result, err
}

type GetLastFillUpTimeResult struct {
LastFillUpTime int64
}
Expand Down Expand Up @@ -2222,6 +2261,39 @@ func DecodeGetTelemintTokenNameResult(stack tlb.VmStack) (resultType string, res
return "GetTelemintTokenNameResult", result, err
}

type GetTimeoutResult struct {
Timeout uint32
}

func GetTimeout(ctx context.Context, executor Executor, reqAccountID ton.AccountID) (string, any, error) {
stack := tlb.VmStack{}

// MethodID = 105070 for "get_timeout" method
errCode, stack, err := executor.RunSmcMethodByID(ctx, reqAccountID, 105070, stack)
if err != nil {
return "", nil, err
}
if errCode != 0 && errCode != 1 {
return "", nil, fmt.Errorf("method execution failed with code: %v", errCode)
}
for _, f := range []func(tlb.VmStack) (string, any, error){DecodeGetTimeoutResult} {
s, r, err := f(stack)
if err == nil {
return s, r, nil
}
}
return "", nil, fmt.Errorf("can not decode outputs")
}

func DecodeGetTimeoutResult(stack tlb.VmStack) (resultType string, resultAny any, err error) {
if len(stack) < 1 || (stack[0].SumType != "VmStkTinyInt" && stack[0].SumType != "VmStkInt") {
return "", nil, fmt.Errorf("invalid stack format")
}
var result GetTimeoutResult
err = stack.Unmarshal(&result)
return "GetTimeoutResult", result, err
}

type GetTorrentHashResult struct {
TorrentHash tlb.Int257
}
Expand Down
18 changes: 17 additions & 1 deletion abi/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,10 @@ var methodInvocationOrder = []MethodDescription{
Name: "get_jetton_data",
InvokeFn: GetJettonData,
},
{
Name: "get_last_clean_time",
InvokeFn: GetLastCleanTime,
},
{
Name: "get_last_fill_up_time",
InvokeFn: GetLastFillUpTime,
Expand Down Expand Up @@ -462,6 +466,10 @@ var methodInvocationOrder = []MethodDescription{
Name: "get_telemint_token_name",
InvokeFn: GetTelemintTokenName,
},
{
Name: "get_timeout",
InvokeFn: GetTimeout,
},
{
Name: "get_torrent_hash",
InvokeFn: GetTorrentHash,
Expand Down Expand Up @@ -747,7 +755,11 @@ var knownContracts = map[ton.Bits256]knownContractDescription{
},
ton.MustParseHash("11acad7955844090f283bf238bc1449871f783e7cc0979408d3f4859483e8525"): {
contractInterfaces: []ContractInterface{WalletHighloadV3R1},
getMethods: []InvokeFn{},
getMethods: []InvokeFn{
GetPublicKey,
GetSubwalletId,
GetTimeout,
},
},
ton.MustParseHash("1bd9c5a39bffb7a0f341588b5dd92b813a842bf65ef14109382200ceaf8f72df"): {
contractInterfaces: []ContractInterface{NftAuctionGetgemsV3},
Expand Down Expand Up @@ -933,6 +945,10 @@ func (c ContractInterface) IntMsgs() []msgDecoderFunc {

func (c ContractInterface) ExtInMsgs() []msgDecoderFunc {
switch c {
case WalletHighloadV3R1:
return []msgDecoderFunc{
decodeFuncHighloadWalletSignedV3ExtInMsgBody,
}
case WalletV3R1:
return []msgDecoderFunc{
decodeFuncWalletSignedV3ExtInMsgBody,
Expand Down
1 change: 1 addition & 0 deletions abi/messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ The list below contains the supported message operations, their names and opcode
| FinishUncooperativeChannelClose| 0x25432a91 |
| GetRoyaltyParams| 0x693d3950 |
| GetStaticData| 0x2fcb26a2 |
| HighloadWalletSignedV3| 0x00000000 |
| InitPaymentChannel| 0x0e0620c2 |
| JettonBurn| 0x595f07bc |
| JettonBurnNotification| 0x7bdd97de |
Expand Down
22 changes: 16 additions & 6 deletions abi/messages_generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -1877,18 +1877,22 @@ var (
decodeFuncWalletSignedV3ExtInMsgBody = decodeMsg(tlb.Tag{Val: 0x00000000, Len: 0}, WalletSignedV3ExtInMsgOp, WalletSignedV3ExtInMsgBody{})
// 0x00000000
decodeFuncWalletSignedV4ExtInMsgBody = decodeMsg(tlb.Tag{Val: 0x00000000, Len: 0}, WalletSignedV4ExtInMsgOp, WalletSignedV4ExtInMsgBody{})
// 0x00000000
decodeFuncHighloadWalletSignedV3ExtInMsgBody = decodeMsg(tlb.Tag{Val: 0x00000000, Len: 0}, HighloadWalletSignedV3ExtInMsgOp, HighloadWalletSignedV3ExtInMsgBody{})
)

var opcodedMsgExtInDecodeFunctions = map[uint32]msgDecoderFunc{}

const (
WalletSignedV3ExtInMsgOp MsgOpName = "WalletSignedV3"
WalletSignedV4ExtInMsgOp MsgOpName = "WalletSignedV4"
WalletSignedV3ExtInMsgOp MsgOpName = "WalletSignedV3"
WalletSignedV4ExtInMsgOp MsgOpName = "WalletSignedV4"
HighloadWalletSignedV3ExtInMsgOp MsgOpName = "HighloadWalletSignedV3"
)

const (
WalletSignedV3ExtInMsgOpCode MsgOpCode = 0x00000000
WalletSignedV4ExtInMsgOpCode MsgOpCode = 0x00000000
WalletSignedV3ExtInMsgOpCode MsgOpCode = 0x00000000
WalletSignedV4ExtInMsgOpCode MsgOpCode = 0x00000000
HighloadWalletSignedV3ExtInMsgOpCode MsgOpCode = 0x00000000
)

type WalletSignedV3ExtInMsgBody struct {
Expand All @@ -1908,9 +1912,15 @@ type WalletSignedV4ExtInMsgBody struct {
Payload WalletV1ToV4Payload
}

type HighloadWalletSignedV3ExtInMsgBody struct {
Signature tlb.Bits512
Msg HighloadV3MsgInner `tlb:"^"`
}

var KnownMsgExtInTypes = map[string]any{
WalletSignedV3ExtInMsgOp: WalletSignedV3ExtInMsgBody{},
WalletSignedV4ExtInMsgOp: WalletSignedV4ExtInMsgBody{},
WalletSignedV3ExtInMsgOp: WalletSignedV3ExtInMsgBody{},
WalletSignedV4ExtInMsgOp: WalletSignedV4ExtInMsgBody{},
HighloadWalletSignedV3ExtInMsgOp: HighloadWalletSignedV3ExtInMsgBody{},
}

var (
Expand Down
Loading

0 comments on commit f9feb54

Please sign in to comment.