compiler: fix a bug with FromAddress handling

Conversion of string to address with FromAddress is performed
at compile time so there is no need to push parameters on stack.
This commit is contained in:
Evgenii Stratonikov 2020-01-27 11:53:47 +03:00
parent 330db36168
commit 097d35b9d5
3 changed files with 52 additions and 3 deletions

View file

@ -185,6 +185,11 @@ func isAppCall(expr ast.Expr) bool {
return ok && t.Sel.Name == "AppCall"
}
func isFromAddress(expr ast.Expr) bool {
t, ok := expr.(*ast.SelectorExpr)
return ok && t.Sel.Name == "FromAddress"
}
func isByteArray(lit *ast.CompositeLit, tInfo *types.Info) bool {
if len(lit.Elts) == 0 {
return false

View file

@ -491,9 +491,13 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
args := n.Args
isAppCall := isAppCall(n.Fun)
// When using APPCALL, script hash is a part of the instruction so
// script hash should be emitted after APPCALL.
if isAppCall {
isFromAddress := isFromAddress(n.Fun)
// There are 2 special cases:
// 1. When using APPCALL, script hash is a part of the instruction so
// script hash should be emitted after APPCALL.
// 2. With FromAddress, parameter conversion is happening at compile-time
// so there is no need to push parameters on stack and perform an actual call
if isAppCall || isFromAddress {
args = n.Args[1:]
}

View file

@ -8,10 +8,50 @@ import (
"github.com/CityOfZion/neo-go/pkg/compiler"
"github.com/CityOfZion/neo-go/pkg/crypto/hash"
"github.com/CityOfZion/neo-go/pkg/encoding/address"
"github.com/CityOfZion/neo-go/pkg/util"
"github.com/stretchr/testify/require"
)
func TestFromAddress(t *testing.T) {
as1 := "Aej1fe4mUgou48Zzup5j8sPrE3973cJ5oz"
addr1, err := address.StringToUint160(as1)
require.NoError(t, err)
as2 := "AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y"
addr2, err := address.StringToUint160(as2)
require.NoError(t, err)
t.Run("append 2 addresses", func(t *testing.T) {
src := `
package foo
import "github.com/CityOfZion/neo-go/pkg/interop/util"
func Main() []byte {
addr1 := util.FromAddress("` + as1 + `")
addr2 := util.FromAddress("` + as2 + `")
sum := append(addr1, addr2...)
return sum
}
`
eval(t, src, append(addr1.BytesBE(), addr2.BytesBE()...))
})
t.Run("append 2 addresses inline", func(t *testing.T) {
src := `
package foo
import "github.com/CityOfZion/neo-go/pkg/interop/util"
func Main() []byte {
addr1 := util.FromAddress("` + as1 + `")
sum := append(addr1, util.FromAddress("` + as2 + `")...)
return sum
}
`
eval(t, src, append(addr1.BytesBE(), addr2.BytesBE()...))
})
}
func TestAppCall(t *testing.T) {
srcInner := `
package foo