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, ¶ms.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, ¶ms.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, ¶ms.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, ¶ms.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 }