From 1c9c96fc3be6429c9c0796c8f3558b4af4f10644 Mon Sep 17 00:00:00 2001 From: zsfelfoldi Date: Mon, 2 Nov 2015 01:20:43 +0100 Subject: [PATCH] odr contract call test --- les/odr_test.go | 106 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 91 insertions(+), 15 deletions(-) diff --git a/les/odr_test.go b/les/odr_test.go index 6f889ca070..df441d6051 100644 --- a/les/odr_test.go +++ b/les/odr_test.go @@ -17,9 +17,33 @@ import ( "github.com/ethereum/go-ethereum/trie" ) +var ( + acc1Key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") + acc2Key, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee") + acc1Addr = crypto.PubkeyToAddress(acc1Key.PublicKey) + acc2Addr = crypto.PubkeyToAddress(acc2Key.PublicKey) + + testContractCode = common.Hex2Bytes("606060405260cc8060106000396000f360606040526000357c01000000000000000000000000000000000000000000000000000000009004806360cd2685146041578063c16431b914606b57603f565b005b6055600480803590602001909190505060a9565b6040518082815260200191505060405180910390f35b60886004808035906020019091908035906020019091905050608a565b005b80600060005083606481101560025790900160005b50819055505b5050565b6000600060005082606481101560025790900160005b5054905060c7565b91905056") + testContractAddr common.Address +) +/* +contract test { + + uint256[100] data; + + function Put(uint256 addr, uint256 value) { + data[addr] = value; + } + + function Get(uint256 addr) constant returns (uint256 value) { + return data[addr]; + } +} +*/ + type odrTestFn func(ca *access.ChainAccess, bc *core.BlockChain, ctx *access.OdrContext, bhash common.Hash) []byte -func TestOdrGetBlockLes1(t *testing.T) { testOdr(t, 1, odrGetBlock) } +func TestOdrGetBlockLes1(t *testing.T) { testOdr(t, 1, 1, odrGetBlock) } func odrGetBlock(ca *access.ChainAccess, bc *core.BlockChain, ctx *access.OdrContext, bhash common.Hash) []byte { block := bc.GetBlock(bhash, ctx) @@ -30,7 +54,7 @@ func odrGetBlock(ca *access.ChainAccess, bc *core.BlockChain, ctx *access.OdrCon return rlp } -func TestOdrGetReceiptsLes1(t *testing.T) { testOdr(t, 1, odrGetReceipts) } +func TestOdrGetReceiptsLes1(t *testing.T) { testOdr(t, 1, 1, odrGetReceipts) } func odrGetReceipts(ca *access.ChainAccess, bc *core.BlockChain, ctx *access.OdrContext, bhash common.Hash) []byte { receipts := core.GetBlockReceipts(ca, bhash, ctx) @@ -41,13 +65,9 @@ func odrGetReceipts(ca *access.ChainAccess, bc *core.BlockChain, ctx *access.Odr return rlp } -func TestOdrAccountsLes1(t *testing.T) { testOdr(t, 1, odrAccounts) } +func TestOdrAccountsLes1(t *testing.T) { testOdr(t, 1, 1, odrAccounts) } func odrAccounts(ca *access.ChainAccess, bc *core.BlockChain, ctx *access.OdrContext, bhash common.Hash) []byte { - acc1Key, _ := crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") - acc2Key, _ := crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee") - acc1Addr := crypto.PubkeyToAddress(acc1Key.PublicKey) - acc2Addr := crypto.PubkeyToAddress(acc2Key.PublicKey) dummyAddr := common.HexToAddress("1234567812345678123456781234567812345678") acc := []common.Address{ testBankAddress, acc1Addr, acc2Addr, dummyAddr} @@ -67,13 +87,57 @@ func odrAccounts(ca *access.ChainAccess, bc *core.BlockChain, ctx *access.OdrCon return res } -func testOdr(t *testing.T, protocol int, fn odrTestFn) { - // Define accounts to simulate transactions with - acc1Key, _ := crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") - acc2Key, _ := crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee") - acc1Addr := crypto.PubkeyToAddress(acc1Key.PublicKey) - acc2Addr := crypto.PubkeyToAddress(acc2Key.PublicKey) +func TestOdrContractCallLes1(t *testing.T) { testOdr(t, 1, 2, odrContractCall) } +// callmsg is the message type used for call transations. +type callmsg struct { + from *state.StateObject + to *common.Address + gas, gasPrice *big.Int + value *big.Int + data []byte +} + +// accessor boilerplate to implement core.Message +func (m callmsg) From() (common.Address, error) { return m.from.Address(), nil } +func (m callmsg) Nonce() uint64 { return m.from.Nonce() } +func (m callmsg) To() *common.Address { return m.to } +func (m callmsg) GasPrice() *big.Int { return m.gasPrice } +func (m callmsg) Gas() *big.Int { return m.gas } +func (m callmsg) Value() *big.Int { return m.value } +func (m callmsg) Data() []byte { return m.data } + +func odrContractCall(ca *access.ChainAccess, bc *core.BlockChain, ctx *access.OdrContext, bhash common.Hash) []byte { + data := common.Hex2Bytes("60CD26850000000000000000000000000000000000000000000000000000000000000000") + + var res []byte + for i:=0; i<3; i++ { + data[35] = byte(i) + header := bc.GetHeader(bhash) + statedb, err := state.New(header.Root, ca, ctx) + if err == nil { + from := statedb.GetOrNewStateObject(testBankAddress) + from.SetBalance(common.MaxBig) + + msg := callmsg{ + from: from, + gas: big.NewInt(100000), + gasPrice: big.NewInt(0), + value: big.NewInt(0), + data: data, + to: &testContractAddr, + } + + vmenv := core.NewEnv(statedb, bc, msg, header) + gp := new(core.GasPool).AddGas(common.MaxBig) + ret, _, _ := core.ApplyMessage(vmenv, msg, gp) + res = append(res, ret...) + } + } + return res +} + +func testOdr(t *testing.T, protocol int, expFail uint64, fn odrTestFn) { // Create a chain generator with some simple transactions (blatantly stolen from @fjl/chain_makerts_test) generator := func(i int, block *core.BlockGen) { switch i { @@ -84,14 +148,23 @@ func testOdr(t *testing.T, protocol int, fn odrTestFn) { case 1: // In block 2, the test bank sends some more ether to account #1. // acc1Addr passes it on to account #2. + // acc1Addr creates a test contract. tx1, _ := types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(1000), params.TxGas, nil, nil).SignECDSA(testBankKey) - tx2, _ := types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1000), params.TxGas, nil, nil).SignECDSA(acc1Key) + nonce := block.TxNonce(acc1Addr) + tx2, _ := types.NewTransaction(nonce, acc2Addr, big.NewInt(1000), params.TxGas, nil, nil).SignECDSA(acc1Key) + nonce++ + tx3, _ := types.NewContractCreation(nonce, big.NewInt(0), big.NewInt(100000), big.NewInt(0), testContractCode).SignECDSA(acc1Key) + testContractAddr = crypto.CreateAddress(acc1Addr, nonce) block.AddTx(tx1) block.AddTx(tx2) + block.AddTx(tx3) case 2: // Block 3 is empty but was mined by account #2. block.SetCoinbase(acc2Addr) block.SetExtra([]byte("yeehaw")) + data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001") + tx, _ := types.NewTransaction(block.TxNonce(testBankAddress), testContractAddr, big.NewInt(0), big.NewInt(100000), nil, data).SignECDSA(testBankKey) + block.AddTx(tx) case 3: // Block 4 includes blocks 2 and 3 as uncle headers (with modified extra data). b2 := block.PrevBlock(1).Header() @@ -100,6 +173,9 @@ func testOdr(t *testing.T, protocol int, fn odrTestFn) { b3 := block.PrevBlock(2).Header() b3.Extra = []byte("foo") block.AddUncle(b3) + data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002") + tx, _ := types.NewTransaction(block.TxNonce(testBankAddress), testContractAddr, big.NewInt(0), big.NewInt(100000), nil, data).SignECDSA(testBankKey) + block.AddTx(tx) } } // Assemble the test environment @@ -130,7 +206,7 @@ func testOdr(t *testing.T, protocol int, fn odrTestFn) { // temporarily remove peer to test odr fails lca.UnregisterPeer(lpeer.id) // expect retrievals to fail (except genesis block) without a les peer - test(1) + test(expFail) lca.RegisterPeer(lpeer.id, lpeer.version, lpeer.Head(), lpeer.RequestBodies, lpeer.RequestNodeData, lpeer.RequestReceipts, lpeer.RequestProofs) // expect all retrievals to pass test(5)