Skip to content

Commit

Permalink
Merge pull request #159 from tonkeeper/txemulator-to-inspect-stateinit
Browse files Browse the repository at this point in the history
TxEmulator to look for library cells in stateInit.code of inMsg
  • Loading branch information
mr-tron authored Jul 21, 2023
2 parents 4cfe5e9 + f805a76 commit ac54854
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 5 deletions.
24 changes: 20 additions & 4 deletions txemulator/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,18 @@ func accountCode(account tlb.ShardAccount) *boc.Cell {
return &cell
}

func msgStateInitCode(msg tlb.Message) *boc.Cell {
if !msg.Init.Exists {
return nil
}
code := msg.Init.Value.Value.Code
if !code.Exists {
return nil
}
cell := code.Value.Value
return &cell
}

func (t *Tracer) Run(ctx context.Context, message tlb.Message) (*TxTree, error) {
if t.counter >= t.limit {
return nil, fmt.Errorf("to many iterations: %v/%v", t.counter, t.limit)
Expand Down Expand Up @@ -195,8 +207,11 @@ func (t *Tracer) Run(ctx context.Context, message tlb.Message) (*TxTree, error)
return nil, err
}
}
var publicLibs map[tongo.Bits256]*boc.Cell
if code := accountCode(state); code != nil {
publicLibs := map[tongo.Bits256]*boc.Cell{}
for _, code := range []*boc.Cell{accountCode(state), msgStateInitCode(message)} {
if code == nil {
continue
}
hashes, err := FindLibraries(code)
if err != nil {
return nil, err
Expand All @@ -206,7 +221,9 @@ func (t *Tracer) Run(ctx context.Context, message tlb.Message) (*TxTree, error)
if err != nil {
return nil, err
}
publicLibs = libs
for hash, cell := range libs {
publicLibs[hash] = cell
}
}
}
if len(publicLibs) > 0 {
Expand All @@ -218,7 +235,6 @@ func (t *Tracer) Run(ctx context.Context, message tlb.Message) (*TxTree, error)
return nil, err
}
}
// TODO: look up libraries in the msg's stateInit, so if it's a deploy contract message, Emulate() won't fail.
result, err := t.e.Emulate(state, message)
if err != nil {
return nil, err
Expand Down
32 changes: 31 additions & 1 deletion txemulator/trace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,40 @@ func TestEmulate(t *testing.T) {
t.Fatalf("tx failed")
}
if len(tree.Children) != 1 {
t.Fatalf("expected tx to has 1 child")
t.Fatalf("expected tx to have 1 child")
}
second := tree.Children[0].TX
if !second.IsSuccess() {
t.Fatalf("second tx failed")
}
}

func TestEmulate_ToUninitContract(t *testing.T) {
// this message is a contract-deploy message for "EQCeL1iwCkDZFIN_w3corAk0HLyDFoFKI9sU-zbpBtsqxwd0", which uses a public library.
c, err := boc.DeserializeSinglRootBase64("te6ccgEBAwEAtQACz4gBPF6xYBSBsikG/4buUVgSaDl5Bi0ClEe2KfZt0g22VY4RgapDllUZl8zqKhXvay+jOBYBQZIi9WgRbY+2Sm0k2sZOpAdn+updccco1ndWlewrbU2NzSA29wvefa9KuFSWIeAAAAAQAQIIQgJYfMeJ7/HIT0bsN5fkX8gJoU/1riTx4MemqZzJ3JBh/wBIAAAAAMRoaqYjP2gxcScR+ePyWBCVr/kSa65hTLtoJPi7y8sP")
if err != nil {
t.Fatal(err)
}
var m tlb.Message
if err = tlb.Unmarshal(c, &m); err != nil {
t.Fatal(err)
}
client, err := liteapi.NewClient(liteapi.Mainnet(), liteapi.FromEnvs())
if err != nil {
t.Fatal(err)
}
emulator, err := NewTraceBuilder(WithAccountsSource(client))
if err != nil {
t.Fatalf("NewTraceBuilder() failed: %v", err)
}
tree, err := emulator.Run(context.Background(), m)
if err != nil {
t.Fatalf("Run() failed: %v", err)
}
if !tree.TX.IsSuccess() {
t.Fatalf("tx failed")
}
if len(tree.Children) != 0 {
t.Fatalf("expected tx to have no children")
}
}

0 comments on commit ac54854

Please sign in to comment.