Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decode ext in msg for highload wallet v3r1 #248

Merged
merged 1 commit into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 131 additions & 1 deletion abi/generated_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,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 @@ -1223,7 +1353,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 @@ -63,6 +64,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 @@ -89,6 +91,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 @@ -114,6 +117,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 @@ -150,6 +154,7 @@ var resultTypes = []interface{}{
&GetEditorResult{},
&GetFullDomainResult{},
&GetJettonDataResult{},
&GetLastCleanTimeResult{},
&GetLastFillUpTimeResult{},
&GetLockerBillDataResult{},
&GetLockerDataResult{},
Expand Down Expand Up @@ -191,6 +196,7 @@ var resultTypes = []interface{}{
&GetTelemintAuctionConfigResult{},
&GetTelemintAuctionStateResult{},
&GetTelemintTokenNameResult{},
&GetTimeoutResult{},
&GetTorrentHashResult{},
&GetValidatorControllerDataResult{},
&GetWalletAddressResult{},
Expand Down Expand Up @@ -730,6 +736,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 @@ -2294,6 +2333,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 @@ -470,6 +474,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 @@ -755,7 +763,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 @@ -941,6 +953,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
Loading