diff --git a/Cargo.lock b/Cargo.lock index ff12faf..bc33e44 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,9 +82,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" +checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704" [[package]] name = "anymap" @@ -137,9 +137,9 @@ dependencies = [ [[package]] name = "async-global-executor" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd8b508d585e01084059b60f06ade4cb7415cd2e4084b71dd1cb44e7d3fb9880" +checksum = "5262ed948da60dd8956c6c5aca4d4163593dddb7b32d73267c93dab7b2e98940" dependencies = [ "async-channel", "async-executor", @@ -147,6 +147,7 @@ dependencies = [ "async-lock", "blocking", "futures-lite", + "num_cpus", "once_cell", ] @@ -180,9 +181,9 @@ dependencies = [ [[package]] name = "async-std" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52580991739c5cdb36cde8b2a516371c0a3b70dda36d916cc08b82372916808c" +checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" dependencies = [ "async-channel", "async-global-executor", @@ -197,7 +198,6 @@ dependencies = [ "kv-log-macro", "log", "memchr", - "num_cpus", "once_cell", "pin-project-lite", "pin-utils", @@ -806,9 +806,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" +checksum = "4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c" dependencies = [ "cfg-if", "crossbeam-utils", @@ -827,15 +827,15 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" +checksum = "07db9d94cbd326813772c968ccd25999e5f8ae22f4f8d1b11effa37ef6ce281d" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "lazy_static", "memoffset", + "once_cell", "scopeguard", ] @@ -851,12 +851,12 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" +checksum = "8ff1f980957787286a554052d03c7aee98d99cc32e09f6d45f0a814133c87978" dependencies = [ "cfg-if", - "lazy_static", + "once_cell", ] [[package]] @@ -2157,10 +2157,12 @@ dependencies = [ "serde", "serde_json", "wabt", + "walkdir", "wasmparser 0.84.0", "wasmprinter", "wast 40.0.0", "wat", + "xshell", ] [[package]] @@ -2186,6 +2188,12 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" + [[package]] name = "heck" version = "0.4.0" @@ -2236,12 +2244,12 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "indexmap" -version = "1.8.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a" +checksum = "6c6392766afd7964e2531940894cffe4bd8d7d17dbc3c1c4857040fd4b33bdb3" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.1", "serde", ] @@ -2679,7 +2687,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" dependencies = [ "crc32fast", - "hashbrown", + "hashbrown 0.11.2", "indexmap", "memchr", ] @@ -2861,9 +2869,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.39" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" +checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" dependencies = [ "unicode-ident", ] @@ -2879,9 +2887,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" dependencies = [ "proc-macro2", ] @@ -3135,9 +3143,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" +checksum = "a0a5f7c728f5d284929a1cccb5bc19884422bfe6ef4d6c409da2c41838983fcf" [[package]] name = "ryu" @@ -3145,6 +3153,15 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -3546,9 +3563,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.96" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf" +checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" dependencies = [ "proc-macro2", "quote", @@ -3649,9 +3666,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd" +checksum = "82501a4c1c0330d640a6e176a3d6a204f5ec5237aca029029d21864a902e27b0" dependencies = [ "itoa", "libc", @@ -3755,6 +3772,17 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi 0.3.9", + "winapi-util", +] + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" diff --git a/examples/erc20/client/client.go b/examples/erc20/client/client.go index 367e4d2..450c625 100644 --- a/examples/erc20/client/client.go +++ b/examples/erc20/client/client.go @@ -1,10 +1,10 @@ package client import ( - bytes "bytes" - context "context" + "bytes" + "context" contract "erc20/contract" - fmt "fmt" + "fmt" address "github.com/filecoin-project/go-address" abi "github.com/filecoin-project/go-state-types/abi" @@ -13,7 +13,7 @@ import ( init8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/init" actors "github.com/filecoin-project/venus/venus-shared/actors" types "github.com/filecoin-project/venus/venus-shared/types" - types2 "github.com/ipfs-force-community/go-fvm-sdk/sdk/types" + sdkTypes "github.com/ipfs-force-community/go-fvm-sdk/sdk/types" cid "github.com/ipfs/go-cid" typegen "github.com/whyrusleeping/cbor-gen" @@ -31,9 +31,9 @@ type IErc20TokenClient interface { Constructor(context.Context, *contract.ConstructorReq) error - GetName(context.Context) (types2.CborString, error) + GetName(context.Context) (sdkTypes.CborString, error) - GetSymbol(context.Context) (types2.CborString, error) + GetSymbol(context.Context) (sdkTypes.CborString, error) GetDecimal(context.Context) (typegen.CborInt, error) @@ -208,7 +208,7 @@ func (c *Erc20TokenClient) Constructor(ctx context.Context, p0 *contract.Constru return nil } -func (c *Erc20TokenClient) GetName(ctx context.Context) (types2.CborString, error) { +func (c *Erc20TokenClient) GetName(ctx context.Context) (sdkTypes.CborString, error) { if c.actor == address.Undef { return "", fmt.Errorf("unset actor address for call") } @@ -239,14 +239,14 @@ func (c *Erc20TokenClient) GetName(ctx context.Context) (types2.CborString, erro return "", fmt.Errorf("expect get result for call") } - result := new(types2.CborString) + result := new(sdkTypes.CborString) result.UnmarshalCBOR(bytes.NewReader(wait.Receipt.Return)) return *result, nil } -func (c *Erc20TokenClient) GetSymbol(ctx context.Context) (types2.CborString, error) { +func (c *Erc20TokenClient) GetSymbol(ctx context.Context) (sdkTypes.CborString, error) { if c.actor == address.Undef { return "", fmt.Errorf("unset actor address for call") } @@ -277,7 +277,7 @@ func (c *Erc20TokenClient) GetSymbol(ctx context.Context) (types2.CborString, er return "", fmt.Errorf("expect get result for call") } - result := new(types2.CborString) + result := new(sdkTypes.CborString) result.UnmarshalCBOR(bytes.NewReader(wait.Receipt.Return)) return *result, nil diff --git a/examples/erc20/entry.go b/examples/erc20/entry.go index 2f2c527..df4afbd 100644 --- a/examples/erc20/entry.go +++ b/examples/erc20/entry.go @@ -5,17 +5,19 @@ import ( "bytes" "fmt" - "github.com/filecoin-project/go-state-types/cbor" + contract "erc20/contract" - typegen "github.com/whyrusleeping/cbor-gen" + address "github.com/filecoin-project/go-address" - "github.com/ipfs-force-community/go-fvm-sdk/sdk" - "github.com/ipfs-force-community/go-fvm-sdk/sdk/ferrors" - "github.com/ipfs-force-community/go-fvm-sdk/sdk/types" + cbor "github.com/filecoin-project/go-state-types/cbor" - contract "erc20/contract" + sdk "github.com/ipfs-force-community/go-fvm-sdk/sdk" - address "github.com/filecoin-project/go-address" + ferrors "github.com/ipfs-force-community/go-fvm-sdk/sdk/ferrors" + + sdkTypes "github.com/ipfs-force-community/go-fvm-sdk/sdk/types" + + typegen "github.com/whyrusleeping/cbor-gen" ) //not support non-main wasm in tinygo at present @@ -36,7 +38,7 @@ func Invoke(blockId uint32) uint32 { } var callResult cbor.Marshaler - var raw *types.ParamsRaw + var raw *sdkTypes.ParamsRaw switch method { case 1: //Constuctor @@ -204,12 +206,12 @@ func Invoke(blockId uint32) uint32 { if err != nil { sdk.Abort(ferrors.USR_ILLEGAL_STATE, fmt.Sprintf("marshal resp fail %s", err)) } - id, err := sdk.PutBlock(types.DAG_CBOR, buf.Bytes()) + id, err := sdk.PutBlock(sdkTypes.DAG_CBOR, buf.Bytes()) if err != nil { sdk.Abort(ferrors.USR_ILLEGAL_STATE, fmt.Sprintf("failed to store return value: %v", err)) } return id } else { - return types.NO_DATA_BLOCK_ID + return sdkTypes.NO_DATA_BLOCK_ID } } diff --git a/examples/erc20/gen/go.mod b/examples/erc20/gen/go.mod index 664dcf0..e86a5b6 100644 --- a/examples/erc20/gen/go.mod +++ b/examples/erc20/gen/go.mod @@ -29,6 +29,7 @@ require ( github.com/klauspost/cpuid/v2 v2.0.9 // indirect github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect github.com/minio/sha256-simd v1.0.0 // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.0.3 // indirect github.com/multiformats/go-base36 v0.1.0 // indirect diff --git a/examples/erc20/gen/go.sum b/examples/erc20/gen/go.sum index 10ddb17..22b1e92 100644 --- a/examples/erc20/gen/go.sum +++ b/examples/erc20/gen/go.sum @@ -1283,6 +1283,7 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= diff --git a/examples/hellocontract/client/client.go b/examples/hellocontract/client/client.go index 7bd5d20..e577fa6 100644 --- a/examples/hellocontract/client/client.go +++ b/examples/hellocontract/client/client.go @@ -1,9 +1,9 @@ package client import ( - bytes "bytes" - context "context" - fmt "fmt" + "bytes" + "context" + "fmt" address "github.com/filecoin-project/go-address" abi "github.com/filecoin-project/go-state-types/abi" @@ -12,7 +12,7 @@ import ( init8 "github.com/filecoin-project/specs-actors/v8/actors/builtin/init" actors "github.com/filecoin-project/venus/venus-shared/actors" types "github.com/filecoin-project/venus/venus-shared/types" - types2 "github.com/ipfs-force-community/go-fvm-sdk/sdk/types" + sdkTypes "github.com/ipfs-force-community/go-fvm-sdk/sdk/types" cid "github.com/ipfs/go-cid" v0 "github.com/filecoin-project/venus/venus-shared/api/chain/v0" @@ -29,7 +29,7 @@ type IStateClient interface { Constructor(context.Context) error - SayHello(context.Context) (types2.CBORBytes, error) + SayHello(context.Context) (sdkTypes.CBORBytes, error) } var _ IStateClient = (*StateClient)(nil) @@ -184,7 +184,7 @@ func (c *StateClient) Constructor(ctx context.Context) error { return nil } -func (c *StateClient) SayHello(ctx context.Context) (types2.CBORBytes, error) { +func (c *StateClient) SayHello(ctx context.Context) (sdkTypes.CBORBytes, error) { if c.actor == address.Undef { return nil, fmt.Errorf("unset actor address for call") } @@ -215,7 +215,7 @@ func (c *StateClient) SayHello(ctx context.Context) (types2.CBORBytes, error) { return nil, fmt.Errorf("expect get result for call") } - result := new(types2.CBORBytes) + result := new(sdkTypes.CBORBytes) result.UnmarshalCBOR(bytes.NewReader(wait.Receipt.Return)) return *result, nil diff --git a/examples/hellocontract/contract/helloworld.go b/examples/hellocontract/contract/helloworld.go index bd38cab..39e36c8 100644 --- a/examples/hellocontract/contract/helloworld.go +++ b/examples/hellocontract/contract/helloworld.go @@ -49,7 +49,7 @@ func Constructor() error { caller, err := sdk.Caller() if err != nil { - sdk.Abort(ferrors.USR_ILLEGAL_STATE, "unbale to get caller") + sdk.Abort(ferrors.USR_ILLEGAL_STATE, "unable to get caller") } if caller != 1 { diff --git a/examples/hellocontract/entry.go b/examples/hellocontract/entry.go index 9096e10..8436f22 100644 --- a/examples/hellocontract/entry.go +++ b/examples/hellocontract/entry.go @@ -5,13 +5,15 @@ import ( "bytes" "fmt" - "github.com/filecoin-project/go-state-types/cbor" + cbor "github.com/filecoin-project/go-state-types/cbor" - typegen "github.com/whyrusleeping/cbor-gen" + sdk "github.com/ipfs-force-community/go-fvm-sdk/sdk" + + ferrors "github.com/ipfs-force-community/go-fvm-sdk/sdk/ferrors" - "github.com/ipfs-force-community/go-fvm-sdk/sdk" - "github.com/ipfs-force-community/go-fvm-sdk/sdk/ferrors" - "github.com/ipfs-force-community/go-fvm-sdk/sdk/types" + sdkTypes "github.com/ipfs-force-community/go-fvm-sdk/sdk/types" + + typegen "github.com/whyrusleeping/cbor-gen" contract "hellocontract/contract" ) @@ -62,12 +64,12 @@ func Invoke(blockId uint32) uint32 { if err != nil { sdk.Abort(ferrors.USR_ILLEGAL_STATE, fmt.Sprintf("marshal resp fail %s", err)) } - id, err := sdk.PutBlock(types.DAG_CBOR, buf.Bytes()) + id, err := sdk.PutBlock(sdkTypes.DAG_CBOR, buf.Bytes()) if err != nil { sdk.Abort(ferrors.USR_ILLEGAL_STATE, fmt.Sprintf("failed to store return value: %v", err)) } return id } else { - return types.NO_DATA_BLOCK_ID + return sdkTypes.NO_DATA_BLOCK_ID } } diff --git a/gen/client_gen.go b/gen/client_gen.go index a13d606..dd1108e 100644 --- a/gen/client_gen.go +++ b/gen/client_gen.go @@ -11,18 +11,6 @@ import ( ) var defaultClientImport = []typegen.Import{ - { - Name: "bytes", - PkgPath: "bytes", - }, - { - Name: "context", - PkgPath: "context", - }, - { - Name: "fmt", - PkgPath: "fmt", - }, { Name: "actors", PkgPath: "github.com/filecoin-project/venus/venus-shared/actors", @@ -47,6 +35,10 @@ var defaultClientImport = []typegen.Import{ Name: "types", PkgPath: "github.com/filecoin-project/venus/venus-shared/types", }, + { + Name: "sdkTypes", + PkgPath: "github.com/ipfs-force-community/go-fvm-sdk/sdk/types", + }, { Name: "cid", PkgPath: "github.com/ipfs/go-cid", @@ -59,6 +51,18 @@ var defaultClientImport = []typegen.Import{ Name: "typegen", PkgPath: "github.com/whyrusleeping/cbor-gen", }, + { + Name: "cbor", + PkgPath: "github.com/filecoin-project/go-state-types/cbor", + }, + { + Name: "sdk", + PkgPath: "github.com/ipfs-force-community/go-fvm-sdk/sdk", + }, + { + Name: "ferrors", + PkgPath: "github.com/ipfs-force-community/go-fvm-sdk/sdk/ferrors", + }, } var funcs = map[string]interface{}{ @@ -313,7 +317,7 @@ type I{{trimPackage .StateName}}Client interface { return render.Execute(w, entry) } -func genClientParamsReturnMethod(w io.Writer, entry methodMap) error { +func genClientParamsReturnMethod(w io.Writer, entry *methodMap) error { tpl := ` func (c *{{trimPackage .StateName}}Client) {{.FuncName}}(ctx context.Context, p0 {{.ParamsTypeName}}) ({{.ReturnTypeName}}, error) { if c.actor == address.Undef { @@ -368,7 +372,7 @@ func (c *{{trimPackage .StateName}}Client) {{.FuncName}}(ctx context.Context, p0 return render.Execute(w, entry) } -func genClientParamsNOReturnMethod(w io.Writer, entry methodMap) error { +func genClientParamsNOReturnMethod(w io.Writer, entry *methodMap) error { tpl := ` func (c *{{trimPackage .StateName}}Client) {{.FuncName}}(ctx context.Context, p0 {{.ParamsTypeName}}) error { if c.actor == address.Undef { @@ -413,7 +417,7 @@ func (c *{{trimPackage .StateName}}Client) {{.FuncName}}(ctx context.Context, p0 return render.Execute(w, entry) } -func genClientNoParamsReturnMethod(w io.Writer, entry methodMap) error { +func genClientNoParamsReturnMethod(w io.Writer, entry *methodMap) error { tpl := ` func (c *{{trimPackage .StateName}}Client) {{.FuncName}}(ctx context.Context) ({{.ReturnTypeName}}, error) { if c.actor == address.Undef { @@ -464,7 +468,7 @@ func (c *{{trimPackage .StateName}}Client) {{.FuncName}}(ctx context.Context) ({ return render.Execute(w, entry) } -func genClientNoParamsNoReturnMethod(w io.Writer, entry methodMap) error { +func genClientNoParamsNoReturnMethod(w io.Writer, entry *methodMap) error { tpl := ` func (c *{{trimPackage .StateName}}Client) {{.FuncName}}(ctx context.Context) error { if c.actor == address.Undef { diff --git a/gen/entry_gen.go b/gen/entry_gen.go index 32a0a8b..c163ef8 100644 --- a/gen/entry_gen.go +++ b/gen/entry_gen.go @@ -100,22 +100,18 @@ func getEntryPackageMeta(pkg string, stateT reflect.Type) (*entryMeta, error) { return nil, fmt.Errorf("assert Export return type fail,") } - stateName := typeName(pkg, stateT) - var methodsMap []methodMap - var imports []typegen.Import - imports = append(imports, typegen.ImportsForType(pkg, stateT)...) + var methodsMap []*methodMap sortedFuncs := sortMap(exports) hasParam := false + typesToImport := []reflect.Type{stateT} for _, sortedFunc := range sortedFuncs { functionT := reflect.TypeOf(sortedFunc.funcT) if functionT.Kind() != reflect.Func { return nil, fmt.Errorf("export must be function ") } - var method = methodMap{} - v := reflect.ValueOf(sortedFunc.funcT) - method.PkgName, method.FuncName = getFunctionName(v) + var method = &methodMap{} + method.FuncT = reflect.ValueOf(sortedFunc.funcT) method.MethodNum = sortedFunc.method_num - method.StateName = stateName // functionT := function.Type if functionT.NumIn() > 1 { @@ -126,9 +122,9 @@ func getEntryPackageMeta(pkg string, stateT reflect.Type) (*entryMeta, error) { return nil, fmt.Errorf("func %s return value at index 1 must be error", method.FuncName) } method.HasParam = true + method.ParamsType = functionT.In(0) hasParam = true - method.ParamsTypeName = typeName(pkg, functionT.In(0)) - imports = append(imports, typegen.ImportsForType(pkg, functionT.In(0))...) + typesToImport = append(typesToImport, functionT.In(0)) } if functionT.NumOut() > 2 { @@ -145,16 +141,15 @@ func getEntryPackageMeta(pkg string, stateT reflect.Type) (*entryMeta, error) { } method.HasReturn = true method.HasError = true - method.ReturnTypeName = typeName(pkg, functionT.Out(0)) - method.DefaultReturn = defaultValue(functionT.Out(0)) - imports = append(imports, typegen.ImportsForType(pkg, functionT.Out(0))...) + method.ReturnType = functionT.Out(0) + typesToImport = append(typesToImport, functionT.Out(0)) } else if functionT.NumOut() == 1 { if functionT.Out(0).AssignableTo(errorT) { method.HasReturn = false method.HasError = true } else { - method.ReturnTypeName = typeName(pkg, functionT.Out(0)) - method.DefaultReturn = defaultValue(functionT.Out(0)) + typesToImport = append(typesToImport, functionT.Out(0)) + method.ReturnType = functionT.Out(0) method.HasReturn = true method.HasError = false } @@ -167,6 +162,26 @@ func getEntryPackageMeta(pkg string, stateT reflect.Type) (*entryMeta, error) { methodsMap = append(methodsMap, method) } + + //resolve package and name + imports := defaultClientImport + for _, importType := range typesToImport { + imports = append(imports, ImportsForType(pkg, importType)...) + } + imports = dedupImports(imports) + + stateName := typeName(pkg, stateT) + for _, m := range methodsMap { + m.PkgName, m.FuncName = getFunctionName(m.FuncT) + m.StateName = stateName + if m.HasParam { + m.ParamsTypeName = typeName(pkg, m.ParamsType) + } + if m.HasReturn { + m.ReturnTypeName = typeName(pkg, m.ReturnType) + m.DefaultReturn = defaultValue(m.ReturnType) + } + } return &entryMeta{ Imports: dedupImports(imports), //PkgName: , @@ -274,23 +289,46 @@ func dedupImports(imps []typegen.Import) []typegen.Import { return deduped } +func ImportsForType(currPkg string, t reflect.Type) []typegen.Import { + switch t.Kind() { + case reflect.Array, reflect.Slice, reflect.Ptr: + return ImportsForType(currPkg, t.Elem()) + case reflect.Map: + return dedupImports(append(ImportsForType(currPkg, t.Key()), ImportsForType(currPkg, t.Elem())...)) + default: + path := t.PkgPath() + if path == "" || path == currPkg { + // built-in or in current package. + return nil + } + + return []typegen.Import{{PkgPath: path, Name: resolvePkgByFullName(path, t.String())}} + } +} + type entryMeta struct { Imports []typegen.Import HasParam bool PkgName string - Methods []methodMap + Methods []*methodMap StateName string + StateType reflect.Type } type methodMap struct { - StateName string - MethodNum int - PkgName string - FuncName string - HasError bool - HasParam bool - HasReturn bool + StateName string + MethodNum int + FuncT reflect.Value + PkgName string + FuncName string + HasError bool + HasParam bool + HasReturn bool + + ParamsType reflect.Type ParamsTypeName string + + ReturnType reflect.Type ReturnTypeName string DefaultReturn string } @@ -301,14 +339,6 @@ package main import ( "bytes" "fmt" - "github.com/filecoin-project/go-state-types/cbor" - - typegen "github.com/whyrusleeping/cbor-gen" - - "github.com/ipfs-force-community/go-fvm-sdk/sdk" - "github.com/ipfs-force-community/go-fvm-sdk/sdk/ferrors" - "github.com/ipfs-force-community/go-fvm-sdk/sdk/types" - {{range .Imports}} {{.Name}} "{{.PkgPath}}" {{end}} @@ -332,7 +362,7 @@ func Invoke(blockId uint32) uint32 { } var callResult cbor.Marshaler -{{if .HasParam}}var raw *types.ParamsRaw{{end}} +{{if .HasParam}}var raw *sdkTypes.ParamsRaw{{end}} switch method { {{range .Methods}}case {{.MethodNum}}: {{if eq .MethodNum 1}} //Constuctor @@ -426,13 +456,13 @@ func Invoke(blockId uint32) uint32 { if err != nil { sdk.Abort(ferrors.USR_ILLEGAL_STATE, fmt.Sprintf("marshal resp fail %s", err)) } - id, err := sdk.PutBlock(types.DAG_CBOR, buf.Bytes()) + id, err := sdk.PutBlock(sdkTypes.DAG_CBOR, buf.Bytes()) if err != nil { sdk.Abort(ferrors.USR_ILLEGAL_STATE, fmt.Sprintf("failed to store return value: %v", err)) } return id } else { - return types.NO_DATA_BLOCK_ID + return sdkTypes.NO_DATA_BLOCK_ID } } @@ -476,11 +506,8 @@ func defaultValue(t reflect.Type) string { //hellocontract/contract.(*State).SayHello func getFunctionName(temp reflect.Value) (string, string) { fullName := runtime.FuncForPC(temp.Pointer()).Name() + fullName = strings.TrimSuffix(fullName, "-fm") - index := strings.LastIndex(fullName, "-") - if index > -1 { - fullName = fullName[:index] - } split := strings.Split(fullName, ".") name := split[len(split)-1] diff --git a/gen/go.mod b/gen/go.mod index 5f705ce..98b4d9d 100644 --- a/gen/go.mod +++ b/gen/go.mod @@ -4,6 +4,7 @@ go 1.17 require ( github.com/filecoin-project/go-state-types v0.1.9 + github.com/modern-go/reflect2 v1.0.2 github.com/whyrusleeping/cbor-gen v0.0.0-20220514204315-f29c37e9c44c golang.org/x/tools v0.1.11 ) diff --git a/gen/go.sum b/gen/go.sum index 1f1ad5e..14048a0 100644 --- a/gen/go.sum +++ b/gen/go.sum @@ -40,6 +40,8 @@ github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+ github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc= diff --git a/sdk/utils.go b/sdk/utils.go index 8839e2d..8f1ac5f 100644 --- a/sdk/utils.go +++ b/sdk/utils.go @@ -34,7 +34,7 @@ func SaveState(state cbor.Marshaler) cid.Cid { func Constructor(state cbor.Marshaler) error { caller, err := Caller() if err != nil { - Abort(ferrors.USR_ILLEGAL_STATE, "unbale to get caller") + Abort(ferrors.USR_ILLEGAL_STATE, "unable to get caller") } if caller != 1 { diff --git a/tools/sdk_tool/Cargo.toml b/tools/sdk_tool/Cargo.toml index cee907f..e5ae24a 100644 --- a/tools/sdk_tool/Cargo.toml +++ b/tools/sdk_tool/Cargo.toml @@ -24,6 +24,8 @@ rand_chacha = "0.3" hex = "0.4.3" path-absolutize = "3.0.13" cid = { version = "0.8.3", default-features = false, features = ["serde-codec"] } +xshell = "0.2" +walkdir = "2" fvm = { git = "https://github.com/ipfs-force-community/ref-fvm.git", branch = "feat/keep_dep_experimental", default-features = false} fvm_shared = { git = "https://github.com/ipfs-force-community/ref-fvm.git", branch = "feat/keep_dep_experimental" } diff --git a/tools/sdk_tool/src/main.rs b/tools/sdk_tool/src/main.rs index 71fa69b..e1b07fe 100644 --- a/tools/sdk_tool/src/main.rs +++ b/tools/sdk_tool/src/main.rs @@ -1,4 +1,6 @@ +mod template; mod testing; +mod utils; mod wasmprocess; use clap::Parser; @@ -18,6 +20,8 @@ enum Commands { Build(wasmprocess::BuildCLiConfig), /// test wasm on fvm Test(testing::TestConfig), + /// create new template project by module name + New(template::NewTemplateConfig), } fn main() { @@ -30,5 +34,11 @@ fn main() { } } Commands::Test(cfg) => testing::run_testing(cfg), + Commands::New(cfg) => { + if let Err(e) = template::new_template_project(cfg) { + println!("run new template command fail {}", e); + std::process::exit(1); + } + } } } diff --git a/tools/sdk_tool/src/template.rs b/tools/sdk_tool/src/template.rs new file mode 100644 index 0000000..c931c79 --- /dev/null +++ b/tools/sdk_tool/src/template.rs @@ -0,0 +1,106 @@ +use crate::utils; +use anyhow::{anyhow, Result}; +use clap::Parser; +use std::env::current_dir; +use std::fs; +use xshell::{cmd, Shell}; + +#[derive(Parser, Debug)] +#[clap(author, version, about, long_about = None)] +pub struct NewTemplateConfig { + //must be a validate go module package name + #[clap(last = true)] + pub name: Option, +} + +pub fn new_template_project(cfg: &NewTemplateConfig) -> Result<()> { + utils::check_tinygo_install()?; + utils::check_go_install()?; + utils::check_fvm_tool_install()?; + let template_name = "gofvm-counter"; + //market + let sh = Shell::new()?; + cmd!( + sh, + "git clone https://github.com/ipfs-force-community/gofvm-counter.git" + ) + .run() + .map_err(|e| anyhow!("unable to checkout template project {}", e))?; + + let mut old_tmp_dir = current_dir()?; + old_tmp_dir.push(template_name); + sh.change_dir(&old_tmp_dir); + cmd!(sh, "rm -rf .git") + .run() + .map_err(|e| anyhow!("unable to remove git {}", e))?; + + sh.change_dir(current_dir()?); + let mut module_name = template_name.to_string(); + if let Some(new_module_name) = &cfg.name { + sh.change_dir(current_dir()?); + sh.cmd("mv") + .args([template_name, new_module_name]) + .run() + .map_err(|e| { + anyhow!( + "unable to rename template project to {} {}", + new_module_name, + e + ) + })?; + module_name = new_module_name.to_string(); + } + + //replace module name + let mut new_cur_dir = current_dir()?; + new_cur_dir.push(module_name.clone()); + if let Some(new_module_name) = &cfg.name { + for file in walkdir::WalkDir::new(&new_cur_dir) + .into_iter() + .filter_map(|file| file.ok()) + .filter(|file| { + if let Ok(meta) = file.metadata() { + return meta.is_file(); + } + false + }) + { + let file_content = fs::read_to_string(file.path())?; + let file_content = file_content.replace(template_name, new_module_name); + fs::write(file.path(), file_content)?; + } + println!("module...."); + } + + sh.change_dir(new_cur_dir.clone()); + cmd!(sh, "mkdir client") + .run() + .map_err(|e| anyhow!("unable to create client dir {}", e))?; + + let mut gen_dir = new_cur_dir.clone(); + gen_dir.push("gen"); + sh.change_dir(gen_dir); + + cmd!(sh, "go mod tidy") + .run() + .map_err(|e| anyhow!("unable to create client dir {}", e))?; + cmd!(sh, "go run main.go") + .run() + .map_err(|e| anyhow!("unable to create run gen tool {}", e))?; + + sh.change_dir(&new_cur_dir); + cmd!(sh, "go mod tidy") + .run() + .map_err(|e| anyhow!("unable to build template in template project {}", e))?; + + sh.cmd("go-fvm-sdk-tools") + .args(["build", "-o", &(module_name + ".wasm")]) + .run() + .map_err(|e| anyhow!("unable to build template in template project {}", e))?; + + cmd!(sh, "go-fvm-sdk-tools test -- ./tests") + .run() + .map_err(|e| anyhow!("unable to run test in template project {}", e))?; + + Ok(()) +} diff --git a/tools/sdk_tool/src/testing.rs b/tools/sdk_tool/src/testing.rs index 498df63..bdcca34 100644 --- a/tools/sdk_tool/src/testing.rs +++ b/tools/sdk_tool/src/testing.rs @@ -20,6 +20,7 @@ use fvm_shared::state::StateTreeVersion; use fvm_shared::version::NetworkVersion; use hex::FromHex; use libsecp256k1::SecretKey; +use path_absolutize::Absolutize; use serde::{Deserialize, Serialize}; use std::fs; use std::iter::Iterator; @@ -119,7 +120,10 @@ pub fn run_action_group( ) -> Result<()> { let path: PathBuf = [root_path, contract_case.binary.to_owned()] .iter() - .collect(); + .collect::() + .absolutize() + .map(|v| v.into_owned()) + .expect("get binary path"); let buf = fs::read(path.clone()) .unwrap_or_else(|_| panic!("path {} not found", path.to_str().unwrap())); // Instantiate tester @@ -218,7 +222,12 @@ pub fn run_action_group( } pub fn run_signle_wasm(root_path: String, accounts: &[InitAccount], wasm_case: &WasmCase) { - let path: PathBuf = [root_path, wasm_case.binary.to_owned()].iter().collect(); + let path: PathBuf = [root_path, wasm_case.binary.to_owned()] + .iter() + .collect::() + .absolutize() + .map(|v| v.into_owned()) + .expect("get binary path"); let buf = fs::read(path.clone()) .unwrap_or_else(|_| panic!("path {} not found", path.to_str().unwrap())); let ret = exec(&buf, accounts, wasm_case).unwrap(); diff --git a/tools/sdk_tool/src/utils.rs b/tools/sdk_tool/src/utils.rs new file mode 100644 index 0000000..e3cb821 --- /dev/null +++ b/tools/sdk_tool/src/utils.rs @@ -0,0 +1,65 @@ +use anyhow::{anyhow, Result}; +use std::io::ErrorKind; +use std::process::{Command, Stdio}; + +pub fn check_tinygo_install() -> Result<()> { + match Command::new("tinygo") + .stdout(Stdio::null()) + .arg("version") + .status() + { + Ok(_) => Ok(()), + Err(e) => { + if let ErrorKind::NotFound = e.kind() { + Err(anyhow!("unable to found tinygo(fvm), please install this tool in https://github.com/ipfs-force-community/tinygo/releases")) + } else { + Err(anyhow!("fvm-tinygo not install, please install err {}", e)) + } + } + } +} + +pub fn check_fvm_tool_install() -> Result<()> { + match Command::new("go-fvm-sdk-tools") + .stdout(Stdio::null()) + .arg("--help") + .status() + { + Ok(_) => Ok(()), + Err(e) => { + if let ErrorKind::NotFound = e.kind() { + Err(anyhow!("unable to found go-fvm-sdk-tools(fvm), please install this tool in https://github.com/ipfs-force-community/go-fvm-sdk/releases")) + } else { + Err(anyhow!("check err {}", e)) + } + } + } +} + +pub fn check_go_install() -> Result { + match Command::new("go") + .stdout(Stdio::piped()) + .arg("version") + .spawn() + { + Ok(child) => { + let output = child.wait_with_output()?; + let version_str = String::from_utf8(output.stdout)?; + if version_str.contains("go1.16.") || version_str.contains("go1.17.") { + Ok(true) + } else { + Err(anyhow!( + "uncorect go version must be go 1.16.x/go1.17.x but got {}", + version_str + )) + } + } + Err(e) => { + if let ErrorKind::NotFound = e.kind() { + Err(anyhow!("unable to found go-fvm-sdk-tools(fvm), please install this tool in https://go.dev/dl")) + } else { + Err(anyhow!("check err {}", e)) + } + } + } +} diff --git a/tools/sdk_tool/src/wasmprocess.rs b/tools/sdk_tool/src/wasmprocess.rs index 2ae7f1d..ad449c2 100644 --- a/tools/sdk_tool/src/wasmprocess.rs +++ b/tools/sdk_tool/src/wasmprocess.rs @@ -1,3 +1,4 @@ +use crate::utils; use anyhow::{anyhow, Result}; use clap::Parser; use parity_wasm::elements::Type::Function; @@ -8,7 +9,6 @@ use parity_wasm::elements::{ use path_absolutize::*; use std::collections::HashMap; use std::env; -use std::io::ErrorKind; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; @@ -128,9 +128,7 @@ impl<'a> GoFvmBinProcessor<'a> { } pub fn build(&mut self) -> Result<&mut Self> { - if !check_tinygo_install()? { - return Err(anyhow!("unbale to found tinygo(fvm), please intall this tool in https://github.com/ipfs-force-community/go-fvm-sdk/releases")); - } + utils::check_tinygo_install()?; let output = Command::new("tinygo") .args([ "build", @@ -507,19 +505,6 @@ impl<'a> GoFvmBinProcessor<'a> { } } -fn check_tinygo_install() -> Result { - match Command::new("tinygo").arg("version").spawn() { - Ok(_) => Ok(true), - Err(e) => { - if let ErrorKind::NotFound = e.kind() { - Ok(false) - } else { - Err(anyhow!("check err {}", e)) - } - } - } -} - trait TryString { fn try_to_string(&self) -> Result; } @@ -527,7 +512,7 @@ trait TryString { impl TryString for PathBuf { fn try_to_string(&self) -> Result { self.to_str() - .ok_or_else(|| anyhow!("unbale to get string from pathbuf")) + .ok_or_else(|| anyhow!("unable to get string from pathbuf")) .map(|v| v.to_string()) } }