Skip to content

Commit

Permalink
Make simulated call use same path as call_context
Browse files Browse the repository at this point in the history
and so handle revert correctly

Signed-off-by: Silas Davis <[email protected]>
  • Loading branch information
Silas Davis committed Aug 16, 2018
1 parent 97d9215 commit e93c9eb
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 118 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ test_integration_bosmarmot: bos build_db
make npm_install && \
GOPATH="${BOSMARMOT_GOPATH}" \
burrow_bin="${REPO}/bin/burrow" \
make test_integration_no_burrow
make test_burrow_js_no_burrow

bin/solc: ./tests/scripts/deps/solc.sh
@mkdir -p bin
Expand Down
66 changes: 31 additions & 35 deletions crypto/crypto.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crypto/public_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func (p PublicKey) Verify(msg []byte, signature Signature) error {
case CurveTypeUnset:
return fmt.Errorf("public key is unset")
case CurveTypeEd25519:
if ed25519.Verify(p.PublicKey, msg, signature.Signature) {
if ed25519.Verify(p.PublicKey.Bytes(), msg, signature.Signature) {
return nil
}
return fmt.Errorf("'%X' is not a valid ed25519 signature for message: %X", signature, msg)
Expand Down
71 changes: 27 additions & 44 deletions execution/simulated_call.go
Original file line number Diff line number Diff line change
@@ -1,76 +1,59 @@
package execution

import (
"fmt"
"runtime/debug"

"github.com/hyperledger/burrow/acm"
"github.com/hyperledger/burrow/acm/state"
"github.com/hyperledger/burrow/bcm"
"github.com/hyperledger/burrow/binary"
"github.com/hyperledger/burrow/crypto"
"github.com/hyperledger/burrow/execution/contexts"
"github.com/hyperledger/burrow/execution/evm"
"github.com/hyperledger/burrow/execution/exec"
"github.com/hyperledger/burrow/logging"
"github.com/hyperledger/burrow/txs"
"github.com/hyperledger/burrow/txs/payload"
)

// Run a contract's code on an isolated and unpersisted state
// Cannot be used to create new contracts
func CallSim(reader state.Reader, tip bcm.BlockchainInfo, fromAddress, address crypto.Address, data []byte,
logger *logging.Logger) (*exec.TxExecution, error) {

if evm.IsRegisteredNativeContract(address.Word256()) {
return nil, fmt.Errorf("attempt to call native contract at address "+
"%X, but native contracts can not be called directly. Use a deployed "+
"contract that calls the native function instead", address)
cache := state.NewCache(reader)
exe := contexts.CallContext{
RunCall: true,
StateWriter: cache,
Tip: tip,
Logger: logger,
}
// This was being run against CheckTx cache, need to understand the reasoning
callee, err := state.GetMutableAccount(reader, address)

txe := exec.NewTxExecution(txs.Enclose(tip.ChainID(), &payload.CallTx{
Input: &payload.TxInput{
Address: fromAddress,
},
Address: &address,
Data: data,
GasLimit: contexts.GasLimit,
}))
err := exe.Execute(txe)
if err != nil {
return nil, err
}
if callee == nil {
return nil, fmt.Errorf("account %s does not exist", address)
}
return CallCodeSim(reader, tip, fromAddress, address, callee.Code(), data, logger)
return txe, nil
}

// Run the given code on an isolated and unpersisted state
// Cannot be used to create new contracts.
func CallCodeSim(reader state.Reader, tip bcm.BlockchainInfo, fromAddress, address crypto.Address, code, data []byte,
logger *logging.Logger) (_ *exec.TxExecution, err error) {
// This was being run against CheckTx cache, need to understand the reasoning
caller := acm.ConcreteAccount{Address: fromAddress}.MutableAccount()
callee := acm.ConcreteAccount{Address: address}.MutableAccount()

txCache := state.NewCache(reader)

params := vmParams(tip)
vmach := evm.NewVM(params, caller.Address(), nil, logger.WithScope("CallCode"))
logger *logging.Logger) (*exec.TxExecution, error) {

txe := &exec.TxExecution{}
vmach.SetEventSink(txe)
gas := params.GasLimit
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic from VM in simulated call: %v\n%s", r, debug.Stack())
}
}()
// Attach code to target account (overwriting target)
cache := state.NewCache(reader)
err := cache.UpdateAccount(acm.ConcreteAccount{
Address: address,
Code: code,
}.MutableAccount())

ret, err := vmach.Call(txCache, caller, callee, code, data, 0, &gas)
if err != nil {
return nil, err
}
txe.Return(ret, params.GasLimit-gas)
return txe, nil
}

func vmParams(tip bcm.BlockchainInfo) evm.Params {
return evm.Params{
BlockHeight: tip.LastBlockHeight(),
BlockHash: binary.LeftPadWord256(tip.LastBlockHash()),
BlockTime: tip.LastBlockTime().Unix(),
GasLimit: contexts.GasLimit,
}
return CallSim(cache, tip, fromAddress, address, data, logger)
}
2 changes: 1 addition & 1 deletion integration/rpctransact/call_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func TestSendTxAsync(t *testing.T) {
require.Equal(t, numSends, <-countCh)
}

func TestCallCode(t *testing.T) {
func TestCallCodeSim(t *testing.T) {
cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress)
// add two integers and return the result
var i, j byte = 123, 21
Expand Down
5 changes: 2 additions & 3 deletions integration/rpctransact/transact_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ import (
"context"
"fmt"
"testing"

"time"

"github.com/hyperledger/burrow/crypto"
"github.com/hyperledger/burrow/execution/exec"
"github.com/hyperledger/burrow/integration/rpctest"
"github.com/hyperledger/burrow/rpc/rpcevents"
Expand All @@ -47,14 +45,15 @@ func TestInputAccountPublicKeySet(t *testing.T) {
require.NoError(t, err)

// Account PublicKey should be initially unset
assert.Equal(t, crypto.PublicKey{}, acc.PublicKey)
assert.False(t, acc.PublicKey.IsSet())

// Sign with this account - should set public key
rpctest.CreateContract(t, tcli, input.Address(), rpctest.Bytecode_strange_loop)
acc, err = qcli.GetAccount(context.Background(), &rpcquery.GetAccountParam{Address: input.Address()})

// Check public key set
require.NoError(t, err)
assert.True(t, acc.PublicKey.IsSet())
assert.Equal(t, input.PublicKey(), acc.PublicKey)
}

Expand Down
2 changes: 1 addition & 1 deletion protobuf/rpc.proto
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ message SyncInfo {
// Time at which we committed the last block
google.protobuf.Timestamp LatestBlockSeenTime = 5 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
// When catching up in fast sync
bool CatchingUp = 6;
bool CatchingUp = 6 [(gogoproto.jsontag) = ""];
}
64 changes: 32 additions & 32 deletions rpc/rpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit e93c9eb

Please sign in to comment.