Skip to content
This repository has been archived by the owner on May 13, 2022. It is now read-only.

Commit

Permalink
Add wasm printMem and other debug functions
Browse files Browse the repository at this point in the history
Signed-off-by: Sean Young <[email protected]>
  • Loading branch information
seanyoung committed Feb 5, 2021
1 parent b64774e commit dbfe3c6
Show file tree
Hide file tree
Showing 23 changed files with 944 additions and 110 deletions.
13 changes: 8 additions & 5 deletions deploy/jobs/jobs_contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -574,14 +574,17 @@ func deployFinalize(client *def.Client, tx payload.Payload, logger *logging.Logg
}

func logEvents(txe *exec.TxExecution, client *def.Client, logger *logging.Logger) {
if client.AllSpecs == nil {
return
}

for _, event := range txe.Events {
print := event.GetPrint()

if print != nil {
logger.InfoMsg("print", "address", print.Address.String(), "msg", string(print.Data))
continue
}

eventLog := event.GetLog()

if eventLog == nil {
if eventLog == nil || client.AllSpecs == nil {
continue
}

Expand Down
2 changes: 2 additions & 0 deletions deploy/jobs/jobs_test_jobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ func QueryContractJob(query *def.QueryContract, do *def.DeployArgs, script *def.
return "", nil, err
}

logEvents(txe, client, logger)

result2 := util.GetReturnValue(query.Variables, logger)
// Finalize
if result2 != "" {
Expand Down
1 change: 1 addition & 0 deletions execution/exec/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const (
TypeEnvelope
TypeEndTx
TypeEndBlock
TypePrint
)

var nameFromType = map[EventType]string{
Expand Down
5 changes: 5 additions & 0 deletions execution/exec/event_sink.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
type EventSink interface {
Call(call *CallEvent, exception *errors.Exception) error
Log(log *LogEvent) error
Print(print *PrintEvent) error
}

type noopEventSink struct {
Expand All @@ -24,6 +25,10 @@ func (es *noopEventSink) Log(log *LogEvent) error {
return nil
}

func (es *noopEventSink) Print(print *PrintEvent) error {
return nil
}

type logFreeEventSink struct {
EventSink
}
Expand Down
11 changes: 11 additions & 0 deletions execution/exec/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ func (evs *Events) Log(log *LogEvent) error {
return nil
}

func (evs *Events) Print(print *PrintEvent) error {
evs.Append(&Event{
Header: &Header{
EventType: TypePrint,
EventID: EventStringLogEvent(print.Address),
},
Print: print,
})
return nil
}

func (evs Events) CallTrace() string {
var calls []string
for _, ev := range evs {
Expand Down
459 changes: 374 additions & 85 deletions execution/exec/exec.pb.go

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions execution/exec/stream_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ func (ev *StreamEvent) EventType() EventType {
return TypeEndTx
case ev.EndBlock != nil:
return TypeEndBlock
case ev.Event.Print != nil:
return TypePrint
}
return TypeUnknown
}
Expand Down
8 changes: 8 additions & 0 deletions execution/exec/tx_execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,14 @@ func (txe *TxExecution) GovernAccount(governAccount *GovernAccountEvent, excepti
})
}

func (txe *TxExecution) Print(print *PrintEvent) error {
txe.Append(&Event{
Header: txe.Header(TypePrint, EventStringLogEvent(print.Address), nil),
Print: print,
})
return nil
}

// Errors pushed to TxExecutions end up in merkle state so it is essential that they are deterministic and independent
// of the code path taken to execution (e.g. replay takes a different path to that of normal consensus reactor so stack
// traces may differ - as they may across architectures)
Expand Down
4 changes: 4 additions & 0 deletions execution/solidity/ewasm.solang
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,8 @@ contract ewasm is E {
function test_events() public {
emit L(102, "Hello from wasm", true);
}

function test_print(int64 arg1, string arg2) public {
print("arg1:{} arg2:{}".format(arg1, arg2));
}
}
4 changes: 2 additions & 2 deletions execution/solidity/ewasm.solang.go

Large diffs are not rendered by default.

136 changes: 136 additions & 0 deletions execution/wasm/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"fmt"
"math/big"

hex "github.com/tmthrgd/go-hex"

"github.com/hyperledger/burrow/execution/evm"
"github.com/hyperledger/burrow/execution/exec"

Expand Down Expand Up @@ -79,6 +81,140 @@ func (ctx *context) ResolveGlobal(module, field string) int64 {
}

func (ctx *context) ResolveFunc(module, field string) lifeExec.FunctionImport {
if module == "debug" {
// See https://github.com/ewasm/hera#interfaces
switch field {
case "print32":
return func(vm *lifeExec.VirtualMachine) int64 {
n := int32(vm.GetCurrentFrame().Locals[0])

s := fmt.Sprintf("%d", n)

err := ctx.state.EventSink.Print(&exec.PrintEvent{
Address: ctx.params.Callee,
Data: []byte(s),
})

if err != nil {
panic(fmt.Sprintf(" => print32 failed: %v", err))
}

return Success
}

case "print64":
return func(vm *lifeExec.VirtualMachine) int64 {
n := int64(vm.GetCurrentFrame().Locals[0])

s := fmt.Sprintf("%d", n)

err := ctx.state.EventSink.Print(&exec.PrintEvent{
Address: ctx.params.Callee,
Data: []byte(s),
})

if err != nil {
panic(fmt.Sprintf(" => print32 failed: %v", err))
}

return Success
}

case "printMem":
return func(vm *lifeExec.VirtualMachine) int64 {
dataPtr := int(uint32(vm.GetCurrentFrame().Locals[0]))
dataLen := int(uint32(vm.GetCurrentFrame().Locals[1]))

s := vm.Memory[dataPtr : dataPtr+dataLen]

err := ctx.state.EventSink.Print(&exec.PrintEvent{
Address: ctx.params.Callee,
Data: s,
})

if err != nil {
panic(fmt.Sprintf(" => printMem failed: %v", err))
}

return Success
}

case "printMemHex":
return func(vm *lifeExec.VirtualMachine) int64 {
dataPtr := int(uint32(vm.GetCurrentFrame().Locals[0]))
dataLen := int(uint32(vm.GetCurrentFrame().Locals[1]))

s := hex.EncodeToString(vm.Memory[dataPtr : dataPtr+dataLen])

err := ctx.state.EventSink.Print(&exec.PrintEvent{
Address: ctx.params.Callee,
Data: []byte(s),
})

if err != nil {
panic(fmt.Sprintf(" => printMemHex failed: %v", err))
}

return Success
}

case "printStorage":
return func(vm *lifeExec.VirtualMachine) int64 {
keyPtr := int(uint32(vm.GetCurrentFrame().Locals[0]))

key := bin.Word256{}

copy(key[:], vm.Memory[keyPtr:keyPtr+32])

val, err := ctx.state.GetStorage(ctx.params.Callee, key)
if err != nil {
panic(err)
}

err = ctx.state.EventSink.Print(&exec.PrintEvent{
Address: ctx.params.Callee,
Data: val,
})

if err != nil {
panic(fmt.Sprintf(" => printStorage failed: %v", err))
}

return Success
}

case "printStorageHex":
return func(vm *lifeExec.VirtualMachine) int64 {
keyPtr := int(uint32(vm.GetCurrentFrame().Locals[0]))

key := bin.Word256{}

copy(key[:], vm.Memory[keyPtr:keyPtr+32])

val, err := ctx.state.GetStorage(ctx.params.Callee, key)
if err != nil {
panic(err)
}

s := hex.EncodeToString(val)

err = ctx.state.EventSink.Print(&exec.PrintEvent{
Address: ctx.params.Callee,
Data: []byte(s),
})

if err != nil {
panic(fmt.Sprintf(" => printStorage failed: %v", err))
}

return Success
}

default:
panic(fmt.Sprintf("function %s unknown for debug module", field))
}
}

if module != "ethereum" {
panic(fmt.Sprintf("unknown module %s", module))
}
Expand Down
2 changes: 1 addition & 1 deletion execution/wasm/storage_test.solang.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ package wasm

import hex "github.com/tmthrgd/go-hex"

var Bytecode_storage_test = hex.MustDecodeString("0061736D01000000011C0660027F7F0060017F006000017F60037F7F7F0060017F017F6000000280010608657468657265756D0C73746F7261676553746F7265000008657468657265756D0C67657443616C6C56616C7565000108657468657265756D0B676574436F646553697A65000208657468657265756D08636F6465436F7079000308657468657265756D0666696E697368000008657468657265756D06726576657274000003060500040502050405017001010105030100020608017F01418080040B071102066D656D6F72790200046D61696E000A0AAB0305240002402001450D00034020004200370300200041086A21002001417F6A22010D000B0B0BA60101047F418080042101024003400240200128020C0D002001280208220220004F0D020B200128020022010D000B41002101410028020821020B02402002200041076A41787122036B22024118490D00200120036A41106A22002001280200220436020002402004450D00200420003602040B2000200241706A3602082000410036020C2000200136020420012000360200200120033602080B2001410136020C200141106A0B2E004100410036028080044100410036028480044100410036028C800441003F0041107441F0FF7B6A36028880040B4E01017F230041C0006B22002400200041386A4200370300200042003703302000420037032820004200370320200041041006200042E600370300200041206A20001000200041C0006A240041000B5E01027F230041106B220024002000100102402000290300200041086A290300844200520D0010084100100241C0736A22003602B00741002000100722013602B407200141C00C2000100310091A410041AE071004000B410041001005000B0BB507010041000BAE070061736D01000000011C0660017F006000017F60037F7F7F0060027F7F0060017F017F600000029F010708657468657265756D0C67657443616C6C56616C7565000008657468657265756D0F67657443616C6C4461746153697A65000108657468657265756D0C63616C6C44617461436F7079000208657468657265756D0B73746F726167654C6F6164000308657468657265756D0C73746F7261676553746F7265000308657468657265756D06726576657274000308657468657265756D0666696E697368000303060503020405050405017001010105030100020608017F01418080040B071102066D656D6F72790200046D61696E000B0AB20505240002402001450D00034020004200370300200041086A21002001417F6A22010D000B0B0B2D002001411F6A21010340200120002D00003A00002001417F6A2101200041016A21002002417F6A22020D000B0BA60101047F418080042101024003400240200128020C0D002001280208220220004F0D020B200128020022010D000B41002101410028020821020B02402002200041076A41787122036B22024118490D00200120036A41106A22002001280200220436020002402004450D00200420003602040B2000200241706A3602082000410036020C2000200136020420012000360200200120033602080B2001410136020C200141106A0B2E004100410036028080044100410036028480044100410036028C800441003F0041107441F0FF7B6A36028880040B850302037F017E230041A0016B22002400200041086A100002400240024002402000290308200041106A290300844200520D00100A41001001220136020441002001100922023602082002410020011002200141034D0D014100200228020022013602000240200141A298B6BE01460D00200141DE9AB88F79470D0220004180016A41186A420037030020004200370390012000420037038801200042003703800120004180016A200041E0006A1003200041C0006A41186A420037030020004200370350200042003703482000420037034020002903602103200041206A410410072000200342017C370320200041C0006A200041206A10044100450D03410041001005000B20004198016A420037030020004200370390012000420037038801200042003703800120004180016A200041E0006A10032000200029036042027C3703184100450D03410041001005000B410041001005000B410041001005000B410041001006000B41201009220141041007200041186A200141081008200141201006000B")
var Bytecode_storage_test = hex.MustDecodeString("0061736D01000000011C0660027F7F0060017F006000017F60037F7F7F0060017F017F6000000280010608657468657265756D0C73746F7261676553746F7265000008657468657265756D0C67657443616C6C56616C7565000108657468657265756D0B676574436F646553697A65000208657468657265756D08636F6465436F7079000308657468657265756D0666696E697368000008657468657265756D06726576657274000003060500040502050405017001010105030100020608017F01418080040B071102066D656D6F72790200046D61696E000A0AAB0305240002402001450D00034020004200370300200041086A21002001417F6A22010D000B0B0BA60101047F418080042101024003400240200128020C0D002001280208220220004F0D020B200128020022010D000B41002101410028020821020B02402002200041076A41787122036B22024118490D00200120036A41106A22002001280200220436020002402004450D00200420003602040B2000200241706A3602082000410036020C2000200136020420012000360200200120033602080B2001410136020C200141106A0B2E004100410036028080044100410036028480044100410036028C800441003F0041107441F0FF7B6A36028880040B4E01017F230041C0006B22002400200041386A4200370300200042003703302000420037032820004200370320200041041006200042E600370300200041206A20001000200041C0006A240041000B5E01027F230041106B220024002000100102402000290300200041086A290300844200520D0010084100100241C0736A22003602B00741002000100722013602B407200141C00C2000100310091A410041AE071004000B410041001005000B0BB507010041000BAE070061736D01000000011C0660017F006000017F60037F7F7F0060027F7F0060017F017F600000029F010708657468657265756D0C67657443616C6C56616C7565000008657468657265756D0F67657443616C6C4461746153697A65000108657468657265756D0C63616C6C44617461436F7079000208657468657265756D0B73746F726167654C6F6164000308657468657265756D06726576657274000308657468657265756D0C73746F7261676553746F7265000308657468657265756D0666696E697368000303060503020405050405017001010105030100020608017F01418080040B071102066D656D6F72790200046D61696E000B0AB20505240002402001450D00034020004200370300200041086A21002001417F6A22010D000B0B0B2D002001411F6A21010340200120002D00003A00002001417F6A2101200041016A21002002417F6A22020D000B0BA60101047F418080042101024003400240200128020C0D002001280208220220004F0D020B200128020022010D000B41002101410028020821020B02402002200041076A41787122036B22024118490D00200120036A41106A22002001280200220436020002402004450D00200420003602040B2000200241706A3602082000410036020C2000200136020420012000360200200120033602080B2001410136020C200141106A0B2E004100410036028080044100410036028480044100410036028C800441003F0041107441F0FF7B6A36028880040B850302037F017E230041A0016B22002400200041086A100002400240024002402000290308200041106A290300844200520D00100A41001001220136020441002001100922023602082002410020011002200141034D0D014100200228020022013602000240200141DE9AB88F79460D00200141A298B6BE01470D0220004198016A420037030020004200370390012000420037038801200042003703800120004180016A200041E0006A10032000200029036042027C3703184100450D03410041001004000B20004180016A41186A420037030020004200370390012000420037038801200042003703800120004180016A200041E0006A1003200041C0006A41186A420037030020004200370350200042003703482000420037034020002903602103200041206A410410072000200342017C370320200041C0006A200041206A10054100450D03410041001004000B410041001004000B410041001004000B41201009220141041007200041186A200141081008200141201006000B410041001006000B")
var Abi_storage_test = []byte(`[{"type":"constructor","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"getFooPlus2","type":"function","inputs":[],"outputs":[{"name":"","type":"uint64","internalType":"uint64"}],"stateMutability":"view"},{"name":"incFoo","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"}]`)
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,6 @@ require (
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
golang.org/x/net v0.0.0-20210119194325-5f4716e94777
google.golang.org/grpc v1.35.0
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 // indirect
gopkg.in/yaml.v2 v2.4.0
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,8 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.35.0 h1:TwIQcH3es+MojMVojxxfQ3l3OF2KzlRxML2xZq0kRo8=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
Expand Down
27 changes: 27 additions & 0 deletions integration/rpctransact/call_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,23 @@ func testCallTx(t *testing.T, kern *core.Kernel, cli rpctransact.TransactClient)
assert.Equal(t, true, f3)
return
})

t.Run("WasmPrint", func(t *testing.T) {
t.Parallel()
createTxe, err := rpctest.CreateWASMContract(cli, inputAddress, solidity.Bytecode_ewasm, nil)
require.NoError(t, err)
address := lastCall(createTxe.Events).CallData.Callee
spec, err := abi.ReadSpec(solidity.Abi_ewasm)
require.NoError(t, err)
data, _, err := spec.Pack("test_print", 102, "Fishy")
require.NoError(t, err)
callTxe, err := rpctest.CallContract(cli, inputAddress, address, data)
require.NoError(t, err)
evs := filterPrint(callTxe.Events)
require.Len(t, evs, 1)
assert.Equal(t, string(evs[0].Data), "arg1:102 arg2:Fishy")
return
})
})
}

Expand Down Expand Up @@ -634,6 +651,16 @@ func filterLogs(evs []*exec.Event) []*exec.LogEvent {
return logEvs
}

func filterPrint(evs []*exec.Event) []*exec.PrintEvent {
var printEvs []*exec.PrintEvent
for _, ev := range evs {
if ev.Print != nil {
printEvs = append(printEvs, ev.Print)
}
}
return printEvs
}

func lastCall(evs []*exec.Event) *exec.CallEvent {
callEvs := filterCalls(evs)
return callEvs[len(callEvs)-1]
Expand Down
36 changes: 36 additions & 0 deletions js/proto/exec_pb.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,12 @@ export class Event extends jspb.Message {
setGovernaccount(value?: GovernAccountEvent): Event;


hasPrint(): boolean;
clearPrint(): void;
getPrint(): PrintEvent | undefined;
setPrint(value?: PrintEvent): Event;


serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): Event.AsObject;
static toObject(includeInstance: boolean, msg: Event): Event.AsObject;
Expand All @@ -529,6 +535,7 @@ export namespace Event {
call?: CallEvent.AsObject,
log?: LogEvent.AsObject,
governaccount?: GovernAccountEvent.AsObject,
print?: PrintEvent.AsObject,
}
}

Expand Down Expand Up @@ -654,6 +661,35 @@ export namespace CallEvent {
}
}

export class PrintEvent extends jspb.Message {
getAddress(): Uint8Array | string;
getAddress_asU8(): Uint8Array;
getAddress_asB64(): string;
setAddress(value: Uint8Array | string): PrintEvent;

getData(): Uint8Array | string;
getData_asU8(): Uint8Array;
getData_asB64(): string;
setData(value: Uint8Array | string): PrintEvent;


serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): PrintEvent.AsObject;
static toObject(includeInstance: boolean, msg: PrintEvent): PrintEvent.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: PrintEvent, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): PrintEvent;
static deserializeBinaryFromReader(message: PrintEvent, reader: jspb.BinaryReader): PrintEvent;
}

export namespace PrintEvent {
export type AsObject = {
address: Uint8Array | string,
data: Uint8Array | string,
}
}

export class GovernAccountEvent extends jspb.Message {

hasAccountupdate(): boolean;
Expand Down
Loading

0 comments on commit dbfe3c6

Please sign in to comment.