From ca5465500f0cd0e5f6a9ebc78588ce0a4acdb000 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Tue, 11 Jun 2019 22:04:31 +0100 Subject: [PATCH 1/7] compile wasm Signed-off-by: Sean Young --- acm/acm.pb.go | 88 +++++++++--- cmd/burrow/commands/deploy.go | 3 + deploy/compile/compilers.go | 59 ++++++++ deploy/def/client.go | 1 + deploy/def/deploy.go | 1 + deploy/jobs/job_manager.go | 43 ++++-- deploy/jobs/jobs_contracts.go | 28 ++-- execution/contexts/call_context.go | 3 + execution/evm/state.go | 9 ++ protobuf/acm.proto | 1 + protobuf/payload.proto | 5 +- txs/payload/payload.pb.go | 218 +++++++++++++++++------------ 12 files changed, 326 insertions(+), 133 deletions(-) diff --git a/acm/acm.pb.go b/acm/acm.pb.go index a5f44adaf..0a99c5182 100644 --- a/acm/acm.pb.go +++ b/acm/acm.pb.go @@ -34,6 +34,7 @@ type Account struct { Balance uint64 `protobuf:"varint,4,opt,name=Balance,proto3" json:"Balance,omitempty"` Code Bytecode `protobuf:"bytes,5,opt,name=Code,proto3,customtype=Bytecode" json:"Code"` Permissions permission.AccountPermissions `protobuf:"bytes,6,opt,name=Permissions,proto3" json:"Permissions"` + WASM Bytecode `protobuf:"bytes,7,opt,name=WASM,proto3,customtype=Bytecode" json:"WASM"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -111,28 +112,28 @@ func init() { proto.RegisterFile("acm.proto", fileDescriptor_49ed775bc0a6adf6) } func init() { golang_proto.RegisterFile("acm.proto", fileDescriptor_49ed775bc0a6adf6) } var fileDescriptor_49ed775bc0a6adf6 = []byte{ - // 323 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x90, 0xbd, 0x4e, 0xfb, 0x30, - 0x14, 0xc5, 0xeb, 0x36, 0xff, 0x7e, 0xb8, 0x1d, 0xfa, 0xf7, 0x64, 0x75, 0x70, 0x0b, 0x62, 0xe8, - 0x00, 0x89, 0xc4, 0x87, 0x90, 0xd8, 0x1a, 0x24, 0x16, 0x24, 0x54, 0x85, 0x8d, 0x2d, 0x71, 0x2e, - 0x69, 0xa4, 0xa6, 0x0e, 0x4e, 0x2c, 0x94, 0x37, 0x61, 0xe4, 0x39, 0x98, 0x18, 0x3b, 0x32, 0x33, - 0x54, 0x28, 0x7d, 0x11, 0x54, 0xe3, 0x86, 0x4c, 0x6c, 0x3e, 0xfe, 0xdd, 0x73, 0xef, 0xd1, 0xc1, - 0x3d, 0x9f, 0x27, 0x76, 0x2a, 0x45, 0x2e, 0x48, 0xcb, 0xe7, 0xc9, 0xe8, 0x24, 0x8a, 0xf3, 0x85, - 0x0a, 0x6c, 0x2e, 0x12, 0x27, 0x12, 0x91, 0x70, 0x34, 0x0b, 0xd4, 0xa3, 0x56, 0x5a, 0xe8, 0xd7, - 0x8f, 0x67, 0x34, 0x4c, 0x41, 0x26, 0x71, 0x96, 0xc5, 0x62, 0x65, 0x7e, 0x06, 0x5c, 0x16, 0x69, - 0x6e, 0xf8, 0xe1, 0x5b, 0x13, 0x77, 0x66, 0x9c, 0x0b, 0xb5, 0xca, 0xc9, 0x1d, 0xee, 0xcc, 0xc2, - 0x50, 0x42, 0x96, 0x51, 0x34, 0x41, 0xd3, 0x81, 0x7b, 0xbe, 0xde, 0x8c, 0x1b, 0x9f, 0x9b, 0xf1, - 0x71, 0xed, 0xe6, 0xa2, 0x48, 0x41, 0x2e, 0x21, 0x8c, 0x40, 0x3a, 0x81, 0x92, 0x52, 0x3c, 0x3b, - 0x66, 0xa1, 0xf1, 0x7a, 0xfb, 0x25, 0xe4, 0x02, 0xf7, 0xe6, 0x2a, 0x58, 0xc6, 0xfc, 0x16, 0x0a, - 0xda, 0x9c, 0xa0, 0x69, 0xff, 0xf4, 0xbf, 0x6d, 0x86, 0x2b, 0xe0, 0x5a, 0xbb, 0x23, 0xde, 0xef, - 0x24, 0x19, 0xe1, 0xee, 0x3d, 0x3c, 0x29, 0x58, 0x71, 0xa0, 0xad, 0x09, 0x9a, 0x5a, 0x5e, 0xa5, - 0x09, 0xc5, 0x1d, 0xd7, 0x5f, 0xfa, 0x3b, 0x64, 0x69, 0xb4, 0x97, 0xe4, 0x08, 0x5b, 0xd7, 0x22, - 0x04, 0xfa, 0x4f, 0x27, 0x1f, 0x9a, 0xe4, 0x5d, 0xb7, 0xc8, 0x81, 0x8b, 0x10, 0x3c, 0x4d, 0xc9, - 0x0d, 0xee, 0xcf, 0xab, 0x42, 0x32, 0xda, 0xd6, 0xa1, 0x98, 0x5d, 0x2b, 0xc9, 0x94, 0x51, 0x9b, - 0x32, 0x09, 0xeb, 0xc6, 0x2b, 0xeb, 0xe5, 0x75, 0xdc, 0x70, 0x2f, 0xd7, 0x25, 0x43, 0x1f, 0x25, - 0x43, 0x5f, 0x25, 0x43, 0xef, 0x5b, 0x86, 0xd6, 0x5b, 0x86, 0x1e, 0x0e, 0xfe, 0x6e, 0xcb, 0xe7, - 0x49, 0xd0, 0xd6, 0xe5, 0x9f, 0x7d, 0x07, 0x00, 0x00, 0xff, 0xff, 0x10, 0xec, 0x45, 0x82, 0xdd, - 0x01, 0x00, 0x00, + // 335 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x91, 0xbf, 0x4e, 0xf3, 0x30, + 0x14, 0xc5, 0xeb, 0x36, 0x5f, 0xd3, 0xba, 0x1d, 0xfa, 0x79, 0xb2, 0x3a, 0xa4, 0x05, 0x31, 0x74, + 0x80, 0x44, 0xe2, 0x8f, 0x90, 0xd8, 0x1a, 0x24, 0x16, 0x04, 0xaa, 0xd2, 0x01, 0x89, 0x2d, 0x71, + 0x2e, 0x69, 0xa4, 0xa6, 0x0e, 0x4e, 0x2c, 0x94, 0x37, 0x61, 0xe4, 0x51, 0x18, 0x3b, 0x32, 0x33, + 0x54, 0x55, 0xfb, 0x22, 0x28, 0xc6, 0x2d, 0x59, 0x60, 0xcb, 0xc9, 0xef, 0xde, 0x7b, 0x8e, 0x8e, + 0x71, 0xdb, 0x67, 0x89, 0x9d, 0x0a, 0x9e, 0x73, 0xd2, 0xf0, 0x59, 0xd2, 0x3f, 0x89, 0xe2, 0x7c, + 0x26, 0x03, 0x9b, 0xf1, 0xc4, 0x89, 0x78, 0xc4, 0x1d, 0xc5, 0x02, 0xf9, 0xa4, 0x94, 0x12, 0xea, + 0xeb, 0x7b, 0xa7, 0xdf, 0x4b, 0x41, 0x24, 0x71, 0x96, 0xc5, 0x7c, 0xa1, 0xff, 0x74, 0x99, 0x28, + 0xd2, 0x5c, 0xf3, 0xc3, 0x75, 0x1d, 0x9b, 0x63, 0xc6, 0xb8, 0x5c, 0xe4, 0xe4, 0x1e, 0x9b, 0xe3, + 0x30, 0x14, 0x90, 0x65, 0x14, 0x0d, 0xd1, 0xa8, 0xeb, 0x9e, 0x2f, 0x57, 0x83, 0xda, 0xe7, 0x6a, + 0x70, 0x5c, 0xf1, 0x9c, 0x15, 0x29, 0x88, 0x39, 0x84, 0x11, 0x08, 0x27, 0x90, 0x42, 0xf0, 0x17, + 0x47, 0x1f, 0xd4, 0xbb, 0xde, 0xee, 0x08, 0xb9, 0xc0, 0xed, 0x89, 0x0c, 0xe6, 0x31, 0xbb, 0x85, + 0x82, 0xd6, 0x87, 0x68, 0xd4, 0x39, 0xfd, 0x6f, 0xeb, 0xe1, 0x3d, 0x70, 0x8d, 0xd2, 0xc4, 0xfb, + 0x99, 0x24, 0x7d, 0xdc, 0x9a, 0xc2, 0xb3, 0x84, 0x05, 0x03, 0xda, 0x18, 0xa2, 0x91, 0xe1, 0xed, + 0x35, 0xa1, 0xd8, 0x74, 0xfd, 0xb9, 0x5f, 0x22, 0x43, 0xa1, 0x9d, 0x24, 0x47, 0xd8, 0xb8, 0xe6, + 0x21, 0xd0, 0x7f, 0x2a, 0x79, 0x4f, 0x27, 0x6f, 0xb9, 0x45, 0x0e, 0x8c, 0x87, 0xe0, 0x29, 0x4a, + 0x6e, 0x70, 0x67, 0xb2, 0x2f, 0x24, 0xa3, 0x4d, 0x15, 0xca, 0xb2, 0x2b, 0x25, 0xe9, 0x32, 0x2a, + 0x53, 0x3a, 0x61, 0x75, 0xb1, 0x74, 0x7b, 0x18, 0x4f, 0xef, 0xa8, 0xf9, 0x9b, 0x5b, 0x49, 0xaf, + 0x8c, 0xd7, 0xb7, 0x41, 0xcd, 0xbd, 0x5c, 0x6e, 0x2c, 0xf4, 0xb1, 0xb1, 0xd0, 0x7a, 0x63, 0xa1, + 0xf7, 0xad, 0x85, 0x96, 0x5b, 0x0b, 0x3d, 0x1e, 0xfc, 0xdd, 0xa9, 0xcf, 0x92, 0xa0, 0xa9, 0x9e, + 0xe8, 0xec, 0x2b, 0x00, 0x00, 0xff, 0xff, 0xeb, 0x36, 0x89, 0x52, 0x03, 0x02, 0x00, 0x00, } func (m *Account) Marshal() (dAtA []byte, err error) { @@ -192,6 +193,14 @@ func (m *Account) MarshalTo(dAtA []byte) (int, error) { return 0, err } i += n4 + dAtA[i] = 0x3a + i++ + i = encodeVarintAcm(dAtA, i, uint64(m.WASM.Size())) + n5, err := m.WASM.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n5 if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -227,6 +236,8 @@ func (m *Account) Size() (n int) { n += 1 + l + sovAcm(uint64(l)) l = m.Permissions.Size() n += 1 + l + sovAcm(uint64(l)) + l = m.WASM.Size() + n += 1 + l + sovAcm(uint64(l)) if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -445,6 +456,39 @@ func (m *Account) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field WASM", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAcm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAcm + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAcm + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.WASM.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipAcm(dAtA[iNdEx:]) diff --git a/cmd/burrow/commands/deploy.go b/cmd/burrow/commands/deploy.go index a45d67af2..6a58887d4 100644 --- a/cmd/burrow/commands/deploy.go +++ b/cmd/burrow/commands/deploy.go @@ -59,6 +59,8 @@ func Deploy(output Output) func(cmd *cli.Cmd) { verboseOpt := cmd.BoolOpt("v verbose", false, "verbose output") + wasmOpt := cmd.BoolOpt("wasm", false, "Compile to WASM using solang (experimental)") + debugOpt := cmd.BoolOpt("d debug", false, "debug level output") proposalVerify := cmd.BoolOpt("proposal-verify", false, "Verify any proposal, do NOT create new proposal or vote") @@ -95,6 +97,7 @@ func Deploy(output Output) func(cmd *cli.Cmd) { args.MempoolSign = *mempoolSigningOpt args.Timeout = *timeoutSecondsOpt args.Path = *pathOpt + args.Wasm = *wasmOpt args.DefaultOutput = *defaultOutputOpt args.DefaultSets = *defaultSetsOpt args.BinPath = *binPathOpt diff --git a/deploy/compile/compilers.go b/deploy/compile/compilers.go index 6c6d544e3..f1744eba7 100644 --- a/deploy/compile/compilers.go +++ b/deploy/compile/compilers.go @@ -55,6 +55,9 @@ type SolidityContract struct { LinkReferences json.RawMessage } } + EWasm struct { + Wasm string + } Devdoc json.RawMessage Userdoc json.RawMessage Metadata string @@ -200,6 +203,62 @@ func Compile(file string, optimize bool, workDir string, libraries map[string]st } } + for _, re := range respItemArray { + logger.TraceMsg("Response formulated", + "name", re.Objectname, + "bin", re.Contract.EWasm.Wasm, + "abi", string(re.Contract.Abi)) + } + + resp := Response{ + Objects: respItemArray, + Warning: warnings, + Error: errors, + } + + return &resp, nil +} + +func CompileWASM(file string, workDir string, logger *logging.Logger) (*Response, error) { + shellCmd := exec.Command("solang", "--json", file) + if workDir != "" { + shellCmd.Dir = workDir + } + output, err := shellCmd.CombinedOutput() + if err != nil { + return nil, err + } + logger.TraceMsg("Command Output", "result", string(output)) + + wasmoutput := SolidityOutput{} + err = json.Unmarshal(output, &output) + if err != nil { + return nil, err + } + + respItemArray := make([]ResponseItem, 0) + + for f, s := range wasmoutput.Contracts { + for contract, item := range s { + respItem := ResponseItem{ + Filename: f, + Objectname: objectName(contract), + Contract: item, + } + respItemArray = append(respItemArray, respItem) + } + } + + warnings := "" + errors := "" + for _, msg := range wasmoutput.Errors { + if msg.Type == "Warning" { + warnings += msg.FormattedMessage + } else { + errors += msg.FormattedMessage + } + } + for _, re := range respItemArray { logger.TraceMsg("Response formulated", "name", re.Objectname, diff --git a/deploy/def/client.go b/deploy/def/client.go index 8c496ccdd..814f3c893 100644 --- a/deploy/def/client.go +++ b/deploy/def/client.go @@ -427,6 +427,7 @@ type CallArg struct { Fee string Gas string Data string + WASM string } func (c *Client) Call(arg *CallArg, logger *logging.Logger) (*payload.CallTx, error) { diff --git a/deploy/def/deploy.go b/deploy/def/deploy.go index 18550adfc..7dc1b9fe1 100644 --- a/deploy/def/deploy.go +++ b/deploy/def/deploy.go @@ -11,6 +11,7 @@ type DeployArgs struct { Chain string `mapstructure:"," json:"," yaml:"," toml:","` KeysService string `mapstructure:"," json:"," yaml:"," toml:","` MempoolSign bool `mapstructure:"," json:"," yaml:"," toml:","` + Wasm bool `mapstructure:"," json:"," yaml:"," toml:","` Timeout int `mapstructure:"," json:"," yaml:"," toml:","` Address string `mapstructure:"," json:"," yaml:"," toml:","` BinPath string `mapstructure:"," json:"," yaml:"," toml:","` diff --git a/deploy/jobs/job_manager.go b/deploy/jobs/job_manager.go index 73efee268..84955281b 100644 --- a/deploy/jobs/job_manager.go +++ b/deploy/jobs/job_manager.go @@ -24,27 +24,40 @@ type solidityCompilerWork struct { workDir string } -type intermediateJob struct { +type compilerJob struct { work solidityCompilerWork compilerResp *compilers.Response err error done chan struct{} } -func intermediateJobRunner(jobs chan *intermediateJob, logger *logging.Logger) { +func solcRunner(jobs chan *compilerJob, logger *logging.Logger) { for { - intermediate, ok := <-jobs + job, ok := <-jobs if !ok { break } - resp, err := compilers.Compile(intermediate.work.contractName, false, intermediate.work.workDir, nil, logger) - (*intermediate).compilerResp = resp - (*intermediate).err = err - close(intermediate.done) + resp, err := compilers.Compile(job.work.contractName, false, job.work.workDir, nil, logger) + (*job).compilerResp = resp + (*job).err = err + close(job.done) } } -func queueCompilerWork(job *def.Job, playbook *def.Playbook, jobs chan *intermediateJob) error { +func solangRunner(jobs chan *compilerJob, logger *logging.Logger) { + for { + job, ok := <-jobs + if !ok { + break + } + resp, err := compilers.CompileWASM(job.work.contractName, job.work.workDir, logger) + (*job).compilerResp = resp + (*job).err = err + close(job.done) + } +} + +func queueCompilerWork(job *def.Job, playbook *def.Playbook, jobs chan *compilerJob) error { payload, err := job.Payload() if err != nil { return fmt.Errorf("could not get Job payload: %v", payload) @@ -53,7 +66,7 @@ func queueCompilerWork(job *def.Job, playbook *def.Playbook, jobs chan *intermed // Do compilation first switch payload.(type) { case *def.Build: - intermediate := intermediateJob{ + intermediate := compilerJob{ done: make(chan struct{}), work: solidityCompilerWork{ contractName: job.Build.Contract, @@ -64,7 +77,7 @@ func queueCompilerWork(job *def.Job, playbook *def.Playbook, jobs chan *intermed jobs <- &intermediate case *def.Deploy: if filepath.Ext(job.Deploy.Contract) == ".sol" { - intermediate := intermediateJob{ + intermediate := compilerJob{ done: make(chan struct{}), work: solidityCompilerWork{ contractName: job.Deploy.Contract, @@ -94,7 +107,7 @@ func queueCompilerWork(job *def.Job, playbook *def.Playbook, jobs chan *intermed } func getCompilerWork(intermediate interface{}) (*compilers.Response, error) { - if intermediate, ok := intermediate.(*intermediateJob); ok { + if intermediate, ok := intermediate.(*compilerJob); ok { <-intermediate.done return intermediate.compilerResp, intermediate.err @@ -271,11 +284,15 @@ func ExecutePlaybook(args *def.DeployArgs, playbook *def.Playbook, client *def.C return fmt.Errorf("error validating Burrow deploy file at %s: %v", playbook.Filename, err) } - jobs := make(chan *intermediateJob, concurrentSolcWorkQueue) + jobs := make(chan *compilerJob, concurrentSolcWorkQueue) defer close(jobs) for i := 0; i < concurrentSolc; i++ { - go intermediateJobRunner(jobs, logger) + if args.Wasm { + go solangRunner(jobs, logger) + } else { + go solcRunner(jobs, logger) + } } for _, job := range playbook.Jobs { diff --git a/deploy/jobs/jobs_contracts.go b/deploy/jobs/jobs_contracts.go index 5b8c06947..d144bed77 100644 --- a/deploy/jobs/jobs_contracts.go +++ b/deploy/jobs/jobs_contracts.go @@ -163,7 +163,7 @@ func FormulateDeployJob(deploy *def.Deploy, do *def.DeployArgs, deployScript *de contractCode = contractCode + callData } - tx, err := deployTx(client, deploy, contractName, string(contractCode), logger) + tx, err := deployTx(client, deploy, contractName, string(contractCode), "", logger) if err != nil { return nil, nil, fmt.Errorf("could not deploy binary contract: %v", err) } @@ -351,11 +351,17 @@ func deployContract(deploy *def.Deploy, do *def.DeployArgs, script *def.Playbook } } - err = contract.Link(libs) - if err != nil { - return nil, err + wasm := "" + data := "" + if contract.EWasm.Wasm != "" { + wasm = contract.EWasm.Wasm + } else { + err = contract.Link(libs) + if err != nil { + return nil, err + } + data = contract.Evm.Bytecode.Object } - contractCode := contract.Evm.Bytecode.Object if deploy.Data != nil { _, callDataArray, err := util.PreProcessInputData(compilersResponse.Objectname, deploy.Data, do, script, client, true, logger) @@ -367,7 +373,7 @@ func deployContract(deploy *def.Deploy, do *def.DeployArgs, script *def.Playbook return nil, err } callData := hex.EncodeToString(packedBytes) - contractCode = contractCode + callData + data = data + callData } else { // No constructor arguments were provided. Did the constructor want any? spec, err := abi.ReadAbiSpec(compilersResponse.Contract.Abi) @@ -381,15 +387,16 @@ func deployContract(deploy *def.Deploy, do *def.DeployArgs, script *def.Playbook } } - return deployTx(client, deploy, compilersResponse.Objectname, contractCode, logger) + return deployTx(client, deploy, compilersResponse.Objectname, data, wasm, logger) } -func deployTx(client *def.Client, deploy *def.Deploy, contractName, contractCode string, logger *logging.Logger) (*payload.CallTx, error) { +func deployTx(client *def.Client, deploy *def.Deploy, contractName, data, wasm string, logger *logging.Logger) (*payload.CallTx, error) { // Deploy contract logger.TraceMsg("Deploying Contract", "contract", contractName, "source", deploy.Source, - "code", contractCode, + "data", data, + "wasm", wasm, "chain", client.ChainAddress) return client.Call(&def.CallArg{ @@ -397,7 +404,8 @@ func deployTx(client *def.Client, deploy *def.Deploy, contractName, contractCode Amount: deploy.Amount, Fee: deploy.Fee, Gas: deploy.Gas, - Data: contractCode, + Data: data, + WASM: wasm, Sequence: deploy.Sequence, }, logger) } diff --git a/execution/contexts/call_context.go b/execution/contexts/call_context.go index c76475338..3e938edad 100644 --- a/execution/contexts/call_context.go +++ b/execution/contexts/call_context.go @@ -130,6 +130,7 @@ func (ctx *CallContext) Deliver(inAcc, outAcc *acm.Account, value uint64) error caller crypto.Address = inAcc.Address callee crypto.Address = crypto.ZeroAddress // initialized below code []byte = nil + wasm []byte = nil ret []byte = nil txCache = evm.NewState(ctx.StateWriter, ctx.Blockchain.BlockHash, acmstate.Named("TxCache")) params = evm.Params{ @@ -144,6 +145,7 @@ func (ctx *CallContext) Deliver(inAcc, outAcc *acm.Account, value uint64) error // We already checked for permission callee = crypto.NewContractAddress(caller, ctx.txe.TxHash) code = ctx.tx.Data + wasm = ctx.tx.WASM txCache.CreateAccount(callee) ctx.Logger.TraceMsg("Creating new contract", "contract_address", callee, @@ -177,6 +179,7 @@ func (ctx *CallContext) Deliver(inAcc, outAcc *acm.Account, value uint64) error } callee = outAcc.Address code = txCache.GetCode(callee) + wasm = txCache.GetWASMCode(callee) ctx.Logger.TraceMsg("Calling existing contract", "contract_address", callee, "input", ctx.tx.Data, diff --git a/execution/evm/state.go b/execution/evm/state.go index 67615c286..30751ddef 100644 --- a/execution/evm/state.go +++ b/execution/evm/state.go @@ -28,6 +28,7 @@ type Reader interface { GetBalance(address crypto.Address) uint64 GetPermissions(address crypto.Address) permission.AccountPermissions GetCode(address crypto.Address) acm.Bytecode + GetWASMCode(address crypto.Address) acm.Bytecode GetSequence(address crypto.Address) uint64 Exists(address crypto.Address) bool // GetBlockHash returns hash of the specific block @@ -140,6 +141,14 @@ func (st *State) GetCode(address crypto.Address) acm.Bytecode { return acc.Code } +func (st *State) GetWASMCode(address crypto.Address) acm.Bytecode { + acc := st.account(address) + if acc == nil { + return nil + } + return acc.WASM +} + func (st *State) Exists(address crypto.Address) bool { acc, err := st.cache.GetAccount(address) if err != nil { diff --git a/protobuf/acm.proto b/protobuf/acm.proto index b3eb08114..b5f1aec18 100644 --- a/protobuf/acm.proto +++ b/protobuf/acm.proto @@ -23,4 +23,5 @@ message Account { uint64 Balance = 4; bytes Code = 5 [(gogoproto.customtype) = "Bytecode", (gogoproto.nullable) = false]; permission.AccountPermissions Permissions = 6 [(gogoproto.nullable) = false]; + bytes WASM = 7 [(gogoproto.customtype) = "Bytecode", (gogoproto.nullable) = false]; } diff --git a/protobuf/payload.proto b/protobuf/payload.proto index f712d324c..ecfdc2439 100644 --- a/protobuf/payload.proto +++ b/protobuf/payload.proto @@ -66,9 +66,10 @@ message CallTx { uint64 GasLimit = 3; // Fee to offer validators for processing transaction uint64 Fee = 4; - // EVM bytecode payload + // EVM bytecode payload or call data bytes Data = 5 [(gogoproto.customtype) = "github.com/hyperledger/burrow/binary.HexBytes", (gogoproto.nullable) = false]; - + // + bytes WASM = 6 [(gogoproto.customtype) = "github.com/hyperledger/burrow/binary.HexBytes", (gogoproto.nullable) = false]; } // A payment between two sets of parties diff --git a/txs/payload/payload.pb.go b/txs/payload/payload.pb.go index e17302550..56d75f97f 100644 --- a/txs/payload/payload.pb.go +++ b/txs/payload/payload.pb.go @@ -300,8 +300,10 @@ type CallTx struct { GasLimit uint64 `protobuf:"varint,3,opt,name=GasLimit,proto3" json:"GasLimit,omitempty"` // Fee to offer validators for processing transaction Fee uint64 `protobuf:"varint,4,opt,name=Fee,proto3" json:"Fee,omitempty"` - // EVM bytecode payload - Data github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,5,opt,name=Data,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"Data"` + // EVM bytecode payload or call data + Data github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,5,opt,name=Data,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"Data"` + // + WASM github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,6,opt,name=WASM,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"WASM"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -969,67 +971,68 @@ func init() { proto.RegisterFile("payload.proto", fileDescriptor_678c914f1bee6d5 func init() { golang_proto.RegisterFile("payload.proto", fileDescriptor_678c914f1bee6d56) } var fileDescriptor_678c914f1bee6d56 = []byte{ - // 958 bytes of a gzipped FileDescriptorProto + // 971 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x4b, 0x6f, 0x23, 0x45, - 0x10, 0x4e, 0x67, 0xc6, 0x8f, 0xad, 0x75, 0x82, 0xb7, 0x79, 0xc8, 0x8a, 0x84, 0xbd, 0x32, 0x08, - 0x96, 0x47, 0x6c, 0xd8, 0xe5, 0x21, 0xe5, 0x82, 0x3c, 0xb1, 0xb3, 0x09, 0x5a, 0x25, 0x51, 0x67, - 0xb2, 0x20, 0x24, 0x0e, 0x63, 0xbb, 0xb1, 0x47, 0x8c, 0xa7, 0x87, 0x99, 0xf6, 0x32, 0xe6, 0xc4, - 0x81, 0x03, 0x57, 0xc4, 0x85, 0x63, 0x0e, 0xfc, 0x01, 0xfe, 0x01, 0xc7, 0x1c, 0x39, 0x73, 0x58, - 0xa1, 0xec, 0x85, 0xff, 0xc0, 0x05, 0x75, 0x4f, 0xf7, 0xb8, 0xed, 0x85, 0x5d, 0x27, 0xa0, 0xbd, - 0x4d, 0x55, 0x7d, 0xdd, 0x55, 0xf5, 0xd5, 0xa3, 0x07, 0x36, 0x22, 0x6f, 0x16, 0x30, 0x6f, 0xd8, - 0x8a, 0x62, 0xc6, 0x19, 0x2e, 0x29, 0x71, 0x6b, 0x7b, 0xe4, 0xf3, 0xf1, 0xb4, 0xdf, 0x1a, 0xb0, - 0x49, 0x7b, 0xc4, 0x46, 0xac, 0x2d, 0xed, 0xfd, 0xe9, 0x17, 0x52, 0x92, 0x82, 0xfc, 0xca, 0xce, - 0x6d, 0x55, 0x23, 0x1a, 0x4f, 0xfc, 0x24, 0xf1, 0x59, 0xa8, 0x34, 0x90, 0x44, 0x74, 0x90, 0x7d, - 0x37, 0x7f, 0xb0, 0xc0, 0xea, 0x84, 0x33, 0xfc, 0x3a, 0x14, 0x77, 0xbd, 0x20, 0x70, 0xd3, 0x1a, - 0xba, 0x89, 0x6e, 0x5d, 0xbf, 0xfd, 0x5c, 0x4b, 0x7b, 0xcf, 0xd4, 0x44, 0x99, 0x05, 0xf0, 0x84, - 0x86, 0x43, 0x37, 0xad, 0xad, 0x2f, 0x01, 0x33, 0x35, 0x51, 0x66, 0x01, 0x3c, 0xf4, 0x26, 0xd4, - 0x4d, 0x6b, 0xd6, 0x12, 0x30, 0x53, 0x13, 0x65, 0xc6, 0x6f, 0x42, 0xe9, 0x98, 0xc6, 0x93, 0xc4, - 0x4d, 0x6b, 0xb6, 0x44, 0x56, 0x73, 0xa4, 0xd2, 0x13, 0x0d, 0xc0, 0xaf, 0x42, 0xe1, 0x2e, 0x7b, - 0xe0, 0xa6, 0xb5, 0x82, 0x44, 0x6e, 0xe6, 0x48, 0xa9, 0x25, 0x99, 0x51, 0xb8, 0x76, 0x98, 0x8c, - 0xb1, 0xb8, 0xe4, 0x3a, 0x53, 0x13, 0x65, 0xc6, 0xdb, 0x50, 0x3e, 0x0d, 0xfb, 0x19, 0xb4, 0x24, - 0xa1, 0x37, 0x72, 0xa8, 0x36, 0x90, 0x1c, 0x22, 0x22, 0x75, 0x3c, 0x3e, 0x18, 0xbb, 0x69, 0xad, - 0xbc, 0x14, 0xa9, 0xd2, 0x13, 0x0d, 0xc0, 0x77, 0x00, 0x8e, 0x63, 0x16, 0xb1, 0xc4, 0x13, 0xa4, - 0x5e, 0x93, 0xf0, 0xe7, 0xe7, 0x89, 0xe5, 0x26, 0x62, 0xc0, 0x76, 0xec, 0xf3, 0xb3, 0x06, 0x6a, - 0xfe, 0x88, 0xa0, 0xe4, 0xa6, 0x07, 0x61, 0x34, 0xe5, 0xf8, 0x10, 0x4a, 0x9d, 0xe1, 0x30, 0xa6, - 0x49, 0x22, 0x0b, 0x53, 0x71, 0xde, 0x3b, 0x7f, 0xd8, 0x58, 0xfb, 0xfd, 0x61, 0xe3, 0x6d, 0xa3, - 0x0b, 0xc6, 0xb3, 0x88, 0xc6, 0x01, 0x1d, 0x8e, 0x68, 0xdc, 0xee, 0x4f, 0xe3, 0x98, 0x7d, 0xdd, - 0x1e, 0xc4, 0xb3, 0x88, 0xb3, 0x96, 0x3a, 0x4b, 0xf4, 0x25, 0xf8, 0x25, 0x28, 0x76, 0x26, 0x6c, - 0x1a, 0x72, 0x59, 0x3e, 0x9b, 0x28, 0x09, 0x6f, 0x41, 0xf9, 0x84, 0x7e, 0x35, 0xa5, 0xe1, 0x80, - 0xca, 0x7a, 0xd9, 0x24, 0x97, 0x77, 0xec, 0x9f, 0xce, 0x1a, 0x6b, 0xcd, 0x14, 0xca, 0x6e, 0x7a, - 0x34, 0xe5, 0xcf, 0x30, 0x2a, 0xe5, 0xf9, 0x2f, 0xa4, 0x9b, 0x13, 0xbf, 0x06, 0x05, 0xc9, 0x8b, - 0xea, 0xd2, 0x39, 0xff, 0x8a, 0x2f, 0x92, 0x99, 0xf1, 0xc7, 0xf3, 0x00, 0xd7, 0x65, 0x80, 0xef, - 0x5c, 0x3d, 0xb8, 0x2d, 0x28, 0xdf, 0xf5, 0x92, 0x7b, 0xfe, 0xc4, 0xe7, 0x9a, 0x1a, 0x2d, 0xe3, - 0x2a, 0x58, 0x7b, 0x94, 0xca, 0xbe, 0xb5, 0x89, 0xf8, 0xc4, 0x07, 0x60, 0x77, 0x3d, 0xee, 0xc9, - 0x06, 0xad, 0x38, 0xef, 0x2b, 0x5e, 0xb6, 0x9f, 0xec, 0xba, 0xef, 0x87, 0x5e, 0x3c, 0x6b, 0xed, - 0xd3, 0xd4, 0x99, 0x71, 0x9a, 0x10, 0x79, 0x85, 0xca, 0xde, 0xd7, 0x03, 0x87, 0x6f, 0x41, 0x51, - 0x66, 0x27, 0x48, 0xb7, 0xfe, 0x31, 0x7b, 0x65, 0xc7, 0x6f, 0x41, 0x29, 0xab, 0x94, 0x48, 0xdf, - 0x5a, 0x68, 0x6b, 0x5d, 0x43, 0xa2, 0x11, 0x3b, 0xe5, 0xef, 0xcf, 0x1a, 0x6b, 0xd2, 0x15, 0xcb, - 0x27, 0x71, 0x65, 0xa2, 0x3f, 0x80, 0xb2, 0x38, 0xd2, 0x89, 0x47, 0x89, 0x5a, 0x08, 0x2f, 0xb4, - 0x8c, 0x85, 0xa3, 0x6d, 0x8e, 0x2d, 0x88, 0x20, 0x39, 0x56, 0xe5, 0x16, 0xe9, 0x1d, 0xb1, 0xb2, - 0x3f, 0x0c, 0xb6, 0x38, 0x21, 0x7d, 0x5d, 0x23, 0xf2, 0x5b, 0xe8, 0x24, 0xe5, 0x56, 0xa6, 0x13, - 0xdf, 0x8f, 0x17, 0x46, 0x79, 0xfc, 0x52, 0xaf, 0x86, 0x4b, 0xb0, 0x39, 0xdf, 0x12, 0xec, 0xdf, - 0xe9, 0xcc, 0x21, 0x06, 0x9f, 0x3f, 0xa3, 0xf9, 0x7e, 0x59, 0x39, 0xc3, 0xc3, 0xe5, 0xd6, 0xfd, - 0xef, 0xb3, 0xb5, 0x4f, 0xfd, 0xd1, 0x58, 0x37, 0xaf, 0x92, 0x8c, 0x30, 0xbf, 0x45, 0x6a, 0xab, - 0x5e, 0x82, 0x93, 0x5d, 0xd8, 0xec, 0x0c, 0x06, 0x62, 0x48, 0x4f, 0xa3, 0xa1, 0xc7, 0xa9, 0x6e, - 0xb4, 0x17, 0x5b, 0xf2, 0x71, 0x71, 0xe9, 0x24, 0x0a, 0x3c, 0x4e, 0x15, 0x46, 0x96, 0x1f, 0x91, - 0xa5, 0x23, 0x46, 0x08, 0x7f, 0x22, 0x73, 0x5d, 0xae, 0xcc, 0x55, 0x13, 0x2a, 0xf7, 0x19, 0xf7, - 0xc3, 0xd1, 0x27, 0x59, 0x86, 0x82, 0x30, 0x8b, 0x2c, 0xe8, 0xf0, 0x29, 0x54, 0xf4, 0xcd, 0xfb, - 0x5e, 0x32, 0x96, 0x2c, 0x54, 0x9c, 0x77, 0x2f, 0x3f, 0x94, 0x0b, 0xd7, 0x88, 0xa6, 0xd0, 0xb2, - 0x7a, 0xb6, 0x6e, 0x3c, 0xb6, 0xdd, 0x49, 0x0e, 0x31, 0x52, 0xfd, 0x3c, 0x7f, 0x44, 0x2e, 0x41, - 0x77, 0x1d, 0x2c, 0x37, 0xd5, 0x1c, 0x57, 0x72, 0x58, 0x27, 0x9c, 0x11, 0x61, 0x30, 0xae, 0xff, - 0x0e, 0x81, 0x7d, 0x9f, 0x71, 0xfa, 0xbf, 0xef, 0xe8, 0x15, 0xb8, 0x36, 0xc2, 0x78, 0x30, 0xa7, - 0x27, 0x9f, 0x59, 0x64, 0xcc, 0xec, 0x4d, 0xb8, 0xde, 0xa5, 0xc9, 0x20, 0xf6, 0x23, 0xee, 0xb3, - 0x50, 0x8d, 0xb3, 0xa9, 0x32, 0x1f, 0x5b, 0xeb, 0x29, 0x8f, 0xad, 0xe1, 0xf7, 0x97, 0x75, 0x28, - 0x3a, 0x5e, 0x10, 0x30, 0xbe, 0x50, 0x21, 0xf4, 0xd4, 0x0a, 0x89, 0x3e, 0xd9, 0xf3, 0x43, 0x2f, - 0xf0, 0xbf, 0xf1, 0xc3, 0x91, 0xfa, 0xbd, 0xb9, 0x5a, 0x9f, 0x98, 0xd7, 0xe0, 0x5d, 0xd8, 0x88, - 0x94, 0x8b, 0x13, 0xee, 0xf1, 0x6c, 0x25, 0x6d, 0xde, 0x7e, 0xd9, 0x48, 0x46, 0x44, 0x9b, 0x47, - 0x24, 0x41, 0x64, 0xf1, 0x0c, 0x7e, 0x05, 0x0a, 0xa2, 0xa6, 0x49, 0xad, 0x20, 0x1b, 0x60, 0x23, - 0x3f, 0x2c, 0xb4, 0x24, 0xb3, 0x35, 0x3f, 0x84, 0x8d, 0x85, 0x4b, 0x70, 0x05, 0xca, 0xc7, 0xe4, - 0xe8, 0xf8, 0xe8, 0xa4, 0xd7, 0xad, 0xae, 0x09, 0xa9, 0xf7, 0x69, 0x6f, 0xf7, 0xd4, 0xed, 0x75, - 0xab, 0x08, 0x03, 0x14, 0xf7, 0x3a, 0x07, 0xf7, 0x7a, 0xdd, 0xea, 0xba, 0xf3, 0xd1, 0xf9, 0x45, - 0x1d, 0xfd, 0x76, 0x51, 0x47, 0x7f, 0x5c, 0xd4, 0xd1, 0xaf, 0x8f, 0xea, 0xe8, 0xfc, 0x51, 0x1d, - 0x7d, 0xf6, 0xc6, 0x93, 0xb3, 0xe6, 0x69, 0xd2, 0x56, 0x51, 0xf4, 0x8b, 0xf2, 0x5f, 0xf2, 0xce, - 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa2, 0x4c, 0xec, 0xa1, 0xb2, 0x0a, 0x00, 0x00, + 0x10, 0x4e, 0x7b, 0xc6, 0x8f, 0xad, 0x75, 0x82, 0xb7, 0x79, 0xc8, 0x8a, 0x84, 0xbd, 0x32, 0x08, + 0x96, 0x47, 0x6c, 0xd8, 0xe5, 0x21, 0xe5, 0x82, 0x3c, 0xb1, 0xb3, 0x09, 0x5a, 0x92, 0xa8, 0x3d, + 0xd9, 0x45, 0x48, 0x1c, 0xc6, 0x76, 0x63, 0x8f, 0x18, 0x4f, 0x0f, 0x33, 0xed, 0x65, 0xcc, 0x89, + 0x03, 0x07, 0xae, 0x88, 0x0b, 0xc7, 0x1c, 0xf8, 0x03, 0xfc, 0x03, 0x4e, 0x28, 0x47, 0xce, 0x1c, + 0x56, 0x28, 0x7b, 0xe1, 0x67, 0xa0, 0xee, 0xe9, 0x1e, 0x8f, 0xbd, 0xb0, 0xb1, 0x03, 0xda, 0xdb, + 0x54, 0xd5, 0xd7, 0x55, 0xd5, 0x5f, 0x3d, 0x7a, 0x60, 0x33, 0x70, 0x66, 0x1e, 0x73, 0x86, 0xcd, + 0x20, 0x64, 0x9c, 0xe1, 0xa2, 0x12, 0xb7, 0x77, 0x46, 0x2e, 0x1f, 0x4f, 0xfb, 0xcd, 0x01, 0x9b, + 0xb4, 0x46, 0x6c, 0xc4, 0x5a, 0xd2, 0xde, 0x9f, 0x7e, 0x21, 0x25, 0x29, 0xc8, 0xaf, 0xe4, 0xdc, + 0x76, 0x25, 0xa0, 0xe1, 0xc4, 0x8d, 0x22, 0x97, 0xf9, 0x4a, 0x03, 0x51, 0x40, 0x07, 0xc9, 0x77, + 0xe3, 0x07, 0x03, 0x8c, 0xb6, 0x3f, 0xc3, 0xaf, 0x43, 0x61, 0xcf, 0xf1, 0x3c, 0x3b, 0xae, 0xa2, + 0x9b, 0xe8, 0xd6, 0xf5, 0xdb, 0xcf, 0x35, 0x75, 0xf4, 0x44, 0x4d, 0x94, 0x59, 0x00, 0x7b, 0xd4, + 0x1f, 0xda, 0x71, 0x35, 0xb7, 0x04, 0x4c, 0xd4, 0x44, 0x99, 0x05, 0xf0, 0xc8, 0x99, 0x50, 0x3b, + 0xae, 0x1a, 0x4b, 0xc0, 0x44, 0x4d, 0x94, 0x19, 0xbf, 0x09, 0xc5, 0x13, 0x1a, 0x4e, 0x22, 0x3b, + 0xae, 0x9a, 0x12, 0x59, 0x49, 0x91, 0x4a, 0x4f, 0x34, 0x00, 0xbf, 0x0a, 0xf9, 0xbb, 0xec, 0xa1, + 0x1d, 0x57, 0xf3, 0x12, 0xb9, 0x95, 0x22, 0xa5, 0x96, 0x24, 0x46, 0x11, 0xda, 0x62, 0x32, 0xc7, + 0xc2, 0x52, 0xe8, 0x44, 0x4d, 0x94, 0x19, 0xef, 0x40, 0xe9, 0xd4, 0xef, 0x27, 0xd0, 0xa2, 0x84, + 0xde, 0x48, 0xa1, 0xda, 0x40, 0x52, 0x88, 0xc8, 0xd4, 0x72, 0xf8, 0x60, 0x6c, 0xc7, 0xd5, 0xd2, + 0x52, 0xa6, 0x4a, 0x4f, 0x34, 0x00, 0xdf, 0x01, 0x38, 0x09, 0x59, 0xc0, 0x22, 0x47, 0x90, 0x7a, + 0x4d, 0xc2, 0x9f, 0x9f, 0x5f, 0x2c, 0x35, 0x91, 0x0c, 0x6c, 0xd7, 0x3c, 0x3f, 0xab, 0xa3, 0xc6, + 0x8f, 0x08, 0x8a, 0x76, 0x7c, 0xe8, 0x07, 0x53, 0x8e, 0x8f, 0xa0, 0xd8, 0x1e, 0x0e, 0x43, 0x1a, + 0x45, 0xb2, 0x30, 0x65, 0xeb, 0xbd, 0xf3, 0x47, 0xf5, 0x8d, 0x3f, 0x1e, 0xd5, 0xdf, 0xce, 0x74, + 0xc1, 0x78, 0x16, 0xd0, 0xd0, 0xa3, 0xc3, 0x11, 0x0d, 0x5b, 0xfd, 0x69, 0x18, 0xb2, 0xaf, 0x5b, + 0x83, 0x70, 0x16, 0x70, 0xd6, 0x54, 0x67, 0x89, 0x76, 0x82, 0x5f, 0x82, 0x42, 0x7b, 0xc2, 0xa6, + 0x3e, 0x97, 0xe5, 0x33, 0x89, 0x92, 0xf0, 0x36, 0x94, 0x7a, 0xf4, 0xab, 0x29, 0xf5, 0x07, 0x54, + 0xd6, 0xcb, 0x24, 0xa9, 0xbc, 0x6b, 0xfe, 0x74, 0x56, 0xdf, 0x68, 0xc4, 0x50, 0xb2, 0xe3, 0xe3, + 0x29, 0x7f, 0x86, 0x59, 0xa9, 0xc8, 0xbf, 0xe5, 0x74, 0x73, 0xe2, 0xd7, 0x20, 0x2f, 0x79, 0x51, + 0x5d, 0x3a, 0xe7, 0x5f, 0xf1, 0x45, 0x12, 0x33, 0xfe, 0x78, 0x9e, 0x60, 0x4e, 0x26, 0xf8, 0xce, + 0xd5, 0x93, 0xdb, 0x86, 0xd2, 0x5d, 0x27, 0xba, 0xe7, 0x4e, 0x5c, 0xae, 0xa9, 0xd1, 0x32, 0xae, + 0x80, 0xb1, 0x4f, 0xa9, 0xec, 0x5b, 0x93, 0x88, 0x4f, 0x7c, 0x08, 0x66, 0xc7, 0xe1, 0x8e, 0x6c, + 0xd0, 0xb2, 0xf5, 0xbe, 0xe2, 0x65, 0xe7, 0xe9, 0xa1, 0xfb, 0xae, 0xef, 0x84, 0xb3, 0xe6, 0x01, + 0x8d, 0xad, 0x19, 0xa7, 0x11, 0x91, 0x2e, 0x84, 0xab, 0x07, 0xed, 0xde, 0x27, 0xb2, 0x89, 0xaf, + 0xee, 0x4a, 0xb8, 0x50, 0x44, 0xba, 0x7a, 0x76, 0xf1, 0x2d, 0x28, 0x48, 0xa2, 0x44, 0xfd, 0x8c, + 0x7f, 0x24, 0x52, 0xd9, 0xf1, 0x5b, 0x50, 0x4c, 0x8a, 0x2e, 0x98, 0x34, 0x16, 0x26, 0x44, 0xb7, + 0x03, 0xd1, 0x88, 0xdd, 0xd2, 0xf7, 0x67, 0xf5, 0x0d, 0x19, 0x8a, 0xa5, 0x43, 0xbd, 0x72, 0xcd, + 0x3e, 0x80, 0x92, 0x38, 0xd2, 0x0e, 0x47, 0x91, 0xda, 0x2d, 0x2f, 0x34, 0x33, 0xbb, 0x4b, 0xdb, + 0x2c, 0x53, 0x10, 0x41, 0x52, 0xac, 0xba, 0x5b, 0xa0, 0xd7, 0xcd, 0xca, 0xf1, 0x30, 0x98, 0xe2, + 0x84, 0x8c, 0x75, 0x8d, 0xc8, 0x6f, 0xa1, 0x93, 0xd5, 0x33, 0x12, 0x9d, 0x2c, 0xc3, 0x13, 0x35, + 0x56, 0x11, 0xbf, 0xd4, 0x5b, 0x66, 0x0d, 0x36, 0xe7, 0x0b, 0x87, 0xfd, 0x3b, 0x9d, 0x29, 0x24, + 0xc3, 0xe7, 0xcf, 0x68, 0xbe, 0xaa, 0x56, 0xbe, 0xe1, 0xd1, 0xf2, 0x14, 0xfc, 0xf7, 0x31, 0x3d, + 0xa0, 0xee, 0x68, 0xac, 0xe7, 0x40, 0x49, 0x99, 0x34, 0xbf, 0x45, 0x6a, 0x41, 0xaf, 0xc1, 0xc9, + 0x1e, 0x6c, 0xb5, 0x07, 0x03, 0x31, 0xef, 0xa7, 0xc1, 0xd0, 0xe1, 0x54, 0x37, 0xda, 0x8b, 0x4d, + 0xf9, 0x4e, 0xd9, 0x74, 0x12, 0x78, 0x0e, 0xa7, 0x0a, 0x23, 0xcb, 0x8f, 0xc8, 0xd2, 0x91, 0x4c, + 0x0a, 0x7f, 0xa1, 0xec, 0xe6, 0x5d, 0x99, 0xab, 0x06, 0x94, 0xef, 0x33, 0xee, 0xfa, 0xa3, 0x07, + 0xc9, 0x0d, 0x05, 0x61, 0x06, 0x59, 0xd0, 0xe1, 0x53, 0x28, 0x6b, 0xcf, 0x07, 0x4e, 0x34, 0x96, + 0x2c, 0x94, 0xad, 0x77, 0xd7, 0x1f, 0xca, 0x05, 0x37, 0xa2, 0x29, 0xb4, 0xac, 0x5e, 0xc0, 0x1b, + 0x4f, 0x3c, 0x14, 0x24, 0x85, 0x64, 0xae, 0xfa, 0x79, 0xfa, 0x1e, 0xad, 0x41, 0x77, 0x0d, 0x0c, + 0x3b, 0xd6, 0x1c, 0x97, 0x53, 0x58, 0xdb, 0x9f, 0x11, 0x61, 0xc8, 0xb8, 0xff, 0x0e, 0x81, 0x79, + 0x9f, 0x71, 0xfa, 0xbf, 0xaf, 0xfb, 0x15, 0xb8, 0xce, 0xa4, 0xf1, 0x70, 0x4e, 0x4f, 0x3a, 0xb3, + 0x28, 0x33, 0xb3, 0x37, 0xe1, 0x7a, 0x87, 0x46, 0x83, 0xd0, 0x0d, 0xb8, 0xcb, 0x7c, 0x35, 0xce, + 0x59, 0x55, 0xf6, 0xdd, 0x36, 0x2e, 0x79, 0xb7, 0x33, 0x71, 0x7f, 0xc9, 0x41, 0xc1, 0x72, 0x3c, + 0x8f, 0xf1, 0x85, 0x0a, 0xa1, 0x4b, 0x2b, 0x24, 0xfa, 0x64, 0xdf, 0xf5, 0x1d, 0xcf, 0xfd, 0xc6, + 0xf5, 0x47, 0xea, 0x4f, 0xe9, 0x6a, 0x7d, 0x92, 0x75, 0x83, 0xf7, 0x60, 0x33, 0x50, 0x21, 0x7a, + 0xdc, 0xe1, 0xc9, 0x4a, 0xda, 0xba, 0xfd, 0x72, 0xe6, 0x32, 0x22, 0xdb, 0x34, 0x23, 0x09, 0x22, + 0x8b, 0x67, 0xf0, 0x2b, 0x90, 0x17, 0x35, 0x8d, 0xaa, 0x79, 0xd9, 0x00, 0x9b, 0xe9, 0x61, 0xa1, + 0x25, 0x89, 0xad, 0xf1, 0x21, 0x6c, 0x2e, 0x38, 0xc1, 0x65, 0x28, 0x9d, 0x90, 0xe3, 0x93, 0xe3, + 0x5e, 0xb7, 0x53, 0xd9, 0x10, 0x52, 0xf7, 0xd3, 0xee, 0xde, 0xa9, 0xdd, 0xed, 0x54, 0x10, 0x06, + 0x28, 0xec, 0xb7, 0x0f, 0xef, 0x75, 0x3b, 0x95, 0x9c, 0xf5, 0xd1, 0xf9, 0x45, 0x0d, 0xfd, 0x7e, + 0x51, 0x43, 0x7f, 0x5e, 0xd4, 0xd0, 0xaf, 0x8f, 0x6b, 0xe8, 0xfc, 0x71, 0x0d, 0x7d, 0xf6, 0xc6, + 0xd3, 0x6f, 0xcd, 0xe3, 0xa8, 0xa5, 0xb2, 0xe8, 0x17, 0xe4, 0x6f, 0xe9, 0x9d, 0xbf, 0x03, 0x00, + 0x00, 0xff, 0xff, 0xe5, 0x14, 0x00, 0x2d, 0xfd, 0x0a, 0x00, 0x00, } func (m *Any) Marshal() (dAtA []byte, err error) { @@ -1269,6 +1272,14 @@ func (m *CallTx) MarshalTo(dAtA []byte) (int, error) { return 0, err } i += n14 + dAtA[i] = 0x32 + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.WASM.Size())) + n15, err := m.WASM.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n15 if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -1339,20 +1350,20 @@ func (m *PermsTx) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintPayload(dAtA, i, uint64(m.Input.Size())) - n15, err := m.Input.MarshalTo(dAtA[i:]) + n16, err := m.Input.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n15 + i += n16 } dAtA[i] = 0x12 i++ i = encodeVarintPayload(dAtA, i, uint64(m.PermArgs.Size())) - n16, err := m.PermArgs.MarshalTo(dAtA[i:]) + n17, err := m.PermArgs.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n16 + i += n17 if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -1378,11 +1389,11 @@ func (m *NameTx) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintPayload(dAtA, i, uint64(m.Input.Size())) - n17, err := m.Input.MarshalTo(dAtA[i:]) + n18, err := m.Input.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n17 + i += n18 } if len(m.Name) > 0 { dAtA[i] = 0x12 @@ -1471,20 +1482,20 @@ func (m *UnbondTx) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintPayload(dAtA, i, uint64(m.Input.Size())) - n18, err := m.Input.MarshalTo(dAtA[i:]) + n19, err := m.Input.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n18 + i += n19 } dAtA[i] = 0x12 i++ i = encodeVarintPayload(dAtA, i, uint64(m.Address.Size())) - n19, err := m.Address.MarshalTo(dAtA[i:]) + n20, err := m.Address.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n19 + i += n20 if m.Height != 0 { dAtA[i] = 0x18 i++ @@ -1560,11 +1571,11 @@ func (m *ProposalTx) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintPayload(dAtA, i, uint64(m.Input.Size())) - n20, err := m.Input.MarshalTo(dAtA[i:]) + n21, err := m.Input.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n20 + i += n21 } if m.VotingWeight != 0 { dAtA[i] = 0x10 @@ -1575,21 +1586,21 @@ func (m *ProposalTx) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintPayload(dAtA, i, uint64(m.ProposalHash.Size())) - n21, err := m.ProposalHash.MarshalTo(dAtA[i:]) + n22, err := m.ProposalHash.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n21 + i += n22 } if m.Proposal != nil { dAtA[i] = 0x22 i++ i = encodeVarintPayload(dAtA, i, uint64(m.Proposal.Size())) - n22, err := m.Proposal.MarshalTo(dAtA[i:]) + n23, err := m.Proposal.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n22 + i += n23 } if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) @@ -1660,11 +1671,11 @@ func (m *Vote) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintPayload(dAtA, i, uint64(m.Address.Size())) - n23, err := m.Address.MarshalTo(dAtA[i:]) + n24, err := m.Address.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n23 + i += n24 if m.VotingWeight != 0 { dAtA[i] = 0x10 i++ @@ -1707,11 +1718,11 @@ func (m *Proposal) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintPayload(dAtA, i, uint64(m.BatchTx.Size())) - n24, err := m.BatchTx.MarshalTo(dAtA[i:]) + n25, err := m.BatchTx.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n24 + i += n25 } if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) @@ -1738,21 +1749,21 @@ func (m *Ballot) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintPayload(dAtA, i, uint64(m.Proposal.Size())) - n25, err := m.Proposal.MarshalTo(dAtA[i:]) + n26, err := m.Proposal.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n25 + i += n26 } if m.FinalizingTx != nil { dAtA[i] = 0x12 i++ i = encodeVarintPayload(dAtA, i, uint64(m.FinalizingTx.Size())) - n26, err := m.FinalizingTx.MarshalTo(dAtA[i:]) + n27, err := m.FinalizingTx.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n26 + i += n27 } if m.ProposalState != 0 { dAtA[i] = 0x20 @@ -1893,6 +1904,8 @@ func (m *CallTx) Size() (n int) { } l = m.Data.Size() n += 1 + l + sovPayload(uint64(l)) + l = m.WASM.Size() + n += 1 + l + sovPayload(uint64(l)) if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -3007,6 +3020,39 @@ func (m *CallTx) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field WASM", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPayload + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.WASM.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipPayload(dAtA[iNdEx:]) From ab4e014c611b335917bd443436cb3f987dd797ca Mon Sep 17 00:00:00 2001 From: Sean Young Date: Wed, 12 Jun 2019 15:07:02 +0100 Subject: [PATCH 2/7] Run WASM in burrow Signed-off-by: Sean Young --- execution/contexts/call_context.go | 68 +++++++++++---- execution/evm/state.go | 17 ++++ go.mod | 3 + go.sum | 6 ++ protobuf/payload.proto | 6 +- txs/payload/payload.pb.go | 129 +++++++++++++++-------------- 6 files changed, 147 insertions(+), 82 deletions(-) diff --git a/execution/contexts/call_context.go b/execution/contexts/call_context.go index 3e938edad..0123970ab 100644 --- a/execution/contexts/call_context.go +++ b/execution/contexts/call_context.go @@ -13,6 +13,7 @@ import ( "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/logging/structure" "github.com/hyperledger/burrow/txs/payload" + wexec "github.com/perlin-network/life/exec" ) // TODO: make configurable @@ -189,27 +190,64 @@ func (ctx *CallContext) Deliver(inAcc, outAcc *acm.Account, value uint64) error txHash := ctx.txe.Envelope.Tx.Hash() logger := ctx.Logger.With(structure.TxHashKey, txHash) - vmach := evm.NewVM(params, caller, txHash, logger, ctx.VMOptions...) - ret, exception := vmach.Call(txCache, ctx.txe, caller, callee, code, ctx.tx.Data, value, &gas) - if exception != nil { - // Failure. Charge the gas fee. The 'value' was otherwise not transferred. - ctx.Logger.InfoMsg("Error on execution", - structure.ErrorKey, exception) - - ctx.txe.PushError(errors.ErrorCodef(exception.ErrorCode(), "call error: %s\nEVM call trace: %s", - exception.String(), ctx.txe.CallTrace())) - } else { - ctx.Logger.TraceMsg("Successful execution") + var exception errors.CodedError + if wasm != nil { + // WASM + config := wexec.VMConfig{ + DisableFloatingPoint: true, + MaxMemoryPages: 2, + DefaultMemoryPages: 2, + } + vm, err := wexec.NewVirtualMachine(wasm, config, &wexec.NopResolver{}, nil) + if err != nil { + ctx.Logger.InfoMsg("Invalid WASM bytecode", + "error", err) + return err + } + wasmFunc := "function" if createContract { - txCache.InitCode(callee, ret) + txCache.InitWASMCode(callee, wasm) + wasmFunc = "constructor" + } + entryID, ok := vm.GetFunctionExport(wasmFunc) + if !ok { + ctx.Logger.InfoMsg("Missing exported WASM function", "export", wasmFunc) + return fmt.Errorf("WASM missing function %s", wasmFunc) } - err := txCache.Sync() + _, err = vm.Run(entryID) if err != nil { + ctx.Logger.InfoMsg("Error returned from WASM", "error", err) return err } + err = txCache.Sync() + if err != nil { + return err + } + } else { + // EVM + vmach := evm.NewVM(params, caller, txHash, logger, ctx.VMOptions...) + ret, exception = vmach.Call(txCache, ctx.txe, caller, callee, code, ctx.tx.Data, value, &gas) + if exception != nil { + // Failure. Charge the gas fee. The 'value' was otherwise not transferred. + ctx.Logger.InfoMsg("Error on execution", + structure.ErrorKey, exception) + + ctx.txe.PushError(errors.ErrorCodef(exception.ErrorCode(), "call error: %s\nEVM call trace: %s", + exception.String(), ctx.txe.CallTrace())) + } else { + ctx.Logger.TraceMsg("Successful execution") + if createContract { + txCache.InitCode(callee, ret) + } + err := txCache.Sync() + if err != nil { + return err + } + } + ctx.CallEvents(exception) + ctx.txe.Return(ret, ctx.tx.GasLimit-gas) } - ctx.CallEvents(exception) - ctx.txe.Return(ret, ctx.tx.GasLimit-gas) + // Create a receipt from the ret and whether it erred. ctx.Logger.TraceMsg("VM call complete", "caller", caller, diff --git a/execution/evm/state.go b/execution/evm/state.go index 30751ddef..d6ed530c8 100644 --- a/execution/evm/state.go +++ b/execution/evm/state.go @@ -38,6 +38,7 @@ type Reader interface { type Writer interface { CreateAccount(address crypto.Address) InitCode(address crypto.Address, code []byte) + InitWASMCode(address crypto.Address, code []byte) RemoveAccount(address crypto.Address) SetStorage(address crypto.Address, key, value binary.Word256) AddToBalance(address crypto.Address, amount uint64) @@ -196,6 +197,22 @@ func (st *State) InitCode(address crypto.Address, code []byte) { st.updateAccount(acc) } +func (st *State) InitWASMCode(address crypto.Address, code []byte) { + acc := st.mustAccount(address) + if acc == nil { + st.PushError(errors.ErrorCodef(errors.ErrorCodeInvalidAddress, + "tried to initialise code for an account that does not exist: %v", address)) + return + } + if acc.Code != nil { + st.PushError(errors.ErrorCodef(errors.ErrorCodeIllegalWrite, + "tried to initialise code for a contract that already exists: %v", address)) + return + } + acc.WASM = code + st.updateAccount(acc) +} + func (st *State) RemoveAccount(address crypto.Address) { if !st.Exists(address) { st.PushError(errors.ErrorCodef(errors.ErrorCodeDuplicateAddress, diff --git a/go.mod b/go.mod index 19d8da494..1792aba69 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module github.com/hyperledger/burrow go 1.12 +replace github.com/go-interpreter/wagon v0.0.0 => github.com/perlin-network/wagon v0.3.1-0.20180825141017-f8cb99b55a39 + require ( github.com/BurntSushi/toml v0.3.1 github.com/OneOfOne/xxhash v1.2.5 @@ -36,6 +38,7 @@ require ( github.com/magiconair/properties v1.8.0 github.com/mattn/go-sqlite3 v1.10.0 github.com/monax/relic v2.0.0+incompatible + github.com/perlin-network/life v0.0.0-20190521143330-57f3819c2df0 github.com/pkg/errors v0.8.1 github.com/prometheus/client_golang v0.9.2 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 diff --git a/go.sum b/go.sum index 9d0bf53f0..deaaddd66 100644 --- a/go.sum +++ b/go.sum @@ -126,6 +126,10 @@ github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/perlin-network/life v0.0.0-20190521143330-57f3819c2df0 h1:fP9xTEHvfuArvWXQhRDYHSBNX/3ZaAfFKlxzpZtUsqs= +github.com/perlin-network/life v0.0.0-20190521143330-57f3819c2df0/go.mod h1:z/EH0mO9zbeuTT5NX4u2VqVSG8y2vDQXz6iDKxikW2I= +github.com/perlin-network/wagon v0.3.1-0.20180825141017-f8cb99b55a39 h1:CYHXy6CWxxL7ugjvCbTELOm2j5iRLEWGPl3AQYvretw= +github.com/perlin-network/wagon v0.3.1-0.20180825141017-f8cb99b55a39/go.mod h1:zHOMvbitcZek8oshsMO5VpyBjWjV9X8cn8WTZwdebpM= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -174,6 +178,8 @@ github.com/tendermint/tendermint v0.31.5/go.mod h1:ymcPyWblXCplCPQjbOYbrF1fWnpsl github.com/tmthrgd/go-hex v0.0.0-20190303111820-0bdcb15db631 h1:IlK6taZBmMKDcGfMqIlD4la5BlekNrrLsdtCMSn6aJI= github.com/tmthrgd/go-hex v0.0.0-20190303111820-0bdcb15db631/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= +github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= diff --git a/protobuf/payload.proto b/protobuf/payload.proto index ecfdc2439..867787ee5 100644 --- a/protobuf/payload.proto +++ b/protobuf/payload.proto @@ -66,10 +66,10 @@ message CallTx { uint64 GasLimit = 3; // Fee to offer validators for processing transaction uint64 Fee = 4; - // EVM bytecode payload or call data + // EVM bytecode bytes Data = 5 [(gogoproto.customtype) = "github.com/hyperledger/burrow/binary.HexBytes", (gogoproto.nullable) = false]; - // - bytes WASM = 6 [(gogoproto.customtype) = "github.com/hyperledger/burrow/binary.HexBytes", (gogoproto.nullable) = false]; + // WASM bytecode + bytes WASM = 6 [(gogoproto.customtype) = "github.com/hyperledger/burrow/binary.HexBytes", (gogoproto.nullable) = false, (gogoproto.jsontag)="tags,omitempty"]; } // A payment between two sets of parties diff --git a/txs/payload/payload.pb.go b/txs/payload/payload.pb.go index 56d75f97f..3f41ab25e 100644 --- a/txs/payload/payload.pb.go +++ b/txs/payload/payload.pb.go @@ -300,10 +300,10 @@ type CallTx struct { GasLimit uint64 `protobuf:"varint,3,opt,name=GasLimit,proto3" json:"GasLimit,omitempty"` // Fee to offer validators for processing transaction Fee uint64 `protobuf:"varint,4,opt,name=Fee,proto3" json:"Fee,omitempty"` - // EVM bytecode payload or call data + // EVM bytecode Data github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,5,opt,name=Data,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"Data"` - // - WASM github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,6,opt,name=WASM,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"WASM"` + // WASM bytecode + WASM github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,6,opt,name=WASM,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"tags,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -971,68 +971,69 @@ func init() { proto.RegisterFile("payload.proto", fileDescriptor_678c914f1bee6d5 func init() { golang_proto.RegisterFile("payload.proto", fileDescriptor_678c914f1bee6d56) } var fileDescriptor_678c914f1bee6d56 = []byte{ - // 971 bytes of a gzipped FileDescriptorProto + // 991 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x4b, 0x6f, 0x23, 0x45, - 0x10, 0x4e, 0x7b, 0xc6, 0x8f, 0xad, 0x75, 0x82, 0xb7, 0x79, 0xc8, 0x8a, 0x84, 0xbd, 0x32, 0x08, - 0x96, 0x47, 0x6c, 0xd8, 0xe5, 0x21, 0xe5, 0x82, 0x3c, 0xb1, 0xb3, 0x09, 0x5a, 0x92, 0xa8, 0x3d, - 0xd9, 0x45, 0x48, 0x1c, 0xc6, 0x76, 0x63, 0x8f, 0x18, 0x4f, 0x0f, 0x33, 0xed, 0x65, 0xcc, 0x89, - 0x03, 0x07, 0xae, 0x88, 0x0b, 0xc7, 0x1c, 0xf8, 0x03, 0xfc, 0x03, 0x4e, 0x28, 0x47, 0xce, 0x1c, - 0x56, 0x28, 0x7b, 0xe1, 0x67, 0xa0, 0xee, 0xe9, 0x1e, 0x8f, 0xbd, 0xb0, 0xb1, 0x03, 0xda, 0xdb, - 0x54, 0xd5, 0xd7, 0x55, 0xd5, 0x5f, 0x3d, 0x7a, 0x60, 0x33, 0x70, 0x66, 0x1e, 0x73, 0x86, 0xcd, - 0x20, 0x64, 0x9c, 0xe1, 0xa2, 0x12, 0xb7, 0x77, 0x46, 0x2e, 0x1f, 0x4f, 0xfb, 0xcd, 0x01, 0x9b, - 0xb4, 0x46, 0x6c, 0xc4, 0x5a, 0xd2, 0xde, 0x9f, 0x7e, 0x21, 0x25, 0x29, 0xc8, 0xaf, 0xe4, 0xdc, - 0x76, 0x25, 0xa0, 0xe1, 0xc4, 0x8d, 0x22, 0x97, 0xf9, 0x4a, 0x03, 0x51, 0x40, 0x07, 0xc9, 0x77, - 0xe3, 0x07, 0x03, 0x8c, 0xb6, 0x3f, 0xc3, 0xaf, 0x43, 0x61, 0xcf, 0xf1, 0x3c, 0x3b, 0xae, 0xa2, - 0x9b, 0xe8, 0xd6, 0xf5, 0xdb, 0xcf, 0x35, 0x75, 0xf4, 0x44, 0x4d, 0x94, 0x59, 0x00, 0x7b, 0xd4, - 0x1f, 0xda, 0x71, 0x35, 0xb7, 0x04, 0x4c, 0xd4, 0x44, 0x99, 0x05, 0xf0, 0xc8, 0x99, 0x50, 0x3b, - 0xae, 0x1a, 0x4b, 0xc0, 0x44, 0x4d, 0x94, 0x19, 0xbf, 0x09, 0xc5, 0x13, 0x1a, 0x4e, 0x22, 0x3b, - 0xae, 0x9a, 0x12, 0x59, 0x49, 0x91, 0x4a, 0x4f, 0x34, 0x00, 0xbf, 0x0a, 0xf9, 0xbb, 0xec, 0xa1, - 0x1d, 0x57, 0xf3, 0x12, 0xb9, 0x95, 0x22, 0xa5, 0x96, 0x24, 0x46, 0x11, 0xda, 0x62, 0x32, 0xc7, - 0xc2, 0x52, 0xe8, 0x44, 0x4d, 0x94, 0x19, 0xef, 0x40, 0xe9, 0xd4, 0xef, 0x27, 0xd0, 0xa2, 0x84, - 0xde, 0x48, 0xa1, 0xda, 0x40, 0x52, 0x88, 0xc8, 0xd4, 0x72, 0xf8, 0x60, 0x6c, 0xc7, 0xd5, 0xd2, - 0x52, 0xa6, 0x4a, 0x4f, 0x34, 0x00, 0xdf, 0x01, 0x38, 0x09, 0x59, 0xc0, 0x22, 0x47, 0x90, 0x7a, - 0x4d, 0xc2, 0x9f, 0x9f, 0x5f, 0x2c, 0x35, 0x91, 0x0c, 0x6c, 0xd7, 0x3c, 0x3f, 0xab, 0xa3, 0xc6, - 0x8f, 0x08, 0x8a, 0x76, 0x7c, 0xe8, 0x07, 0x53, 0x8e, 0x8f, 0xa0, 0xd8, 0x1e, 0x0e, 0x43, 0x1a, - 0x45, 0xb2, 0x30, 0x65, 0xeb, 0xbd, 0xf3, 0x47, 0xf5, 0x8d, 0x3f, 0x1e, 0xd5, 0xdf, 0xce, 0x74, - 0xc1, 0x78, 0x16, 0xd0, 0xd0, 0xa3, 0xc3, 0x11, 0x0d, 0x5b, 0xfd, 0x69, 0x18, 0xb2, 0xaf, 0x5b, - 0x83, 0x70, 0x16, 0x70, 0xd6, 0x54, 0x67, 0x89, 0x76, 0x82, 0x5f, 0x82, 0x42, 0x7b, 0xc2, 0xa6, - 0x3e, 0x97, 0xe5, 0x33, 0x89, 0x92, 0xf0, 0x36, 0x94, 0x7a, 0xf4, 0xab, 0x29, 0xf5, 0x07, 0x54, - 0xd6, 0xcb, 0x24, 0xa9, 0xbc, 0x6b, 0xfe, 0x74, 0x56, 0xdf, 0x68, 0xc4, 0x50, 0xb2, 0xe3, 0xe3, - 0x29, 0x7f, 0x86, 0x59, 0xa9, 0xc8, 0xbf, 0xe5, 0x74, 0x73, 0xe2, 0xd7, 0x20, 0x2f, 0x79, 0x51, - 0x5d, 0x3a, 0xe7, 0x5f, 0xf1, 0x45, 0x12, 0x33, 0xfe, 0x78, 0x9e, 0x60, 0x4e, 0x26, 0xf8, 0xce, - 0xd5, 0x93, 0xdb, 0x86, 0xd2, 0x5d, 0x27, 0xba, 0xe7, 0x4e, 0x5c, 0xae, 0xa9, 0xd1, 0x32, 0xae, - 0x80, 0xb1, 0x4f, 0xa9, 0xec, 0x5b, 0x93, 0x88, 0x4f, 0x7c, 0x08, 0x66, 0xc7, 0xe1, 0x8e, 0x6c, - 0xd0, 0xb2, 0xf5, 0xbe, 0xe2, 0x65, 0xe7, 0xe9, 0xa1, 0xfb, 0xae, 0xef, 0x84, 0xb3, 0xe6, 0x01, - 0x8d, 0xad, 0x19, 0xa7, 0x11, 0x91, 0x2e, 0x84, 0xab, 0x07, 0xed, 0xde, 0x27, 0xb2, 0x89, 0xaf, - 0xee, 0x4a, 0xb8, 0x50, 0x44, 0xba, 0x7a, 0x76, 0xf1, 0x2d, 0x28, 0x48, 0xa2, 0x44, 0xfd, 0x8c, - 0x7f, 0x24, 0x52, 0xd9, 0xf1, 0x5b, 0x50, 0x4c, 0x8a, 0x2e, 0x98, 0x34, 0x16, 0x26, 0x44, 0xb7, - 0x03, 0xd1, 0x88, 0xdd, 0xd2, 0xf7, 0x67, 0xf5, 0x0d, 0x19, 0x8a, 0xa5, 0x43, 0xbd, 0x72, 0xcd, - 0x3e, 0x80, 0x92, 0x38, 0xd2, 0x0e, 0x47, 0x91, 0xda, 0x2d, 0x2f, 0x34, 0x33, 0xbb, 0x4b, 0xdb, - 0x2c, 0x53, 0x10, 0x41, 0x52, 0xac, 0xba, 0x5b, 0xa0, 0xd7, 0xcd, 0xca, 0xf1, 0x30, 0x98, 0xe2, - 0x84, 0x8c, 0x75, 0x8d, 0xc8, 0x6f, 0xa1, 0x93, 0xd5, 0x33, 0x12, 0x9d, 0x2c, 0xc3, 0x13, 0x35, - 0x56, 0x11, 0xbf, 0xd4, 0x5b, 0x66, 0x0d, 0x36, 0xe7, 0x0b, 0x87, 0xfd, 0x3b, 0x9d, 0x29, 0x24, - 0xc3, 0xe7, 0xcf, 0x68, 0xbe, 0xaa, 0x56, 0xbe, 0xe1, 0xd1, 0xf2, 0x14, 0xfc, 0xf7, 0x31, 0x3d, - 0xa0, 0xee, 0x68, 0xac, 0xe7, 0x40, 0x49, 0x99, 0x34, 0xbf, 0x45, 0x6a, 0x41, 0xaf, 0xc1, 0xc9, - 0x1e, 0x6c, 0xb5, 0x07, 0x03, 0x31, 0xef, 0xa7, 0xc1, 0xd0, 0xe1, 0x54, 0x37, 0xda, 0x8b, 0x4d, - 0xf9, 0x4e, 0xd9, 0x74, 0x12, 0x78, 0x0e, 0xa7, 0x0a, 0x23, 0xcb, 0x8f, 0xc8, 0xd2, 0x91, 0x4c, - 0x0a, 0x7f, 0xa1, 0xec, 0xe6, 0x5d, 0x99, 0xab, 0x06, 0x94, 0xef, 0x33, 0xee, 0xfa, 0xa3, 0x07, - 0xc9, 0x0d, 0x05, 0x61, 0x06, 0x59, 0xd0, 0xe1, 0x53, 0x28, 0x6b, 0xcf, 0x07, 0x4e, 0x34, 0x96, - 0x2c, 0x94, 0xad, 0x77, 0xd7, 0x1f, 0xca, 0x05, 0x37, 0xa2, 0x29, 0xb4, 0xac, 0x5e, 0xc0, 0x1b, - 0x4f, 0x3c, 0x14, 0x24, 0x85, 0x64, 0xae, 0xfa, 0x79, 0xfa, 0x1e, 0xad, 0x41, 0x77, 0x0d, 0x0c, - 0x3b, 0xd6, 0x1c, 0x97, 0x53, 0x58, 0xdb, 0x9f, 0x11, 0x61, 0xc8, 0xb8, 0xff, 0x0e, 0x81, 0x79, - 0x9f, 0x71, 0xfa, 0xbf, 0xaf, 0xfb, 0x15, 0xb8, 0xce, 0xa4, 0xf1, 0x70, 0x4e, 0x4f, 0x3a, 0xb3, - 0x28, 0x33, 0xb3, 0x37, 0xe1, 0x7a, 0x87, 0x46, 0x83, 0xd0, 0x0d, 0xb8, 0xcb, 0x7c, 0x35, 0xce, - 0x59, 0x55, 0xf6, 0xdd, 0x36, 0x2e, 0x79, 0xb7, 0x33, 0x71, 0x7f, 0xc9, 0x41, 0xc1, 0x72, 0x3c, - 0x8f, 0xf1, 0x85, 0x0a, 0xa1, 0x4b, 0x2b, 0x24, 0xfa, 0x64, 0xdf, 0xf5, 0x1d, 0xcf, 0xfd, 0xc6, - 0xf5, 0x47, 0xea, 0x4f, 0xe9, 0x6a, 0x7d, 0x92, 0x75, 0x83, 0xf7, 0x60, 0x33, 0x50, 0x21, 0x7a, - 0xdc, 0xe1, 0xc9, 0x4a, 0xda, 0xba, 0xfd, 0x72, 0xe6, 0x32, 0x22, 0xdb, 0x34, 0x23, 0x09, 0x22, - 0x8b, 0x67, 0xf0, 0x2b, 0x90, 0x17, 0x35, 0x8d, 0xaa, 0x79, 0xd9, 0x00, 0x9b, 0xe9, 0x61, 0xa1, - 0x25, 0x89, 0xad, 0xf1, 0x21, 0x6c, 0x2e, 0x38, 0xc1, 0x65, 0x28, 0x9d, 0x90, 0xe3, 0x93, 0xe3, - 0x5e, 0xb7, 0x53, 0xd9, 0x10, 0x52, 0xf7, 0xd3, 0xee, 0xde, 0xa9, 0xdd, 0xed, 0x54, 0x10, 0x06, - 0x28, 0xec, 0xb7, 0x0f, 0xef, 0x75, 0x3b, 0x95, 0x9c, 0xf5, 0xd1, 0xf9, 0x45, 0x0d, 0xfd, 0x7e, - 0x51, 0x43, 0x7f, 0x5e, 0xd4, 0xd0, 0xaf, 0x8f, 0x6b, 0xe8, 0xfc, 0x71, 0x0d, 0x7d, 0xf6, 0xc6, - 0xd3, 0x6f, 0xcd, 0xe3, 0xa8, 0xa5, 0xb2, 0xe8, 0x17, 0xe4, 0x6f, 0xe9, 0x9d, 0xbf, 0x03, 0x00, - 0x00, 0xff, 0xff, 0xe5, 0x14, 0x00, 0x2d, 0xfd, 0x0a, 0x00, 0x00, + 0x10, 0xce, 0x78, 0xc6, 0x8f, 0xad, 0x75, 0x82, 0xb7, 0x79, 0xc8, 0x8a, 0x84, 0xbd, 0x32, 0x08, + 0x16, 0xd8, 0xd8, 0xb0, 0xcb, 0x43, 0xca, 0x05, 0x79, 0x62, 0xe7, 0x81, 0x96, 0x24, 0x6a, 0x4f, + 0x76, 0x11, 0x88, 0x43, 0xdb, 0x6e, 0xec, 0x11, 0x9e, 0xe9, 0x61, 0xa6, 0xbd, 0x8c, 0x39, 0x71, + 0xe0, 0xc0, 0x15, 0x71, 0xe1, 0x98, 0x03, 0x7f, 0x80, 0x7f, 0xc0, 0x31, 0x47, 0x8e, 0x88, 0x43, + 0x84, 0xb2, 0x17, 0xc4, 0xaf, 0x40, 0xdd, 0xd3, 0x3d, 0x1e, 0x7b, 0x61, 0xd7, 0x09, 0x88, 0xdb, + 0x54, 0xd5, 0xd7, 0x55, 0xd5, 0x5f, 0x3d, 0x7a, 0x60, 0x3d, 0x20, 0xb3, 0x09, 0x23, 0xc3, 0x66, + 0x10, 0x32, 0xce, 0x50, 0x51, 0x89, 0x9b, 0x5b, 0x23, 0x97, 0x8f, 0xa7, 0xfd, 0xe6, 0x80, 0x79, + 0xad, 0x11, 0x1b, 0xb1, 0x96, 0xb4, 0xf7, 0xa7, 0x9f, 0x49, 0x49, 0x0a, 0xf2, 0x2b, 0x39, 0xb7, + 0x59, 0x09, 0x68, 0xe8, 0xb9, 0x51, 0xe4, 0x32, 0x5f, 0x69, 0x20, 0x0a, 0xe8, 0x20, 0xf9, 0x6e, + 0x7c, 0x67, 0x82, 0xd9, 0xf6, 0x67, 0xe8, 0x55, 0x28, 0xec, 0x90, 0xc9, 0xc4, 0x89, 0xab, 0xc6, + 0x4d, 0xe3, 0xd6, 0xf5, 0x3b, 0xcf, 0x34, 0x75, 0xf4, 0x44, 0x8d, 0x95, 0x59, 0x00, 0x7b, 0xd4, + 0x1f, 0x3a, 0x71, 0x35, 0xb7, 0x04, 0x4c, 0xd4, 0x58, 0x99, 0x05, 0xf0, 0x90, 0x78, 0xd4, 0x89, + 0xab, 0xe6, 0x12, 0x30, 0x51, 0x63, 0x65, 0x46, 0xaf, 0x43, 0xf1, 0x98, 0x86, 0x5e, 0xe4, 0xc4, + 0x55, 0x4b, 0x22, 0x2b, 0x29, 0x52, 0xe9, 0xb1, 0x06, 0xa0, 0x97, 0x21, 0xbf, 0xc7, 0x1e, 0x3a, + 0x71, 0x35, 0x2f, 0x91, 0x1b, 0x29, 0x52, 0x6a, 0x71, 0x62, 0x14, 0xa1, 0x6d, 0x26, 0x73, 0x2c, + 0x2c, 0x85, 0x4e, 0xd4, 0x58, 0x99, 0xd1, 0x16, 0x94, 0x4e, 0xfc, 0x7e, 0x02, 0x2d, 0x4a, 0xe8, + 0x8d, 0x14, 0xaa, 0x0d, 0x38, 0x85, 0x88, 0x4c, 0x6d, 0xc2, 0x07, 0x63, 0x27, 0xae, 0x96, 0x96, + 0x32, 0x55, 0x7a, 0xac, 0x01, 0xe8, 0x2e, 0xc0, 0x71, 0xc8, 0x02, 0x16, 0x11, 0x41, 0xea, 0x35, + 0x09, 0x7f, 0x76, 0x7e, 0xb1, 0xd4, 0x84, 0x33, 0xb0, 0x6d, 0xeb, 0xec, 0xb4, 0x6e, 0x34, 0xbe, + 0x37, 0xa0, 0xe8, 0xc4, 0x07, 0x7e, 0x30, 0xe5, 0xe8, 0x10, 0x8a, 0xed, 0xe1, 0x30, 0xa4, 0x51, + 0x24, 0x0b, 0x53, 0xb6, 0xdf, 0x3e, 0x3b, 0xaf, 0xaf, 0xfd, 0x76, 0x5e, 0xbf, 0x9d, 0xe9, 0x82, + 0xf1, 0x2c, 0xa0, 0xe1, 0x84, 0x0e, 0x47, 0x34, 0x6c, 0xf5, 0xa7, 0x61, 0xc8, 0xbe, 0x6c, 0x0d, + 0xc2, 0x59, 0xc0, 0x59, 0x53, 0x9d, 0xc5, 0xda, 0x09, 0x7a, 0x01, 0x0a, 0x6d, 0x8f, 0x4d, 0x7d, + 0x2e, 0xcb, 0x67, 0x61, 0x25, 0xa1, 0x4d, 0x28, 0xf5, 0xe8, 0x17, 0x53, 0xea, 0x0f, 0xa8, 0xac, + 0x97, 0x85, 0x53, 0x79, 0xdb, 0xfa, 0xe1, 0xb4, 0xbe, 0xd6, 0x88, 0xa1, 0xe4, 0xc4, 0x47, 0x53, + 0xfe, 0x3f, 0x66, 0xa5, 0x22, 0xff, 0x9a, 0xd3, 0xcd, 0x89, 0x5e, 0x81, 0xbc, 0xe4, 0x45, 0x75, + 0xe9, 0x9c, 0x7f, 0xc5, 0x17, 0x4e, 0xcc, 0xe8, 0x83, 0x79, 0x82, 0x39, 0x99, 0xe0, 0x9b, 0x57, + 0x4f, 0x6e, 0x13, 0x4a, 0x7b, 0x24, 0xba, 0xe7, 0x7a, 0x2e, 0xd7, 0xd4, 0x68, 0x19, 0x55, 0xc0, + 0xdc, 0xa5, 0x54, 0xf6, 0xad, 0x85, 0xc5, 0x27, 0x3a, 0x00, 0xab, 0x43, 0x38, 0x91, 0x0d, 0x5a, + 0xb6, 0xdf, 0x51, 0xbc, 0x6c, 0x3d, 0x39, 0x74, 0xdf, 0xf5, 0x49, 0x38, 0x6b, 0xee, 0xd3, 0xd8, + 0x9e, 0x71, 0x1a, 0x61, 0xe9, 0x02, 0x7d, 0x02, 0xd6, 0x83, 0x76, 0xef, 0x43, 0xd9, 0xc4, 0x65, + 0x7b, 0xef, 0x4a, 0xae, 0xfe, 0x3c, 0xaf, 0x6f, 0x70, 0x32, 0x8a, 0x6e, 0x33, 0xcf, 0xe5, 0xd4, + 0x0b, 0xf8, 0x0c, 0x4b, 0xa7, 0x8a, 0x5a, 0x57, 0x4f, 0x33, 0xba, 0x05, 0x05, 0x49, 0x9d, 0xa8, + 0xa8, 0xf9, 0xb7, 0xd4, 0x2a, 0x3b, 0x7a, 0x03, 0x8a, 0x49, 0x1b, 0x08, 0x6e, 0xcd, 0x85, 0x99, + 0xd1, 0x0d, 0x82, 0x35, 0x62, 0xbb, 0xf4, 0xed, 0x69, 0x7d, 0x4d, 0x86, 0x62, 0xe9, 0x98, 0xaf, + 0x5c, 0xc5, 0x77, 0xa1, 0x24, 0x8e, 0xb4, 0xc3, 0x51, 0xa4, 0xb6, 0xcd, 0x73, 0xcd, 0xcc, 0x36, + 0xd3, 0x36, 0xdb, 0x12, 0xd4, 0xe0, 0x14, 0xab, 0xee, 0x16, 0xe8, 0x05, 0xb4, 0x72, 0x3c, 0x04, + 0x96, 0x38, 0x21, 0x63, 0x5d, 0xc3, 0xf2, 0x5b, 0xe8, 0x64, 0x3d, 0xcd, 0x44, 0x27, 0x0b, 0xf3, + 0x58, 0xd5, 0x55, 0xc4, 0xcf, 0xf5, 0xde, 0xb9, 0x04, 0x9b, 0xf3, 0x15, 0xc4, 0xfe, 0x99, 0xce, + 0x14, 0x92, 0xe1, 0xf3, 0x47, 0x63, 0xbe, 0xbc, 0x56, 0xbe, 0xe1, 0xe1, 0xf2, 0x5c, 0xfc, 0xfb, + 0xc1, 0xdd, 0xa7, 0xee, 0x68, 0xac, 0x27, 0x43, 0x49, 0x99, 0x34, 0xbf, 0x36, 0xd4, 0xca, 0xbe, + 0x04, 0x27, 0x3b, 0xb0, 0xd1, 0x1e, 0x0c, 0xc4, 0x06, 0x38, 0x09, 0x86, 0x84, 0x53, 0xdd, 0x68, + 0xcf, 0x37, 0xe5, 0xcb, 0xe5, 0x50, 0x2f, 0x98, 0x10, 0x4e, 0x15, 0x46, 0x96, 0xdf, 0xc0, 0x4b, + 0x47, 0x32, 0x29, 0xfc, 0x61, 0x64, 0x77, 0xf1, 0xca, 0x5c, 0x35, 0xa0, 0x7c, 0x9f, 0x71, 0xd7, + 0x1f, 0x3d, 0x48, 0x6e, 0x28, 0x08, 0x33, 0xf1, 0x82, 0x0e, 0x9d, 0x40, 0x59, 0x7b, 0xde, 0x27, + 0xd1, 0x58, 0xb2, 0x50, 0xb6, 0xdf, 0xba, 0xfc, 0xc4, 0x2f, 0xb8, 0x11, 0x4d, 0xa1, 0x65, 0xf5, + 0x26, 0xde, 0x78, 0xec, 0xe9, 0xc0, 0x29, 0x24, 0x73, 0xd5, 0x4f, 0xd3, 0x17, 0xea, 0x12, 0x74, + 0xd7, 0xc0, 0x74, 0x62, 0xcd, 0x71, 0x39, 0x85, 0xb5, 0xfd, 0x19, 0x16, 0x86, 0x8c, 0xfb, 0x6f, + 0x0c, 0xb0, 0xee, 0x33, 0x4e, 0xff, 0xf3, 0x07, 0x60, 0x05, 0xae, 0x33, 0x69, 0x3c, 0x9c, 0xd3, + 0x93, 0xce, 0xac, 0x91, 0x99, 0xd9, 0x9b, 0x70, 0xbd, 0x43, 0xa3, 0x41, 0xe8, 0x06, 0xdc, 0x65, + 0xbe, 0x1a, 0xe7, 0xac, 0x2a, 0xfb, 0x92, 0x9b, 0x4f, 0x79, 0xc9, 0x33, 0x71, 0x7f, 0xca, 0x41, + 0xc1, 0x26, 0x93, 0x09, 0xe3, 0x0b, 0x15, 0x32, 0x9e, 0x5a, 0x21, 0xd1, 0x27, 0xbb, 0xae, 0x4f, + 0x26, 0xee, 0x57, 0xae, 0x3f, 0x52, 0xff, 0x4e, 0x57, 0xeb, 0x93, 0xac, 0x1b, 0xb4, 0x03, 0xeb, + 0x81, 0x0a, 0xd1, 0xe3, 0x84, 0x27, 0x2b, 0x69, 0xe3, 0xce, 0x8b, 0x99, 0xcb, 0x88, 0x6c, 0xd3, + 0x8c, 0x24, 0x08, 0x2f, 0x9e, 0x41, 0x2f, 0x41, 0x5e, 0xd4, 0x34, 0xaa, 0xe6, 0x65, 0x03, 0xac, + 0xa7, 0x87, 0x85, 0x16, 0x27, 0xb6, 0xc6, 0x7b, 0xb0, 0xbe, 0xe0, 0x04, 0x95, 0xa1, 0x74, 0x8c, + 0x8f, 0x8e, 0x8f, 0x7a, 0xdd, 0x4e, 0x65, 0x4d, 0x48, 0xdd, 0x8f, 0xba, 0x3b, 0x27, 0x4e, 0xb7, + 0x53, 0x31, 0x10, 0x40, 0x61, 0xb7, 0x7d, 0x70, 0xaf, 0xdb, 0xa9, 0xe4, 0xec, 0xf7, 0xcf, 0x2e, + 0x6a, 0xc6, 0x2f, 0x17, 0x35, 0xe3, 0xf7, 0x8b, 0x9a, 0xf1, 0xf3, 0xa3, 0x9a, 0x71, 0xf6, 0xa8, + 0x66, 0x7c, 0xfc, 0xda, 0x93, 0x6f, 0xcd, 0xe3, 0xa8, 0xa5, 0xb2, 0xe8, 0x17, 0xe4, 0x8f, 0xea, + 0xdd, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x02, 0x7a, 0xba, 0xca, 0x0f, 0x0b, 0x00, 0x00, } func (m *Any) Marshal() (dAtA []byte, err error) { From 4ab18da7814ccf3ac31a33293e7967d064f225a1 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Thu, 13 Jun 2019 21:27:20 +0100 Subject: [PATCH 3/7] Define WASM externals Note that this changes the storage value from Word256 to []byte Signed-off-by: Sean Young --- acm/acm.pb.go | 67 ++++++++------ acm/acmstate/dump_state.go | 3 +- acm/acmstate/memory_state.go | 16 ++-- acm/acmstate/state.go | 6 +- acm/acmstate/state_cache.go | 14 +-- acm/acmstate/state_cache_test.go | 26 +++--- cmd/burrow/commands/deploy.go | 2 +- deploy/compile/compilers.go | 4 +- deploy/def/client.go | 12 ++- deploy/def/client_test.go | 2 +- deploy/jobs/jobs_contracts.go | 6 +- dump/dump.go | 2 +- dump/dump.pb.go | 71 +++++++------- execution/contexts/call_context.go | 36 ++------ execution/errors/errors.go | 3 + execution/evm/fake_app_state.go | 8 +- execution/evm/state.go | 18 ++-- execution/evm/vm.go | 4 +- execution/evm/vm_test.go | 6 +- execution/execution.go | 2 +- execution/execution_test.go | 2 +- execution/state/accounts.go | 23 +++-- execution/wasm/wasm.go | 144 +++++++++++++++++++++++++++++ protobuf/acm.proto | 2 +- protobuf/dump.proto | 2 +- protobuf/rpcquery.proto | 2 +- rpc/rpcquery/rpcquery.pb.go | 121 ++++++++++++------------ rpc/service.go | 9 +- txs/json_codec_test.go | 1 + 29 files changed, 382 insertions(+), 232 deletions(-) create mode 100644 execution/wasm/wasm.go diff --git a/acm/acm.pb.go b/acm/acm.pb.go index 0a99c5182..5949fb48b 100644 --- a/acm/acm.pb.go +++ b/acm/acm.pb.go @@ -34,7 +34,7 @@ type Account struct { Balance uint64 `protobuf:"varint,4,opt,name=Balance,proto3" json:"Balance,omitempty"` Code Bytecode `protobuf:"bytes,5,opt,name=Code,proto3,customtype=Bytecode" json:"Code"` Permissions permission.AccountPermissions `protobuf:"bytes,6,opt,name=Permissions,proto3" json:"Permissions"` - WASM Bytecode `protobuf:"bytes,7,opt,name=WASM,proto3,customtype=Bytecode" json:"WASM"` + WASM *Bytecode `protobuf:"bytes,7,opt,name=WASM,proto3,customtype=Bytecode" json:"WASM,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -112,28 +112,29 @@ func init() { proto.RegisterFile("acm.proto", fileDescriptor_49ed775bc0a6adf6) } func init() { golang_proto.RegisterFile("acm.proto", fileDescriptor_49ed775bc0a6adf6) } var fileDescriptor_49ed775bc0a6adf6 = []byte{ - // 335 bytes of a gzipped FileDescriptorProto + // 339 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x91, 0xbf, 0x4e, 0xf3, 0x30, - 0x14, 0xc5, 0xeb, 0x36, 0x5f, 0xd3, 0xba, 0x1d, 0xfa, 0x79, 0xb2, 0x3a, 0xa4, 0x05, 0x31, 0x74, + 0x14, 0xc5, 0xeb, 0x36, 0x5f, 0xd3, 0xba, 0x1d, 0xfa, 0x79, 0xb2, 0x3a, 0xa4, 0x01, 0x31, 0x74, 0x80, 0x44, 0xe2, 0x8f, 0x90, 0xd8, 0x1a, 0x24, 0x16, 0x04, 0xaa, 0xd2, 0x01, 0x89, 0x2d, 0x71, - 0x2e, 0x69, 0xa4, 0xa6, 0x0e, 0x4e, 0x2c, 0x94, 0x37, 0x61, 0xe4, 0x51, 0x18, 0x3b, 0x32, 0x33, - 0x54, 0x55, 0xfb, 0x22, 0x28, 0xc6, 0x2d, 0x59, 0x60, 0xcb, 0xc9, 0xef, 0xde, 0x7b, 0x8e, 0x8e, - 0x71, 0xdb, 0x67, 0x89, 0x9d, 0x0a, 0x9e, 0x73, 0xd2, 0xf0, 0x59, 0xd2, 0x3f, 0x89, 0xe2, 0x7c, - 0x26, 0x03, 0x9b, 0xf1, 0xc4, 0x89, 0x78, 0xc4, 0x1d, 0xc5, 0x02, 0xf9, 0xa4, 0x94, 0x12, 0xea, - 0xeb, 0x7b, 0xa7, 0xdf, 0x4b, 0x41, 0x24, 0x71, 0x96, 0xc5, 0x7c, 0xa1, 0xff, 0x74, 0x99, 0x28, - 0xd2, 0x5c, 0xf3, 0xc3, 0x75, 0x1d, 0x9b, 0x63, 0xc6, 0xb8, 0x5c, 0xe4, 0xe4, 0x1e, 0x9b, 0xe3, - 0x30, 0x14, 0x90, 0x65, 0x14, 0x0d, 0xd1, 0xa8, 0xeb, 0x9e, 0x2f, 0x57, 0x83, 0xda, 0xe7, 0x6a, - 0x70, 0x5c, 0xf1, 0x9c, 0x15, 0x29, 0x88, 0x39, 0x84, 0x11, 0x08, 0x27, 0x90, 0x42, 0xf0, 0x17, - 0x47, 0x1f, 0xd4, 0xbb, 0xde, 0xee, 0x08, 0xb9, 0xc0, 0xed, 0x89, 0x0c, 0xe6, 0x31, 0xbb, 0x85, - 0x82, 0xd6, 0x87, 0x68, 0xd4, 0x39, 0xfd, 0x6f, 0xeb, 0xe1, 0x3d, 0x70, 0x8d, 0xd2, 0xc4, 0xfb, - 0x99, 0x24, 0x7d, 0xdc, 0x9a, 0xc2, 0xb3, 0x84, 0x05, 0x03, 0xda, 0x18, 0xa2, 0x91, 0xe1, 0xed, - 0x35, 0xa1, 0xd8, 0x74, 0xfd, 0xb9, 0x5f, 0x22, 0x43, 0xa1, 0x9d, 0x24, 0x47, 0xd8, 0xb8, 0xe6, - 0x21, 0xd0, 0x7f, 0x2a, 0x79, 0x4f, 0x27, 0x6f, 0xb9, 0x45, 0x0e, 0x8c, 0x87, 0xe0, 0x29, 0x4a, - 0x6e, 0x70, 0x67, 0xb2, 0x2f, 0x24, 0xa3, 0x4d, 0x15, 0xca, 0xb2, 0x2b, 0x25, 0xe9, 0x32, 0x2a, - 0x53, 0x3a, 0x61, 0x75, 0xb1, 0x74, 0x7b, 0x18, 0x4f, 0xef, 0xa8, 0xf9, 0x9b, 0x5b, 0x49, 0xaf, - 0x8c, 0xd7, 0xb7, 0x41, 0xcd, 0xbd, 0x5c, 0x6e, 0x2c, 0xf4, 0xb1, 0xb1, 0xd0, 0x7a, 0x63, 0xa1, - 0xf7, 0xad, 0x85, 0x96, 0x5b, 0x0b, 0x3d, 0x1e, 0xfc, 0xdd, 0xa9, 0xcf, 0x92, 0xa0, 0xa9, 0x9e, - 0xe8, 0xec, 0x2b, 0x00, 0x00, 0xff, 0xff, 0xeb, 0x36, 0x89, 0x52, 0x03, 0x02, 0x00, 0x00, + 0x2e, 0x69, 0xa4, 0xa6, 0x0e, 0x4e, 0x2c, 0x94, 0x37, 0x61, 0xe4, 0x51, 0x18, 0x3b, 0x32, 0x23, + 0x54, 0xa1, 0xf6, 0x45, 0x50, 0x8d, 0x5b, 0xc2, 0xc2, 0x96, 0x93, 0xdf, 0xbd, 0xf7, 0x1c, 0x1d, + 0xe3, 0x76, 0xc0, 0x52, 0x27, 0x13, 0xbc, 0xe0, 0xa4, 0x11, 0xb0, 0xb4, 0x7f, 0x14, 0x27, 0xc5, + 0x54, 0x86, 0x0e, 0xe3, 0xa9, 0x1b, 0xf3, 0x98, 0xbb, 0x8a, 0x85, 0xf2, 0x41, 0x29, 0x25, 0xd4, + 0xd7, 0xf7, 0x4e, 0xbf, 0x97, 0x81, 0x48, 0x93, 0x3c, 0x4f, 0xf8, 0x5c, 0xff, 0xe9, 0x32, 0x51, + 0x66, 0x85, 0xe6, 0xfb, 0x1f, 0x75, 0x6c, 0x8e, 0x18, 0xe3, 0x72, 0x5e, 0x90, 0x5b, 0x6c, 0x8e, + 0xa2, 0x48, 0x40, 0x9e, 0x53, 0x64, 0xa3, 0x61, 0xd7, 0x3b, 0x5d, 0x2c, 0x07, 0xb5, 0xf7, 0xe5, + 0xe0, 0xb0, 0xe2, 0x39, 0x2d, 0x33, 0x10, 0x33, 0x88, 0x62, 0x10, 0x6e, 0x28, 0x85, 0xe0, 0x4f, + 0xae, 0x3e, 0xa8, 0x77, 0xfd, 0xed, 0x11, 0x72, 0x86, 0xdb, 0x63, 0x19, 0xce, 0x12, 0x76, 0x0d, + 0x25, 0xad, 0xdb, 0x68, 0xd8, 0x39, 0xfe, 0xef, 0xe8, 0xe1, 0x1d, 0xf0, 0x8c, 0x8d, 0x89, 0xff, + 0x33, 0x49, 0xfa, 0xb8, 0x35, 0x81, 0x47, 0x09, 0x73, 0x06, 0xb4, 0x61, 0xa3, 0xa1, 0xe1, 0xef, + 0x34, 0xa1, 0xd8, 0xf4, 0x82, 0x59, 0xb0, 0x41, 0x86, 0x42, 0x5b, 0x49, 0x0e, 0xb0, 0x71, 0xc9, + 0x23, 0xa0, 0xff, 0x54, 0xf2, 0x9e, 0x4e, 0xde, 0xf2, 0xca, 0x02, 0x18, 0x8f, 0xc0, 0x57, 0x94, + 0x5c, 0xe1, 0xce, 0x78, 0x57, 0x48, 0x4e, 0x9b, 0x2a, 0x94, 0xe5, 0x54, 0x4a, 0xd2, 0x65, 0x54, + 0xa6, 0x74, 0xc2, 0xea, 0x22, 0xb1, 0xb1, 0x71, 0x37, 0x9a, 0xdc, 0x50, 0x53, 0xb9, 0x75, 0x7f, + 0x3b, 0x6d, 0xc8, 0x85, 0xf1, 0xfc, 0x32, 0xa8, 0x79, 0xe7, 0x8b, 0x95, 0x85, 0xde, 0x56, 0x16, + 0xfa, 0x5c, 0x59, 0xe8, 0x75, 0x6d, 0xa1, 0xc5, 0xda, 0x42, 0xf7, 0x7b, 0x7f, 0xf7, 0x19, 0xb0, + 0x34, 0x6c, 0xaa, 0xe7, 0x39, 0xf9, 0x0a, 0x00, 0x00, 0xff, 0xff, 0xcb, 0x97, 0x60, 0xcc, 0xff, + 0x01, 0x00, 0x00, } func (m *Account) Marshal() (dAtA []byte, err error) { @@ -193,14 +194,16 @@ func (m *Account) MarshalTo(dAtA []byte) (int, error) { return 0, err } i += n4 - dAtA[i] = 0x3a - i++ - i = encodeVarintAcm(dAtA, i, uint64(m.WASM.Size())) - n5, err := m.WASM.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err + if m.WASM != nil { + dAtA[i] = 0x3a + i++ + i = encodeVarintAcm(dAtA, i, uint64(m.WASM.Size())) + n5, err := m.WASM.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n5 } - i += n5 if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -236,8 +239,10 @@ func (m *Account) Size() (n int) { n += 1 + l + sovAcm(uint64(l)) l = m.Permissions.Size() n += 1 + l + sovAcm(uint64(l)) - l = m.WASM.Size() - n += 1 + l + sovAcm(uint64(l)) + if m.WASM != nil { + l = m.WASM.Size() + n += 1 + l + sovAcm(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -485,6 +490,8 @@ func (m *Account) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } + var v Bytecode + m.WASM = &v if err := m.WASM.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } diff --git a/acm/acmstate/dump_state.go b/acm/acmstate/dump_state.go index 22c73f4bb..185f2290e 100644 --- a/acm/acmstate/dump_state.go +++ b/acm/acmstate/dump_state.go @@ -6,7 +6,6 @@ import ( "encoding/json" "github.com/hyperledger/burrow/acm" - "github.com/hyperledger/burrow/binary" "github.com/hyperledger/burrow/crypto" ) @@ -32,7 +31,7 @@ func (dw *DumpState) RemoveAccount(address crypto.Address) error { return nil } -func (dw *DumpState) SetStorage(address crypto.Address, key, value binary.Word256) error { +func (dw *DumpState) SetStorage(address crypto.Address, key, value []byte) error { dw.WriteString("SetStorage\n") dw.WriteString(address.String()) dw.WriteByte('/') diff --git a/acm/acmstate/memory_state.go b/acm/acmstate/memory_state.go index 6e2395a9b..10bef6c0d 100644 --- a/acm/acmstate/memory_state.go +++ b/acm/acmstate/memory_state.go @@ -10,7 +10,7 @@ import ( type MemoryState struct { Accounts map[crypto.Address]*acm.Account - Storage map[crypto.Address]map[binary.Word256]binary.Word256 + Storage map[crypto.Address]map[binary.Word256][]byte } var _ IterableReaderWriter = &MemoryState{} @@ -19,7 +19,7 @@ var _ IterableReaderWriter = &MemoryState{} func NewMemoryState() *MemoryState { return &MemoryState{ Accounts: make(map[crypto.Address]*acm.Account), - Storage: make(map[crypto.Address]map[binary.Word256]binary.Word256), + Storage: make(map[crypto.Address]map[binary.Word256][]byte), } } @@ -40,22 +40,22 @@ func (ms *MemoryState) RemoveAccount(address crypto.Address) error { return nil } -func (ms *MemoryState) GetStorage(address crypto.Address, key binary.Word256) (binary.Word256, error) { +func (ms *MemoryState) GetStorage(address crypto.Address, key binary.Word256) ([]byte, error) { storage, ok := ms.Storage[address] if !ok { - return binary.Zero256, fmt.Errorf("could not find storage for account %s", address) + return []byte{}, fmt.Errorf("could not find storage for account %s", address) } value, ok := storage[key] if !ok { - return binary.Zero256, fmt.Errorf("could not find key %x for account %s", key, address) + return []byte{}, fmt.Errorf("could not find key %x for account %s", key, address) } return value, nil } -func (ms *MemoryState) SetStorage(address crypto.Address, key, value binary.Word256) error { +func (ms *MemoryState) SetStorage(address crypto.Address, key binary.Word256, value []byte) error { storage, ok := ms.Storage[address] if !ok { - storage = make(map[binary.Word256]binary.Word256) + storage = make(map[binary.Word256][]byte) ms.Storage[address] = storage } storage[key] = value @@ -71,7 +71,7 @@ func (ms *MemoryState) IterateAccounts(consumer func(*acm.Account) error) (err e return nil } -func (ms *MemoryState) IterateStorage(address crypto.Address, consumer func(key, value binary.Word256) error) (err error) { +func (ms *MemoryState) IterateStorage(address crypto.Address, consumer func(key binary.Word256, value []byte) error) (err error) { for key, value := range ms.Storage[address] { if err := consumer(key, value); err != nil { return err diff --git a/acm/acmstate/state.go b/acm/acmstate/state.go index 2c7b968ed..1f72d15de 100644 --- a/acm/acmstate/state.go +++ b/acm/acmstate/state.go @@ -30,19 +30,19 @@ type AccountUpdater interface { type StorageGetter interface { // Retrieve a 32-byte value stored at key for the account at address, return Zero256 if key does not exist but // error if address does not - GetStorage(address crypto.Address, key binary.Word256) (value binary.Word256, err error) + GetStorage(address crypto.Address, key binary.Word256) (value []byte, err error) } type StorageSetter interface { // Store a 32-byte value at key for the account at address, setting to Zero256 removes the key - SetStorage(address crypto.Address, key, value binary.Word256) error + SetStorage(address crypto.Address, key binary.Word256, value []byte) error } type StorageIterable interface { // Iterates through the storage of account ad address calling the passed function once per account, // if the iterator function returns true the iteration breaks and returns true to indicate it iteration // was escaped - IterateStorage(address crypto.Address, consumer func(key, value binary.Word256) error) (err error) + IterateStorage(address crypto.Address, consumer func(key binary.Word256, value []byte) error) (err error) } type AccountStats struct { diff --git a/acm/acmstate/state_cache.go b/acm/acmstate/state_cache.go index 2f2c79ec0..52aeb49b0 100644 --- a/acm/acmstate/state_cache.go +++ b/acm/acmstate/state_cache.go @@ -37,7 +37,7 @@ type Cache struct { type accountInfo struct { sync.RWMutex account *acm.Account - storage map[binary.Word256]binary.Word256 + storage map[binary.Word256][]byte removed bool updated bool } @@ -135,10 +135,10 @@ func (cache *Cache) IterateCachedAccount(consumer func(*acm.Account) (stop bool) return false, nil } -func (cache *Cache) GetStorage(address crypto.Address, key binary.Word256) (binary.Word256, error) { +func (cache *Cache) GetStorage(address crypto.Address, key binary.Word256) ([]byte, error) { accInfo, err := cache.get(address) if err != nil { - return binary.Zero256, err + return []byte{}, err } // Check cache accInfo.RLock() @@ -152,7 +152,7 @@ func (cache *Cache) GetStorage(address crypto.Address, key binary.Word256) (bina // Load from backend value, err = cache.backend.GetStorage(address, key) if err != nil { - return binary.Zero256, err + return []byte{}, err } accInfo.storage[key] = value } @@ -161,7 +161,7 @@ func (cache *Cache) GetStorage(address crypto.Address, key binary.Word256) (bina } // NOTE: Set value to zero to remove. -func (cache *Cache) SetStorage(address crypto.Address, key binary.Word256, value binary.Word256) error { +func (cache *Cache) SetStorage(address crypto.Address, key binary.Word256, value []byte) error { if cache.readonly { return errors.ErrorCodef(errors.ErrorCodeIllegalWrite, "SetStorage called in a read-only context on account %v", address) @@ -186,7 +186,7 @@ func (cache *Cache) SetStorage(address crypto.Address, key binary.Word256, value // Iterates over all cached storage items first in cache and then in backend until consumer returns true for 'stop' func (cache *Cache) IterateCachedStorage(address crypto.Address, - consumer func(key, value binary.Word256) error) error { + consumer func(key binary.Word256, value []byte) error) error { accInfo, err := cache.get(address) if err != nil { return err @@ -294,7 +294,7 @@ func (cache *Cache) get(address crypto.Address) (*accountInfo, error) { } accInfo = &accountInfo{ account: account, - storage: make(map[binary.Word256]binary.Word256), + storage: make(map[binary.Word256][]byte), } cache.accounts[address] = accInfo } diff --git a/acm/acmstate/state_cache_test.go b/acm/acmstate/state_cache_test.go index 5c87f44c5..36376a09e 100644 --- a/acm/acmstate/state_cache_test.go +++ b/acm/acmstate/state_cache_test.go @@ -171,7 +171,7 @@ func TestStateCache_GetStorage(t *testing.T) { cache.UpdateAccount(acc) //Check for correct cache storage value - assert.Equal(t, word("NO YOU ARE A KEY"), accStorage) + assert.Equal(t, "NO YOU ARE A KEY", string(accStorage)) //Sync account to backend err = cache.Sync(writeBackend) @@ -183,7 +183,7 @@ func TestStateCache_GetStorage(t *testing.T) { require.NotNil(t, accStorage) //Check for correct backend storage value - assert.Equal(t, word("NO YOU ARE A KEY"), accStorage) + assert.Equal(t, "NO YOU ARE A KEY", string(accStorage)) } func TestStateCache_SetStorage(t *testing.T) { @@ -195,13 +195,13 @@ func TestStateCache_SetStorage(t *testing.T) { newAcc := acm.NewAccountFromSecret("newAcc") err := cache.UpdateAccount(newAcc) require.NoError(t, err) - err = cache.SetStorage(newAcc.Address, word("What?"), word("Huh?")) + err = cache.SetStorage(newAcc.Address, word("What?"), []byte("Huh?")) require.NoError(t, err) //Check for correct cache storage value newAccStorage, err := cache.GetStorage(newAcc.Address, word("What?")) require.NoError(t, err) - assert.Equal(t, word("Huh?"), newAccStorage) + assert.Equal(t, "Huh?", string(newAccStorage)) //Sync account to backend err = cache.Sync(backend) @@ -210,15 +210,15 @@ func TestStateCache_SetStorage(t *testing.T) { //Check for correct backend storage value newAccStorage, err = backend.GetStorage(newAcc.Address, word("What?")) require.NoError(t, err) - assert.Equal(t, word("Huh?"), newAccStorage) + assert.Equal(t, "Huh?", string(newAccStorage)) noone := acm.NewAccountFromSecret("noone at all") - err = cache.SetStorage(noone.Address, binary.Word256{3, 4, 5}, binary.Word256{102, 103, 104}) + err = cache.SetStorage(noone.Address, binary.Word256{3, 4, 5}, []byte{102, 103, 104}) require.Error(t, err, "should not be able to write to non-existent account") err = cache.UpdateAccount(noone) require.NoError(t, err) - err = cache.SetStorage(noone.Address, binary.Word256{3, 4, 5}, binary.Word256{102, 103, 104}) + err = cache.SetStorage(noone.Address, binary.Word256{3, 4, 5}, []byte{102, 103, 104}) require.NoError(t, err, "should be able to update account after creating it") } @@ -228,8 +228,8 @@ func TestStateCache_Sync(t *testing.T) { cache := NewCache(backend) // Create new account - newAcc := acm.NewAccountFromSecret("newAcc") // Create account + newAcc := acm.NewAccountFromSecret("newAcc") err := cache.UpdateAccount(newAcc) require.NoError(t, err) @@ -238,7 +238,7 @@ func TestStateCache_Sync(t *testing.T) { newAcc.Balance = balance // Set storage for account - err = cache.SetStorage(newAcc.Address, word("God save"), word("the queen!")) + err = cache.SetStorage(newAcc.Address, word("God save"), []byte("the queen!")) require.NoError(t, err) //Update cache with account changes @@ -253,7 +253,7 @@ func TestStateCache_Sync(t *testing.T) { //Confirm changes to account storage in cache newAccStorage, err := cache.GetStorage(newAcc.Address, word("God save")) require.NoError(t, err) - assert.Equal(t, word("the queen!"), newAccStorage) + assert.Equal(t, "the queen!", string(newAccStorage)) //Sync account to backend err = cache.Sync(backend) @@ -267,7 +267,7 @@ func TestStateCache_Sync(t *testing.T) { //Confirm changes to account storage synced correctly to backend newAccStorage, err = cache.GetStorage(newAcc.Address, word("God save")) require.NoError(t, err) - assert.Equal(t, word("the queen!"), newAccStorage) + assert.Equal(t, "the queen!", string(newAccStorage)) //Remove account from cache err = cache.RemoveAccount(newAcc.Address) @@ -334,9 +334,9 @@ func addressOf(secret string) crypto.Address { func account(acc *acm.Account, keyvals ...string) *MemoryState { ts := NewMemoryState() ts.Accounts[acc.Address] = acc - ts.Storage[acc.Address] = make(map[binary.Word256]binary.Word256) + ts.Storage[acc.Address] = make(map[binary.Word256][]byte) for i := 0; i < len(keyvals); i += 2 { - ts.Storage[acc.Address][word(keyvals[i])] = word(keyvals[i+1]) + ts.Storage[acc.Address][word(keyvals[i])] = []byte(keyvals[i+1]) } return ts } diff --git a/cmd/burrow/commands/deploy.go b/cmd/burrow/commands/deploy.go index 6a58887d4..ec78ae590 100644 --- a/cmd/burrow/commands/deploy.go +++ b/cmd/burrow/commands/deploy.go @@ -74,7 +74,7 @@ func Deploy(output Output) func(cmd *cli.Cmd) { proposalList := cmd.StringOpt("list-proposals state", "", "List proposals, either all, executed, expired, or current") cmd.Spec = "[--chain=] [--keys=] [--mempool-signing] [--dir=] " + - "[--output=] [--set=]... [--bin-path=] [--gas=] " + + "[--output=] [--wasm] [--set=]... [--bin-path=] [--gas=] " + "[--jobs=] [--address=
] [--fee=] [--amount=] " + "[--verbose] [--debug] [--timeout=] [--proposal-create|--proposal-verify|--proposal-create] FILE..." diff --git a/deploy/compile/compilers.go b/deploy/compile/compilers.go index f1744eba7..b09d86322 100644 --- a/deploy/compile/compilers.go +++ b/deploy/compile/compilers.go @@ -220,7 +220,7 @@ func Compile(file string, optimize bool, workDir string, libraries map[string]st } func CompileWASM(file string, workDir string, logger *logging.Logger) (*Response, error) { - shellCmd := exec.Command("solang", "--json", file) + shellCmd := exec.Command("solang", "--standard-json", file) if workDir != "" { shellCmd.Dir = workDir } @@ -231,7 +231,7 @@ func CompileWASM(file string, workDir string, logger *logging.Logger) (*Response logger.TraceMsg("Command Output", "result", string(output)) wasmoutput := SolidityOutput{} - err = json.Unmarshal(output, &output) + err = json.Unmarshal(output, &wasmoutput) if err != nil { return nil, err } diff --git a/deploy/def/client.go b/deploy/def/client.go index 814f3c893..1670680fc 100644 --- a/deploy/def/client.go +++ b/deploy/def/client.go @@ -140,10 +140,10 @@ func (c *Client) GetAccount(address crypto.Address) (*acm.Account, error) { return c.queryClient.GetAccount(ctx, &rpcquery.GetAccountParam{Address: address}) } -func (c *Client) GetStorage(address crypto.Address, key binary.Word256) (binary.Word256, error) { +func (c *Client) GetStorage(address crypto.Address, key binary.Word256) ([]byte, error) { val, err := c.queryClient.GetStorage(context.Background(), &rpcquery.GetStorageParam{Address: address, Key: key}) if err != nil { - return binary.Word256{}, err + return []byte{}, err } return val.Value, err } @@ -436,7 +436,8 @@ func (c *Client) Call(arg *CallArg, logger *logging.Logger) (*payload.CallTx, er "amount", arg.Amount, "sequence", arg.Sequence, "address", arg.Address, - "data", arg.Data) + "data", arg.Data, + "wasm", arg.WASM) input, err := c.TxInput(arg.Input, arg.Amount, arg.Sequence, true, logger) if err != nil { return nil, err @@ -461,10 +462,15 @@ func (c *Client) Call(arg *CallArg, logger *logging.Logger) (*payload.CallTx, er if err != nil { return nil, err } + wasm, err := hex.DecodeString(arg.WASM) + if err != nil { + return nil, err + } tx := &payload.CallTx{ Input: input, Address: contractAddress, Data: code, + WASM: wasm, Fee: fee, GasLimit: gas, } diff --git a/deploy/def/client_test.go b/deploy/def/client_test.go index fe8cb5809..d64ad7742 100644 --- a/deploy/def/client_test.go +++ b/deploy/def/client_test.go @@ -13,5 +13,5 @@ func TestArgMap(t *testing.T) { }) fmt.Println(mp) assert.Equal(t, "fooo", mp["Address"]) - assert.Len(t, mp, 7) + assert.Len(t, mp, 8) } diff --git a/deploy/jobs/jobs_contracts.go b/deploy/jobs/jobs_contracts.go index d144bed77..e8bc54065 100644 --- a/deploy/jobs/jobs_contracts.go +++ b/deploy/jobs/jobs_contracts.go @@ -196,7 +196,7 @@ func FormulateDeployJob(deploy *def.Deploy, do *def.DeployArgs, deployScript *de "path", contractPath, "abi", string(response.Contract.Abi), "bin", response.Contract.Evm.Bytecode.Object) - if response.Contract.Evm.Bytecode.Object == "" { + if response.Contract.Evm.Bytecode.Object == "" && response.Contract.EWasm.Wasm == "" { return nil, nil, errCodeMissing } mergeAbiSpecBytes(client, response.Contract.Abi) @@ -214,7 +214,7 @@ func FormulateDeployJob(deploy *def.Deploy, do *def.DeployArgs, deployScript *de var baseContract *compilers.ResponseItem deployedCount := 0 for i, response := range resp.Objects { - if response.Contract.Evm.Bytecode.Object == "" { + if response.Contract.Evm.Bytecode.Object == "" && response.Contract.EWasm.Wasm == "" { continue } mergeAbiSpecBytes(client, response.Contract.Abi) @@ -248,7 +248,7 @@ func FormulateDeployJob(deploy *def.Deploy, do *def.DeployArgs, deployScript *de continue } if matchInstanceName(response.Objectname, deploy.Instance) { - if response.Contract.Evm.Bytecode.Object == "" { + if response.Contract.Evm.Bytecode.Object == "" && response.Contract.EWasm.Wasm == "" { return nil, nil, errCodeMissing } logger.TraceMsg("Deploy contract", diff --git a/dump/dump.go b/dump/dump.go index 7f5261169..929593bbd 100644 --- a/dump/dump.go +++ b/dump/dump.go @@ -74,7 +74,7 @@ func (ds *Dumper) Transmit(stream Sender, startHeight, endHeight uint64, options Storage: make([]*Storage, 0), } - err = st.IterateStorage(acc.Address, func(key, value binary.Word256) error { + err = st.IterateStorage(acc.Address, func(key binary.Word256, value []byte) error { storage.Storage = append(storage.Storage, &Storage{Key: key, Value: value}) return nil }) diff --git a/dump/dump.pb.go b/dump/dump.pb.go index 5078268ec..91ef3b076 100644 --- a/dump/dump.pb.go +++ b/dump/dump.pb.go @@ -34,11 +34,11 @@ var _ = time.Kitchen const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package type Storage struct { - Key github_com_hyperledger_burrow_binary.Word256 `protobuf:"bytes,1,opt,name=Key,proto3,customtype=github.com/hyperledger/burrow/binary.Word256" json:"Key"` - Value github_com_hyperledger_burrow_binary.Word256 `protobuf:"bytes,2,opt,name=Value,proto3,customtype=github.com/hyperledger/burrow/binary.Word256" json:"Value"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Key github_com_hyperledger_burrow_binary.Word256 `protobuf:"bytes,1,opt,name=Key,proto3,customtype=github.com/hyperledger/burrow/binary.Word256" json:"Key"` + Value github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,2,opt,name=Value,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"Value"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Storage) Reset() { *m = Storage{} } @@ -297,36 +297,37 @@ func init() { proto.RegisterFile("dump.proto", fileDescriptor_58418148159c29a6) func init() { golang_proto.RegisterFile("dump.proto", fileDescriptor_58418148159c29a6) } var fileDescriptor_58418148159c29a6 = []byte{ - // 463 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x52, 0xbb, 0x6e, 0x13, 0x41, - 0x14, 0x65, 0xe2, 0x75, 0x9c, 0x5c, 0x87, 0x14, 0x23, 0x84, 0x56, 0x2e, 0xd6, 0xd6, 0x0a, 0x41, - 0x84, 0x60, 0x2c, 0x99, 0x87, 0x52, 0xd0, 0xc4, 0xc4, 0x88, 0x67, 0x8a, 0x21, 0x0a, 0x12, 0xdd, - 0x3e, 0x86, 0xf1, 0x4a, 0xde, 0x9d, 0xd5, 0xec, 0x2c, 0xb0, 0x3d, 0x0d, 0x1d, 0x3f, 0xc0, 0xbf, - 0x50, 0xba, 0x44, 0x94, 0x14, 0x01, 0x39, 0x3f, 0x82, 0x76, 0x1e, 0x18, 0x52, 0x20, 0xa1, 0x74, - 0xf7, 0xde, 0x33, 0xf7, 0xcc, 0x99, 0x73, 0x06, 0x20, 0xad, 0xf3, 0x92, 0x94, 0x52, 0x28, 0x81, - 0xbd, 0xb6, 0x1e, 0xdc, 0xe6, 0x99, 0x9a, 0xd7, 0x31, 0x49, 0x44, 0x3e, 0xe6, 0x82, 0x8b, 0xb1, - 0x06, 0xe3, 0xfa, 0x8d, 0xee, 0x74, 0xa3, 0x2b, 0xb3, 0x34, 0x18, 0x72, 0x21, 0xf8, 0x82, 0xad, - 0x4f, 0xa9, 0x2c, 0x67, 0x95, 0x8a, 0x1c, 0xeb, 0x60, 0x3b, 0x4a, 0x72, 0x5b, 0x02, 0x7b, 0xcf, - 0x12, 0x5b, 0xf7, 0x8b, 0x28, 0x67, 0x95, 0x69, 0xc2, 0xcf, 0x08, 0x7a, 0x2f, 0x95, 0x90, 0x11, - 0x67, 0xf8, 0x11, 0x74, 0x9e, 0xb1, 0xc6, 0x47, 0x23, 0xb4, 0xb7, 0x33, 0xbd, 0xbb, 0x3c, 0x1d, - 0x5e, 0xfa, 0x7e, 0x3a, 0xbc, 0xf5, 0x87, 0xa8, 0x79, 0x53, 0x32, 0xb9, 0x60, 0x29, 0x67, 0x72, - 0x1c, 0xd7, 0x52, 0x8a, 0x77, 0xe3, 0x38, 0x2b, 0x22, 0xd9, 0x90, 0x57, 0x42, 0xa6, 0x93, 0x7b, - 0xf7, 0x69, 0x4b, 0x80, 0x9f, 0x42, 0xf7, 0x24, 0x5a, 0xd4, 0xcc, 0xdf, 0xb8, 0x00, 0x93, 0xa1, - 0x08, 0x3f, 0x22, 0xd8, 0x3d, 0x48, 0x12, 0x51, 0x17, 0xca, 0xc9, 0x3c, 0x82, 0xde, 0x41, 0x9a, - 0x4a, 0x56, 0x55, 0xff, 0x27, 0x35, 0x91, 0x4d, 0xa9, 0x04, 0xb1, 0xbb, 0xd4, 0x91, 0xe0, 0x1b, - 0xbf, 0x1d, 0xf0, 0x37, 0x46, 0x9d, 0xbd, 0xfe, 0xe4, 0x32, 0xd1, 0xd1, 0xd8, 0x21, 0x75, 0x68, - 0xf8, 0x01, 0xc1, 0xd6, 0xec, 0xe4, 0xc5, 0xec, 0x2d, 0x2b, 0x14, 0xf6, 0xa1, 0xf7, 0x70, 0x1e, - 0x65, 0xc5, 0x93, 0x43, 0xad, 0x62, 0x9b, 0xba, 0x16, 0xef, 0x83, 0x77, 0x9c, 0xe5, 0xe6, 0xf5, - 0xfd, 0xc9, 0x80, 0x98, 0x98, 0x88, 0x8b, 0x89, 0x1c, 0xbb, 0x98, 0xa6, 0x5b, 0xad, 0xf0, 0x4f, - 0x3f, 0x86, 0x88, 0xea, 0x0d, 0x7c, 0x0d, 0xba, 0x9a, 0xdc, 0xef, 0xe8, 0xd5, 0x5d, 0xa2, 0x53, - 0x7b, 0x2e, 0xb8, 0x9e, 0x52, 0x03, 0x86, 0xdf, 0x10, 0x78, 0x87, 0x75, 0x5e, 0xe2, 0xab, 0xb0, - 0xf9, 0x98, 0x65, 0x7c, 0xae, 0xb4, 0x02, 0x8f, 0xda, 0x0e, 0x5f, 0x87, 0x9e, 0xb5, 0xcc, 0x6a, - 0xd8, 0x21, 0xed, 0x4f, 0xb0, 0x33, 0xea, 0x40, 0xfc, 0xe0, 0xbc, 0xb5, 0xf6, 0xde, 0x2b, 0xe6, - 0xfd, 0x7f, 0x63, 0xf4, 0x7c, 0x0c, 0x37, 0xd7, 0x66, 0xf8, 0x9e, 0xd5, 0xab, 0xf7, 0xdc, 0x94, - 0xae, 0xcd, 0x1a, 0x81, 0x77, 0x14, 0xe5, 0xcc, 0xef, 0x5a, 0x39, 0xe6, 0x07, 0xce, 0x0a, 0x25, - 0x1b, 0xaa, 0x91, 0xe9, 0xfe, 0x72, 0x15, 0xa0, 0xaf, 0xab, 0x00, 0xfd, 0x5c, 0x05, 0xe8, 0xcb, - 0x59, 0x80, 0x96, 0x67, 0x01, 0x7a, 0x1d, 0xfe, 0x3b, 0xd1, 0xf6, 0xba, 0x78, 0x53, 0x1b, 0x7b, - 0xe7, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0xcf, 0xbc, 0xb3, 0xac, 0x50, 0x03, 0x00, 0x00, + // 475 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x52, 0xbf, 0x6f, 0x13, 0x31, + 0x14, 0xc6, 0xcd, 0xa5, 0x69, 0x9d, 0xd2, 0xc1, 0x42, 0xe8, 0x94, 0xe1, 0x12, 0x9d, 0x10, 0x54, + 0x88, 0x3a, 0x52, 0xa0, 0xa8, 0x03, 0x4b, 0x43, 0x83, 0x8a, 0x0a, 0x1d, 0x4c, 0x55, 0x24, 0xb6, + 0xfb, 0xf1, 0xf0, 0x9d, 0x94, 0x3b, 0x9f, 0x7c, 0x3e, 0xe8, 0xed, 0x2c, 0x6c, 0xfc, 0x05, 0xfc, + 0x2d, 0x8c, 0x19, 0x11, 0x23, 0x43, 0x41, 0xe9, 0x3f, 0x82, 0xce, 0x67, 0x13, 0xe8, 0x80, 0xe8, + 0xf6, 0xde, 0xfb, 0xfc, 0x3e, 0x7f, 0xfe, 0x3e, 0x63, 0x1c, 0x57, 0x59, 0x41, 0x0b, 0x29, 0x94, + 0x20, 0x4e, 0x53, 0x0f, 0x76, 0x79, 0xaa, 0x92, 0x2a, 0xa4, 0x91, 0xc8, 0xc6, 0x5c, 0x70, 0x31, + 0xd6, 0x60, 0x58, 0xbd, 0xd5, 0x9d, 0x6e, 0x74, 0xd5, 0x2e, 0x0d, 0x86, 0x5c, 0x08, 0x3e, 0x87, + 0xd5, 0x29, 0x95, 0x66, 0x50, 0xaa, 0xc0, 0xb2, 0x0e, 0x36, 0x83, 0x28, 0x33, 0x25, 0x86, 0x73, + 0x88, 0x4c, 0xdd, 0xcf, 0x83, 0x0c, 0xca, 0xb6, 0xf1, 0x3f, 0x23, 0xdc, 0x7b, 0xa5, 0x84, 0x0c, + 0x38, 0x90, 0x67, 0xb8, 0x73, 0x0c, 0xb5, 0x8b, 0x46, 0x68, 0x67, 0x6b, 0xfa, 0x68, 0x71, 0x31, + 0xbc, 0xf1, 0xfd, 0x62, 0xf8, 0xe0, 0x0f, 0x51, 0x49, 0x5d, 0x80, 0x9c, 0x43, 0xcc, 0x41, 0x8e, + 0xc3, 0x4a, 0x4a, 0xf1, 0x7e, 0x1c, 0xa6, 0x79, 0x20, 0x6b, 0xfa, 0x5a, 0xc8, 0x78, 0xb2, 0xf7, + 0x98, 0x35, 0x04, 0xe4, 0x18, 0x77, 0xcf, 0x82, 0x79, 0x05, 0xee, 0x9a, 0x66, 0xda, 0x33, 0x4c, + 0xbb, 0xff, 0xc5, 0x74, 0x04, 0xe7, 0xd3, 0x5a, 0x41, 0xc9, 0x5a, 0x0e, 0xff, 0x23, 0xc2, 0xdb, + 0x07, 0x51, 0x24, 0xaa, 0x5c, 0x59, 0x9d, 0x27, 0xb8, 0x77, 0x10, 0xc7, 0x12, 0xca, 0xf2, 0x7a, + 0x5a, 0x23, 0x59, 0x17, 0x4a, 0x50, 0xb3, 0xcb, 0x2c, 0x09, 0xb9, 0xf7, 0xdb, 0x02, 0x77, 0x6d, + 0xd4, 0xd9, 0xe9, 0x4f, 0x6e, 0x52, 0x9d, 0x8d, 0x19, 0x32, 0x8b, 0xfa, 0x1f, 0x10, 0xde, 0x98, + 0x9d, 0xbd, 0x9c, 0xbd, 0x83, 0x5c, 0x11, 0x17, 0xf7, 0x9e, 0x26, 0x41, 0x9a, 0x3f, 0x3f, 0xd4, + 0x2a, 0x36, 0x99, 0x6d, 0xc9, 0x3e, 0x76, 0x4e, 0xd3, 0xac, 0x7d, 0x7e, 0x7f, 0x32, 0xa0, 0x6d, + 0x4e, 0xd4, 0xe6, 0x44, 0x4f, 0x6d, 0x4e, 0xd3, 0x8d, 0x46, 0xf8, 0xa7, 0x1f, 0x43, 0xc4, 0xf4, + 0x06, 0xb9, 0x83, 0xbb, 0x9a, 0xdc, 0xed, 0xe8, 0xd5, 0x6d, 0xaa, 0x63, 0x7b, 0x21, 0xb8, 0x9e, + 0xb2, 0x16, 0xf4, 0xbf, 0x21, 0xec, 0x1c, 0x56, 0x59, 0x41, 0x6e, 0xe3, 0xf5, 0x23, 0x48, 0x79, + 0xa2, 0xb4, 0x02, 0x87, 0x99, 0x8e, 0xdc, 0xc5, 0x3d, 0x63, 0x99, 0xd1, 0xb0, 0x45, 0x9b, 0xaf, + 0x60, 0x66, 0xcc, 0x82, 0xe4, 0xc9, 0x55, 0x6b, 0xcd, 0xbd, 0xb7, 0xda, 0xf7, 0xff, 0x8d, 0xb1, + 0xab, 0x31, 0xdc, 0x5f, 0x99, 0xe1, 0x3a, 0x46, 0xaf, 0xde, 0xb3, 0x53, 0xb6, 0x32, 0x6b, 0x84, + 0x9d, 0x93, 0x20, 0x03, 0xb7, 0x6b, 0xe4, 0xb4, 0x5f, 0x70, 0x96, 0x2b, 0x59, 0x33, 0x8d, 0x4c, + 0xf7, 0x17, 0x4b, 0x0f, 0x7d, 0x5d, 0x7a, 0xe8, 0xe7, 0xd2, 0x43, 0x5f, 0x2e, 0x3d, 0xb4, 0xb8, + 0xf4, 0xd0, 0x1b, 0xff, 0xdf, 0x89, 0x36, 0xd7, 0x85, 0xeb, 0xda, 0xd8, 0x87, 0xbf, 0x02, 0x00, + 0x00, 0xff, 0xff, 0x60, 0x4c, 0x49, 0xe5, 0x51, 0x03, 0x00, 0x00, } func (m *Storage) Marshal() (dAtA []byte, err error) { diff --git a/execution/contexts/call_context.go b/execution/contexts/call_context.go index 0123970ab..acfc22e50 100644 --- a/execution/contexts/call_context.go +++ b/execution/contexts/call_context.go @@ -10,10 +10,10 @@ import ( "github.com/hyperledger/burrow/execution/errors" "github.com/hyperledger/burrow/execution/evm" "github.com/hyperledger/burrow/execution/exec" + "github.com/hyperledger/burrow/execution/wasm" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/logging/structure" "github.com/hyperledger/burrow/txs/payload" - wexec "github.com/perlin-network/life/exec" ) // TODO: make configurable @@ -131,7 +131,7 @@ func (ctx *CallContext) Deliver(inAcc, outAcc *acm.Account, value uint64) error caller crypto.Address = inAcc.Address callee crypto.Address = crypto.ZeroAddress // initialized below code []byte = nil - wasm []byte = nil + wcode []byte = nil ret []byte = nil txCache = evm.NewState(ctx.StateWriter, ctx.Blockchain.BlockHash, acmstate.Named("TxCache")) params = evm.Params{ @@ -146,13 +146,13 @@ func (ctx *CallContext) Deliver(inAcc, outAcc *acm.Account, value uint64) error // We already checked for permission callee = crypto.NewContractAddress(caller, ctx.txe.TxHash) code = ctx.tx.Data - wasm = ctx.tx.WASM + wcode = ctx.tx.WASM txCache.CreateAccount(callee) ctx.Logger.TraceMsg("Creating new contract", "contract_address", callee, "init_code", code) } else { - if outAcc == nil || len(outAcc.Code) == 0 { + if outAcc == nil || (len(outAcc.Code) == 0 && outAcc.WASM == nil) { // if you call an account that doesn't exist // or an account with no code then we take fees (sorry pal) // NOTE: it's fine to create a contract and call it within one @@ -180,7 +180,7 @@ func (ctx *CallContext) Deliver(inAcc, outAcc *acm.Account, value uint64) error } callee = outAcc.Address code = txCache.GetCode(callee) - wasm = txCache.GetWASMCode(callee) + wcode = txCache.GetWASMCode(callee) ctx.Logger.TraceMsg("Calling existing contract", "contract_address", callee, "input", ctx.tx.Data, @@ -191,30 +191,11 @@ func (ctx *CallContext) Deliver(inAcc, outAcc *acm.Account, value uint64) error txHash := ctx.txe.Envelope.Tx.Hash() logger := ctx.Logger.With(structure.TxHashKey, txHash) var exception errors.CodedError - if wasm != nil { - // WASM - config := wexec.VMConfig{ - DisableFloatingPoint: true, - MaxMemoryPages: 2, - DefaultMemoryPages: 2, - } - vm, err := wexec.NewVirtualMachine(wasm, config, &wexec.NopResolver{}, nil) - if err != nil { - ctx.Logger.InfoMsg("Invalid WASM bytecode", - "error", err) - return err - } - wasmFunc := "function" + if wcode != nil { if createContract { - txCache.InitWASMCode(callee, wasm) - wasmFunc = "constructor" - } - entryID, ok := vm.GetFunctionExport(wasmFunc) - if !ok { - ctx.Logger.InfoMsg("Missing exported WASM function", "export", wasmFunc) - return fmt.Errorf("WASM missing function %s", wasmFunc) + txCache.InitWASMCode(callee, wcode) } - _, err = vm.Run(entryID) + ret, err := wasm.RunWASM(txCache, callee, createContract, wcode, ctx.tx.Data) if err != nil { ctx.Logger.InfoMsg("Error returned from WASM", "error", err) return err @@ -223,6 +204,7 @@ func (ctx *CallContext) Deliver(inAcc, outAcc *acm.Account, value uint64) error if err != nil { return err } + ctx.txe.Return(ret, ctx.tx.GasLimit-gas) } else { // EVM vmach := evm.NewVM(params, caller, txHash, logger, ctx.VMOptions...) diff --git a/execution/errors/errors.go b/execution/errors/errors.go index e6bd8c779..4ee23f821 100644 --- a/execution/errors/errors.go +++ b/execution/errors/errors.go @@ -60,6 +60,7 @@ const ( ErrorCodeInvalidBlockNumber ErrorCodeBlockNumberOutOfRange ErrorCodeAlreadyVoted + ErrorCodeUnresolvedSymbols ) func (c Code) ErrorCode() Code { @@ -152,6 +153,8 @@ func (c Code) String() string { return "block number out of range" case ErrorCodeAlreadyVoted: return "vote already registered for this address" + case ErrorCodeUnresolvedSymbols: + return "code has unresolved symbols" default: return "Unknown error" } diff --git a/execution/evm/fake_app_state.go b/execution/evm/fake_app_state.go index 1e9e95f32..2e3cbddc9 100644 --- a/execution/evm/fake_app_state.go +++ b/execution/evm/fake_app_state.go @@ -27,7 +27,7 @@ import ( type FakeAppState struct { accounts map[crypto.Address]*acm.Account - storage map[string]Word256 + storage map[string][]byte } var _ acmstate.ReaderWriter = &FakeAppState{} @@ -53,7 +53,7 @@ func (fas *FakeAppState) RemoveAccount(address crypto.Address) error { return nil } -func (fas *FakeAppState) GetStorage(addr crypto.Address, key Word256) (Word256, error) { +func (fas *FakeAppState) GetStorage(addr crypto.Address, key Word256) ([]byte, error) { _, ok := fas.accounts[addr] if !ok { panic(fmt.Sprintf("Invalid account addr: %s", addr)) @@ -63,11 +63,11 @@ func (fas *FakeAppState) GetStorage(addr crypto.Address, key Word256) (Word256, if ok { return value, nil } else { - return Zero256, nil + return []byte{}, nil } } -func (fas *FakeAppState) SetStorage(addr crypto.Address, key Word256, value Word256) error { +func (fas *FakeAppState) SetStorage(addr crypto.Address, key Word256, value []byte) error { _, ok := fas.accounts[addr] if !ok { diff --git a/execution/evm/state.go b/execution/evm/state.go index d6ed530c8..0aad68f61 100644 --- a/execution/evm/state.go +++ b/execution/evm/state.go @@ -24,7 +24,7 @@ type Interface interface { } type Reader interface { - GetStorage(address crypto.Address, key binary.Word256) binary.Word256 + GetStorage(address crypto.Address, key binary.Word256) []byte GetBalance(address crypto.Address) uint64 GetPermissions(address crypto.Address) permission.AccountPermissions GetCode(address crypto.Address) acm.Bytecode @@ -40,7 +40,7 @@ type Writer interface { InitCode(address crypto.Address, code []byte) InitWASMCode(address crypto.Address, code []byte) RemoveAccount(address crypto.Address) - SetStorage(address crypto.Address, key, value binary.Word256) + SetStorage(address crypto.Address, key binary.Word256, value []byte) AddToBalance(address crypto.Address, amount uint64) SubtractFromBalance(address crypto.Address, amount uint64) SetPermission(address crypto.Address, permFlag permission.PermFlag, value bool) @@ -109,11 +109,11 @@ func (st *State) PushError(err error) { // Reader -func (st *State) GetStorage(address crypto.Address, key binary.Word256) binary.Word256 { +func (st *State) GetStorage(address crypto.Address, key binary.Word256) []byte { value, err := st.cache.GetStorage(address, key) if err != nil { st.PushError(err) - return binary.Zero256 + return []byte{} } return value } @@ -144,10 +144,11 @@ func (st *State) GetCode(address crypto.Address) acm.Bytecode { func (st *State) GetWASMCode(address crypto.Address) acm.Bytecode { acc := st.account(address) - if acc == nil { + if acc == nil || acc.WASM == nil { return nil } - return acc.WASM + + return *acc.WASM } func (st *State) Exists(address crypto.Address) bool { @@ -209,7 +210,8 @@ func (st *State) InitWASMCode(address crypto.Address, code []byte) { "tried to initialise code for a contract that already exists: %v", address)) return } - acc.WASM = code + bc, _ := acm.NewBytecode(code) + acc.WASM = &bc st.updateAccount(acc) } @@ -222,7 +224,7 @@ func (st *State) RemoveAccount(address crypto.Address) { st.removeAccount(address) } -func (st *State) SetStorage(address crypto.Address, key, value binary.Word256) { +func (st *State) SetStorage(address crypto.Address, key binary.Word256, value []byte) { err := st.cache.SetStorage(address, key, value) if err != nil { st.PushError(err) diff --git a/execution/evm/vm.go b/execution/evm/vm.go index 9a3194aa2..2852c7e9d 100644 --- a/execution/evm/vm.go +++ b/execution/evm/vm.go @@ -699,14 +699,14 @@ func (vm *VM) execute(callState Interface, eventSink EventSink, caller, callee c case SLOAD: // 0x54 loc := stack.Pop() - data := callState.GetStorage(callee, loc) + data := LeftPadWord256(callState.GetStorage(callee, loc)) stack.Push(data) vm.Debugf("%s {0x%X = 0x%X}\n", callee, loc, data) case SSTORE: // 0x55 loc, data := stack.Pop(), stack.Pop() useGasNegative(gas, GasStorageUpdate, callState) - callState.SetStorage(callee, loc, data) + callState.SetStorage(callee, loc, data.Bytes()) vm.Debugf("%s {0x%X := 0x%X}\n", callee, loc, data) case JUMP: // 0x56 diff --git a/execution/evm/vm_test.go b/execution/evm/vm_test.go index d3f3ac897..519074991 100644 --- a/execution/evm/vm_test.go +++ b/execution/evm/vm_test.go @@ -62,7 +62,7 @@ func NewTestState(st acmstate.ReaderWriter, blockHashGetter func(uint64) []byte) func newAppState() *FakeAppState { fas := &FakeAppState{ accounts: make(map[crypto.Address]*acm.Account), - storage: make(map[string]Word256), + storage: make(map[string][]byte), } // For default permissions fas.accounts[acm.GlobalPermissionsAddress] = &acm.Account{ @@ -675,7 +675,7 @@ func TestRevert(t *testing.T) { account2 := newAccount(cache, "1, 0, 1") key, value := []byte{0x00}, []byte{0x00} - cache.SetStorage(account1, LeftPadWord256(key), LeftPadWord256(value)) + cache.SetStorage(account1, LeftPadWord256(key), value) var gas uint64 = 100000 @@ -692,7 +692,7 @@ func TestRevert(t *testing.T) { assert.Error(t, cErr, "Expected execution reverted error") storageVal := cache.GetStorage(account1, LeftPadWord256(key)) - assert.Equal(t, LeftPadWord256(value), storageVal) + assert.Equal(t, value, storageVal) t.Logf("Output: %v\n", output) } diff --git a/execution/execution.go b/execution/execution.go index 4913343d7..d741e253f 100644 --- a/execution/execution.go +++ b/execution/execution.go @@ -375,7 +375,7 @@ func (exe *executor) GetAccount(address crypto.Address) (*acm.Account, error) { } // Storage -func (exe *executor) GetStorage(address crypto.Address, key binary.Word256) (binary.Word256, error) { +func (exe *executor) GetStorage(address crypto.Address, key binary.Word256) ([]byte, error) { exe.RLock() defer exe.RUnlock() return exe.stateCache.GetStorage(address, key) diff --git a/execution/execution_test.go b/execution/execution_test.go index 6462db242..79bc7bb90 100644 --- a/execution/execution_test.go +++ b/execution/execution_test.go @@ -1189,7 +1189,7 @@ func TestCreates(t *testing.T) { require.NoError(t, err) require.NotEqual(t, Zero256, secondCreatedAddress, "should not be zero address") - if firstCreatedAddress == secondCreatedAddress { + if bytes.Equal(firstCreatedAddress, secondCreatedAddress) { t.Errorf("Multiple contracts created with the same address!") } } diff --git a/execution/state/accounts.go b/execution/state/accounts.go index 957a70c6f..bc1df204e 100644 --- a/execution/state/accounts.go +++ b/execution/state/accounts.go @@ -102,30 +102,37 @@ func (s *State) GetAccountStats() acmstate.AccountStats { // Storage -func (s *ReadState) GetStorage(address crypto.Address, key binary.Word256) (binary.Word256, error) { +func (s *ReadState) GetStorage(address crypto.Address, key binary.Word256) ([]byte, error) { keyFormat := keys.Storage.Fix(address) tree, err := s.Forest.Reader(keyFormat.Prefix()) if err != nil { - return binary.Zero256, err + return []byte{}, err } - return binary.LeftPadWord256(tree.Get(keyFormat.KeyNoPrefix(key))), nil + return tree.Get(keyFormat.KeyNoPrefix(key)), nil } -func (ws *writeState) SetStorage(address crypto.Address, key, value binary.Word256) error { +func (ws *writeState) SetStorage(address crypto.Address, key binary.Word256, value []byte) error { keyFormat := keys.Storage.Fix(address) tree, err := ws.forest.Writer(keyFormat.Prefix()) if err != nil { return err } - if value == binary.Zero256 { + zero := true + for _, b := range value { + if b != 0 { + zero = false + break + } + } + if zero { tree.Delete(keyFormat.KeyNoPrefix(key)) } else { - tree.Set(keyFormat.KeyNoPrefix(key), value.Bytes()) + tree.Set(keyFormat.KeyNoPrefix(key), value) } return nil } -func (s *ReadState) IterateStorage(address crypto.Address, consumer func(key, value binary.Word256) error) error { +func (s *ReadState) IterateStorage(address crypto.Address, consumer func(key binary.Word256, value []byte) error) error { keyFormat := keys.Storage.Fix(address) tree, err := s.Forest.Reader(keyFormat.Prefix()) if err != nil { @@ -142,6 +149,6 @@ func (s *ReadState) IterateStorage(address crypto.Address, consumer func(key, va return fmt.Errorf("value '%X' stored for account %s is not a %v-byte word", key, address, binary.Word256Length) } - return consumer(binary.LeftPadWord256(key), binary.LeftPadWord256(value)) + return consumer(binary.LeftPadWord256(key), value) }) } diff --git a/execution/wasm/wasm.go b/execution/wasm/wasm.go new file mode 100644 index 000000000..7555120d0 --- /dev/null +++ b/execution/wasm/wasm.go @@ -0,0 +1,144 @@ +package wasm + +import ( + "encoding/binary" + "fmt" + + burrow_binary "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/crypto" + "github.com/hyperledger/burrow/execution/errors" + "github.com/hyperledger/burrow/execution/evm" + "github.com/perlin-network/life/exec" +) + +type execContext struct { + address crypto.Address + state evm.Interface +} + +// In EVM, the code for an account is created by the EVM code itself; the code in the EVM deploy transaction is run, and the EVM code +// returns (via the RETURN) opcode) the code for the contract. In addition, when a new contract is created using the "new C()" construct +// is soldity, the EVM itself passes the code for the new contract. + +// The compiler must embed any contract code for smart contracts it wants to create. +// - This does not allow for circular references: contract A creates contract B, contract B creates contract A. +// - This makes it very hard to support other languages; e.g. go or rust have no such bizarre concepts, and would require tricking into supporting this +// - This makes it possible for tricksy contracts that create different contracts at differen times. Very hard to support static analysis on these contracts +// - This makes it hard to know ahead-of-time what the code for a contract will be + +// Our WASM implememtation does not allow for this. The code passed to the deploy transaction, is the contract. Any child contracts must be passed +// during the initial deployment (not implemented yet) + +// ABIs +// Our WASM ABI is entirely compatible with Solidity. This means that solidity EVM can call wasm contracts and vice versa. However, in the EVM ABI model +// the difference between constructor calls and function calls are implicit: the constructor code path is different from the function call code path, +// and there is nothing visible in the binary ABI encoded arguments telling you that it is a function call or a constructor. Note function calls do +// have a 4 byte prefix but this is not required; without it the fallback function should be called. + +// So in our WASM model the smart contract has two entry points: constructor and function. + +// ABIs memory space +// In the EVM model, ABIs are passed via the calldata opcodes. This means that the ABI encoded data is not directly accessible and has to be copied to +// smart contract memory. Solidity exposes this via the calldata and memory modifiers on variables. + +// In our wasm model, the function and constructor wasm fuctions have one argument and return value. The argument is where in wasm memory the ABI encoded +// arguments are and the return value is the offset where the return data can be found. At this offset we first find a 32 bit little endian encoded +// length (since wasm is little endian and we are using 32 bit memory model) followed by the bytes themselves. + +// Contract Storage +// In the EVM model, contract storage is addressed via 256 bit key and the contents is a 256 bit value. For wasm, we've changed the contents to a +// arbitary byte string. This makes it much easier to store/retrieve smaller values (e.g. int64) and dynamic length fields (e.g. strings/arrays). + +// Access to contract storage is via wasm externals. +// - set_storage32(uint32 key, uint8* data, uint32 len) // set contract storage +// - get_storage32(uint32 key, uint8* data, uint32 len) // get contract storage (right pad with zeros) + +// RunWASM creates a wasm VM, and executes the given wasm contract code +func RunWASM(state evm.Interface, address crypto.Address, createContract bool, wasm, input []byte) (output []byte, cerr errors.CodedError) { + defer func() { + if r := recover(); r != nil { + cerr = errors.ErrorCodeExecutionAborted + } + }() + // WASM + config := exec.VMConfig{ + DisableFloatingPoint: true, + MaxMemoryPages: 2, + DefaultMemoryPages: 2, + } + + execContext := execContext{address, state} + + vm, err := exec.NewVirtualMachine(wasm, config, &execContext, nil) + + if err != nil { + return []byte{}, errors.ErrorCodeInvalidContract + } + + // FIXME: Check length + if len(input) > 0 { + binary.LittleEndian.PutUint32(vm.Memory[:], uint32(len(input))) + copy(vm.Memory[4:], input) + } + + wasmFunc := "function" + if createContract { + wasmFunc = "constructor" + } + entryID, ok := vm.GetFunctionExport(wasmFunc) + if !ok { + return []byte{}, errors.ErrorCodeUnresolvedSymbols + } + + // The 0 argument is the offset where our calldata is stored (if any) + offset, err := vm.Run(entryID, 0) + if err != nil { + return []byte{}, errors.ErrorCodeExecutionAborted + } + + if offset > 0 { + // FIXME: Check length + length := binary.LittleEndian.Uint32(vm.Memory[offset : offset+4]) + output = vm.Memory[offset+4 : offset+4+int64(length)] + } + + return +} + +func (e *execContext) ResolveFunc(module, field string) exec.FunctionImport { + if module != "env" { + panic(fmt.Sprintf("unknown module %s", module)) + } + + switch field { + case "set_storage32": + return func(vm *exec.VirtualMachine) int64 { + key := int(uint32(vm.GetCurrentFrame().Locals[0])) + ptr := int(uint32(vm.GetCurrentFrame().Locals[1])) + len := int(uint32(vm.GetCurrentFrame().Locals[2])) + // FIXME: Check length + e.state.SetStorage(e.address, burrow_binary.Int64ToWord256(int64(key)), vm.Memory[ptr:ptr+len]) + return 0 + } + + case "get_storage32": + return func(vm *exec.VirtualMachine) int64 { + key := int(uint32(vm.GetCurrentFrame().Locals[0])) + ptr := int(uint32(vm.GetCurrentFrame().Locals[1])) + length := int(uint32(vm.GetCurrentFrame().Locals[2])) + val := e.state.GetStorage(e.address, burrow_binary.Int64ToWord256(int64(key))) + if len(val) < length { + val = append(val, make([]byte, length-len(val))...) + } + // FIXME: Check length + copy(vm.Memory[ptr:ptr+length], val) + return 0 + } + default: + panic(fmt.Sprintf("unknown function %s", field)) + } +} + +func (e *execContext) ResolveGlobal(module, field string) int64 { + panic(fmt.Sprintf("global %s module %s not found", field, module)) +} diff --git a/protobuf/acm.proto b/protobuf/acm.proto index b5f1aec18..21e4ef92b 100644 --- a/protobuf/acm.proto +++ b/protobuf/acm.proto @@ -23,5 +23,5 @@ message Account { uint64 Balance = 4; bytes Code = 5 [(gogoproto.customtype) = "Bytecode", (gogoproto.nullable) = false]; permission.AccountPermissions Permissions = 6 [(gogoproto.nullable) = false]; - bytes WASM = 7 [(gogoproto.customtype) = "Bytecode", (gogoproto.nullable) = false]; + bytes WASM = 7 [(gogoproto.customtype) = "Bytecode"]; } diff --git a/protobuf/dump.proto b/protobuf/dump.proto index 93d3a39a2..9f0bc24f0 100644 --- a/protobuf/dump.proto +++ b/protobuf/dump.proto @@ -24,7 +24,7 @@ option (gogoproto.messagename_all) = true; message Storage { bytes Key = 1 [(gogoproto.customtype) = "github.com/hyperledger/burrow/binary.Word256", (gogoproto.nullable) = false]; - bytes Value = 2 [(gogoproto.customtype) = "github.com/hyperledger/burrow/binary.Word256", (gogoproto.nullable) = false]; + bytes Value = 2 [(gogoproto.customtype) = "github.com/hyperledger/burrow/binary.HexBytes", (gogoproto.nullable) = false]; } message AccountStorage { diff --git a/protobuf/rpcquery.proto b/protobuf/rpcquery.proto index c5acdd397..c52bf156a 100644 --- a/protobuf/rpcquery.proto +++ b/protobuf/rpcquery.proto @@ -55,7 +55,7 @@ message GetStorageParam { } message StorageValue { - bytes Value = 1 [(gogoproto.customtype) = "github.com/hyperledger/burrow/binary.Word256", (gogoproto.nullable) = false]; + bytes Value = 1 [(gogoproto.customtype) = "github.com/hyperledger/burrow/binary.HexBytes", (gogoproto.nullable) = false]; } message ListAccountsParam { diff --git a/rpc/rpcquery/rpcquery.pb.go b/rpc/rpcquery/rpcquery.pb.go index a0bf24bd4..65e755274 100644 --- a/rpc/rpcquery/rpcquery.pb.go +++ b/rpc/rpcquery/rpcquery.pb.go @@ -183,10 +183,10 @@ func (*GetStorageParam) XXX_MessageName() string { } type StorageValue struct { - Value github_com_hyperledger_burrow_binary.Word256 `protobuf:"bytes,1,opt,name=Value,proto3,customtype=github.com/hyperledger/burrow/binary.Word256" json:"Value"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Value github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,1,opt,name=Value,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"Value"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *StorageValue) Reset() { *m = StorageValue{} } @@ -938,62 +938,63 @@ func init() { proto.RegisterFile("rpcquery.proto", fileDescriptor_88e25d9b99e39f func init() { golang_proto.RegisterFile("rpcquery.proto", fileDescriptor_88e25d9b99e39f02) } var fileDescriptor_88e25d9b99e39f02 = []byte{ - // 872 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0x4f, 0x8f, 0xdb, 0x44, - 0x14, 0xc7, 0xbb, 0xdd, 0xec, 0xee, 0xcb, 0xbf, 0x76, 0xba, 0x84, 0xe0, 0x42, 0x5a, 0x8d, 0xc4, - 0x76, 0xa9, 0xc0, 0x89, 0x42, 0x17, 0x10, 0x1c, 0xa0, 0x41, 0x90, 0x2c, 0x7f, 0x56, 0x8b, 0x83, - 0x5a, 0xa9, 0x07, 0xa4, 0x89, 0x3d, 0x24, 0x16, 0x8e, 0xc7, 0x8c, 0xc7, 0x45, 0xfe, 0x48, 0x7c, - 0x0b, 0x8e, 0x7b, 0xe4, 0xcc, 0xa1, 0x42, 0xdb, 0x6f, 0xc1, 0x09, 0x79, 0xfe, 0x38, 0xb6, 0x37, - 0xad, 0xe0, 0xc0, 0x25, 0x7a, 0xef, 0xcd, 0xef, 0xfd, 0x9e, 0xf3, 0xe6, 0xfd, 0xde, 0x40, 0x87, - 0xc7, 0xde, 0x2f, 0x29, 0xe5, 0x99, 0x13, 0x73, 0x26, 0x18, 0x3a, 0x30, 0xbe, 0xfd, 0xfe, 0x32, - 0x10, 0xab, 0x74, 0xe1, 0x78, 0x6c, 0x3d, 0x5c, 0xb2, 0x25, 0x1b, 0x4a, 0xc0, 0x22, 0xfd, 0x49, - 0x7a, 0xd2, 0x91, 0x96, 0x4a, 0xb4, 0x3f, 0x2a, 0xc1, 0x05, 0x8d, 0x7c, 0xca, 0xd7, 0x41, 0x24, - 0xca, 0x26, 0x59, 0x78, 0xc1, 0x50, 0x64, 0x31, 0x4d, 0xd4, 0xaf, 0x4e, 0x6c, 0x46, 0x64, 0x5d, - 0x38, 0x87, 0xc4, 0x5b, 0x6b, 0xb3, 0xfb, 0x8c, 0x84, 0x81, 0x4f, 0x04, 0xe3, 0xe6, 0x8c, 0xc7, - 0x9e, 0x36, 0xdb, 0x31, 0xc9, 0x42, 0x46, 0x7c, 0xe5, 0xe2, 0x00, 0x9a, 0x73, 0x41, 0x44, 0x9a, - 0x5c, 0x10, 0x4e, 0xd6, 0xe8, 0x04, 0xba, 0x93, 0x90, 0x79, 0x3f, 0xff, 0x10, 0xac, 0xe9, 0x93, - 0x40, 0xac, 0x82, 0xa8, 0x6f, 0xdd, 0xb3, 0x4e, 0x0e, 0xdd, 0x7a, 0x18, 0x8d, 0xe0, 0xb6, 0x0c, - 0xcd, 0x29, 0x8d, 0x4a, 0xe8, 0x1d, 0x89, 0xde, 0x76, 0x84, 0x09, 0x74, 0xa7, 0x54, 0x3c, 0xf2, - 0x3c, 0x96, 0x46, 0x42, 0x95, 0x3b, 0x87, 0xfd, 0x47, 0xbe, 0xcf, 0x69, 0x92, 0xc8, 0x32, 0xad, - 0xc9, 0xc3, 0xcb, 0xe7, 0x77, 0x5f, 0xfb, 0xf3, 0xf9, 0xdd, 0xf7, 0x4a, 0x2d, 0x59, 0x65, 0x31, - 0xe5, 0x21, 0xf5, 0x97, 0x94, 0x0f, 0x17, 0x29, 0xe7, 0xec, 0xd7, 0xa1, 0xc7, 0xb3, 0x58, 0x30, - 0x47, 0xe7, 0xba, 0x86, 0x04, 0xff, 0x66, 0xc9, 0x1a, 0x73, 0xc1, 0x38, 0x59, 0xd2, 0xff, 0xa5, - 0x06, 0xfa, 0x0a, 0x76, 0xbf, 0xa1, 0x99, 0xfc, 0xa3, 0xff, 0x9a, 0x6b, 0x11, 0x44, 0x84, 0x67, - 0xce, 0x13, 0xc6, 0xfd, 0xf1, 0xe9, 0x87, 0x6e, 0x4e, 0x80, 0x9f, 0x42, 0x4b, 0x7f, 0xe7, 0x63, - 0x12, 0xa6, 0x14, 0x7d, 0x0d, 0x7b, 0xd2, 0xf8, 0x6f, 0x5f, 0x59, 0x63, 0x56, 0x14, 0xf8, 0x5d, - 0xb8, 0xf5, 0x6d, 0x90, 0x98, 0x5e, 0xeb, 0xbb, 0x3d, 0x82, 0xbd, 0xef, 0xf3, 0xf1, 0xd4, 0x37, - 0xaa, 0x1c, 0x8c, 0xa1, 0x35, 0xa5, 0xe2, 0x9c, 0xac, 0x75, 0xbb, 0x10, 0xdc, 0xc8, 0x1d, 0x0d, - 0x92, 0x36, 0x3e, 0x86, 0x4e, 0x4e, 0x97, 0xdb, 0xaf, 0xe4, 0xea, 0xc1, 0xd1, 0x94, 0x8a, 0xc7, - 0x66, 0xf8, 0xe6, 0x54, 0x5d, 0x33, 0x9e, 0xc2, 0x9d, 0x5a, 0x7c, 0x16, 0x24, 0x82, 0xf1, 0xac, - 0x18, 0xba, 0xb3, 0xc8, 0x0b, 0x53, 0x9f, 0x5e, 0x70, 0xfa, 0x2c, 0x60, 0xa9, 0xba, 0xa9, 0x5d, - 0xb7, 0x1e, 0xc6, 0x53, 0xb8, 0xbd, 0x85, 0x05, 0x8d, 0x60, 0x5f, 0x9b, 0x7d, 0xeb, 0xde, 0xee, - 0x49, 0x73, 0xdc, 0x73, 0x0a, 0x6d, 0x96, 0xf1, 0xae, 0x81, 0xe1, 0x73, 0x68, 0x95, 0x0f, 0x50, - 0x0f, 0x1a, 0x2b, 0x1a, 0x2c, 0x57, 0x42, 0x56, 0xbe, 0xe1, 0x6a, 0x0f, 0x1d, 0xc3, 0xee, 0x9c, - 0x8a, 0xfe, 0x8e, 0x64, 0x3d, 0x72, 0x36, 0xba, 0x2a, 0xb2, 0xdd, 0x1c, 0x80, 0x8f, 0xe1, 0xe6, - 0x94, 0x8a, 0x0b, 0xce, 0x62, 0x96, 0x90, 0xb0, 0xe8, 0xe4, 0x8c, 0x24, 0x2b, 0x75, 0x9f, 0xae, - 0xb4, 0xf1, 0x08, 0x50, 0xde, 0x49, 0x03, 0xd4, 0xdd, 0xb4, 0xe1, 0x40, 0x45, 0xa8, 0x2f, 0xd1, - 0x07, 0x6e, 0xe1, 0xe3, 0xef, 0xa0, 0x63, 0xd0, 0x2e, 0x4d, 0xd2, 0x50, 0x6c, 0xe3, 0x45, 0xf7, - 0xa1, 0x31, 0x21, 0x61, 0xc8, 0x84, 0x9c, 0xcb, 0xe6, 0xb8, 0xeb, 0x18, 0x99, 0xab, 0xb0, 0xab, - 0x8f, 0x71, 0x17, 0xda, 0x52, 0x20, 0x44, 0x4f, 0x05, 0xa6, 0xb0, 0x27, 0x3d, 0xf4, 0x00, 0x6e, - 0x9a, 0x79, 0xc9, 0x05, 0xfb, 0x05, 0xf3, 0xa9, 0x6e, 0xc6, 0xb5, 0x78, 0x2e, 0xfe, 0x72, 0x8c, - 0xa5, 0x42, 0xc2, 0x77, 0x24, 0x7c, 0xdb, 0x11, 0xbe, 0x2f, 0xeb, 0xca, 0xb5, 0xa0, 0xfe, 0x73, - 0x0f, 0x1a, 0xb3, 0x4a, 0xc7, 0x95, 0x37, 0xfe, 0x7b, 0x4f, 0x8f, 0x16, 0x1a, 0x43, 0x43, 0xad, - 0x26, 0xf4, 0xfa, 0xe6, 0x3a, 0x4b, 0xcb, 0xca, 0xbe, 0x95, 0x87, 0x1d, 0xd5, 0x15, 0x8d, 0x3c, - 0x05, 0xd8, 0xec, 0x18, 0xf4, 0xe6, 0x26, 0xaf, 0xb6, 0x79, 0xec, 0x96, 0x93, 0xaf, 0x4b, 0x03, - 0xfc, 0x4c, 0xa6, 0x69, 0x39, 0xd6, 0xd2, 0xca, 0xcb, 0xc4, 0xee, 0x95, 0xbf, 0xa4, 0x24, 0xde, - 0x4f, 0xa1, 0x55, 0x16, 0x1c, 0xba, 0xb3, 0xc1, 0x5d, 0x13, 0x62, 0xb5, 0xf6, 0xc8, 0x42, 0x43, - 0xd8, 0xd7, 0x12, 0x44, 0xbd, 0x4a, 0xe9, 0x42, 0x95, 0x76, 0xcb, 0x51, 0xab, 0xfe, 0xcb, 0x48, - 0xf0, 0x0c, 0x9d, 0xc2, 0x61, 0xa1, 0x47, 0xd4, 0xaf, 0x96, 0xda, 0x88, 0xb4, 0x9a, 0x34, 0xb2, - 0xd0, 0x99, 0x5c, 0x8e, 0x95, 0xb9, 0x1f, 0x54, 0xea, 0x5d, 0x53, 0xae, 0xfd, 0x12, 0x21, 0xa1, - 0x1f, 0xa1, 0xb7, 0x5d, 0xd1, 0xe8, 0x9d, 0x97, 0x32, 0x96, 0x35, 0x6f, 0xbf, 0xbd, 0x9d, 0xd8, - 0xb0, 0x7c, 0x02, 0xcd, 0x92, 0x9e, 0x90, 0x5d, 0x21, 0xad, 0xc8, 0xcc, 0xae, 0x8f, 0x3a, 0x3a, - 0x83, 0x76, 0x45, 0x63, 0xe8, 0xad, 0x6a, 0x87, 0xaa, 0xe2, 0xb3, 0x4b, 0xfd, 0xab, 0x0a, 0x6d, - 0x64, 0xa1, 0x87, 0x70, 0x60, 0xd4, 0x82, 0xde, 0xa8, 0x4d, 0x85, 0x51, 0x90, 0xdd, 0xad, 0x4e, - 0x67, 0x82, 0x3e, 0x86, 0x8e, 0x99, 0xf5, 0x19, 0x25, 0x3e, 0xe5, 0xb5, 0xdc, 0x8d, 0x0a, 0xec, - 0xb6, 0xa3, 0xde, 0x73, 0x85, 0x9b, 0x7c, 0x7e, 0x79, 0x35, 0xb0, 0xfe, 0xb8, 0x1a, 0x58, 0x7f, - 0x5d, 0x0d, 0xac, 0xdf, 0x5f, 0x0c, 0xac, 0xcb, 0x17, 0x03, 0xeb, 0xe9, 0x83, 0x57, 0x3f, 0x01, - 0x3c, 0xf6, 0x86, 0x86, 0x7e, 0xd1, 0x90, 0xcf, 0xfa, 0x07, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, - 0x3d, 0x0c, 0x60, 0xec, 0x9d, 0x08, 0x00, 0x00, + // 883 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0x5f, 0x8f, 0xdb, 0x44, + 0x10, 0xc7, 0x77, 0xbd, 0xdc, 0xdd, 0x24, 0x77, 0x69, 0xb7, 0x47, 0x08, 0x2e, 0xa4, 0xd5, 0x4a, + 0x5c, 0x8f, 0x8a, 0x3a, 0x51, 0x68, 0x00, 0xc1, 0x03, 0x34, 0x08, 0x92, 0x53, 0xe1, 0x74, 0x38, + 0xa8, 0x95, 0x40, 0x42, 0xda, 0xd8, 0x4b, 0x62, 0xe1, 0x78, 0xcd, 0x7a, 0x5d, 0xf0, 0x47, 0xe2, + 0x5b, 0xf0, 0x78, 0x8f, 0x3c, 0xf3, 0x50, 0xa1, 0xeb, 0xb7, 0xe0, 0x09, 0x79, 0xff, 0x38, 0xb6, + 0x2f, 0xad, 0xee, 0x85, 0x97, 0x68, 0x66, 0xf6, 0x37, 0xbf, 0x71, 0x66, 0xe7, 0x37, 0x0b, 0x87, + 0x3c, 0xf6, 0x7e, 0x4d, 0x29, 0xcf, 0x9c, 0x98, 0x33, 0xc1, 0xd0, 0x9e, 0xf1, 0xed, 0x87, 0x8b, + 0x40, 0x2c, 0xd3, 0xb9, 0xe3, 0xb1, 0x55, 0x7f, 0xc1, 0x16, 0xac, 0x2f, 0x01, 0xf3, 0xf4, 0x67, + 0xe9, 0x49, 0x47, 0x5a, 0x2a, 0xd1, 0xfe, 0xb8, 0x04, 0x17, 0x34, 0xf2, 0x29, 0x5f, 0x05, 0x91, + 0x28, 0x9b, 0x64, 0xee, 0x05, 0x7d, 0x91, 0xc5, 0x34, 0x51, 0xbf, 0x3a, 0xb1, 0x19, 0x91, 0x55, + 0xe1, 0xec, 0x13, 0x6f, 0xa5, 0xcd, 0xf6, 0x73, 0x12, 0x06, 0x3e, 0x11, 0x8c, 0x9b, 0x33, 0x1e, + 0x7b, 0xda, 0x3c, 0x88, 0x49, 0x16, 0x32, 0xe2, 0x2b, 0x17, 0x07, 0xd0, 0x9c, 0x09, 0x22, 0xd2, + 0xe4, 0x9c, 0x70, 0xb2, 0x42, 0x27, 0xd0, 0x1e, 0x87, 0xcc, 0xfb, 0xe5, 0xfb, 0x60, 0x45, 0x9f, + 0x05, 0x62, 0x19, 0x44, 0x5d, 0xeb, 0x9e, 0x75, 0xb2, 0xef, 0xd6, 0xc3, 0x68, 0x00, 0xb7, 0x65, + 0x68, 0x46, 0x69, 0x54, 0x42, 0x6f, 0x49, 0xf4, 0xa6, 0x23, 0x4c, 0xa0, 0x3d, 0xa1, 0xe2, 0xb1, + 0xe7, 0xb1, 0x34, 0x12, 0xaa, 0xdc, 0x19, 0xec, 0x3e, 0xf6, 0x7d, 0x4e, 0x93, 0x44, 0x96, 0x69, + 0x8d, 0x1f, 0x5d, 0xbc, 0xb8, 0xfb, 0xc6, 0xdf, 0x2f, 0xee, 0x7e, 0x50, 0x6a, 0xc9, 0x32, 0x8b, + 0x29, 0x0f, 0xa9, 0xbf, 0xa0, 0xbc, 0x3f, 0x4f, 0x39, 0x67, 0xbf, 0xf5, 0x3d, 0x9e, 0xc5, 0x82, + 0x39, 0x3a, 0xd7, 0x35, 0x24, 0xf8, 0x0f, 0x4b, 0xd6, 0x98, 0x09, 0xc6, 0xc9, 0x82, 0xfe, 0x2f, + 0x35, 0xd0, 0xd7, 0xb0, 0xfd, 0x84, 0x66, 0xf2, 0x8f, 0x5e, 0x9b, 0x6b, 0x1e, 0x44, 0x84, 0x67, + 0xce, 0x33, 0xc6, 0xfd, 0xe1, 0xe8, 0x23, 0x37, 0x27, 0xc0, 0x3f, 0x42, 0x4b, 0x7f, 0xe7, 0x53, + 0x12, 0xa6, 0x14, 0x3d, 0x81, 0x1d, 0x69, 0xe8, 0xaf, 0x1c, 0x69, 0xe6, 0x87, 0xd7, 0x62, 0x9e, + 0xd2, 0xdf, 0xc7, 0x99, 0xa0, 0x89, 0xab, 0x38, 0xf0, 0xfb, 0x70, 0xeb, 0x9b, 0x20, 0x31, 0xcd, + 0xd6, 0x97, 0x7b, 0x04, 0x3b, 0xdf, 0xe5, 0xf3, 0xa9, 0xaf, 0x54, 0x39, 0x18, 0x43, 0x6b, 0x42, + 0xc5, 0x19, 0x59, 0xe9, 0x7e, 0x21, 0xb8, 0x91, 0x3b, 0x1a, 0x24, 0x6d, 0x7c, 0x0c, 0x87, 0x39, + 0x5d, 0x6e, 0xbf, 0x96, 0xab, 0x03, 0x47, 0x13, 0x2a, 0x9e, 0x9a, 0xe9, 0x9b, 0x51, 0x75, 0xcf, + 0x78, 0x02, 0x77, 0x6a, 0xf1, 0x69, 0x90, 0x08, 0xc6, 0xb3, 0x62, 0xea, 0x4e, 0x23, 0x2f, 0x4c, + 0x7d, 0x7a, 0xce, 0xe9, 0xf3, 0x80, 0xa5, 0xea, 0xaa, 0xb6, 0xdd, 0x7a, 0x18, 0x4f, 0xe0, 0xf6, + 0x06, 0x16, 0x34, 0x80, 0x5d, 0x6d, 0x76, 0xad, 0x7b, 0xdb, 0x27, 0xcd, 0x61, 0xc7, 0x29, 0xc4, + 0x59, 0xc6, 0xbb, 0x06, 0x86, 0xcf, 0xa0, 0x55, 0x3e, 0x40, 0x1d, 0x68, 0x2c, 0x69, 0xb0, 0x58, + 0x0a, 0x59, 0xf9, 0x86, 0xab, 0x3d, 0x74, 0x0c, 0xdb, 0x33, 0x2a, 0xba, 0x5b, 0x92, 0xf5, 0xc8, + 0x59, 0x0b, 0xab, 0xc8, 0x76, 0x73, 0x00, 0x3e, 0x86, 0x9b, 0x13, 0x2a, 0xce, 0x39, 0x8b, 0x59, + 0x42, 0xc2, 0xa2, 0x93, 0x53, 0x92, 0x2c, 0xd5, 0x85, 0xba, 0xd2, 0xc6, 0x03, 0x40, 0x79, 0x27, + 0x0d, 0x50, 0x77, 0xd3, 0x86, 0x3d, 0x15, 0xa1, 0xbe, 0x44, 0xef, 0xb9, 0x85, 0x8f, 0xbf, 0x85, + 0x43, 0x83, 0x76, 0x69, 0x92, 0x86, 0x62, 0x13, 0x2f, 0xba, 0x0f, 0x8d, 0x31, 0x09, 0x43, 0x26, + 0xe4, 0x60, 0x36, 0x87, 0x6d, 0xc7, 0xe8, 0x5c, 0x85, 0x5d, 0x7d, 0x8c, 0xdb, 0x70, 0x20, 0x15, + 0x42, 0xf4, 0x54, 0x60, 0x0a, 0x3b, 0xd2, 0x43, 0x0f, 0xe0, 0xa6, 0x99, 0x97, 0x5c, 0xb1, 0x5f, + 0x32, 0x9f, 0xea, 0x66, 0x5c, 0x89, 0xe7, 0xea, 0x2f, 0xc7, 0x58, 0x2a, 0x24, 0x7c, 0x4b, 0xc2, + 0x37, 0x1d, 0xe1, 0xfb, 0xb2, 0xae, 0xdc, 0x0b, 0xea, 0x3f, 0x77, 0xa0, 0x31, 0xad, 0x74, 0x5c, + 0x79, 0xc3, 0x7f, 0x77, 0xf4, 0x68, 0xa1, 0x21, 0x34, 0xd4, 0x6e, 0x42, 0x6f, 0xae, 0xaf, 0xb3, + 0xb4, 0xad, 0xec, 0x5b, 0x79, 0xd8, 0x51, 0x5d, 0xd1, 0xc8, 0x11, 0xc0, 0x7a, 0xc9, 0xa0, 0xb7, + 0xd7, 0x79, 0xb5, 0xd5, 0x63, 0xb7, 0x9c, 0x7c, 0x5f, 0x1a, 0xe0, 0xe7, 0x32, 0x4d, 0xeb, 0xb1, + 0x96, 0x56, 0xde, 0x26, 0x76, 0xa7, 0xfc, 0x25, 0x25, 0xf5, 0x7e, 0x06, 0xad, 0xb2, 0xe0, 0xd0, + 0x9d, 0x35, 0xee, 0x8a, 0x10, 0xab, 0xb5, 0x07, 0x16, 0xea, 0xc3, 0xae, 0x96, 0x20, 0xea, 0x54, + 0x4a, 0x17, 0xaa, 0xb4, 0x5b, 0x8e, 0xda, 0xf5, 0x5f, 0x45, 0x82, 0x67, 0x68, 0x04, 0xfb, 0x85, + 0x1e, 0x51, 0xb7, 0x5a, 0x6a, 0x2d, 0xd2, 0x6a, 0xd2, 0xc0, 0x42, 0xa7, 0x72, 0x3b, 0x56, 0xe6, + 0xbe, 0x57, 0xa9, 0x77, 0x45, 0xb9, 0xf6, 0x2b, 0x84, 0x84, 0x7e, 0x82, 0xce, 0x66, 0x45, 0xa3, + 0xf7, 0x5e, 0xc9, 0x58, 0xd6, 0xbc, 0xfd, 0xee, 0x66, 0x62, 0xc3, 0xf2, 0x29, 0x34, 0x4b, 0x7a, + 0x42, 0x76, 0x85, 0xb4, 0x22, 0x33, 0xbb, 0x3e, 0xea, 0xe8, 0x14, 0x0e, 0x2a, 0x1a, 0x43, 0xef, + 0x54, 0x3b, 0x54, 0x15, 0x9f, 0x5d, 0xea, 0x5f, 0x55, 0x68, 0x03, 0x0b, 0x3d, 0x82, 0x3d, 0xa3, + 0x16, 0xf4, 0x56, 0x6d, 0x2a, 0x8c, 0x82, 0xec, 0x76, 0x75, 0x3a, 0x13, 0xf4, 0x09, 0x1c, 0x9a, + 0x59, 0x9f, 0x52, 0xe2, 0x53, 0x5e, 0xcb, 0x5d, 0xab, 0xc0, 0x3e, 0x70, 0xd4, 0x83, 0xae, 0x70, + 0xe3, 0x2f, 0x2e, 0x2e, 0x7b, 0xd6, 0x5f, 0x97, 0x3d, 0xeb, 0x9f, 0xcb, 0x9e, 0xf5, 0xe7, 0xcb, + 0x9e, 0x75, 0xf1, 0xb2, 0x67, 0xfd, 0xf0, 0xe0, 0xf5, 0x6f, 0x00, 0x8f, 0xbd, 0xbe, 0xa1, 0x9f, + 0x37, 0xe4, 0xbb, 0xfe, 0xe1, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xac, 0x5a, 0x15, 0x64, 0x9e, + 0x08, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/rpc/service.go b/rpc/service.go index 7304795a3..18dcc026b 100644 --- a/rpc/service.go +++ b/rpc/service.go @@ -190,10 +190,7 @@ func (s *Service) Storage(address crypto.Address, key []byte) (*ResultStorage, e if err != nil { return nil, err } - if value == binary.Zero256 { - return &ResultStorage{Key: key, Value: nil}, nil - } - return &ResultStorage{Key: key, Value: value.UnpadLeft()}, nil + return &ResultStorage{Key: key, Value: value}, nil } func (s *Service) DumpStorage(address crypto.Address) (*ResultDumpStorage, error) { @@ -205,8 +202,8 @@ func (s *Service) DumpStorage(address crypto.Address) (*ResultDumpStorage, error return nil, fmt.Errorf("UnknownAddress: %X", address) } var storageItems []StorageItem - err = s.state.IterateStorage(address, func(key, value binary.Word256) error { - storageItems = append(storageItems, StorageItem{Key: key.UnpadLeft(), Value: value.UnpadLeft()}) + err = s.state.IterateStorage(address, func(key binary.Word256, value []byte) error { + storageItems = append(storageItems, StorageItem{Key: key.UnpadLeft(), Value: value}) return nil }) if err != nil { diff --git a/txs/json_codec_test.go b/txs/json_codec_test.go index 3ea74d06b..1c10c8568 100644 --- a/txs/json_codec_test.go +++ b/txs/json_codec_test.go @@ -52,6 +52,7 @@ func TestJSONEncodeTxDecodeTx_CallTx(t *testing.T) { Fee: 2, Address: nil, Data: []byte("code"), + WASM: []byte("wasm"), } txEnv := Enclose(chainID, tx) require.NoError(t, txEnv.Sign(inputAccount)) From 9e92881ea8a1e8af8175e48d98baeb6e332df687 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Sat, 15 Jun 2019 15:15:09 +0100 Subject: [PATCH 4/7] Add wasm test Signed-off-by: Sean Young --- Makefile | 9 ++++ deploy/compile/compilers.go | 1 + deploy/compile/solgo/main.go | 31 ++++++++++--- execution/wasm/storage_test.solang | 17 +++++++ execution/wasm/storage_test.solang.go | 6 +++ execution/wasm/wasm_test.go | 66 +++++++++++++++++++++++++++ project/history.go | 5 +- 7 files changed, 128 insertions(+), 7 deletions(-) create mode 100644 execution/wasm/storage_test.solang create mode 100644 execution/wasm/storage_test.solang.go create mode 100644 execution/wasm/wasm_test.go diff --git a/Makefile b/Makefile index f5b60e0ba..13a272240 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,8 @@ PROTO_GO_FILES_REAL = $(shell find . -path ./vendor -prune -o -type f -name '*.p # Our own Go files containing the compiled bytecode of solidity files as a constant SOLIDITY_FILES = $(shell find . -path ./vendor -prune -o -path ./tests -prune -o -type f -name '*.sol' -print) SOLIDITY_GO_FILES = $(patsubst %.sol, %.sol.go, $(SOLIDITY_FILES)) +SOLANG_FILES = $(shell find . -path ./vendor -prune -o -path ./tests -prune -o -type f -name '*.solang' -print) +SOLANG_GO_FILES = $(patsubst %.solang, %.solang.go, $(SOLANG_FILES)) CI_IMAGE="hyperledger/burrow:ci" @@ -148,9 +150,16 @@ docker_build: check commit_hash %.sol.go: %.sol @go run ./deploy/compile/solgo/main.go $^ +# Solidity fixtures +%.solang.go: %.solang + @go run ./deploy/compile/solgo/main.go -wasm $^ + .PHONY: solidity solidity: $(SOLIDITY_GO_FILES) +.PHONY: solang +solang: $(SOLANG_GO_FILES) + # Test .PHONY: test diff --git a/deploy/compile/compilers.go b/deploy/compile/compilers.go index b09d86322..9704f37d4 100644 --- a/deploy/compile/compilers.go +++ b/deploy/compile/compilers.go @@ -226,6 +226,7 @@ func CompileWASM(file string, workDir string, logger *logging.Logger) (*Response } output, err := shellCmd.CombinedOutput() if err != nil { + logger.InfoMsg("solang failed", "output", string(output)) return nil, err } logger.TraceMsg("Command Output", "result", string(output)) diff --git a/deploy/compile/solgo/main.go b/deploy/compile/solgo/main.go index 6a86b4edd..b45a52a86 100644 --- a/deploy/compile/solgo/main.go +++ b/deploy/compile/solgo/main.go @@ -1,6 +1,7 @@ package main import ( + "flag" "fmt" "os" "path" @@ -10,11 +11,25 @@ import ( ) func main() { - for _, solfile := range os.Args[1:] { - resp, err := compile.Compile(solfile, false, "", nil, logging.NewNoopLogger()) - if err != nil { - fmt.Printf("failed compile solidity: %v\n", err) - os.Exit(1) + wasmPtr := flag.Bool("wasm", false, "Use solang rather than solc") + flag.Parse() + + for _, solfile := range flag.Args() { + var resp *compile.Response + var err error + + if *wasmPtr { + resp, err = compile.CompileWASM(solfile, "", logging.NewNoopLogger()) + if err != nil { + fmt.Printf("failed compile solidity to wasm: %v\n", err) + os.Exit(1) + } + } else { + resp, err = compile.Compile(solfile, false, "", nil, logging.NewNoopLogger()) + if err != nil { + fmt.Printf("failed compile solidity: %v\n", err) + os.Exit(1) + } } if resp.Error != "" { @@ -37,8 +52,12 @@ func main() { f.WriteString("import hex \"github.com/tmthrgd/go-hex\"\n\n") for _, c := range resp.Objects { + code := c.Contract.Evm.Bytecode.Object + if code == "" { + code = c.Contract.EWasm.Wasm + } f.WriteString(fmt.Sprintf("var Bytecode_%s = hex.MustDecodeString(\"%s\")\n", - c.Objectname, c.Contract.Evm.Bytecode.Object)) + c.Objectname, code)) f.WriteString(fmt.Sprintf("var Abi_%s = []byte(`%s`)\n", c.Objectname, c.Contract.Abi)) } diff --git a/execution/wasm/storage_test.solang b/execution/wasm/storage_test.solang new file mode 100644 index 000000000..5ad6e43ff --- /dev/null +++ b/execution/wasm/storage_test.solang @@ -0,0 +1,17 @@ + + +contract storage_test { + uint64 foo; + + constructor() public { + foo = 102; + } + + function getFooPlus2() public view returns (uint64) { + return foo + 2; + } + + function incFoo() public { + foo += 1; + } +} diff --git a/execution/wasm/storage_test.solang.go b/execution/wasm/storage_test.solang.go new file mode 100644 index 000000000..f3635e11b --- /dev/null +++ b/execution/wasm/storage_test.solang.go @@ -0,0 +1,6 @@ +package wasm + +import hex "github.com/tmthrgd/go-hex" + +var Bytecode_storage_test = hex.MustDecodeString("0061736D0100000001220760037F7F7F0060027F7F0060000060017F0060017F017F60027F7F017F6000017E02380303656E760D7365745F73746F726167653332000003656E760D6765745F73746F726167653332000003656E76066D656D6F727902010202030F0E00010102030405000002060203040608017F01418080040B07BB010E095F5F6D656D637079380002085F5F627A65726F380003075F5F627365743800040B5F5F696E69745F686561700005065F5F667265650006085F5F6D616C6C6F630007095F5F7265616C6C6F6300080B5F5F62653332746F6C654E00090B5F5F6C654E746F62653332000A12736F6C3A3A5F5F636F6E7374727563746F72000B10736F6C3A3A676574466F6F506C757332000C0B736F6C3A3A696E63466F6F000D0B636F6E7374727563746F72000E0866756E6374696F6E000F0AF8080E2600034020002001290300370300200041086A2100200141086A21012002417F6A22020D000B0B1C00034020004200370300200041086A21002001417F6A22010D000B0B1C0003402000427F370300200041086A21002001417F6A22010D000B0B2B00410041003602808004410041003602848004410041003A008C800441003F0041F0FF7B6A36028880040BB90101037F02402000450D00410021012000417C6A41003A0000024002400240200041706A22022802002203450D0020032D000C450D01200321010B200041746A2802002203450D020C010B20022003280200220136020002402001450D00200120023602040B200041786A2202200328020820022802006A41106A360200200041746A2802002203450D010B20032D000C0D0020012003360204200320013602002003200041786A28020020032802086A41106A3602080F0B0BA90101047F41808004210102400340024020012D000C0D002001280208220220004F0D020B200128020022010D000B41002101410028020821020B02402002200041076A41787122036B22024118490D00200120036A41106A22002001280200220436020002402004450D00200420003602040B2000200241706A360208200041003A000C2000200136020420012000360200200141086A20033602000B200141013A000C200141106A0BF50101057F024002400240200041706A22022802002203450D0020032D000C0D00200041786A220428020020032802086A41106A220520014F0D010B41002103410020014103766B21022001100721010340200120036A200020036A290300370300200341086A2103200241016A22020D000B20001006200121000C010B20042005360200200328020022032002360204200220033602002005200141076A41787122066B22054118490D00200020066A2201200336020002402003450D00200341046A20013602000B2001200541706A360208200141003A000C20012002360204200220013602002004200636020020000F0B20000B2D002000411F6A21000340200120002D00003A0000200141016A21012000417F6A21002002417F6A22020D000B0B2D002001411F6A21010340200120002D00003A00002001417F6A2101200041016A21002002417F6A22020D000B0B2701017F230041106B22002400200042E6003703084100200041086A41081000200041106A24000B2D02017F017E230041106B220024004100200041086A4108100120002903082101200041106A2400200142027C0B3701017F230041106B220024004100200041086A410810012000200029030842017C3703084100200041086A41081000200041106A24000B12001005024020002802000D00100B0F0B000B8E0103037F017E017F23002201210202402000280200220341034D0D002003417C6A21030240200041046A28020041DE9AB88F79470D0020030D01100D41041007220041003602002002240020000F0B20030D00100C21044124100722004120360200200041046A220541041003200141706A2203240020032004370300200320054108100A2002240020000F0B000B") +var Abi_storage_test = []byte(`[{"name":"","type":"constructor","inputs":[],"outputs":[],"constant":false,"payable":false,"stateMutability":"nonpayable"},{"name":"getFooPlus2","type":"function","inputs":[],"outputs":[{"name":"","type":"uint64"}],"constant":true,"payable":false,"stateMutability":"view"},{"name":"incFoo","type":"function","inputs":[],"outputs":[],"constant":false,"payable":false,"stateMutability":"nonpayable"}]`) diff --git a/execution/wasm/wasm_test.go b/execution/wasm/wasm_test.go new file mode 100644 index 000000000..7e9a29293 --- /dev/null +++ b/execution/wasm/wasm_test.go @@ -0,0 +1,66 @@ +package wasm + +import ( + "fmt" + "testing" + + "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/execution/evm" + + "github.com/hyperledger/burrow/acm/acmstate" + "github.com/hyperledger/burrow/execution/evm/abi" + + "github.com/hyperledger/burrow/crypto" + "github.com/stretchr/testify/require" +) + +func TestStaticCallWithValue(t *testing.T) { + cache := evm.NewState(acmstate.NewMemoryState(), blockHashGetter) + + cache.CreateAccount(crypto.ZeroAddress) + // run constructor + _, cerr := RunWASM(cache, crypto.ZeroAddress, true, Bytecode_storage_test, []byte{}) + require.NoError(t, cerr) + + // run getFooPlus2 + spec, err := abi.ReadAbiSpec(Abi_storage_test) + require.NoError(t, err) + calldata, _, err := spec.Pack("getFooPlus2") + + returndata, cerr := RunWASM(cache, crypto.ZeroAddress, false, Bytecode_storage_test, calldata) + require.NoError(t, cerr) + + data := abi.GetPackingTypes(spec.Functions["getFooPlus2"].Outputs) + + err = spec.Unpack(returndata, "getFooPlus2", data...) + require.NoError(t, err) + returnValue := *data[0].(*uint64) + var expected uint64 + expected = 104 + require.Equal(t, expected, returnValue) + + // call incFoo + calldata, _, err = spec.Pack("incFoo") + + returndata, cerr = RunWASM(cache, crypto.ZeroAddress, false, Bytecode_storage_test, calldata) + require.NoError(t, cerr) + + require.Equal(t, returndata, []byte{}) + + // run getFooPlus2 + calldata, _, err = spec.Pack("getFooPlus2") + require.NoError(t, err) + + returndata, cerr = RunWASM(cache, crypto.ZeroAddress, false, Bytecode_storage_test, calldata) + require.NoError(t, cerr) + + spec.Unpack(returndata, "getFooPlus2", data...) + expected = 105 + returnValue = *data[0].(*uint64) + + require.Equal(t, expected, returnValue) +} + +func blockHashGetter(height uint64) []byte { + return binary.LeftPadWord256([]byte(fmt.Sprintf("block_hash_%d", height))).Bytes() +} diff --git a/project/history.go b/project/history.go index 596e7e66e..891ce8bf1 100644 --- a/project/history.go +++ b/project/history.go @@ -49,7 +49,10 @@ func FullVersion() string { var History relic.ImmutableHistory = relic.NewHistory("Hyperledger Burrow", "https://github.com/hyperledger/burrow"). MustDeclareReleases( "", - `### Fixed + `### Added +- [WASM] Support for WASM contracts written in Solidity compiled using solang + +### Fixed -[RPC/Transact] CallCodeSim and CallTxSim were run against uncommitted checker state rather than committed state were all other reads are routed. They were also passed through Transactor for no particularly good reason. This changes them to run against committed DB state and removes the code path through Transactor. ### Changed From 58e7c10ca195b4c28a1a87b559b617a80f2d60c7 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 17 Jun 2019 09:48:42 +0100 Subject: [PATCH 5/7] Do not show progress meter Signed-off-by: Sean Young --- .circleci/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/Dockerfile b/.circleci/Dockerfile index 57832735c..5097163cc 100644 --- a/.circleci/Dockerfile +++ b/.circleci/Dockerfile @@ -26,8 +26,8 @@ RUN apk add --update --no-cache \ RUN pip install docker-compose # get docker client WORKDIR /usr/bin -RUN curl -L https://download.docker.com/linux/static/stable/x86_64/docker-$DOCKER_VERSION.tgz | tar xz --strip-components 1 docker/docker -RUN curl -L https://github.com/goreleaser/goreleaser/releases/download/$GORELEASER_VERSION/goreleaser_Linux_x86_64.tar.gz | tar xz goreleaser +RUN curl -sS -L https://download.docker.com/linux/static/stable/x86_64/docker-$DOCKER_VERSION.tgz | tar xz --strip-components 1 docker/docker +RUN curl -sS -L https://github.com/goreleaser/goreleaser/releases/download/$GORELEASER_VERSION/goreleaser_Linux_x86_64.tar.gz | tar xz goreleaser RUN npm install -g mocha RUN npm install -g mocha-circleci-reporter ENV CI=true From d0745f9e2d3e15c1b1ee1493c0a7ff2b9ce3d7b0 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Sat, 22 Jun 2019 20:46:45 +0200 Subject: [PATCH 6/7] Review comments Signed-off-by: Sean Young --- acm/account.go | 6 +- acm/account_test.go | 12 ++-- acm/acm.pb.go | 89 +++++++++++------------- acm/acmstate/state_cache_test.go | 2 +- deploy/compile/compilers.go | 16 +++-- deploy/compile/compilers_test.go | 6 +- deploy/compile/solgo/main.go | 4 +- deploy/jobs/job_manager.go | 6 +- dump/mock_reader_test.go | 2 +- execution/contexts/call_context.go | 4 +- execution/contexts/governance_context.go | 2 +- execution/evm/state.go | 19 +++-- execution/evm/vm.go | 16 ++--- execution/evm/vm_test.go | 16 ++--- execution/execution_test.go | 36 +++++----- execution/simulated_call.go | 2 +- execution/state/accounts.go | 4 +- execution/state/state.go | 2 +- execution/wasm/wasm.go | 44 +++++++----- protobuf/acm.proto | 4 +- rpc/service.go | 2 +- 21 files changed, 151 insertions(+), 143 deletions(-) diff --git a/acm/account.go b/acm/account.go index dd968ad0e..1cf3eebe0 100644 --- a/acm/account.go +++ b/acm/account.go @@ -92,7 +92,7 @@ func FromAddressable(addressable crypto.Addressable) *Account { Address: addressable.GetAddress(), PublicKey: addressable.GetPublicKey(), // Since nil slices and maps compare differently to empty ones - Code: Bytecode{}, + EVMCode: Bytecode{}, Permissions: permission.AccountPermissions{ Roles: []string{}, }, @@ -124,13 +124,13 @@ func (acc *Account) Equal(accOther *Account) bool { func (acc Account) String() string { return fmt.Sprintf("Account{Address: %s; Sequence: %v; PublicKey: %v Balance: %v; CodeLength: %v; Permissions: %v}", - acc.Address, acc.Sequence, acc.PublicKey, acc.Balance, len(acc.Code), acc.Permissions) + acc.Address, acc.Sequence, acc.PublicKey, acc.Balance, len(acc.EVMCode), acc.Permissions) } func (acc *Account) Tagged() query.Tagged { return &TaggedAccount{ Account: acc, - Tagged: query.MergeTags(query.MustReflectTags(acc, "Address", "Balance", "Sequence", "Code"), + Tagged: query.MergeTags(query.MustReflectTags(acc, "Address", "Balance", "Sequence", "EVMCode"), query.TagMap{ "Permissions": acc.Permissions.Base.ResultantPerms(), "Roles": acc.Permissions.Roles, diff --git a/acm/account_test.go b/acm/account_test.go index 1173bdae6..445d3ef82 100644 --- a/acm/account_test.go +++ b/acm/account_test.go @@ -85,7 +85,7 @@ func TestDecode(t *testing.T) { func TestMarshalJSON(t *testing.T) { acc := NewAccountFromSecret("Super Semi Secret") - acc.Code = []byte{60, 23, 45} + acc.EVMCode = []byte{60, 23, 45} acc.Permissions = permission.AccountPermissions{ Base: permission.BasePermissions{ Perms: permission.AllPermFlags, @@ -96,7 +96,7 @@ func TestMarshalJSON(t *testing.T) { bs, err := json.Marshal(acc) expected := fmt.Sprintf(`{"Address":"%s","PublicKey":{"CurveType":"ed25519","PublicKey":"%s"},`+ - `"Sequence":4,"Balance":10,"Code":"3C172D",`+ + `"Sequence":4,"Balance":10,"EVMCode":"3C172D",`+ `"Permissions":{"Base":{"Perms":"root | send | call | createContract | createAccount | bond | name | proposal | input | batch | hasBase | setBase | unsetBase | setGlobal | hasRole | addRole | removeRole","SetBit":""}}}`, acc.Address, acc.PublicKey) assert.Equal(t, expected, string(bs)) @@ -108,16 +108,16 @@ func TestAccountTags(t *testing.T) { perms.Roles = []string{"frogs", "dogs"} acc := &Account{ Permissions: perms, - Code: solidity.Bytecode_StrangeLoop, + EVMCode: solidity.Bytecode_StrangeLoop, } tagged := acc.Tagged() - assert.Equal(t, []string{"Address", "Balance", "Sequence", "Code", "Permissions", "Roles"}, tagged.Keys()) + assert.Equal(t, []string{"Address", "Balance", "Sequence", "EVMCode", "Permissions", "Roles"}, tagged.Keys()) str, _ := tagged.Get("Permissions") assert.Equal(t, "send | call | createContract | createAccount | bond | name | proposal | input | batch | hasBase | hasRole", str) str, _ = tagged.Get("Roles") assert.Equal(t, "frogs;dogs", str) - tagged.Get("Code") - qry, err := query.New("Code CONTAINS '0116002556001600360006101000A815'") + tagged.Get("EVMCode") + qry, err := query.New("EVMCode CONTAINS '0116002556001600360006101000A815'") require.NoError(t, err) assert.True(t, qry.Matches(tagged)) } diff --git a/acm/acm.pb.go b/acm/acm.pb.go index 5949fb48b..c826d45dc 100644 --- a/acm/acm.pb.go +++ b/acm/acm.pb.go @@ -32,9 +32,9 @@ type Account struct { PublicKey crypto.PublicKey `protobuf:"bytes,2,opt,name=PublicKey,proto3" json:"PublicKey"` Sequence uint64 `protobuf:"varint,3,opt,name=Sequence,proto3" json:"Sequence,omitempty"` Balance uint64 `protobuf:"varint,4,opt,name=Balance,proto3" json:"Balance,omitempty"` - Code Bytecode `protobuf:"bytes,5,opt,name=Code,proto3,customtype=Bytecode" json:"Code"` + EVMCode Bytecode `protobuf:"bytes,5,opt,name=EVMCode,proto3,customtype=Bytecode" json:"EVMCode"` Permissions permission.AccountPermissions `protobuf:"bytes,6,opt,name=Permissions,proto3" json:"Permissions"` - WASM *Bytecode `protobuf:"bytes,7,opt,name=WASM,proto3,customtype=Bytecode" json:"WASM,omitempty"` + WASMCode Bytecode `protobuf:"bytes,7,opt,name=WASMCode,proto3,customtype=Bytecode" json:",omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -112,29 +112,30 @@ func init() { proto.RegisterFile("acm.proto", fileDescriptor_49ed775bc0a6adf6) } func init() { golang_proto.RegisterFile("acm.proto", fileDescriptor_49ed775bc0a6adf6) } var fileDescriptor_49ed775bc0a6adf6 = []byte{ - // 339 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x91, 0xbf, 0x4e, 0xf3, 0x30, - 0x14, 0xc5, 0xeb, 0x36, 0x5f, 0xd3, 0xba, 0x1d, 0xfa, 0x79, 0xb2, 0x3a, 0xa4, 0x01, 0x31, 0x74, - 0x80, 0x44, 0xe2, 0x8f, 0x90, 0xd8, 0x1a, 0x24, 0x16, 0x04, 0xaa, 0xd2, 0x01, 0x89, 0x2d, 0x71, - 0x2e, 0x69, 0xa4, 0xa6, 0x0e, 0x4e, 0x2c, 0x94, 0x37, 0x61, 0xe4, 0x51, 0x18, 0x3b, 0x32, 0x23, - 0x54, 0xa1, 0xf6, 0x45, 0x50, 0x8d, 0x5b, 0xc2, 0xc2, 0x96, 0x93, 0xdf, 0xbd, 0xf7, 0x1c, 0x1d, - 0xe3, 0x76, 0xc0, 0x52, 0x27, 0x13, 0xbc, 0xe0, 0xa4, 0x11, 0xb0, 0xb4, 0x7f, 0x14, 0x27, 0xc5, - 0x54, 0x86, 0x0e, 0xe3, 0xa9, 0x1b, 0xf3, 0x98, 0xbb, 0x8a, 0x85, 0xf2, 0x41, 0x29, 0x25, 0xd4, - 0xd7, 0xf7, 0x4e, 0xbf, 0x97, 0x81, 0x48, 0x93, 0x3c, 0x4f, 0xf8, 0x5c, 0xff, 0xe9, 0x32, 0x51, - 0x66, 0x85, 0xe6, 0xfb, 0x1f, 0x75, 0x6c, 0x8e, 0x18, 0xe3, 0x72, 0x5e, 0x90, 0x5b, 0x6c, 0x8e, - 0xa2, 0x48, 0x40, 0x9e, 0x53, 0x64, 0xa3, 0x61, 0xd7, 0x3b, 0x5d, 0x2c, 0x07, 0xb5, 0xf7, 0xe5, - 0xe0, 0xb0, 0xe2, 0x39, 0x2d, 0x33, 0x10, 0x33, 0x88, 0x62, 0x10, 0x6e, 0x28, 0x85, 0xe0, 0x4f, - 0xae, 0x3e, 0xa8, 0x77, 0xfd, 0xed, 0x11, 0x72, 0x86, 0xdb, 0x63, 0x19, 0xce, 0x12, 0x76, 0x0d, - 0x25, 0xad, 0xdb, 0x68, 0xd8, 0x39, 0xfe, 0xef, 0xe8, 0xe1, 0x1d, 0xf0, 0x8c, 0x8d, 0x89, 0xff, - 0x33, 0x49, 0xfa, 0xb8, 0x35, 0x81, 0x47, 0x09, 0x73, 0x06, 0xb4, 0x61, 0xa3, 0xa1, 0xe1, 0xef, - 0x34, 0xa1, 0xd8, 0xf4, 0x82, 0x59, 0xb0, 0x41, 0x86, 0x42, 0x5b, 0x49, 0x0e, 0xb0, 0x71, 0xc9, - 0x23, 0xa0, 0xff, 0x54, 0xf2, 0x9e, 0x4e, 0xde, 0xf2, 0xca, 0x02, 0x18, 0x8f, 0xc0, 0x57, 0x94, - 0x5c, 0xe1, 0xce, 0x78, 0x57, 0x48, 0x4e, 0x9b, 0x2a, 0x94, 0xe5, 0x54, 0x4a, 0xd2, 0x65, 0x54, - 0xa6, 0x74, 0xc2, 0xea, 0x22, 0xb1, 0xb1, 0x71, 0x37, 0x9a, 0xdc, 0x50, 0x53, 0xb9, 0x75, 0x7f, - 0x3b, 0x6d, 0xc8, 0x85, 0xf1, 0xfc, 0x32, 0xa8, 0x79, 0xe7, 0x8b, 0x95, 0x85, 0xde, 0x56, 0x16, - 0xfa, 0x5c, 0x59, 0xe8, 0x75, 0x6d, 0xa1, 0xc5, 0xda, 0x42, 0xf7, 0x7b, 0x7f, 0xf7, 0x19, 0xb0, - 0x34, 0x6c, 0xaa, 0xe7, 0x39, 0xf9, 0x0a, 0x00, 0x00, 0xff, 0xff, 0xcb, 0x97, 0x60, 0xcc, 0xff, - 0x01, 0x00, 0x00, + // 355 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x51, 0xbf, 0x4f, 0xfa, 0x40, + 0x1c, 0xe5, 0xa0, 0x5f, 0x0a, 0x07, 0x03, 0xdf, 0x9b, 0x1a, 0x86, 0x16, 0x9d, 0x88, 0xc1, 0x36, + 0xf1, 0x47, 0x4c, 0xd8, 0xa8, 0xd1, 0xc5, 0x68, 0x48, 0x49, 0x34, 0x71, 0x6b, 0xaf, 0x67, 0x69, + 0xc2, 0x71, 0xf5, 0x7a, 0x8d, 0xe9, 0x7f, 0xe2, 0xe8, 0x9f, 0xe2, 0xc8, 0xe8, 0xec, 0x40, 0x0c, + 0x6c, 0xfe, 0x0d, 0x0e, 0x86, 0xe3, 0xa8, 0x8d, 0x83, 0x5b, 0x5f, 0xdf, 0x7b, 0x9f, 0xf7, 0xf2, + 0x0e, 0x36, 0x7d, 0x4c, 0xed, 0x84, 0x33, 0xc1, 0x50, 0xcd, 0xc7, 0xb4, 0x7b, 0x18, 0xc5, 0x62, + 0x9a, 0x05, 0x36, 0x66, 0xd4, 0x89, 0x58, 0xc4, 0x1c, 0xc9, 0x05, 0xd9, 0x83, 0x44, 0x12, 0xc8, + 0xaf, 0xad, 0xa7, 0xdb, 0x49, 0x08, 0xa7, 0x71, 0x9a, 0xc6, 0x6c, 0xae, 0xfe, 0xb4, 0x31, 0xcf, + 0x13, 0xa1, 0xf8, 0xfd, 0xaf, 0x2a, 0xd4, 0x47, 0x18, 0xb3, 0x6c, 0x2e, 0xd0, 0x0d, 0xd4, 0x47, + 0x61, 0xc8, 0x49, 0x9a, 0x1a, 0xa0, 0x07, 0xfa, 0x6d, 0xf7, 0x64, 0xb1, 0xb4, 0x2a, 0xef, 0x4b, + 0x6b, 0x50, 0xca, 0x9c, 0xe6, 0x09, 0xe1, 0x33, 0x12, 0x46, 0x84, 0x3b, 0x41, 0xc6, 0x39, 0x7b, + 0x72, 0xd4, 0x41, 0xe5, 0xf5, 0x76, 0x47, 0xd0, 0x29, 0x6c, 0x8e, 0xb3, 0x60, 0x16, 0xe3, 0x2b, + 0x92, 0x1b, 0xd5, 0x1e, 0xe8, 0xb7, 0x8e, 0xfe, 0xdb, 0x4a, 0x5c, 0x10, 0xae, 0xb6, 0x09, 0xf1, + 0x7e, 0x94, 0xa8, 0x0b, 0x1b, 0x13, 0xf2, 0x98, 0x91, 0x39, 0x26, 0x46, 0xad, 0x07, 0xfa, 0x9a, + 0x57, 0x60, 0x64, 0x40, 0xdd, 0xf5, 0x67, 0xfe, 0x86, 0xd2, 0x24, 0xb5, 0x83, 0xe8, 0x00, 0xea, + 0x17, 0xb7, 0xd7, 0xe7, 0x2c, 0x24, 0xc6, 0x3f, 0x59, 0xbe, 0xa3, 0xca, 0x37, 0xdc, 0x5c, 0x10, + 0xcc, 0x42, 0xe2, 0xed, 0x04, 0xe8, 0x12, 0xb6, 0xc6, 0xc5, 0x2c, 0xa9, 0x51, 0x97, 0xd5, 0x4c, + 0xbb, 0x34, 0x95, 0x9a, 0xa4, 0xa4, 0x52, 0x3d, 0xcb, 0x46, 0x34, 0x84, 0x8d, 0xbb, 0xd1, 0x64, + 0x1b, 0xaa, 0xcb, 0x50, 0xf3, 0x77, 0xe8, 0xe7, 0xd2, 0x82, 0x03, 0x46, 0x63, 0x41, 0x68, 0x22, + 0x72, 0xaf, 0xd0, 0x0f, 0xb5, 0xe7, 0x17, 0xab, 0xe2, 0x9e, 0x2d, 0x56, 0x26, 0x78, 0x5b, 0x99, + 0xe0, 0x63, 0x65, 0x82, 0xd7, 0xb5, 0x09, 0x16, 0x6b, 0x13, 0xdc, 0xef, 0xfd, 0xbd, 0xb7, 0x8f, + 0x69, 0x50, 0x97, 0xcf, 0x77, 0xfc, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x65, 0x02, 0xa3, 0x8e, 0x1f, + 0x02, 0x00, 0x00, } func (m *Account) Marshal() (dAtA []byte, err error) { @@ -180,8 +181,8 @@ func (m *Account) MarshalTo(dAtA []byte) (int, error) { } dAtA[i] = 0x2a i++ - i = encodeVarintAcm(dAtA, i, uint64(m.Code.Size())) - n3, err := m.Code.MarshalTo(dAtA[i:]) + i = encodeVarintAcm(dAtA, i, uint64(m.EVMCode.Size())) + n3, err := m.EVMCode.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -194,16 +195,14 @@ func (m *Account) MarshalTo(dAtA []byte) (int, error) { return 0, err } i += n4 - if m.WASM != nil { - dAtA[i] = 0x3a - i++ - i = encodeVarintAcm(dAtA, i, uint64(m.WASM.Size())) - n5, err := m.WASM.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n5 + dAtA[i] = 0x3a + i++ + i = encodeVarintAcm(dAtA, i, uint64(m.WASMCode.Size())) + n5, err := m.WASMCode.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err } + i += n5 if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -235,14 +234,12 @@ func (m *Account) Size() (n int) { if m.Balance != 0 { n += 1 + sovAcm(uint64(m.Balance)) } - l = m.Code.Size() + l = m.EVMCode.Size() n += 1 + l + sovAcm(uint64(l)) l = m.Permissions.Size() n += 1 + l + sovAcm(uint64(l)) - if m.WASM != nil { - l = m.WASM.Size() - n += 1 + l + sovAcm(uint64(l)) - } + l = m.WASMCode.Size() + n += 1 + l + sovAcm(uint64(l)) if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -397,7 +394,7 @@ func (m *Account) Unmarshal(dAtA []byte) error { } case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field EVMCode", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -424,7 +421,7 @@ func (m *Account) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Code.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.EVMCode.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -463,7 +460,7 @@ func (m *Account) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field WASM", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field WASMCode", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -490,9 +487,7 @@ func (m *Account) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v Bytecode - m.WASM = &v - if err := m.WASM.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.WASMCode.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/acm/acmstate/state_cache_test.go b/acm/acmstate/state_cache_test.go index 36376a09e..3ac275f53 100644 --- a/acm/acmstate/state_cache_test.go +++ b/acm/acmstate/state_cache_test.go @@ -317,7 +317,7 @@ func testAccounts() *MemoryState { acc2 := acm.NewAccountFromSecret("acc2") acc2.Permissions.Base.Perms = permission.AddRole | permission.Send acc2.Permissions.Base.SetBit = acc1.Permissions.Base.Perms - acc2.Code, _ = acm.NewBytecode(asm.PUSH1, 0x20) + acc2.EVMCode, _ = acm.NewBytecode(asm.PUSH1, 0x20) cache := combine( account(acc1, "I AM A KEY", "NO YOU ARE A KEY"), diff --git a/deploy/compile/compilers.go b/deploy/compile/compilers.go index 9704f37d4..b625c40c7 100644 --- a/deploy/compile/compilers.go +++ b/deploy/compile/compilers.go @@ -149,7 +149,15 @@ func (contract *SolidityContract) Link(libraries map[string]string) error { return nil } -func Compile(file string, optimize bool, workDir string, libraries map[string]string, logger *logging.Logger) (*Response, error) { +func (contract *SolidityContract) Code() (code string) { + code = contract.Evm.Bytecode.Object + if code == "" { + code = contract.EWasm.Wasm + } + return +} + +func EVM(file string, optimize bool, workDir string, libraries map[string]string, logger *logging.Logger) (*Response, error) { input := SolidityInput{Language: "Solidity", Sources: make(map[string]SolidityInputSource)} input.Sources[file] = SolidityInputSource{Urls: []string{file}} @@ -206,7 +214,7 @@ func Compile(file string, optimize bool, workDir string, libraries map[string]st for _, re := range respItemArray { logger.TraceMsg("Response formulated", "name", re.Objectname, - "bin", re.Contract.EWasm.Wasm, + "bin", re.Contract.Code(), "abi", string(re.Contract.Abi)) } @@ -219,7 +227,7 @@ func Compile(file string, optimize bool, workDir string, libraries map[string]st return &resp, nil } -func CompileWASM(file string, workDir string, logger *logging.Logger) (*Response, error) { +func WASM(file string, workDir string, logger *logging.Logger) (*Response, error) { shellCmd := exec.Command("solang", "--standard-json", file) if workDir != "" { shellCmd.Dir = workDir @@ -303,7 +311,7 @@ func PrintResponse(resp Response, cli bool, logger *logging.Logger) { for _, r := range resp.Objects { logger.InfoMsg("Response", "name", r.Objectname, - "bin", r.Contract.Evm.Bytecode, + "bin", r.Contract.Code(), "abi", string(r.Contract.Abi[:]), "link", string(r.Contract.Evm.Bytecode.LinkReferences[:]), ) diff --git a/deploy/compile/compilers_test.go b/deploy/compile/compilers_test.go index 8a3b107fe..33f25d3e2 100644 --- a/deploy/compile/compilers_test.go +++ b/deploy/compile/compilers_test.go @@ -62,7 +62,7 @@ func TestLocalMulti(t *testing.T) { Version: "", Error: "", } - resp, err := Compile("contractImport1.sol", false, "", make(map[string]string), logging.NewNoopLogger()) + resp, err := EVM("contractImport1.sol", false, "", make(map[string]string), logging.NewNoopLogger()) if err != nil { t.Fatal(err) } @@ -110,7 +110,7 @@ func TestLocalSingle(t *testing.T) { Version: "", Error: "", } - resp, err := Compile("simpleContract.sol", false, "", make(map[string]string), logging.NewNoopLogger()) + resp, err := EVM("simpleContract.sol", false, "", make(map[string]string), logging.NewNoopLogger()) if err != nil { t.Fatal(err) } @@ -126,7 +126,7 @@ func TestFaultyContract(t *testing.T) { const faultyContractFile = "tests/compilers_fixtures/faultyContract.sol" actualOutput, err := exec.Command("solc", "--combined-json", "bin,abi", faultyContractFile).CombinedOutput() require.EqualError(t, err, "exit status 1") - resp, err := Compile(faultyContractFile, false, "", make(map[string]string), logging.NewNoopLogger()) + resp, err := EVM(faultyContractFile, false, "", make(map[string]string), logging.NewNoopLogger()) require.NoError(t, err) if err != nil { if string(actualOutput) != resp.Error { diff --git a/deploy/compile/solgo/main.go b/deploy/compile/solgo/main.go index b45a52a86..ea747c646 100644 --- a/deploy/compile/solgo/main.go +++ b/deploy/compile/solgo/main.go @@ -19,13 +19,13 @@ func main() { var err error if *wasmPtr { - resp, err = compile.CompileWASM(solfile, "", logging.NewNoopLogger()) + resp, err = compile.WASM(solfile, "", logging.NewNoopLogger()) if err != nil { fmt.Printf("failed compile solidity to wasm: %v\n", err) os.Exit(1) } } else { - resp, err = compile.Compile(solfile, false, "", nil, logging.NewNoopLogger()) + resp, err = compile.EVM(solfile, false, "", nil, logging.NewNoopLogger()) if err != nil { fmt.Printf("failed compile solidity: %v\n", err) os.Exit(1) diff --git a/deploy/jobs/job_manager.go b/deploy/jobs/job_manager.go index 84955281b..10fe303b0 100644 --- a/deploy/jobs/job_manager.go +++ b/deploy/jobs/job_manager.go @@ -37,7 +37,7 @@ func solcRunner(jobs chan *compilerJob, logger *logging.Logger) { if !ok { break } - resp, err := compilers.Compile(job.work.contractName, false, job.work.workDir, nil, logger) + resp, err := compilers.EVM(job.work.contractName, false, job.work.workDir, nil, logger) (*job).compilerResp = resp (*job).err = err close(job.done) @@ -48,9 +48,9 @@ func solangRunner(jobs chan *compilerJob, logger *logging.Logger) { for { job, ok := <-jobs if !ok { - break + return } - resp, err := compilers.CompileWASM(job.work.contractName, job.work.workDir, logger) + resp, err := compilers.WASM(job.work.contractName, job.work.workDir, logger) (*job).compilerResp = resp (*job).err = err close(job.done) diff --git a/dump/mock_reader_test.go b/dump/mock_reader_test.go index bad31933c..8eecb732b 100644 --- a/dump/mock_reader_test.go +++ b/dump/mock_reader_test.go @@ -32,7 +32,7 @@ func (m *MockDumpReader) Next() (*Dump, error) { } if m.accounts%2 > 0 { - row.Account.Code = make([]byte, rand.Int()%10000) + row.Account.EVMCode = make([]byte, rand.Int()%10000) } else { row.Account.PublicKey = crypto.PublicKey{} } diff --git a/execution/contexts/call_context.go b/execution/contexts/call_context.go index acfc22e50..b41c4f57f 100644 --- a/execution/contexts/call_context.go +++ b/execution/contexts/call_context.go @@ -152,7 +152,7 @@ func (ctx *CallContext) Deliver(inAcc, outAcc *acm.Account, value uint64) error "contract_address", callee, "init_code", code) } else { - if outAcc == nil || (len(outAcc.Code) == 0 && outAcc.WASM == nil) { + if outAcc == nil || (len(outAcc.EVMCode) == 0 && len(outAcc.WASMCode) == 0) { // if you call an account that doesn't exist // or an account with no code then we take fees (sorry pal) // NOTE: it's fine to create a contract and call it within one @@ -179,7 +179,7 @@ func (ctx *CallContext) Deliver(inAcc, outAcc *acm.Account, value uint64) error return nil } callee = outAcc.Address - code = txCache.GetCode(callee) + code = txCache.GetEVMCode(callee) wcode = txCache.GetWASMCode(callee) ctx.Logger.TraceMsg("Calling existing contract", "contract_address", callee, diff --git a/execution/contexts/governance_context.go b/execution/contexts/governance_context.go index 0de857342..3847edd36 100644 --- a/execution/contexts/governance_context.go +++ b/execution/contexts/governance_context.go @@ -111,7 +111,7 @@ func (ctx *GovernanceContext) UpdateAccount(account *acm.Account, update *spec.T } } if update.Code != nil { - account.Code = *update.Code + account.EVMCode = *update.Code if err != nil { return ev, err } diff --git a/execution/evm/state.go b/execution/evm/state.go index 0aad68f61..7fafeed60 100644 --- a/execution/evm/state.go +++ b/execution/evm/state.go @@ -27,7 +27,7 @@ type Reader interface { GetStorage(address crypto.Address, key binary.Word256) []byte GetBalance(address crypto.Address) uint64 GetPermissions(address crypto.Address) permission.AccountPermissions - GetCode(address crypto.Address) acm.Bytecode + GetEVMCode(address crypto.Address) acm.Bytecode GetWASMCode(address crypto.Address) acm.Bytecode GetSequence(address crypto.Address) uint64 Exists(address crypto.Address) bool @@ -134,21 +134,21 @@ func (st *State) GetPermissions(address crypto.Address) permission.AccountPermis return acc.Permissions } -func (st *State) GetCode(address crypto.Address) acm.Bytecode { +func (st *State) GetEVMCode(address crypto.Address) acm.Bytecode { acc := st.account(address) if acc == nil { return nil } - return acc.Code + return acc.EVMCode } func (st *State) GetWASMCode(address crypto.Address) acm.Bytecode { acc := st.account(address) - if acc == nil || acc.WASM == nil { + if acc == nil { return nil } - return *acc.WASM + return acc.WASMCode } func (st *State) Exists(address crypto.Address) bool { @@ -189,12 +189,12 @@ func (st *State) InitCode(address crypto.Address, code []byte) { "tried to initialise code for an account that does not exist: %v", address)) return } - if acc.Code != nil { + if acc.EVMCode != nil || acc.WASMCode != nil { st.PushError(errors.ErrorCodef(errors.ErrorCodeIllegalWrite, "tried to initialise code for a contract that already exists: %v", address)) return } - acc.Code = code + acc.EVMCode = code st.updateAccount(acc) } @@ -205,13 +205,12 @@ func (st *State) InitWASMCode(address crypto.Address, code []byte) { "tried to initialise code for an account that does not exist: %v", address)) return } - if acc.Code != nil { + if acc.EVMCode != nil || acc.WASMCode != nil { st.PushError(errors.ErrorCodef(errors.ErrorCodeIllegalWrite, "tried to initialise code for a contract that already exists: %v", address)) return } - bc, _ := acm.NewBytecode(code) - acc.WASM = &bc + acc.WASMCode = code st.updateAccount(acc) } diff --git a/execution/evm/vm.go b/execution/evm/vm.go index 2852c7e9d..862b968d5 100644 --- a/execution/evm/vm.go +++ b/execution/evm/vm.go @@ -567,7 +567,7 @@ func (vm *VM) execute(callState Interface, eventSink EventSink, caller, callee c address := stack.PopAddress() useGasNegative(gas, GasGetAccount, callState) if callState.Exists(address) { - code := callState.GetCode(address) + code := callState.GetEVMCode(address) l := int64(len(code)) stack.Push64(l) vm.Debugf(" => %d\n", l) @@ -590,7 +590,7 @@ func (vm *VM) execute(callState Interface, eventSink EventSink, caller, callee c callState.PushError(errors.ErrorCodeUnknownAddress) continue } - code := callState.GetCode(address) + code := callState.GetEVMCode(address) memOff := stack.PopBigInt() codeOff := stack.Pop64() length := stack.Pop64() @@ -621,7 +621,7 @@ func (vm *VM) execute(callState Interface, eventSink EventSink, caller, callee c // In case the account does not exist 0 is pushed to the stack. stack.PushU64(0) } else { - code := callState.GetCode(address) + code := callState.GetEVMCode(address) if code == nil { // In case the account does not have code the keccak256 hash of empty data code = acm.Bytecode{} @@ -793,7 +793,7 @@ func (vm *VM) execute(callState Interface, eventSink EventSink, caller, callee c newAccount = crypto.NewContractAddress(callee, nonce) } else if op == CREATE2 { salt := stack.Pop() - newAccount = crypto.NewContractAddress2(callee, salt, callState.GetCode(callee)) + newAccount = crypto.NewContractAddress2(callee, salt, callState.GetEVMCode(callee)) } // Check the CreateContract permission for this account @@ -889,23 +889,23 @@ func (vm *VM) execute(callState Interface, eventSink EventSink, caller, callee c switch op { case CALL: childCallState = callState.NewCache() - returnData, callErr = vm.call(childCallState, eventSink, callee, address, callState.GetCode(address), + returnData, callErr = vm.call(childCallState, eventSink, callee, address, callState.GetEVMCode(address), args, value, &gasLimit, exec.CallTypeCall) case CALLCODE: childCallState = callState.NewCache() - returnData, callErr = vm.call(childCallState, eventSink, callee, callee, callState.GetCode(address), + returnData, callErr = vm.call(childCallState, eventSink, callee, callee, callState.GetEVMCode(address), args, value, &gasLimit, exec.CallTypeCode) case DELEGATECALL: childCallState = callState.NewCache() returnData, callErr = vm.delegateCall(childCallState, eventSink, caller, callee, - callState.GetCode(address), args, value, &gasLimit, exec.CallTypeDelegate) + callState.GetEVMCode(address), args, value, &gasLimit, exec.CallTypeDelegate) case STATICCALL: childCallState = callState.NewCache(acmstate.ReadOnly) returnData, callErr = vm.delegateCall(childCallState, NewLogFreeEventSink(eventSink), - callee, address, callState.GetCode(address), args, value, &gasLimit, exec.CallTypeStatic) + callee, address, callState.GetEVMCode(address), args, value, &gasLimit, exec.CallTypeStatic) default: panic(fmt.Errorf("switch statement should be exhaustive so this should not have been reached")) diff --git a/execution/evm/vm_test.go b/execution/evm/vm_test.go index 519074991..8a1af4a41 100644 --- a/execution/evm/vm_test.go +++ b/execution/evm/vm_test.go @@ -764,7 +764,7 @@ func TestStaticCallReadOnly(t *testing.T) { PUSH1, value, PUSH20, callee, PUSH2, gas1, gas2, STATICCALL, PUSH1, retSize, PUSH1, retOff, RETURN)) - txe := runVM(cache, ourVm, caller, callee, cache.GetCode(caller), 1000) + txe := runVM(cache, ourVm, caller, callee, cache.GetEVMCode(caller), 1000) // the topmost caller can never *illegally* modify state require.Error(t, txe.Exception) assertErrorCode(t, errors.ErrorCodeIllegalWrite, txe.Exception, @@ -792,7 +792,7 @@ func TestStaticCallWithValue(t *testing.T) { PUSH1, retOff, RETURN)) cache.AddToBalance(callee, 100000) - txe := runVM(cache, ourVm, caller, callee, cache.GetCode(caller), 1000) + txe := runVM(cache, ourVm, caller, callee, cache.GetEVMCode(caller), 1000) require.NotNil(t, txe.Exception) assertErrorCode(t, errors.ErrorCodeIllegalWrite, txe.Exception, "expected static call violation because of call with value") } @@ -817,7 +817,7 @@ func TestStaticCallNoValue(t *testing.T) { PUSH1, retOff, RETURN)) cache.AddToBalance(callee, 100000) - txe := runVM(cache, ourVm, caller, callee, cache.GetCode(caller), 1000) + txe := runVM(cache, ourVm, caller, callee, cache.GetEVMCode(caller), 1000) // no exceptions expected because value never set in children require.NoError(t, txe.Exception.AsError()) exCalls := txe.ExceptionalCalls() @@ -839,7 +839,7 @@ func TestCreate(t *testing.T) { var gas uint64 = 100000 caller := newAccount(cache, "1, 2, 3") - output, err := ourVm.Call(cache, NewNoopEventSink(), caller, callee, cache.GetCode(callee), []byte{}, 0, &gas) + output, err := ourVm.Call(cache, NewNoopEventSink(), caller, callee, cache.GetEVMCode(callee), []byte{}, 0, &gas) assert.NoError(t, err, "Should return new address without error") assert.Equal(t, addr.Bytes(), output, "Addresses should be equal") } @@ -853,11 +853,11 @@ func TestCreate2(t *testing.T) { // salt of 0s var salt [32]byte callee := makeAccountWithCode(cache, "callee", MustSplice(PUSH1, 0x0, PUSH1, 0x0, PUSH1, 0x0, PUSH32, salt[:], CREATE2, PUSH1, 0, MSTORE, PUSH1, 20, PUSH1, 12, RETURN)) - addr := crypto.NewContractAddress2(callee, salt, cache.GetCode(callee)) + addr := crypto.NewContractAddress2(callee, salt, cache.GetEVMCode(callee)) var gas uint64 = 100000 caller := newAccount(cache, "1, 2, 3") - output, err := ourVm.Call(cache, NewNoopEventSink(), caller, callee, cache.GetCode(callee), []byte{}, 0, &gas) + output, err := ourVm.Call(cache, NewNoopEventSink(), caller, callee, cache.GetEVMCode(callee), []byte{}, 0, &gas) assert.NoError(t, err, "Should return new address without error") assert.Equal(t, addr.Bytes(), output, "Returned value not equal to create2 address") } @@ -907,7 +907,7 @@ func TestDelegateCallGas(t *testing.T) { delegateCallCost, callerCodeSuffix)) // Should pass - txe := runVM(cache, ourVm, caller, callee, cache.GetCode(caller), 100) + txe := runVM(cache, ourVm, caller, callee, cache.GetEVMCode(caller), 100) assert.Nil(t, txe.Exception, "Should have sufficient funds for call") assert.Equal(t, Int64ToWord256(calleeReturnValue).Bytes(), txe.Result.Return) @@ -916,7 +916,7 @@ func TestDelegateCallGas(t *testing.T) { delegateCallCost-1, callerCodeSuffix)) // Should fail - txe = runVM(cache, ourVm, caller2, callee, cache.GetCode(caller2), 100) + txe = runVM(cache, ourVm, caller2, callee, cache.GetEVMCode(caller2), 100) assert.NotNil(t, txe.Exception, "Should have insufficient gas for call") } diff --git a/execution/execution_test.go b/execution/execution_test.go index 79bc7bb90..9b80710c4 100644 --- a/execution/execution_test.go +++ b/execution/execution_test.go @@ -331,7 +331,7 @@ func TestCallPermission(t *testing.T) { simpleAcc := &acm.Account{ Address: simpleContractAddr, Balance: 0, - Code: []byte{0x60}, + EVMCode: []byte{0x60}, Sequence: 0, Permissions: permission.ZeroAccountPermissions, } @@ -352,7 +352,7 @@ func TestCallPermission(t *testing.T) { caller1Acc := &acm.Account{ Address: caller1ContractAddr, Balance: 10000, - Code: contractCode, + EVMCode: contractCode, Sequence: 0, Permissions: permission.ZeroAccountPermissions, } @@ -393,7 +393,7 @@ func TestCallPermission(t *testing.T) { caller2Acc := &acm.Account{ Address: caller2ContractAddr, Balance: 1000, - Code: contractCode2, + EVMCode: contractCode2, Sequence: 0, Permissions: permission.ZeroAccountPermissions, } @@ -459,8 +459,8 @@ func TestCreatePermission(t *testing.T) { if contractAcc == nil { t.Fatalf("failed to create contract %s", contractAddr) } - if !bytes.Equal(contractAcc.Code, contractCode) { - t.Fatalf("contract does not have correct code. Got %X, expected %X", contractAcc.Code, contractCode) + if !bytes.Equal(contractAcc.EVMCode, contractCode) { + t.Fatalf("contract does not have correct code. Got %X, expected %X", contractAcc.EVMCode, contractCode) } //------------------------------ @@ -483,8 +483,8 @@ func TestCreatePermission(t *testing.T) { if contractAcc == nil { t.Fatalf("failed to create contract %s", contractAddr) } - if !bytes.Equal(contractAcc.Code, factoryCode) { - t.Fatalf("contract does not have correct code. Got %X, expected %X", contractAcc.Code, factoryCode) + if !bytes.Equal(contractAcc.EVMCode, factoryCode) { + t.Fatalf("contract does not have correct code. Got %X, expected %X", contractAcc.EVMCode, factoryCode) } //------------------------------ @@ -522,7 +522,7 @@ func TestCreatePermission(t *testing.T) { contractAcc = &acm.Account{ Address: contractAddr, Balance: 1000, - Code: code, + EVMCode: code, Sequence: 0, Permissions: permission.ZeroAccountPermissions, } @@ -538,7 +538,7 @@ func TestCreatePermission(t *testing.T) { _, err = execTxWaitAccountCall(t, exe, txEnv, crypto.Address{}) // require.NoError(t, err) zeroAcc := getAccount(exe.stateCache, crypto.Address{}) - if len(zeroAcc.Code) != 0 { + if len(zeroAcc.EVMCode) != 0 { t.Fatal("the zero account was given code from a CALL!") } } @@ -638,7 +638,7 @@ func TestCreateAccountPermission(t *testing.T) { caller1Acc := &acm.Account{ Address: caller1ContractAddr, Balance: 0, - Code: contractCode, + EVMCode: contractCode, Sequence: 0, Permissions: permission.ZeroAccountPermissions, } @@ -703,7 +703,7 @@ func TestSNativeCALL(t *testing.T) { doug := &acm.Account{ Address: DougAddress, Balance: 0, - Code: nil, + EVMCode: nil, Sequence: 0, Permissions: permission.ZeroAccountPermissions, } @@ -1141,9 +1141,9 @@ func TestCreates(t *testing.T) { exe := makeExecutor(st) newAcc1 := getAccount(st, acc1.Address) - newAcc1.Code = preFactoryCode + newAcc1.EVMCode = preFactoryCode newAcc2 := getAccount(st, acc2.Address) - newAcc2.Code = factoryCode + newAcc2.EVMCode = factoryCode exe.updateAccounts(t, newAcc1, newAcc2) @@ -1211,7 +1211,7 @@ func TestContractSend(t *testing.T) { acc2 := getAccount(st, privAccounts[2].GetAddress()) newAcc1 := getAccount(st, acc1.Address) - newAcc1.Code = callerCode + newAcc1.EVMCode = callerCode _, _, err := st.Update(func(up state.Updatable) error { return up.UpdateAccount(newAcc1) }) @@ -1293,7 +1293,7 @@ func TestMerklePanic(t *testing.T) { { stateCallTx := makeExecutor(copyState(t, st)) newAcc1 := getAccount(stateCallTx, acc1.Address) - newAcc1.Code = []byte{0x60} + newAcc1.EVMCode = []byte{0x60} err := stateCallTx.stateCache.UpdateAccount(newAcc1) require.NoError(t, err) tx := &payload.CallTx{ @@ -1356,7 +1356,7 @@ func TestTxs(t *testing.T) { { stateCallTx := copyState(t, st) newAcc1 := getAccount(stateCallTx, acc1.Address) - newAcc1.Code = []byte{0x60} + newAcc1.EVMCode = []byte{0x60} _, _, err := stateCallTx.Update(func(up state.Updatable) error { return up.UpdateAccount(newAcc1) }) @@ -1459,7 +1459,7 @@ func TestSelfDestruct(t *testing.T) { contractCode := []byte{0x60, 0x01, 0x60, 0x01, 0x55, 0x73} contractCode = append(contractCode, acc2.Address.Bytes()...) contractCode = append(contractCode, 0xff) - newAcc1.Code = contractCode + newAcc1.EVMCode = contractCode _, _, err := st.Update(func(up state.Updatable) error { return up.UpdateAccount(newAcc1) }) @@ -1695,7 +1695,7 @@ func testSNativeCALL(t *testing.T, expectPass bool, exe *testExecutor, doug *acm doug.Permissions.Base.Set(snativePerm, true) } - doug.Code = callContractCode(snativeAddress) + doug.EVMCode = callContractCode(snativeAddress) dougAddress := doug.Address exe.updateAccounts(t, doug) diff --git a/execution/simulated_call.go b/execution/simulated_call.go index 66d1bb125..ac7e877a5 100644 --- a/execution/simulated_call.go +++ b/execution/simulated_call.go @@ -49,7 +49,7 @@ func CallCodeSim(reader acmstate.Reader, blockchain bcm.BlockchainInfo, fromAddr cache := acmstate.NewCache(reader) err := cache.UpdateAccount(&acm.Account{ Address: address, - Code: code, + EVMCode: code, }) if err != nil { diff --git a/execution/state/accounts.go b/execution/state/accounts.go index bc1df204e..28b1352c1 100644 --- a/execution/state/accounts.go +++ b/execution/state/accounts.go @@ -24,7 +24,7 @@ func (s *ReadState) GetAccount(address crypto.Address) (*acm.Account, error) { func (ws *writeState) statsAddAccount(acc *acm.Account) { if acc != nil { - if len(acc.Code) > 0 { + if len(acc.EVMCode) > 0 || len(acc.WASMCode) > 0 { ws.accountStats.AccountsWithCode++ } else { ws.accountStats.AccountsWithoutCode++ @@ -34,7 +34,7 @@ func (ws *writeState) statsAddAccount(acc *acm.Account) { func (ws *writeState) statsRemoveAccount(acc *acm.Account) { if acc != nil { - if len(acc.Code) > 0 { + if len(acc.EVMCode) > 0 || len(acc.WASMCode) > 0 { ws.accountStats.AccountsWithCode-- } else { ws.accountStats.AccountsWithoutCode-- diff --git a/execution/state/state.go b/execution/state/state.go index 25302c8c3..3b125c567 100644 --- a/execution/state/state.go +++ b/execution/state/state.go @@ -200,7 +200,7 @@ func LoadState(db dbm.DB, version int64) (*State, error) { } // Populate stats. If this starts taking too long, store the value rather than the full scan at startup err = s.IterateAccounts(func(acc *acm.Account) error { - if len(acc.Code) > 0 { + if len(acc.EVMCode) > 0 || len(acc.WASMCode) > 0 { s.writeState.accountStats.AccountsWithCode++ } else { s.writeState.accountStats.AccountsWithoutCode++ diff --git a/execution/wasm/wasm.go b/execution/wasm/wasm.go index 7555120d0..1e3f24218 100644 --- a/execution/wasm/wasm.go +++ b/execution/wasm/wasm.go @@ -16,44 +16,50 @@ type execContext struct { state evm.Interface } -// In EVM, the code for an account is created by the EVM code itself; the code in the EVM deploy transaction is run, and the EVM code -// returns (via the RETURN) opcode) the code for the contract. In addition, when a new contract is created using the "new C()" construct -// is soldity, the EVM itself passes the code for the new contract. +// In EVM, the code for an account is created by the EVM code itself; the code in the EVM deploy transaction is run, +// and the EVM code returns (via the RETURN) opcode) the code for the contract. In addition, when a new contract is +// created using the "new C()" construct is soldity, the EVM itself passes the code for the new contract. // The compiler must embed any contract code for smart contracts it wants to create. // - This does not allow for circular references: contract A creates contract B, contract B creates contract A. -// - This makes it very hard to support other languages; e.g. go or rust have no such bizarre concepts, and would require tricking into supporting this -// - This makes it possible for tricksy contracts that create different contracts at differen times. Very hard to support static analysis on these contracts +// - This makes it very hard to support other languages; e.g. go or rust have no such bizarre concepts, and would +// require tricking into supporting this +// - This makes it possible for tricksy contracts that create different contracts at different times. Very hard to +// support static analysis on these contracts // - This makes it hard to know ahead-of-time what the code for a contract will be -// Our WASM implememtation does not allow for this. The code passed to the deploy transaction, is the contract. Any child contracts must be passed +// Our WASM implementation does not allow for this. The code passed to the deploy transaction, is the contract. Any child contracts must be passed // during the initial deployment (not implemented yet) // ABIs -// Our WASM ABI is entirely compatible with Solidity. This means that solidity EVM can call wasm contracts and vice versa. However, in the EVM ABI model -// the difference between constructor calls and function calls are implicit: the constructor code path is different from the function call code path, -// and there is nothing visible in the binary ABI encoded arguments telling you that it is a function call or a constructor. Note function calls do -// have a 4 byte prefix but this is not required; without it the fallback function should be called. +// Our WASM ABI is entirely compatible with Solidity. This means that solidity EVM can call WASM contracts and vice +// versa. However, in the EVM ABI model the difference between constructor calls and function calls are implicit: the +// constructor code path is different from the function call code path, and there is nothing visible in the binary ABI +// encoded arguments telling you that it is a function call or a constructor. Note function calls do have a 4 byte +// prefix but this is not required; without it the fallback function should be called. // So in our WASM model the smart contract has two entry points: constructor and function. // ABIs memory space -// In the EVM model, ABIs are passed via the calldata opcodes. This means that the ABI encoded data is not directly accessible and has to be copied to -// smart contract memory. Solidity exposes this via the calldata and memory modifiers on variables. +// In the EVM model, ABIs are passed via the calldata opcodes. This means that the ABI encoded data is not directly +// accessible and has to be copied to smart contract memory. Solidity exposes this via the calldata and memory +// modifiers on variables. -// In our wasm model, the function and constructor wasm fuctions have one argument and return value. The argument is where in wasm memory the ABI encoded -// arguments are and the return value is the offset where the return data can be found. At this offset we first find a 32 bit little endian encoded -// length (since wasm is little endian and we are using 32 bit memory model) followed by the bytes themselves. +// In our WASM model, the function and constructor WASM fuctions have one argument and return value. The argument is +// where in WASM memory the ABI encoded arguments are and the return value is the offset where the return data can be +// found. At this offset we first find a 32 bit little endian encoded length (since WASM is little endian and we are +// using 32 bit memory model) followed by the bytes themselves. // Contract Storage -// In the EVM model, contract storage is addressed via 256 bit key and the contents is a 256 bit value. For wasm, we've changed the contents to a -// arbitary byte string. This makes it much easier to store/retrieve smaller values (e.g. int64) and dynamic length fields (e.g. strings/arrays). +// In the EVM model, contract storage is addressed via 256 bit key and the contents is a 256 bit value. For WASM, +// we've changed the contents to a arbitary byte string. This makes it much easier to store/retrieve smaller values +// (e.g. int64) and dynamic length fields (e.g. strings/arrays). -// Access to contract storage is via wasm externals. +// Access to contract storage is via WASM externals. // - set_storage32(uint32 key, uint8* data, uint32 len) // set contract storage // - get_storage32(uint32 key, uint8* data, uint32 len) // get contract storage (right pad with zeros) -// RunWASM creates a wasm VM, and executes the given wasm contract code +// RunWASM creates a WASM VM, and executes the given WASM contract code func RunWASM(state evm.Interface, address crypto.Address, createContract bool, wasm, input []byte) (output []byte, cerr errors.CodedError) { defer func() { if r := recover(); r != nil { diff --git a/protobuf/acm.proto b/protobuf/acm.proto index 21e4ef92b..76966b83b 100644 --- a/protobuf/acm.proto +++ b/protobuf/acm.proto @@ -21,7 +21,7 @@ message Account { crypto.PublicKey PublicKey = 2 [(gogoproto.nullable) = false]; uint64 Sequence = 3; uint64 Balance = 4; - bytes Code = 5 [(gogoproto.customtype) = "Bytecode", (gogoproto.nullable) = false]; + bytes EVMCode = 5 [(gogoproto.customtype) = "Bytecode", (gogoproto.nullable) = false]; permission.AccountPermissions Permissions = 6 [(gogoproto.nullable) = false]; - bytes WASM = 7 [(gogoproto.customtype) = "Bytecode"]; + bytes WASMCode = 7 [(gogoproto.customtype) = "Bytecode", (gogoproto.jsontag) = ",omitempty", (gogoproto.nullable) = false]; } diff --git a/rpc/service.go b/rpc/service.go index 18dcc026b..eb366bd8a 100644 --- a/rpc/service.go +++ b/rpc/service.go @@ -222,7 +222,7 @@ func (s *Service) AccountHumanReadable(address crypto.Address) (*ResultAccountHu if acc == nil { return &ResultAccountHumanReadable{}, nil } - tokens, err := acc.Code.Tokens() + tokens, err := acc.EVMCode.Tokens() if err != nil { return nil, err } From 6e3b00bce5e073cbd5d4653b645a8cd4f5e22504 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Sun, 23 Jun 2019 17:27:25 +0200 Subject: [PATCH 7/7] Next version will be 0.27.0 Signed-off-by: Sean Young --- CHANGELOG.md | 12 ++++++++++-- NOTES.md | 8 +++++++- acm/acm.pb.go | 5 +++-- acm/balance/balance.pb.go | 5 +++-- acm/validator/validator.pb.go | 5 +++-- bcm/bcm.pb.go | 7 ++++--- consensus/tendermint/tendermint.pb.go | 5 +++-- crypto/crypto.pb.go | 5 +++-- dump/dump.pb.go | 7 ++++--- execution/contexts/call_context.go | 24 +++++++++++++++--------- execution/errors/errors.pb.go | 5 +++-- execution/exec/exec.pb.go | 7 ++++--- execution/names/names.pb.go | 5 +++-- genesis/spec/spec.pb.go | 5 +++-- keys/keys.pb.go | 5 +++-- permission/permission.pb.go | 5 +++-- project/history.go | 2 +- rpc/rpc.pb.go | 5 +++-- rpc/rpcdump/rpcdump.pb.go | 5 +++-- rpc/rpcevents/rpcevents.pb.go | 5 +++-- rpc/rpcquery/rpcquery.pb.go | 5 +++-- rpc/rpctransact/rpctransact.pb.go | 7 ++++--- txs/payload/payload.pb.go | 5 +++-- txs/txs.pb.go | 5 +++-- 24 files changed, 97 insertions(+), 57 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2d4afadd..078ae7298 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # [Hyperledger Burrow](https://github.com/hyperledger/burrow) Changelog -## [Unreleased] +## [0.27.0] - 2019-06-23 +### Added +- [WASM] Support for WASM contracts written in Solidity compiled using solang + +### Fixed +-[RPC/Transact] CallCodeSim and CallTxSim were run against uncommitted checker state rather than committed state were all other reads are routed. They were also passed through Transactor for no particularly good reason. This changes them to run against committed DB state and removes the code path through Transactor. + +### Changed +- [State] TxExecution's Envelope now stored in state so will be reproduced in Vent Tx tables and over RPC, and so matches TxExecutions served from *Sync rpctransact methods ## [0.26.2] - 2019-06-19 @@ -507,7 +515,7 @@ This release marks the start of Eris-DB as the full permissioned blockchain node - [Blockchain] Fix getBlocks to respect block height cap. -[Unreleased]: https://github.com/hyperledger/burrow/compare/v0.26.2...HEAD +[0.27.0]: https://github.com/hyperledger/burrow/compare/v0.26.2...v0.27.0 [0.26.2]: https://github.com/hyperledger/burrow/compare/v0.26.1...v0.26.2 [0.26.1]: https://github.com/hyperledger/burrow/compare/v0.26.0...v0.26.1 [0.26.0]: https://github.com/hyperledger/burrow/compare/v0.25.1...v0.26.0 diff --git a/NOTES.md b/NOTES.md index b4cee2e1e..30d091dc2 100644 --- a/NOTES.md +++ b/NOTES.md @@ -1,3 +1,9 @@ +### Added +- [WASM] Support for WASM contracts written in Solidity compiled using solang + ### Fixed -- [Blockchain] Persist LastBlockTime in Blockchain - before this patch LastBlockTime would only be set correctly after the first block had been received after a node is restarted - this can lead to non-determinism in the EVM via the TIMESTAMP opcode that use the LastBlockTime which is itself sourced from Tendermint's block header (from their implementation of BFT time). Implementing no empty blocks made observing this bug more likely by increasing the amount of time spent in a bad state (LastBlockTime is initially set to GenesisTime). +-[RPC/Transact] CallCodeSim and CallTxSim were run against uncommitted checker state rather than committed state were all other reads are routed. They were also passed through Transactor for no particularly good reason. This changes them to run against committed DB state and removes the code path through Transactor. + +### Changed +- [State] TxExecution's Envelope now stored in state so will be reproduced in Vent Tx tables and over RPC, and so matches TxExecutions served from *Sync rpctransact methods diff --git a/acm/acm.pb.go b/acm/acm.pb.go index c826d45dc..716122b25 100644 --- a/acm/acm.pb.go +++ b/acm/acm.pb.go @@ -5,14 +5,15 @@ package acm import ( fmt "fmt" + io "io" + math "math" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" golang_proto "github.com/golang/protobuf/proto" crypto "github.com/hyperledger/burrow/crypto" github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto" permission "github.com/hyperledger/burrow/permission" - io "io" - math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/acm/balance/balance.pb.go b/acm/balance/balance.pb.go index dcf845e9e..1e52810f1 100644 --- a/acm/balance/balance.pb.go +++ b/acm/balance/balance.pb.go @@ -5,11 +5,12 @@ package balance import ( fmt "fmt" + io "io" + math "math" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" golang_proto "github.com/golang/protobuf/proto" - io "io" - math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/acm/validator/validator.pb.go b/acm/validator/validator.pb.go index 2487af8d4..14decd2a3 100644 --- a/acm/validator/validator.pb.go +++ b/acm/validator/validator.pb.go @@ -5,13 +5,14 @@ package validator import ( fmt "fmt" + io "io" + math "math" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" golang_proto "github.com/golang/protobuf/proto" crypto "github.com/hyperledger/burrow/crypto" github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto" - io "io" - math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/bcm/bcm.pb.go b/bcm/bcm.pb.go index 4c0f45b50..9173306b5 100644 --- a/bcm/bcm.pb.go +++ b/bcm/bcm.pb.go @@ -5,6 +5,10 @@ package bcm import ( fmt "fmt" + io "io" + math "math" + time "time" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" @@ -12,9 +16,6 @@ import ( _ "github.com/golang/protobuf/ptypes/duration" _ "github.com/golang/protobuf/ptypes/timestamp" github_com_hyperledger_burrow_binary "github.com/hyperledger/burrow/binary" - io "io" - math "math" - time "time" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/consensus/tendermint/tendermint.pb.go b/consensus/tendermint/tendermint.pb.go index feb604bdf..f3bf40096 100644 --- a/consensus/tendermint/tendermint.pb.go +++ b/consensus/tendermint/tendermint.pb.go @@ -5,13 +5,14 @@ package tendermint import ( fmt "fmt" + io "io" + math "math" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" golang_proto "github.com/golang/protobuf/proto" github_com_hyperledger_burrow_binary "github.com/hyperledger/burrow/binary" github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto" - io "io" - math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/crypto/crypto.pb.go b/crypto/crypto.pb.go index 4b0490195..a7bce82f6 100644 --- a/crypto/crypto.pb.go +++ b/crypto/crypto.pb.go @@ -5,12 +5,13 @@ package crypto import ( fmt "fmt" + io "io" + math "math" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" golang_proto "github.com/golang/protobuf/proto" github_com_hyperledger_burrow_binary "github.com/hyperledger/burrow/binary" - io "io" - math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/dump/dump.pb.go b/dump/dump.pb.go index 91ef3b076..adb99f74b 100644 --- a/dump/dump.pb.go +++ b/dump/dump.pb.go @@ -5,6 +5,10 @@ package dump import ( fmt "fmt" + io "io" + math "math" + time "time" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" @@ -15,9 +19,6 @@ import ( github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto" exec "github.com/hyperledger/burrow/execution/exec" names "github.com/hyperledger/burrow/execution/names" - io "io" - math "math" - time "time" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/execution/contexts/call_context.go b/execution/contexts/call_context.go index b41c4f57f..75a1f5132 100644 --- a/execution/contexts/call_context.go +++ b/execution/contexts/call_context.go @@ -195,14 +195,20 @@ func (ctx *CallContext) Deliver(inAcc, outAcc *acm.Account, value uint64) error if createContract { txCache.InitWASMCode(callee, wcode) } - ret, err := wasm.RunWASM(txCache, callee, createContract, wcode, ctx.tx.Data) - if err != nil { - ctx.Logger.InfoMsg("Error returned from WASM", "error", err) - return err - } - err = txCache.Sync() - if err != nil { - return err + ret, exception = wasm.RunWASM(txCache, callee, createContract, wcode, ctx.tx.Data) + if exception != nil { + // Failure. Charge the gas fee. The 'value' was otherwise not transferred. + ctx.Logger.InfoMsg("Error on WASM execution", + structure.ErrorKey, exception) + + ctx.txe.PushError(errors.ErrorCodef(exception.ErrorCode(), "call error: %s\n", + exception.String())) + } else { + ctx.Logger.TraceMsg("Successful execution") + err := txCache.Sync() + if err != nil { + return err + } } ctx.txe.Return(ret, ctx.tx.GasLimit-gas) } else { @@ -211,7 +217,7 @@ func (ctx *CallContext) Deliver(inAcc, outAcc *acm.Account, value uint64) error ret, exception = vmach.Call(txCache, ctx.txe, caller, callee, code, ctx.tx.Data, value, &gas) if exception != nil { // Failure. Charge the gas fee. The 'value' was otherwise not transferred. - ctx.Logger.InfoMsg("Error on execution", + ctx.Logger.InfoMsg("Error on EVM execution", structure.ErrorKey, exception) ctx.txe.PushError(errors.ErrorCodef(exception.ErrorCode(), "call error: %s\nEVM call trace: %s", diff --git a/execution/errors/errors.pb.go b/execution/errors/errors.pb.go index 97fb131a2..a75c80951 100644 --- a/execution/errors/errors.pb.go +++ b/execution/errors/errors.pb.go @@ -5,11 +5,12 @@ package errors import ( fmt "fmt" + io "io" + math "math" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" golang_proto "github.com/golang/protobuf/proto" - io "io" - math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/execution/exec/exec.pb.go b/execution/exec/exec.pb.go index de5c18e22..bee8cee9c 100644 --- a/execution/exec/exec.pb.go +++ b/execution/exec/exec.pb.go @@ -5,6 +5,10 @@ package exec import ( fmt "fmt" + io "io" + math "math" + time "time" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" @@ -20,9 +24,6 @@ import ( txs "github.com/hyperledger/burrow/txs" github_com_hyperledger_burrow_txs_payload "github.com/hyperledger/burrow/txs/payload" types "github.com/tendermint/tendermint/abci/types" - io "io" - math "math" - time "time" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/execution/names/names.pb.go b/execution/names/names.pb.go index 0c6b9dd23..c6e76166f 100644 --- a/execution/names/names.pb.go +++ b/execution/names/names.pb.go @@ -5,12 +5,13 @@ package names import ( fmt "fmt" + io "io" + math "math" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" golang_proto "github.com/golang/protobuf/proto" github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto" - io "io" - math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/genesis/spec/spec.pb.go b/genesis/spec/spec.pb.go index 47170ba4a..e5dc717d4 100644 --- a/genesis/spec/spec.pb.go +++ b/genesis/spec/spec.pb.go @@ -5,6 +5,9 @@ package spec import ( fmt "fmt" + io "io" + math "math" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" golang_proto "github.com/golang/protobuf/proto" @@ -12,8 +15,6 @@ import ( balance "github.com/hyperledger/burrow/acm/balance" crypto "github.com/hyperledger/burrow/crypto" github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto" - io "io" - math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/keys/keys.pb.go b/keys/keys.pb.go index 5a262dce5..d38370086 100644 --- a/keys/keys.pb.go +++ b/keys/keys.pb.go @@ -6,13 +6,14 @@ package keys import ( context "context" fmt "fmt" + io "io" + math "math" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" golang_proto "github.com/golang/protobuf/proto" crypto "github.com/hyperledger/burrow/crypto" grpc "google.golang.org/grpc" - io "io" - math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/permission/permission.pb.go b/permission/permission.pb.go index bb07ce156..b91f0d764 100644 --- a/permission/permission.pb.go +++ b/permission/permission.pb.go @@ -5,12 +5,13 @@ package permission import ( fmt "fmt" + io "io" + math "math" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" golang_proto "github.com/golang/protobuf/proto" github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto" - io "io" - math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/project/history.go b/project/history.go index 891ce8bf1..f9d484cf3 100644 --- a/project/history.go +++ b/project/history.go @@ -48,7 +48,7 @@ func FullVersion() string { // release tagging script: ./scripts/tag_release.sh var History relic.ImmutableHistory = relic.NewHistory("Hyperledger Burrow", "https://github.com/hyperledger/burrow"). MustDeclareReleases( - "", + "0.27.0 - 2019-06-23", `### Added - [WASM] Support for WASM contracts written in Solidity compiled using solang diff --git a/rpc/rpc.pb.go b/rpc/rpc.pb.go index 61aac4f75..ad538aa98 100644 --- a/rpc/rpc.pb.go +++ b/rpc/rpc.pb.go @@ -5,6 +5,9 @@ package rpc import ( fmt "fmt" + io "io" + math "math" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" golang_proto "github.com/golang/protobuf/proto" @@ -12,8 +15,6 @@ import ( bcm "github.com/hyperledger/burrow/bcm" github_com_hyperledger_burrow_binary "github.com/hyperledger/burrow/binary" tendermint "github.com/hyperledger/burrow/consensus/tendermint" - io "io" - math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/rpc/rpcdump/rpcdump.pb.go b/rpc/rpcdump/rpcdump.pb.go index 79ec1923e..22a0239d7 100644 --- a/rpc/rpcdump/rpcdump.pb.go +++ b/rpc/rpcdump/rpcdump.pb.go @@ -6,13 +6,14 @@ package rpcdump import ( context "context" fmt "fmt" + io "io" + math "math" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" golang_proto "github.com/golang/protobuf/proto" dump "github.com/hyperledger/burrow/dump" grpc "google.golang.org/grpc" - io "io" - math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/rpc/rpcevents/rpcevents.pb.go b/rpc/rpcevents/rpcevents.pb.go index db293aaea..ea0229c54 100644 --- a/rpc/rpcevents/rpcevents.pb.go +++ b/rpc/rpcevents/rpcevents.pb.go @@ -6,14 +6,15 @@ package rpcevents import ( context "context" fmt "fmt" + io "io" + math "math" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" golang_proto "github.com/golang/protobuf/proto" github_com_hyperledger_burrow_binary "github.com/hyperledger/burrow/binary" exec "github.com/hyperledger/burrow/execution/exec" grpc "google.golang.org/grpc" - io "io" - math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/rpc/rpcquery/rpcquery.pb.go b/rpc/rpcquery/rpcquery.pb.go index 65e755274..d9ea7463d 100644 --- a/rpc/rpcquery/rpcquery.pb.go +++ b/rpc/rpcquery/rpcquery.pb.go @@ -6,6 +6,9 @@ package rpcquery import ( context "context" fmt "fmt" + io "io" + math "math" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" golang_proto "github.com/golang/protobuf/proto" @@ -18,8 +21,6 @@ import ( payload "github.com/hyperledger/burrow/txs/payload" types "github.com/tendermint/tendermint/abci/types" grpc "google.golang.org/grpc" - io "io" - math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/rpc/rpctransact/rpctransact.pb.go b/rpc/rpctransact/rpctransact.pb.go index 915e0c193..ea6523360 100644 --- a/rpc/rpctransact/rpctransact.pb.go +++ b/rpc/rpctransact/rpctransact.pb.go @@ -6,6 +6,10 @@ package rpctransact import ( context "context" fmt "fmt" + io "io" + math "math" + time "time" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" @@ -17,9 +21,6 @@ import ( txs "github.com/hyperledger/burrow/txs" payload "github.com/hyperledger/burrow/txs/payload" grpc "google.golang.org/grpc" - io "io" - math "math" - time "time" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/txs/payload/payload.pb.go b/txs/payload/payload.pb.go index 3f41ab25e..c99de74e1 100644 --- a/txs/payload/payload.pb.go +++ b/txs/payload/payload.pb.go @@ -5,6 +5,9 @@ package payload import ( fmt "fmt" + io "io" + math "math" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" golang_proto "github.com/golang/protobuf/proto" @@ -12,8 +15,6 @@ import ( github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto" spec "github.com/hyperledger/burrow/genesis/spec" permission "github.com/hyperledger/burrow/permission" - io "io" - math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/txs/txs.pb.go b/txs/txs.pb.go index e95880013..0e9ac84c0 100644 --- a/txs/txs.pb.go +++ b/txs/txs.pb.go @@ -5,6 +5,9 @@ package txs import ( fmt "fmt" + io "io" + math "math" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" golang_proto "github.com/golang/protobuf/proto" @@ -12,8 +15,6 @@ import ( crypto "github.com/hyperledger/burrow/crypto" github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto" github_com_hyperledger_burrow_txs_payload "github.com/hyperledger/burrow/txs/payload" - io "io" - math "math" ) // Reference imports to suppress errors if they are not otherwise used.