Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return an error if the ccr tries to modify the state of the suapp #107

Merged
merged 3 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1941,6 +1941,33 @@ func (s *TransactionAPI) SendRawTransaction(ctx context.Context, input hexutil.B
return SubmitTransaction(ctx, s.b, tx)
}

type mevmStateLogger struct {
hasStoredState bool
}

func (m *mevmStateLogger) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
}

func (m *mevmStateLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
if op == vm.SSTORE {
m.hasStoredState = true
}
}

func (m *mevmStateLogger) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {
}

func (m *mevmStateLogger) CaptureEnd(output []byte, gasUsed uint64, err error) {}

func (m *mevmStateLogger) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
}

func (m *mevmStateLogger) CaptureExit(output []byte, gasUsed uint64, err error) {}

func (m *mevmStateLogger) CaptureTxStart(gasLimit uint64) {}

func (m *mevmStateLogger) CaptureTxEnd(restGas uint64) {}

// TODO: should be its own api
func runMEVM(ctx context.Context, b Backend, state *state.StateDB, header *types.Header, tx *types.Transaction, msg *core.Message, isCall bool) (*types.Transaction, *core.ExecutionResult, func() error, error) {
var cancel context.CancelFunc
Expand All @@ -1960,9 +1987,11 @@ func runMEVM(ctx context.Context, b Backend, state *state.StateDB, header *types
return nil, nil, nil, err
}

storageAccessTracer := &mevmStateLogger{}

blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil)
suaveCtx := b.SuaveContext(tx, confidentialRequest)
evm, storeFinalize, vmError := b.GetMEVM(ctx, msg, state, header, &vm.Config{IsConfidential: true, NoBaseFee: isCall}, &blockCtx, &suaveCtx)
evm, storeFinalize, vmError := b.GetMEVM(ctx, msg, state, header, &vm.Config{IsConfidential: true, NoBaseFee: isCall, Tracer: storageAccessTracer}, &blockCtx, &suaveCtx)

// Wait for the context to be done and cancel the evm. Even if the
// EVM has finished, cancelling may be done (repeatedly)
Expand Down Expand Up @@ -1991,6 +2020,10 @@ func runMEVM(ctx context.Context, b Backend, state *state.StateDB, header *types
return nil, nil, nil, fmt.Errorf("%w: %s", result.Err, hexutil.Encode(result.Revert()))
}

if storageAccessTracer.hasStoredState {
return nil, nil, nil, fmt.Errorf("confidential request cannot modify state storage")
}

// Check for call in return
var computeResult []byte

