github.com/kisexp/xdchain@v0.0.0-20211206025815-490d6b732aa7/core/dual_state_test.go (about)

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