Skip to content
Draft
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
474 changes: 237 additions & 237 deletions abi/get_methods.go

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions abi/parser/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -410,14 +410,15 @@ func buildInputStackValues(r []StackRecord) string {

func buildOutputStackCheck(r []StackRecord, isFixed bool) string {
var builder strings.Builder
n := len(r)
if isFixed {
builder.WriteString(fmt.Sprintf("if len(stack) != %d ", len(r)))
builder.WriteString(fmt.Sprintf("if stack.Len() != %d ", n))
} else {
builder.WriteString(fmt.Sprintf("if len(stack) < %d ", len(r)))
builder.WriteString(fmt.Sprintf("if stack.Len() < %d ", n))
}
for i, s := range r {
nullableCheck := ""
stackType := fmt.Sprintf("stack[%d].SumType", i)
stackType := fmt.Sprintf("stack.Peek(%d).SumType", n-1-i)
if s.Nullable || (s.XMLName.Local == "tuple" && s.List) {
nullableCheck = fmt.Sprintf(" && %s != \"VmStkNull\"", stackType)
}
Expand Down
10 changes: 5 additions & 5 deletions contract/dns/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ func (d *DNS) Resolve(ctx context.Context, domain string) (map[DNSCategory]tlb.D

func (d *DNS) resolve(ctx context.Context, resolver ton.AccountID, dom []byte) (map[DNSCategory]tlb.DNSRecord, error) {
n := int64(len(dom))
stack := tlb.VmStack{}
argStack := tlb.VmStack{}
val, err := tlb.TlbStructToVmCellSlice(dom)
if err != nil {
return nil, err
}
stack.Put(val)
stack.Put(tlb.VmStackValue{SumType: "VmStkInt", VmStkInt: tlb.Int257{}})
exitCode, stack, err := d.executor.RunSmcMethodByID(ctx, resolver, 123660, stack)
argStack.Put(val)
argStack.Put(tlb.VmStackValue{SumType: "VmStkInt", VmStkInt: tlb.Int257{}})
exitCode, stack, err := d.executor.RunSmcMethodByID(ctx, resolver, 123660, argStack)
if err != nil && strings.Contains(err.Error(), "method execution failed") {
return nil, fmt.Errorf("%w: %v", ErrNotResolved, err)
}
Expand All @@ -86,7 +86,7 @@ func (d *DNS) resolve(ctx context.Context, resolver ton.AccountID, dom []byte) (
ResolvedBits int64
Result boc.Cell
}
if len(stack) == 2 && stack[0].SumType == "VmStkTinyInt" && stack[0].VmStkTinyInt == 0 && stack[1].SumType == "VmStkNull" {
if stack.Len() == 2 && stack.Peek(1).SumType == "VmStkTinyInt" && stack.Peek(1).VmStkTinyInt == 0 && stack.Peek(0).SumType == "VmStkNull" {
return nil, ErrNotResolved
}
err = stack.Unmarshal(&result)
Expand Down
6 changes: 3 additions & 3 deletions examples/tvm/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func main() {
panic(err)
}

code, res, err := emulator.RunSmcMethod(context.Background(), account.ID, "get_nft_address_by_index", tlb.VmStack{val})
code, res, err := emulator.RunSmcMethod(context.Background(), account.ID, "get_nft_address_by_index", val.ToStack())
if err != nil {
panic(err)
}
Expand All @@ -46,11 +46,11 @@ func main() {
panic("TVM execution failed")
}

if len(res) != 1 || res[0].SumType != "VmStkSlice" {
if res.Len() != 1 || res.Peek(0).SumType != "VmStkSlice" {
panic("invalid stack data")
}

c := res[0].VmStkSlice.Cell()
c := res.Peek(0).VmStkSlice.Cell()
var a tlb.MsgAddress
err = tlb.Unmarshal(c, &a)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion liteapi/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ func (c *Client) RunSmcMethodByID(ctx context.Context, accountID ton.AccountID,
}
var result tlb.VmStack
if res.ExitCode == 4294967040 { //-256
return res.ExitCode, nil, ErrAccountNotFound
return res.ExitCode, tlb.VmStack{}, ErrAccountNotFound
}
cells, err := boc.DeserializeBoc(res.Result)
if err != nil {
Expand Down
11 changes: 6 additions & 5 deletions liteapi/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,16 @@ func (c *Client) DnsResolve(ctx context.Context, address ton.AccountID, domain s
if errCode != 0 && errCode != 1 {
return 0, nil, fmt.Errorf("method execution failed with code: %v", errCode)
}
if len(stack) != 2 ||
stack[0].SumType != "VmStkTinyInt" ||
(stack[1].SumType != "VmStkCell" && stack[1].SumType != "VmStkNull") {
if stack.Len() != 2 ||
stack.Peek(1).SumType != "VmStkTinyInt" ||
(stack.Peek(0).SumType != "VmStkCell" && stack.Peek(0).SumType != "VmStkNull") {
return 0, nil, fmt.Errorf("invalid stack")
}
if stack[1].SumType == "VmStkNull" {
if stack.Peek(0).SumType == "VmStkNull" {
return 0, nil, nil
}
return int(stack[0].VmStkTinyInt), &stack[1].VmStkCell.Value, err
topVal := stack.Peek(0).VmStkCell.Value
return int(stack.Peek(1).VmStkTinyInt), &topVal, err
}

func (c *Client) GetRootDNS(ctx context.Context) (ton.AccountID, error) {
Expand Down
34 changes: 18 additions & 16 deletions liteapi/jetton.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,18 @@ func (c *Client) GetJettonWallet(ctx context.Context, master, owner ton.AccountI
if err != nil {
return ton.AccountID{}, err
}
errCode, stack, err := c.RunSmcMethod(ctx, master, "get_wallet_address", tlb.VmStack{val})
errCode, stack, err := c.RunSmcMethod(ctx, master, "get_wallet_address", val.ToStack())
if err != nil {
return ton.AccountID{}, err
}
if errCode != 0 && errCode != 1 {
return ton.AccountID{}, fmt.Errorf("method execution failed with code: %v", errCode)
}
if len(stack) != 1 || stack[0].SumType != "VmStkSlice" {
if stack.Len() != 1 || stack.Peek(0).SumType != "VmStkSlice" {
return ton.AccountID{}, fmt.Errorf("invalid stack")
}
var res tlb.MsgAddress
err = stack[0].VmStkSlice.UnmarshalToTlbStruct(&res)
err = stack.Peek(0).VmStkSlice.UnmarshalToTlbStruct(&res)
if err != nil {
return ton.AccountID{}, err
}
Expand All @@ -58,14 +58,15 @@ func (c *Client) GetJettonData(ctx context.Context, master ton.AccountID) (tep64
if errCode != 0 && errCode != 1 {
return tep64.Metadata{}, fmt.Errorf("method execution failed with code: %v", errCode)
}
if len(stack) != 5 || (stack[0].SumType != "VmStkTinyInt" && stack[0].SumType != "VmStkInt") ||
stack[1].SumType != "VmStkTinyInt" ||
stack[2].SumType != "VmStkSlice" ||
stack[3].SumType != "VmStkCell" ||
stack[4].SumType != "VmStkCell" {
if stack.Len() != 5 || (stack.Peek(4).SumType != "VmStkTinyInt" && stack.Peek(4).SumType != "VmStkInt") ||
stack.Peek(3).SumType != "VmStkTinyInt" ||
stack.Peek(2).SumType != "VmStkSlice" ||
stack.Peek(1).SumType != "VmStkCell" ||
stack.Peek(0).SumType != "VmStkCell" {
return tep64.Metadata{}, fmt.Errorf("invalid stack")
}
cell := &stack[3].VmStkCell.Value
elem1 := stack.Peek(1)
cell := &elem1.VmStkCell.Value
var content tlb.FullContent
err = tlb.Unmarshal(cell, &content)
if err != nil {
Expand Down Expand Up @@ -95,15 +96,16 @@ func (c *Client) GetJettonBalance(ctx context.Context, jettonWallet ton.AccountI
if errCode != 0 && errCode != 1 {
return nil, fmt.Errorf("method execution failed with code: %v", errCode)
}
if len(stack) != 4 || (stack[0].SumType != "VmStkTinyInt" && stack[0].SumType != "VmStkInt") ||
stack[1].SumType != "VmStkSlice" ||
stack[2].SumType != "VmStkSlice" ||
stack[3].SumType != "VmStkCell" {
if stack.Len() != 4 || (stack.Peek(3).SumType != "VmStkTinyInt" && stack.Peek(3).SumType != "VmStkInt") ||
stack.Peek(2).SumType != "VmStkSlice" ||
stack.Peek(1).SumType != "VmStkSlice" ||
stack.Peek(0).SumType != "VmStkCell" {
return nil, fmt.Errorf("invalid stack")
}
if stack[0].SumType == "VmStkTinyInt" {
return big.NewInt(stack[0].VmStkTinyInt), nil
bottom := stack.Peek(3)
if bottom.SumType == "VmStkTinyInt" {
return big.NewInt(bottom.VmStkTinyInt), nil
}
res := big.Int(stack[0].VmStkInt)
res := big.Int(bottom.VmStkInt)
return &res, nil
}
4 changes: 2 additions & 2 deletions liteapi/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ func (c *Client) GetSeqno(ctx context.Context, account ton.AccountID) (uint32, e
} else if errCode != 0 && errCode != 1 {
return 0, fmt.Errorf("method execution failed with code: %v", errCode)
}
if len(stack) != 1 || stack[0].SumType != "VmStkTinyInt" {
if stack.Len() != 1 || stack.Peek(0).SumType != "VmStkTinyInt" {
return 0, fmt.Errorf("invalid stack")
}
return uint32(stack[0].VmStkTinyInt), nil
return uint32(stack.Peek(0).VmStkTinyInt), nil
}
41 changes: 41 additions & 0 deletions tlb/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,47 @@ type ShardAccount struct {
Account Account `tlb:"^"`
LastTransHash Bits256
LastTransLt uint64

accountCell *boc.Cell
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Как будто бы, есть очень много мест, где ячейка может оказаться обрезанная. Может есть какой-то способ сделать это лучше (у нас есть pruned resolver, но если на этапе десериализации мы не знаем, что подставить вместо хэша, то он не поможет)

}

func (s *ShardAccount) UnmarshalTLB(c *boc.Cell, decoder *Decoder) error {
ref, err := c.NextRef()
if err != nil {
return err
}
if ref.CellType() == boc.PrunedBranchCell {
s.Account = Account{}
s.accountCell = ref
} else {
s.accountCell = nil
if err := decoder.Unmarshal(ref, &s.Account); err != nil {
return err
}
}
if err := decoder.Unmarshal(c, &s.LastTransHash); err != nil {
return err
}
return decoder.Unmarshal(c, &s.LastTransLt)
}

func (s ShardAccount) MarshalTLB(c *boc.Cell, encoder *Encoder) error {
ref, err := c.NewRef()
if err != nil {
return err
}
switch {
case s.accountCell != nil && s.Account.SumType == "":
*ref = *cloneCell(s.accountCell)
default:
if err := encoder.Marshal(ref, s.Account); err != nil {
return err
}
}
if err := encoder.Marshal(c, s.LastTransHash); err != nil {
return err
}
return encoder.Marshal(c, s.LastTransLt)
}

// Account
Expand Down
31 changes: 29 additions & 2 deletions tlb/bintree.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,35 @@ func decodeRecursiveBinTree(c *boc.Cell) ([]*boc.Cell, error) {
}

func (b BinTree[T]) MarshalTLB(c *boc.Cell, encoder *Encoder) error {
// TODO: implement
return fmt.Errorf("BinTree marshaling not implemented")
if len(b.Values) == 0 {
return fmt.Errorf("BinTree must have at least one value")
}
return b.marshalRecursive(c, b.Values, encoder)
}

func (b BinTree[T]) marshalRecursive(c *boc.Cell, values []T, encoder *Encoder) error {
if len(values) == 1 {
if err := c.WriteBit(false); err != nil {
return err
}
return encoder.Marshal(c, values[0])
}
if err := c.WriteBit(true); err != nil {
return err
}
mid := len(values) / 2
l, err := c.NewRef()
if err != nil {
return err
}
if err := b.marshalRecursive(l, values[:mid], encoder); err != nil {
return err
}
r, err := c.NewRef()
if err != nil {
return err
}
return b.marshalRecursive(r, values[mid:], encoder)
}

func (b *BinTree[T]) UnmarshalTLB(c *boc.Cell, decoder *Decoder) error {
Expand Down
Loading
Loading