Expand Down
11 changes: 9 additions & 2 deletions suave/artifacts/example.sol/ExampleEthCallSource.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,19 @@
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "ilegalStateTransition",
"outputs": [],
"stateMutability": "payable",
"type": "function"
}
],
"deployedBytecode": {
"object": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c806348bce06414610030575b600080fd5b61004361003e366004610183565b610045565b005b6040805160048152602481019091526020810180516001600160e01b0316631b53398f60e21b17905260009061007c9084906100b2565b905060008180602001905181019061009491906101bb565b67ffffffffffffffff1690508281146100ac57600080fd5b50505050565b606060008063421000036001600160a01b031685856040516020016100d8929190610210565b60408051601f19818403018152908290526100f291610252565b600060405180830381855afa9150503d806000811461012d576040519150601f19603f3d011682016040523d82523d6000602084013e610132565b606091505b509150915081610166576342100003816040516375fff46760e01b815260040161015d929190610210565b60405180910390fd5b8080602001905181019061017a9190610284565b95945050505050565b6000806040838503121561019657600080fd5b82356001600160a01b03811681146101ad57600080fd5b946020939093013593505050565b6000602082840312156101cd57600080fd5b815167ffffffffffffffff811681146101e557600080fd5b9392505050565b60005b838110156102075781810151838201526020016101ef565b50506000910152565b60018060a01b0383168152604060208201526000825180604084015261023d8160608501602087016101ec565b601f01601f1916919091016060019392505050565b600082516102648184602087016101ec565b9190910192915050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561029657600080fd5b815167ffffffffffffffff808211156102ae57600080fd5b818401915084601f8301126102c257600080fd5b8151818111156102d4576102d461026e565b604051601f8201601f19908116603f011681019083821181831017156102fc576102fc61026e565b8160405282815287602084870101111561031557600080fd5b6103268360208301602088016101ec565b97965050505050505056fea164736f6c6343000813000a"
"object": "0x6080604052600436106100295760003560e01c806348bce0641461002e5780639476e96614610050575b600080fd5b34801561003a57600080fd5b5061004e6100493660046101d8565b610058565b005b61004e6100c5565b6040805160048152602481019091526020810180516001600160e01b0316631b53398f60e21b17905260009061008f908490610107565b90506000818060200190518101906100a79190610210565b67ffffffffffffffff1690508281146100bf57600080fd5b50505050565b6000805467ffffffffffffffff1690806100de83610241565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b606060008063421000036001600160a01b0316858560405160200161012d92919061029a565b60408051601f1981840301815290829052610147916102dc565b600060405180830381855afa9150503d8060008114610182576040519150601f19603f3d011682016040523d82523d6000602084013e610187565b606091505b5091509150816101bb576342100003816040516375fff46760e01b81526004016101b292919061029a565b60405180910390fd5b808060200190518101906101cf919061030e565b95945050505050565b600080604083850312156101eb57600080fd5b82356001600160a01b038116811461020257600080fd5b946020939093013593505050565b60006020828403121561022257600080fd5b815167ffffffffffffffff8116811461023a57600080fd5b9392505050565b600067ffffffffffffffff80831681810361026c57634e487b7160e01b600052601160045260246000fd5b6001019392505050565b60005b83811015610291578181015183820152602001610279565b50506000910152565b60018060a01b038316815260406020820152600082518060408401526102c7816060850160208701610276565b601f01601f1916919091016060019392505050565b600082516102ee818460208701610276565b9190910192915050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561032057600080fd5b815167ffffffffffffffff8082111561033857600080fd5b818401915084601f83011261034c57600080fd5b81518181111561035e5761035e6102f8565b604051601f8201601f19908116603f01168101908382118183101715610386576103866102f8565b8160405282815287602084870101111561039f57600080fd5b6103b0836020830160208801610276565b97965050505050505056fea164736f6c6343000813000a"
},
"bytecode": {
"object": "0x608060405234801561001057600080fd5b5061033e806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c806348bce06414610030575b600080fd5b61004361003e366004610183565b610045565b005b6040805160048152602481019091526020810180516001600160e01b0316631b53398f60e21b17905260009061007c9084906100b2565b905060008180602001905181019061009491906101bb565b67ffffffffffffffff1690508281146100ac57600080fd5b50505050565b606060008063421000036001600160a01b031685856040516020016100d8929190610210565b60408051601f19818403018152908290526100f291610252565b600060405180830381855afa9150503d806000811461012d576040519150601f19603f3d011682016040523d82523d6000602084013e610132565b606091505b509150915081610166576342100003816040516375fff46760e01b815260040161015d929190610210565b60405180910390fd5b8080602001905181019061017a9190610284565b95945050505050565b6000806040838503121561019657600080fd5b82356001600160a01b03811681146101ad57600080fd5b946020939093013593505050565b6000602082840312156101cd57600080fd5b815167ffffffffffffffff811681146101e557600080fd5b9392505050565b60005b838110156102075781810151838201526020016101ef565b50506000910152565b60018060a01b0383168152604060208201526000825180604084015261023d8160608501602087016101ec565b601f01601f1916919091016060019392505050565b600082516102648184602087016101ec565b9190910192915050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561029657600080fd5b815167ffffffffffffffff808211156102ae57600080fd5b818401915084601f8301126102c257600080fd5b8151818111156102d4576102d461026e565b604051601f8201601f19908116603f011681019083821181831017156102fc576102fc61026e565b8160405282815287602084870101111561031557600080fd5b6103268360208301602088016101ec565b97965050505050505056fea164736f6c6343000813000a"
"object": "0x608060405234801561001057600080fd5b506103c8806100206000396000f3fe6080604052600436106100295760003560e01c806348bce0641461002e5780639476e96614610050575b600080fd5b34801561003a57600080fd5b5061004e6100493660046101d8565b610058565b005b61004e6100c5565b6040805160048152602481019091526020810180516001600160e01b0316631b53398f60e21b17905260009061008f908490610107565b90506000818060200190518101906100a79190610210565b67ffffffffffffffff1690508281146100bf57600080fd5b50505050565b6000805467ffffffffffffffff1690806100de83610241565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b606060008063421000036001600160a01b0316858560405160200161012d92919061029a565b60408051601f1981840301815290829052610147916102dc565b600060405180830381855afa9150503d8060008114610182576040519150601f19603f3d011682016040523d82523d6000602084013e610187565b606091505b5091509150816101bb576342100003816040516375fff46760e01b81526004016101b292919061029a565b60405180910390fd5b808060200190518101906101cf919061030e565b95945050505050565b600080604083850312156101eb57600080fd5b82356001600160a01b038116811461020257600080fd5b946020939093013593505050565b60006020828403121561022257600080fd5b815167ffffffffffffffff8116811461023a57600080fd5b9392505050565b600067ffffffffffffffff80831681810361026c57634e487b7160e01b600052601160045260246000fd5b6001019392505050565b60005b83811015610291578181015183820152602001610279565b50506000910152565b60018060a01b038316815260406020820152600082518060408401526102c7816060850160208701610276565b601f01601f1916919091016060019392505050565b600082516102ee818460208701610276565b9190910192915050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561032057600080fd5b815167ffffffffffffffff8082111561033857600080fd5b818401915084601f83011261034c57600080fd5b81518181111561035e5761035e6102f8565b604051601f8201601f19908116603f01168101908382118183101715610386576103866102f8565b8160405282815287602084870101111561039f57600080fd5b6103b0836020830160208801610276565b97965050505050505056fea164736f6c6343000813000a"
}
}
15 changes: 15 additions & 0 deletions suave/e2e/workflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,21 @@ func TestE2EKettleAddressEndpoint(t *testing.T) {
require.NotEmpty(t, addrs)
}

func TestE2EOnChainStateTransition(t *testing.T) {
// This end-to-end tests that the callx precompile gets called from a confidential request
fr := newFramework(t)
defer fr.Close()

clt := fr.NewSDKClient()

contractAddr := common.Address{0x3}
sourceContract := sdk.GetContract(contractAddr, exampleCallSourceContract.Abi, clt)

// a confidential request cannot make a state change
_, err := sourceContract.SendTransaction("ilegalStateTransition", []interface{}{}, nil)
require.Error(t, err)
}

type clientWrapper struct {
t *testing.T

Expand Down
6 changes: 6 additions & 0 deletions suave/sol/standard_peekers/example.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@ pragma solidity ^0.8.8;
import "../libraries/Suave.sol";

contract ExampleEthCallSource {
uint64 state;

function callTarget(address target, uint256 expected) public {
bytes memory output = Suave.ethcall(target, abi.encodeWithSignature("get()"));
(uint256 num) = abi.decode(output, (uint64));
require(num == expected);
}

function ilegalStateTransition() public payable {
state++;
}
}

contract ExampleEthCallTarget {
Expand Down
Loading