github.com/Night-mk/quorum@v21.1.0+incompatible/core/dual_state_test.go (about)

     1  package core
     2  
     3  import (
     4  	"math/big"
     5  	"testing"
     6  
     7  	"github.com/ethereum/go-ethereum/common"
     8  	"github.com/ethereum/go-ethereum/core/rawdb"
     9  	"github.com/ethereum/go-ethereum/core/state"
    10  	"github.com/ethereum/go-ethereum/core/types"
    11  	"github.com/ethereum/go-ethereum/core/vm"
    12  	"github.com/ethereum/go-ethereum/params"
    13  )
    14  
    15  var dualStateTestHeader = types.Header{
    16  	Number:     new(big.Int),
    17  	Time:       43,
    18  	Difficulty: new(big.Int).SetUint64(1000488),
    19  	GasLimit:   4700000,
    20  }
    21  
    22  //[1] PUSH1 0x01 (out size)
    23  //[3] PUSH1 0x00 (out offset)
    24  //[5] PUSH1 0x00 (in size)
    25  //[7] PUSH1 0x00 (in offset)
    26  //[9] PUSH1 0x00 (value)
    27  //[30] PUSH20 0x0200000000000000000000000000000000000000 (to)
    28  //[34] PUSH3 0x0186a0 (gas)
    29  //[35] CALL
    30  //[37] PUSH1 0x00
    31  //[38] MLOAD
    32  //[40] PUSH1 0x00
    33  //[41] SSTORE
    34  //[42] STOP
    35  
    36  func TestDualStatePrivateToPublicCall(t *testing.T) {
    37  	callAddr := common.Address{1}
    38  
    39  	db := rawdb.NewMemoryDatabase()
    40  	publicState, _ := state.New(common.Hash{}, state.NewDatabase(db))
    41  	publicState.SetCode(common.Address{2}, common.Hex2Bytes("600a6000526001601ff300"))
    42  
    43  	privateState, _ := state.New(common.Hash{}, state.NewDatabase(db))
    44  	privateState.SetCode(callAddr, common.Hex2Bytes("60016000600060006000730200000000000000000000000000000000000000620186a0f160005160005500"))
    45  
    46  	author := common.Address{}
    47  	msg := callmsg{
    48  		addr:     author,
    49  		to:       &callAddr,
    50  		value:    big.NewInt(1),
    51  		gas:      1000000,
    52  		gasPrice: new(big.Int),
    53  		data:     nil,
    54  	}
    55  
    56  	ctx := NewEVMContext(msg, &dualStateTestHeader, nil, &author)
    57  	env := vm.NewEVM(ctx, publicState, privateState, &params.ChainConfig{}, vm.Config{})
    58  	env.Call(vm.AccountRef(author), callAddr, msg.data, msg.gas, new(big.Int))
    59  
    60  	if value := privateState.GetState(callAddr, common.Hash{}); value != (common.Hash{10}) {
    61  		t.Errorf("expected 10 got %x", value)
    62  	}
    63  }
    64  
    65  func TestDualStatePublicToPrivateCall(t *testing.T) {
    66  	callAddr := common.Address{1}
    67  
    68  	db := rawdb.NewMemoryDatabase()
    69  	privateState, _ := state.New(common.Hash{}, state.NewDatabase(db))
    70  	privateState.SetCode(common.Address{2}, common.Hex2Bytes("600a6000526001601ff300"))
    71  
    72  	publicState, _ := state.New(common.Hash{}, state.NewDatabase(db))
    73  	publicState.SetCode(callAddr, common.Hex2Bytes("60016000600060006000730200000000000000000000000000000000000000620186a0f160005160005500"))
    74  
    75  	author := common.Address{}
    76  	msg := callmsg{
    77  		addr:     author,
    78  		to:       &callAddr,
    79  		value:    big.NewInt(1),
    80  		gas:      1000000,
    81  		gasPrice: new(big.Int),
    82  		data:     nil,
    83  	}
    84  
    85  	ctx := NewEVMContext(msg, &dualStateTestHeader, nil, &author)
    86  	env := vm.NewEVM(ctx, publicState, publicState, &params.ChainConfig{}, vm.Config{})
    87  	env.Call(vm.AccountRef(author), callAddr, msg.data, msg.gas, new(big.Int))
    88  
    89  	if value := publicState.GetState(callAddr, common.Hash{}); value != (common.Hash{}) {
    90  		t.Errorf("expected 0 got %x", value)
    91  	}
    92  }
    93  
    94  func TestDualStateReadOnly(t *testing.T) {
    95  	callAddr := common.Address{1}
    96  
    97  	db := rawdb.NewMemoryDatabase()
    98  	publicState, _ := state.New(common.Hash{}, state.NewDatabase(db))
    99  	publicState.SetCode(common.Address{2}, common.Hex2Bytes("600a60005500"))
   100  
   101  	privateState, _ := state.New(common.Hash{}, state.NewDatabase(db))
   102  	privateState.SetCode(callAddr, common.Hex2Bytes("60016000600060006000730200000000000000000000000000000000000000620186a0f160005160005500"))
   103  
   104  	author := common.Address{}
   105  	msg := callmsg{
   106  		addr:     author,
   107  		to:       &callAddr,
   108  		value:    big.NewInt(1),
   109  		gas:      1000000,
   110  		gasPrice: new(big.Int),
   111  		data:     nil,
   112  	}
   113  
   114  	ctx := NewEVMContext(msg, &dualStateTestHeader, nil, &author)
   115  	env := vm.NewEVM(ctx, publicState, privateState, &params.ChainConfig{}, vm.Config{})
   116  	env.Call(vm.AccountRef(author), callAddr, msg.data, msg.gas, new(big.Int))
   117  
   118  	if value := publicState.GetState(common.Address{2}, common.Hash{}); value != (common.Hash{0}) {
   119  		t.Errorf("expected 0 got %x", value)
   120  	}
   121  }
   122  
   123  var (
   124  	calleeAddress      = common.Address{2}
   125  	calleeContractCode = "600a6000526001601ff300" // a function that returns 10
   126  	callerAddress      = common.Address{1}
   127  	// a functionn that calls the callee's function at its address and return the same value
   128  	//000000: PUSH1 0x01
   129  	//000002: PUSH1 0x00
   130  	//000004: PUSH1 0x00
   131  	//000006: PUSH1 0x00
   132  	//000008: PUSH20 0x0200000000000000000000000000000000000000
   133  	//000029: PUSH3 0x0186a0
   134  	//000033: STATICCALL
   135  	//000034: PUSH1 0x01
   136  	//000036: PUSH1 0x00
   137  	//000038: RETURN
   138  	//000039: STOP
   139  	callerContractCode = "6001600060006000730200000000000000000000000000000000000000620186a0fa60016000f300"
   140  )
   141  
   142  func verifyStaticCall(t *testing.T, privateState *state.StateDB, publicState *state.StateDB, expectedHash common.Hash) {
   143  	author := common.Address{}
   144  	msg := callmsg{
   145  		addr:     author,
   146  		to:       &callerAddress,
   147  		value:    big.NewInt(1),
   148  		gas:      1000000,
   149  		gasPrice: new(big.Int),
   150  		data:     nil,
   151  	}
   152  
   153  	ctx := NewEVMContext(msg, &dualStateTestHeader, nil, &author)
   154  	env := vm.NewEVM(ctx, publicState, privateState, &params.ChainConfig{
   155  		ByzantiumBlock: new(big.Int),
   156  	}, vm.Config{})
   157  
   158  	ret, _, err := env.Call(vm.AccountRef(author), callerAddress, msg.data, msg.gas, new(big.Int))
   159  
   160  	if err != nil {
   161  		t.Fatalf("Call error: %s", err)
   162  	}
   163  	value := common.Hash{ret[0]}
   164  	if value != expectedHash {
   165  		t.Errorf("expected %x got %x", expectedHash, value)
   166  	}
   167  }
   168  
   169  func TestStaticCall_whenPublicToPublic(t *testing.T) {
   170  	db := rawdb.NewMemoryDatabase()
   171  
   172  	publicState, _ := state.New(common.Hash{}, state.NewDatabase(db))
   173  	publicState.SetCode(callerAddress, common.Hex2Bytes(callerContractCode))
   174  	publicState.SetCode(calleeAddress, common.Hex2Bytes(calleeContractCode))
   175  
   176  	verifyStaticCall(t, publicState, publicState, common.Hash{10})
   177  }
   178  
   179  func TestStaticCall_whenPublicToPrivateInTheParty(t *testing.T) {
   180  	db := rawdb.NewMemoryDatabase()
   181  
   182  	privateState, _ := state.New(common.Hash{}, state.NewDatabase(db))
   183  	privateState.SetCode(calleeAddress, common.Hex2Bytes(calleeContractCode))
   184  
   185  	publicState, _ := state.New(common.Hash{}, state.NewDatabase(db))
   186  	publicState.SetCode(callerAddress, common.Hex2Bytes(callerContractCode))
   187  
   188  	verifyStaticCall(t, privateState, publicState, common.Hash{10})
   189  }
   190  
   191  func TestStaticCall_whenPublicToPrivateNotInTheParty(t *testing.T) {
   192  
   193  	db := rawdb.NewMemoryDatabase()
   194  
   195  	privateState, _ := state.New(common.Hash{}, state.NewDatabase(db))
   196  
   197  	publicState, _ := state.New(common.Hash{}, state.NewDatabase(db))
   198  	publicState.SetCode(callerAddress, common.Hex2Bytes(callerContractCode))
   199  
   200  	verifyStaticCall(t, privateState, publicState, common.Hash{0})
   201  }
   202  
   203  func TestStaticCall_whenPrivateToPublic(t *testing.T) {
   204  	db := rawdb.NewMemoryDatabase()
   205  
   206  	privateState, _ := state.New(common.Hash{}, state.NewDatabase(db))
   207  	privateState.SetCode(callerAddress, common.Hex2Bytes(callerContractCode))
   208  
   209  	publicState, _ := state.New(common.Hash{}, state.NewDatabase(db))
   210  	publicState.SetCode(calleeAddress, common.Hex2Bytes(calleeContractCode))
   211  
   212  	verifyStaticCall(t, privateState, publicState, common.Hash{10})
   213  }