From bf2167bce82c1f742f9342584d825e82080704aa Mon Sep 17 00:00:00 2001 From: Miguel Victoria Date: Wed, 8 Jan 2025 22:48:40 +0100 Subject: [PATCH] implement DerivePkgAddr on gno --- .../r/demo/keystore/keystore_test.gno | 5 +-- gnovm/stdlibs/generated.go | 28 --------------- gnovm/stdlibs/std/crypto.gno | 35 ++++++++++++++----- gnovm/stdlibs/std/crypto_test.gno | 19 ++++++++++ gnovm/stdlibs/std/native.gno | 5 --- gnovm/stdlibs/std/native.go | 4 --- 6 files changed, 49 insertions(+), 47 deletions(-) diff --git a/examples/gno.land/r/demo/keystore/keystore_test.gno b/examples/gno.land/r/demo/keystore/keystore_test.gno index c004d402718..41597016ea3 100644 --- a/examples/gno.land/r/demo/keystore/keystore_test.gno +++ b/examples/gno.land/r/demo/keystore/keystore_test.gno @@ -11,8 +11,9 @@ import ( ) func TestRender(t *testing.T) { - // For some reason non native function fails with - // gno.land/r/demo/keystore/keystore_test.gno:15:3: constant overflows (code=2) + // https://github.com/gnolang/gno/pull/3375 changed const -> var : + // For some reason non native functions fails on constants with + // constant overflows (code=2), this does not happens when using a variable // TODO: check this issue after and if this PR is merged var ( author1 std.Address = testutils.TestAddress("author1") diff --git a/gnovm/stdlibs/generated.go b/gnovm/stdlibs/generated.go index d0a9100e3be..ab35fc6b6bf 100644 --- a/gnovm/stdlibs/generated.go +++ b/gnovm/stdlibs/generated.go @@ -640,34 +640,6 @@ var nativeFuncs = [...]NativeFunc{ )) }, }, - { - "std", - "derivePkgAddr", - []gno.FieldTypeExpr{ - {Name: gno.N("p0"), Type: gno.X("string")}, - }, - []gno.FieldTypeExpr{ - {Name: gno.N("r0"), Type: gno.X("string")}, - }, - false, - func(m *gno.Machine) { - b := m.LastBlock() - var ( - p0 string - rp0 = reflect.ValueOf(&p0).Elem() - ) - - gno.Gno2GoValue(b.GetPointerTo(nil, gno.NewValuePathBlock(1, 0, "")).TV, rp0) - - r0 := libs_std.X_derivePkgAddr(p0) - - m.PushValue(gno.Go2GnoValue( - m.Alloc, - m.Store, - reflect.ValueOf(&r0).Elem(), - )) - }, - }, { "std", "assertCallerIsRealm", diff --git a/gnovm/stdlibs/std/crypto.gno b/gnovm/stdlibs/std/crypto.gno index be3f9ca81ee..adb6f687b56 100644 --- a/gnovm/stdlibs/std/crypto.gno +++ b/gnovm/stdlibs/std/crypto.gno @@ -2,11 +2,15 @@ package std import ( "crypto/bech32" + "crypto/sha256" "errors" ) type Address string // NOTE: bech32 +// bech32AddrPrefix defines the Bech32 prefix of an address +const bech32AddrPrefix = "g" + func (a Address) String() string { return string(a) } @@ -34,14 +38,7 @@ func DecodeBech32(addr Address) (string, [20]byte, bool) { if err != nil || len(bz) != 20 { return "", [20]byte{}, false } - /* For some reason [20]byte(bz) fails with: 'cannot convert []uint8 to ArrayKind' - Maybe there is an issue to create - */ - result := [20]byte{} - for index, b := range bz { - result[index] = b - } - return prefix, result, true + return prefix, convertTo20Byte(bz), true } func convertAndEncode(hrp string, data []byte) (string, error) { @@ -63,3 +60,25 @@ func decodeAndConvert(bech string) (string, []byte, error) { } return hrp, converted, nil } + +func DerivePkgAddr(pkgPath string) Address { + data := sumTruncated([]byte("pkgPath:" + pkgPath)) + return EncodeBech32(bech32AddrPrefix, data) +} + +func sumTruncated(bz []byte) [20]byte { + hash := sha256.Sum256(bz) + return convertTo20Byte(hash[:RawAddressSize]) +} + +func convertTo20Byte(in []byte) [20]byte { + /* For some reason [20]byte(bz) fails with: 'cannot convert []uint8 to ArrayKind' + Maybe there is an issue to create + */ + result := [20]byte{} + for index, b := range in { + result[index] = b + } + + return result +} diff --git a/gnovm/stdlibs/std/crypto_test.gno b/gnovm/stdlibs/std/crypto_test.gno index 75283c03523..70b42e43860 100644 --- a/gnovm/stdlibs/std/crypto_test.gno +++ b/gnovm/stdlibs/std/crypto_test.gno @@ -39,3 +39,22 @@ func TestValid(t *testing.T) { } } } + +func TestDerivePkgAddr(t *testing.T) { + type test struct { + inputPath string + expected string + } + + testCases := []test{ + {inputPath: "gno.land/r/gnoland/faucet", expected: "g1ttrq7mp4zy6dssnmgyyktnn4hcj3ys8xhju0n7"}, + {inputPath: "gno.land/r/demo/tamagotchi", expected: "g1a3tu874agjlkrpzt9x90xv3uzncapcn959yte4"}, + } + + for _, tc := range testCases { + result := DerivePkgAddr(tc.inputPath) + if result.String() != tc.expected { + t.Fatalf("Expected: %t, got: %t", tc.expected, result) + } + } +} diff --git a/gnovm/stdlibs/std/native.gno b/gnovm/stdlibs/std/native.gno index 6e6e792051a..9cf8808a07e 100644 --- a/gnovm/stdlibs/std/native.gno +++ b/gnovm/stdlibs/std/native.gno @@ -45,15 +45,10 @@ func GetCallerAt(n int) Address { return Address(callerAt(n)) } -func DerivePkgAddr(pkgPath string) Address { - return Address(derivePkgAddr(pkgPath)) -} - // Variations which don't use named types. func origSend() (denoms []string, amounts []int64) func origCaller() string func origPkgAddr() string func callerAt(n int) string func getRealm(height int) (address string, pkgPath string) -func derivePkgAddr(pkgPath string) string func assertCallerIsRealm() diff --git a/gnovm/stdlibs/std/native.go b/gnovm/stdlibs/std/native.go index 525611d3062..9e398e907a2 100644 --- a/gnovm/stdlibs/std/native.go +++ b/gnovm/stdlibs/std/native.go @@ -141,10 +141,6 @@ func currentRealm(m *gno.Machine) (address, pkgPath string) { return X_getRealm(m, 0) } -func X_derivePkgAddr(pkgPath string) string { - return string(gno.DerivePkgAddr(pkgPath).Bech32()) -} - func X_assertCallerIsRealm(m *gno.Machine) { frame := m.Frames[m.NumFrames()-2] if path := frame.LastPackage.PkgPath; !gno.IsRealmPath(path) {