diff --git a/auth/chainconfig_middleware.go b/auth/chainconfig_middleware.go index 9459a836f1..e9b62de93f 100644 --- a/auth/chainconfig_middleware.go +++ b/auth/chainconfig_middleware.go @@ -33,7 +33,7 @@ func NewChainConfigMiddleware( } // Filters out any auth.ChainConfig(s) that haven't been enabled by the majority of validators. -func getEnabledChains(chains map[string]ChainConfig, state loomchain.State) map[string]ChainConfig { +func getEnabledChains(chains map[string]ChainConfig, state loomchain.ReadOnlyState) map[string]ChainConfig { enabledChains := map[string]ChainConfig{} for chainID, config := range chains { if state.FeatureEnabled(features.AuthSigTxFeaturePrefix+chainID, false) { diff --git a/e2e/tests/truffle/test/EthFunctions.js b/e2e/tests/truffle/test/EthFunctions.js index e1ac140092..509c6ab121 100644 --- a/e2e/tests/truffle/test/EthFunctions.js +++ b/e2e/tests/truffle/test/EthFunctions.js @@ -8,6 +8,7 @@ const { const ethers = require('ethers').ethers const { getContractFuncInterface, getLatestBlock, getMappedAccount } = require('./helpers') const MyToken = artifacts.require('MyToken'); +const { waitForXBlocks } = require('./helpers'); // web3 functions called using truffle objects use the loomProvider // web3 functions called uisng we3js access the loom QueryInterface directly @@ -92,11 +93,10 @@ contract('MyToken', async (accounts) => { const tokenContract = await MyToken.deployed(); const result = await tokenContract.mintToken(102, { from: alice }); const txObj = await web3js.eth.getTransaction(result.tx); - + await waitForXBlocks(nodeAddr, 1) + const receipt = await web3js.eth.getTransactionReceipt(result.tx); assert.equal(txObj.to.toLowerCase(), tokenContract.address.toLowerCase(), "transaction object to address and contract address"); - assert.equal(txObj.from.toLowerCase(), alice.toLowerCase(), "transaction object from address and caller"); - // TODO: Need to fix GetTxObjectFromBlockResult so the caller address matches on the receipt & tx - //assert.equal(result.receipt.from.toLowerCase(), alice.toLowerCase(), "receipt from and caller"); + assert.equal(txObj.from.toLowerCase(), receipt.from.toLowerCase(), "transaction object from address and caller"); }); it('eth_getCode', async () => { @@ -109,7 +109,7 @@ contract('MyToken', async (accounts) => { const tokenContract = await MyToken.deployed(); const result = await tokenContract.mintToken(103, { from: alice }); await tokenContract.mintToken(104, { from: alice }); - + await waitForXBlocks(nodeAddr, 1) const txObject = await web3js.eth.getTransaction(result.tx, true); const blockByHash = await web3js.eth.getBlock(txObject.blockHash, true); @@ -117,8 +117,8 @@ contract('MyToken', async (accounts) => { assert.equal(txObject.blockNumber, blockByHash.number, "receipt block number and block object number"); assert.equal(blockByHash.transactions.length, 1, "block transaction count"); - // TODO: the from on the tx should be the local address, not the eth address, just like on the tx receipt - assert.equal(blockByHash.transactions[0].from.toLowerCase(), alice.toLowerCase(), "caller and block transaction from"); + const txReceipt = await web3js.eth.getTransactionReceipt(result.tx); + assert.equal(blockByHash.transactions[0].from.toLowerCase(), txReceipt.from.toLowerCase(), "caller and block transaction from"); assert.equal(blockByHash.transactions[0].to.toLowerCase(), tokenContract.address.toLowerCase(), "token address and block transaction to"); assert.equal(txObject.blockNumber, blockByHash.transactions[0].blockNumber, "receipt block number and block transaction block bumber"); assert.equal(txObject.hash.toLowerCase(), blockByHash.transactions[0].hash.toLowerCase(), "receipt tx hash and block transaction hash"); @@ -149,13 +149,13 @@ contract('MyToken', async (accounts) => { it('eth_getTransactionByBlockHashAndIndex', async () => { const tokenContract = await MyToken.deployed(); const result = await tokenContract.mintToken(107, { from: alice }); + await waitForXBlocks(nodeAddr, 1) // Do second transaction to move to next block await tokenContract.mintToken(108, { from: alice }); const tx1 = await web3js.eth.getTransaction(result.tx, true); const tx2 = await web3js.eth.getTransactionFromBlock(tx1.blockHash, 0); - - // TODO: the from on the tx should be the local address, not the eth address, just like on the tx receipt - assert.equal(tx2.from.toLowerCase(), alice.toLowerCase(), "caller and transaction object from"); + const receipt = await web3js.eth.getTransactionReceipt(result.tx); + assert.equal(tx2.from.toLowerCase(), receipt.from.toLowerCase(), "caller and transaction object from"); assert.equal(tx2.to.toLowerCase(), tokenContract.address.toLowerCase(), "contract address and transaction object to"); assert.equal(tx1.blockNumber, tx2.blockNumber, "receipt block number and transaction object block number"); assert.equal(tx1.hash.toLowerCase(), tx2.hash.toLowerCase(), "transaction hash and transaction object hash"); diff --git a/eth/polls/eth_subscribe.go b/eth/polls/eth_subscribe.go index 03e53ac6b0..03b982f5d5 100644 --- a/eth/polls/eth_subscribe.go +++ b/eth/polls/eth_subscribe.go @@ -6,6 +6,8 @@ import ( "fmt" "sync" + "github.com/loomnetwork/go-loom" + evmaux "github.com/loomnetwork/loomchain/store/evm_aux" "github.com/loomnetwork/loomchain/store" @@ -20,9 +22,24 @@ var ( ) type EthPoll interface { - AllLogs(state loomchain.ReadOnlyState, id string, readReceipts loomchain.ReadReceiptHandler) (interface{}, error) - Poll(state loomchain.ReadOnlyState, id string, readReceipts loomchain.ReadReceiptHandler) (EthPoll, interface{}, error) - LegacyPoll(state loomchain.ReadOnlyState, id string, readReceipts loomchain.ReadReceiptHandler) (EthPoll, []byte, error) + AllLogs( + state loomchain.State, + id string, + readReceipts loomchain.ReadReceiptHandler, + resolveAccountToLocalAddr func(loomchain.State, loom.Address) (loom.Address, error), + ) (interface{}, error) + Poll( + state loomchain.State, + id string, + readReceipts loomchain.ReadReceiptHandler, + resolveAccountToLocalAddr func(loomchain.State, loom.Address) (loom.Address, error), + ) (EthPoll, interface{}, error) + LegacyPoll( + state loomchain.State, + id string, + readReceipts loomchain.ReadReceiptHandler, + resolveAccountToLocalAddr func(loomchain.State, loom.Address) (loom.Address, error), + ) (EthPoll, []byte, error) } type EthSubscriptions struct { @@ -111,7 +128,10 @@ func (s *EthSubscriptions) AddTxPoll(height uint64) string { } func (s *EthSubscriptions) AllLogs( - state loomchain.ReadOnlyState, id string, readReceipts loomchain.ReadReceiptHandler, + state loomchain.State, + id string, + readReceipts loomchain.ReadReceiptHandler, + resolveAccountToLocalAddr func(loomchain.State, loom.Address) (loom.Address, error), ) (interface{}, error) { s.mutex.RLock() defer s.mutex.RUnlock() @@ -119,12 +139,15 @@ func (s *EthSubscriptions) AllLogs( if poll, ok := s.polls[id]; !ok { return nil, fmt.Errorf("subscription not found") } else { - return poll.AllLogs(state, id, readReceipts) + return poll.AllLogs(state, id, readReceipts, resolveAccountToLocalAddr) } } func (s *EthSubscriptions) Poll( - state loomchain.ReadOnlyState, id string, readReceipts loomchain.ReadReceiptHandler, + state loomchain.State, + id string, + readReceipts loomchain.ReadReceiptHandler, + resolveAccountToLocalAddr func(loomchain.State, loom.Address) (loom.Address, error), ) (interface{}, error) { s.mutex.Lock() defer s.mutex.Unlock() @@ -133,7 +156,7 @@ func (s *EthSubscriptions) Poll( if !ok { return nil, fmt.Errorf("subscription not found") } - newPoll, result, err := poll.Poll(state, id, readReceipts) + newPoll, result, err := poll.Poll(state, id, readReceipts, resolveAccountToLocalAddr) s.polls[id] = newPoll s.resetTimestamp(id, uint64(state.Block().Height)) @@ -142,7 +165,10 @@ func (s *EthSubscriptions) Poll( } func (s *EthSubscriptions) LegacyPoll( - state loomchain.ReadOnlyState, id string, readReceipts loomchain.ReadReceiptHandler, + state loomchain.State, + id string, + readReceipts loomchain.ReadReceiptHandler, + resolveAccountToLocalAddr func(loomchain.State, loom.Address) (loom.Address, error), ) ([]byte, error) { s.mutex.Lock() defer s.mutex.Unlock() @@ -151,7 +177,7 @@ func (s *EthSubscriptions) LegacyPoll( if !ok { return nil, fmt.Errorf("subscription not found") } - newPoll, result, err := poll.LegacyPoll(state, id, readReceipts) + newPoll, result, err := poll.LegacyPoll(state, id, readReceipts, resolveAccountToLocalAddr) s.polls[id] = newPoll s.resetTimestamp(id, uint64(state.Block().Height)) diff --git a/eth/polls/pollblocks.go b/eth/polls/pollblocks.go index 55c1ae1225..322b65f134 100644 --- a/eth/polls/pollblocks.go +++ b/eth/polls/pollblocks.go @@ -4,8 +4,10 @@ package polls import ( "github.com/gogo/protobuf/proto" + "github.com/loomnetwork/go-loom" "github.com/loomnetwork/go-loom/plugin/types" "github.com/loomnetwork/loomchain" + "github.com/loomnetwork/loomchain/rpc/eth" "github.com/loomnetwork/loomchain/store" evmaux "github.com/loomnetwork/loomchain/store/evm_aux" @@ -30,7 +32,11 @@ func NewEthBlockPoll(height uint64, evmAuxStore *evmaux.EvmAuxStore, blockStore } func (p *EthBlockPoll) Poll( - state loomchain.ReadOnlyState, id string, readReceipts loomchain.ReadReceiptHandler, + state loomchain.State, + id string, + readReceipts loomchain.ReadReceiptHandler, + _ func(loomchain.State, loom.Address) (loom.Address, error), + ) (EthPoll, interface{}, error) { if p.lastBlock+1 > uint64(state.Block().Height) { return p, nil, nil @@ -44,14 +50,17 @@ func (p *EthBlockPoll) Poll( } func (p *EthBlockPoll) AllLogs( - state loomchain.ReadOnlyState, id string, readReceipts loomchain.ReadReceiptHandler, + state loomchain.State, + id string, + readReceipts loomchain.ReadReceiptHandler, + _ func(loomchain.State, loom.Address) (loom.Address, error), ) (interface{}, error) { _, results, err := getBlockHashes(p.blockStore, state, p.startBlock) return eth.EncBytesArray(results), err } func getBlockHashes( - blockStore store.BlockStore, state loomchain.ReadOnlyState, lastBlockRead uint64, + blockStore store.BlockStore, state loomchain.State, lastBlockRead uint64, ) (uint64, [][]byte, error) { result, err := blockStore.GetBlockRangeByHeight(int64(lastBlockRead+1), state.Block().Height) if err != nil { @@ -70,8 +79,12 @@ func getBlockHashes( return lastBlockRead, blockHashes, nil } -func (p *EthBlockPoll) LegacyPoll(state loomchain.ReadOnlyState, id string, - readReceipts loomchain.ReadReceiptHandler) (EthPoll, []byte, error) { +func (p *EthBlockPoll) LegacyPoll( + state loomchain.State, + id string, + readReceipts loomchain.ReadReceiptHandler, + _ func(loomchain.State, loom.Address) (loom.Address, error), +) (EthPoll, []byte, error) { if p.lastBlock+1 > uint64(state.Block().Height) { return p, nil, nil } diff --git a/eth/polls/polllogs.go b/eth/polls/polllogs.go index 708e7c78fc..35cfb132e2 100644 --- a/eth/polls/polllogs.go +++ b/eth/polls/polllogs.go @@ -5,6 +5,8 @@ package polls import ( "fmt" + "github.com/loomnetwork/go-loom" + "github.com/pkg/errors" "github.com/loomnetwork/loomchain/store" @@ -13,6 +15,7 @@ import ( "github.com/gogo/protobuf/proto" "github.com/loomnetwork/go-loom/plugin/types" "github.com/loomnetwork/loomchain" + "github.com/loomnetwork/loomchain/eth/query" "github.com/loomnetwork/loomchain/eth/utils" "github.com/loomnetwork/loomchain/rpc/eth" @@ -40,7 +43,10 @@ func NewEthLogPoll(filter string, evmAuxStore *evmaux.EvmAuxStore, blockStore st } func (p *EthLogPoll) Poll( - state loomchain.ReadOnlyState, id string, readReceipts loomchain.ReadReceiptHandler, + state loomchain.State, + id string, + readReceipts loomchain.ReadReceiptHandler, + resolveAccountToLocalAddr func(loomchain.State, loom.Address) (loom.Address, error), ) (EthPoll, interface{}, error) { start, err := eth.DecBlockHeight(state.Block().Height, p.filter.FromBlock) if err != nil { @@ -63,7 +69,14 @@ func (p *EthLogPoll) Poll( } eventLogs, err := query.GetBlockLogRange( - p.blockStore, state, start, end, p.filter.EthBlockFilter, readReceipts, p.evmAuxStore, + p.blockStore, + state, + start, + end, + p.filter.EthBlockFilter, + readReceipts, + p.evmAuxStore, + resolveAccountToLocalAddr, ) if err != nil { return p, nil, err @@ -75,8 +88,12 @@ func (p *EthLogPoll) Poll( return newLogPoll, eth.EncLogs(eventLogs), nil } -func (p *EthLogPoll) AllLogs(state loomchain.ReadOnlyState, - id string, readReceipts loomchain.ReadReceiptHandler) (interface{}, error) { +func (p *EthLogPoll) AllLogs( + state loomchain.State, + id string, + readReceipts loomchain.ReadReceiptHandler, + resolveAccountToLocalAddr func(loomchain.State, loom.Address) (loom.Address, error), +) (interface{}, error) { start, err := eth.DecBlockHeight(state.Block().Height, p.filter.FromBlock) if err != nil { return nil, err @@ -90,7 +107,14 @@ func (p *EthLogPoll) AllLogs(state loomchain.ReadOnlyState, } eventLogs, err := query.GetBlockLogRange( - p.blockStore, state, start, end, p.filter.EthBlockFilter, readReceipts, p.evmAuxStore, + p.blockStore, + state, + start, + end, + p.filter.EthBlockFilter, + readReceipts, + p.evmAuxStore, + resolveAccountToLocalAddr, ) if err != nil { return nil, err @@ -98,8 +122,12 @@ func (p *EthLogPoll) AllLogs(state loomchain.ReadOnlyState, return eth.EncLogs(eventLogs), nil } -func (p *EthLogPoll) LegacyPoll(state loomchain.ReadOnlyState, - id string, readReceipts loomchain.ReadReceiptHandler) (EthPoll, []byte, error) { +func (p *EthLogPoll) LegacyPoll( + state loomchain.State, + id string, + readReceipts loomchain.ReadReceiptHandler, + resolveAccountToLocalAddr func(loomchain.State, loom.Address) (loom.Address, error), +) (EthPoll, []byte, error) { start, err := eth.DecBlockHeight(state.Block().Height, p.filter.FromBlock) if err != nil { return p, nil, err @@ -117,7 +145,14 @@ func (p *EthLogPoll) LegacyPoll(state loomchain.ReadOnlyState, } } eventLogs, err := query.GetBlockLogRange( - p.blockStore, state, start, end, p.filter.EthBlockFilter, readReceipts, p.evmAuxStore, + p.blockStore, + state, + start, + end, + p.filter.EthBlockFilter, + readReceipts, + p.evmAuxStore, + resolveAccountToLocalAddr, ) if err != nil { return p, nil, err diff --git a/eth/polls/polls_test.go b/eth/polls/polls_test.go index a2168b922e..d0c8fff31b 100644 --- a/eth/polls/polls_test.go +++ b/eth/polls/polls_test.go @@ -7,7 +7,12 @@ import ( "sync" "testing" + "github.com/loomnetwork/go-loom/plugin/contractpb" + "github.com/pkg/errors" + "github.com/loomnetwork/loomchain/auth" + "github.com/loomnetwork/loomchain/log" + "github.com/loomnetwork/loomchain/plugin" "github.com/loomnetwork/loomchain/rpc/eth" "github.com/loomnetwork/loomchain/vm" @@ -26,6 +31,7 @@ import ( var ( addr1 = loom.MustParseAddress("chain:0xb16a379ec18d4093666f8f38b11a3071c920207d") contract = loom.MustParseAddress("chain:0x5cecd1f7261e1f4c684e297be3edf03b825e01c4") + authCfg = &auth.Config{} ) const ( @@ -55,7 +61,7 @@ func TestLogPoll(t *testing.T) { require.NoError(t, err) state5 := common.MockStateAt(state, uint64(5)) - result, err := sub.LegacyPoll(state5, id, receiptHandler) + result, err := sub.LegacyPoll(state5, id, receiptHandler, resolveAccountToLocalAddr) require.NoError(t, err) var envolope types.EthFilterEnvelope var logs *types.EthFilterLogList @@ -65,7 +71,7 @@ func TestLogPoll(t *testing.T) { require.Equal(t, 1, len(logs.EthBlockLogs), "wrong number of logs returned") require.Equal(t, "height4", string(logs.EthBlockLogs[0].Data)) state40 := common.MockStateAt(state, uint64(40)) - result, err = sub.LegacyPoll(state40, id, receiptHandler) + result, err = sub.LegacyPoll(state40, id, receiptHandler, resolveAccountToLocalAddr) require.NoError(t, err) require.NoError(t, proto.Unmarshal(result, &envolope), "unmarshalling EthFilterEnvelope") logs = envolope.GetEthFilterLogList() @@ -76,7 +82,7 @@ func TestLogPoll(t *testing.T) { require.Equal(t, "height30", string(logs.EthBlockLogs[2].Data)) state50 := common.MockStateAt(state, uint64(50)) - result, err = sub.LegacyPoll(state50, id, receiptHandler) + result, err = sub.LegacyPoll(state50, id, receiptHandler, resolveAccountToLocalAddr) require.NoError(t, err) require.NoError(t, proto.Unmarshal(result, &envolope), "unmarshalling EthFilterEnvelope") logs = envolope.GetEthFilterLogList() @@ -84,7 +90,7 @@ func TestLogPoll(t *testing.T) { require.Equal(t, 0, len(logs.EthBlockLogs), "wrong number of logs returned") state60 := common.MockStateAt(state, uint64(60)) sub.Remove(id) - _, err = sub.LegacyPoll(state60, id, receiptHandler) + _, err = sub.LegacyPoll(state60, id, receiptHandler, resolveAccountToLocalAddr) require.Error(t, err, "subscription not removed") require.NoError(t, receiptHandler.Close()) evmAuxStore.ClearData() @@ -110,7 +116,7 @@ func testLegacyTxPoll(t *testing.T) { var envolope types.EthFilterEnvelope var txHashes *types.EthTxHashList state27 := common.MockStateAt(state, uint64(27)) - result, err := sub.LegacyPoll(state27, id, receiptHandler) + result, err := sub.LegacyPoll(state27, id, receiptHandler, resolveAccountToLocalAddr) require.NoError(t, err) require.NoError(t, proto.Unmarshal(result, &envolope), "unmarshalling EthFilterEnvelope") @@ -119,7 +125,7 @@ func testLegacyTxPoll(t *testing.T) { require.Equal(t, 2, len(txHashes.EthTxHash), "wrong number of logs returned") state50 := common.MockStateAt(state, uint64(50)) - result, err = sub.LegacyPoll(state50, id, receiptHandler) + result, err = sub.LegacyPoll(state50, id, receiptHandler, resolveAccountToLocalAddr) require.NoError(t, err) require.NoError(t, proto.Unmarshal(result, &envolope), "unmarshalling EthFilterEnvelope") @@ -129,7 +135,7 @@ func testLegacyTxPoll(t *testing.T) { state60 := common.MockStateAt(state, uint64(60)) sub.Remove(id) - _, err = sub.LegacyPoll(state60, id, receiptHandler) + _, err = sub.LegacyPoll(state60, id, receiptHandler, resolveAccountToLocalAddr) require.Error(t, err, "subscription not removed") require.NoError(t, receiptHandler.Close()) } @@ -147,7 +153,7 @@ func testTxPoll(t *testing.T) { id := sub.AddTxPoll(uint64(5)) state27 := common.MockStateAt(state, uint64(27)) - result, err := sub.Poll(state27, id, receiptHandler) + result, err := sub.Poll(state27, id, receiptHandler, resolveAccountToLocalAddr) require.NoError(t, err) require.NotEqual(t, nil, result) data, ok := result.([]eth.Data) @@ -155,7 +161,7 @@ func testTxPoll(t *testing.T) { require.Equal(t, 2, len(data), "wrong number of logs returned") state50 := common.MockStateAt(state, uint64(50)) - result, err = sub.Poll(state50, id, receiptHandler) + result, err = sub.Poll(state50, id, receiptHandler, resolveAccountToLocalAddr) require.NoError(t, err) require.NotEqual(t, nil, result) data, ok = result.([]eth.Data) @@ -163,7 +169,7 @@ func testTxPoll(t *testing.T) { require.Equal(t, 1, len(data), "wrong number of logs returned") state105 := common.MockStateAt(state, uint64(105)) - result, err = sub.Poll(state105, id, receiptHandler) + result, err = sub.Poll(state105, id, receiptHandler, resolveAccountToLocalAddr) require.NoError(t, err) require.NotEqual(t, nil, result) data, ok = result.([]eth.Data) @@ -171,7 +177,7 @@ func testTxPoll(t *testing.T) { require.Equal(t, 5, len(data), "wrong number of logs returned") state115 := common.MockStateAt(state, uint64(115)) - result, err = sub.Poll(state115, id, receiptHandler) + result, err = sub.Poll(state115, id, receiptHandler, resolveAccountToLocalAddr) require.NoError(t, err) require.NotEqual(t, nil, result) data, ok = result.([]eth.Data) @@ -179,7 +185,7 @@ func testTxPoll(t *testing.T) { require.Equal(t, 10, len(data), "wrong number of logs returned") state140 := common.MockStateAt(state, uint64(140)) - result, err = sub.Poll(state140, id, receiptHandler) + result, err = sub.Poll(state140, id, receiptHandler, resolveAccountToLocalAddr) require.NoError(t, err) require.NotEqual(t, nil, result) data, ok = result.([]eth.Data) @@ -192,7 +198,7 @@ func testTxPoll(t *testing.T) { wg.Add(2) go func(s *EthSubscriptions) { defer wg.Done() - result, err = s.Poll(state220, id, receiptHandler) + result, err = s.Poll(state220, id, receiptHandler, resolveAccountToLocalAddr) }(sub) go func(s *EthSubscriptions) { defer wg.Done() @@ -200,7 +206,7 @@ func testTxPoll(t *testing.T) { }(sub) wg.Wait() - result, err = sub.Poll(state220, id, receiptHandler) + result, err = sub.Poll(state220, id, receiptHandler, resolveAccountToLocalAddr) require.Error(t, err, "subscription not removed") require.NoError(t, receiptHandler.Close()) } @@ -228,7 +234,7 @@ func testTimeout(t *testing.T, version handler.ReceiptHandlerVersion) { state5 := common.MockStateAt(state, uint64(5)) _ = sub.AddTxPoll(uint64(5)) - result, err := sub.LegacyPoll(state5, id, receiptHandler) + result, err := sub.LegacyPoll(state5, id, receiptHandler, resolveAccountToLocalAddr) require.NoError(t, err) require.NoError(t, proto.Unmarshal(result, &envolope), "unmarshalling EthFilterEnvelope") txHashes = envolope.GetEthTxHashList() @@ -238,7 +244,7 @@ func testTimeout(t *testing.T, version handler.ReceiptHandlerVersion) { state12 := common.MockStateAt(state, uint64(12)) _ = sub.AddTxPoll(uint64(12)) - result, err = sub.LegacyPoll(state12, id, receiptHandler) + result, err = sub.LegacyPoll(state12, id, receiptHandler, resolveAccountToLocalAddr) require.NoError(t, err) require.NoError(t, proto.Unmarshal(result, &envolope), "unmarshalling EthFilterEnvelope") txHashes = envolope.GetEthTxHashList() @@ -248,13 +254,13 @@ func testTimeout(t *testing.T, version handler.ReceiptHandlerVersion) { state40 := common.MockStateAt(state, uint64(40)) _ = sub.AddTxPoll(uint64(40)) - result, err = sub.LegacyPoll(state40, id, receiptHandler) + result, err = sub.LegacyPoll(state40, id, receiptHandler, resolveAccountToLocalAddr) require.Error(t, err, "poll did not timed out") require.NoError(t, receiptHandler.Close()) } func makeMockState(t *testing.T, receiptHandler *handler.ReceiptHandler, blockStore *store.MockBlockStore) loomchain.State { - state := common.MockState(0) + state := common.MockState(0, "") mockEvent4 := []*types.EventData{ { @@ -410,3 +416,32 @@ func mockSignedTx(t *testing.T, id uint32, to loom.Address, from loom.Address, d return signedTx } + +func resolveAccountToLocalAddr(state loomchain.State, addr loom.Address) (loom.Address, error) { + return auth.ResolveAccountAddress(addr, state, authCfg, createAddressMapperCtx) +} + +func createAddressMapperCtx(state loomchain.State) (contractpb.StaticContext, error) { + return createStaticContractCtx(state, "addressmapper") +} + +func createStaticContractCtx(state loomchain.State, name string) (contractpb.StaticContext, error) { + ctx, err := plugin.NewInternalContractContext( + name, + plugin.NewPluginVM( + nil, //s.Loader, + state, + nil, //s.CreateRegistry(state), + nil, // event handler + log.Default, + nil, //s.NewABMFactory, + nil, // receipt writer + nil, // receipt reader + ), + true, + ) + if err != nil { + return nil, errors.Wrapf(err, "failed to create %s context", name) + } + return ctx, nil +} diff --git a/eth/polls/polltx.go b/eth/polls/polltx.go index e1161ddcfb..0ec0ffefa5 100644 --- a/eth/polls/polltx.go +++ b/eth/polls/polltx.go @@ -4,8 +4,10 @@ package polls import ( "github.com/gogo/protobuf/proto" + "github.com/loomnetwork/go-loom" "github.com/loomnetwork/go-loom/plugin/types" "github.com/loomnetwork/loomchain" + "github.com/loomnetwork/loomchain/rpc/eth" "github.com/loomnetwork/loomchain/store" evmaux "github.com/loomnetwork/loomchain/store/evm_aux" @@ -30,12 +32,15 @@ func NewEthTxPoll(height uint64, evmAuxStore *evmaux.EvmAuxStore, blockStore sto } func (p *EthTxPoll) Poll( - state loomchain.ReadOnlyState, id string, readReceipt loomchain.ReadReceiptHandler, + state loomchain.State, + id string, + readReceipts loomchain.ReadReceiptHandler, + _ func(loomchain.State, loom.Address) (loom.Address, error), ) (EthPoll, interface{}, error) { if p.lastBlockRead+1 > uint64(state.Block().Height) { return p, nil, nil } - lastBlock, results, err := getTxHashes(state, p.lastBlockRead, readReceipt, p.evmAuxStore) + lastBlock, results, err := getTxHashes(state, p.lastBlockRead, readReceipts, p.evmAuxStore) if err != nil { return p, nil, nil } @@ -44,13 +49,16 @@ func (p *EthTxPoll) Poll( } func (p *EthTxPoll) AllLogs( - state loomchain.ReadOnlyState, id string, readReceipts loomchain.ReadReceiptHandler, + state loomchain.State, + id string, + readReceipts loomchain.ReadReceiptHandler, + _ func(loomchain.State, loom.Address) (loom.Address, error), ) (interface{}, error) { _, results, err := getTxHashes(state, p.startBlock, readReceipts, p.evmAuxStore) return eth.EncBytesArray(results), err } -func getTxHashes(state loomchain.ReadOnlyState, lastBlockRead uint64, +func getTxHashes(state loomchain.State, lastBlockRead uint64, readReceipts loomchain.ReadReceiptHandler, evmAuxStore *evmaux.EvmAuxStore) (uint64, [][]byte, error) { var txHashes [][]byte for height := lastBlockRead + 1; height < uint64(state.Block().Height); height++ { @@ -68,7 +76,10 @@ func getTxHashes(state loomchain.ReadOnlyState, lastBlockRead uint64, } func (p *EthTxPoll) LegacyPoll( - state loomchain.ReadOnlyState, id string, readReceipts loomchain.ReadReceiptHandler, + state loomchain.State, + id string, + readReceipts loomchain.ReadReceiptHandler, + _ func(loomchain.State, loom.Address) (loom.Address, error), ) (EthPoll, []byte, error) { if p.lastBlockRead+1 > uint64(state.Block().Height) { return p, nil, nil diff --git a/eth/query/block.go b/eth/query/block.go index ba73b4ef91..f74c8c1044 100644 --- a/eth/query/block.go +++ b/eth/query/block.go @@ -9,16 +9,18 @@ import ( etypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rlp" "github.com/gogo/protobuf/proto" + "github.com/loomnetwork/go-loom" "github.com/loomnetwork/go-loom/auth" "github.com/loomnetwork/go-loom/plugin/types" ltypes "github.com/loomnetwork/go-loom/types" "github.com/loomnetwork/go-loom/vm" + "github.com/pkg/errors" + ctypes "github.com/tendermint/tendermint/rpc/core/types" + "github.com/loomnetwork/loomchain" "github.com/loomnetwork/loomchain/rpc/eth" "github.com/loomnetwork/loomchain/store" evmaux "github.com/loomnetwork/loomchain/store/evm_aux" - "github.com/pkg/errors" - ctypes "github.com/tendermint/tendermint/rpc/core/types" ) var ( @@ -27,10 +29,11 @@ var ( func GetBlockByNumber( blockStore store.BlockStore, - state loomchain.ReadOnlyState, + state loomchain.State, height int64, full bool, evmAuxStore *evmaux.EvmAuxStore, + resolveAccountToLocalAddr func(loomchain.State, loom.Address) (loom.Address, error), ) (resp eth.JsonBlockObject, err error) { // todo make information about pending block available if height > state.Block().Height { @@ -99,7 +102,14 @@ func GetBlockByNumber( // TODO: When full is false this code ends up doing a bunch of useless encoding, should refactor // things a bit. - txObj, _, err := GetTxObjectFromBlockResult(blockResult, txResultData, int64(index), evmAuxStore) + txObj, _, err := GetTxObjectFromBlockResult( + blockResult, + txResultData, + int64(index), + evmAuxStore, + state, + resolveAccountToLocalAddr, + ) if err != nil { return resp, errors.Wrapf(err, "failed to decode tx, hash %X", tx.Hash()) } @@ -119,7 +129,12 @@ func GetBlockByNumber( } func GetTxObjectFromBlockResult( - blockResult *ctypes.ResultBlock, txResultData []byte, txIndex int64, evmAuxStore *evmaux.EvmAuxStore, + blockResult *ctypes.ResultBlock, + txResultData []byte, + txIndex int64, + evmAuxStore *evmaux.EvmAuxStore, + state loomchain.State, + resolveAccountToLocalAddr func(loomchain.State, loom.Address) (loom.Address, error), ) (eth.JsonTxObject, *eth.Data, error) { tx := blockResult.Block.Data.Txs[txIndex] var contractAddress *eth.Data @@ -153,10 +168,12 @@ func GetTxObjectFromBlockResult( if err := proto.Unmarshal(txTx.Data, &msg); err != nil { return eth.GetEmptyTxObject(), nil, err } - // TODO: For EVM txs if this is a foreign address map it to a local address because the EVM tx - // receipt will have the local address, so the receipt & tx should have matching caller - // addresses. - txObj.From = eth.EncAddress(msg.From) + + addr, err := resolveAccountToLocalAddr(state, loom.UnmarshalAddressPB(msg.From)) + if err != nil { + return eth.GetEmptyTxObject(), nil, err + } + txObj.From = eth.EncAddress(addr.MarshalPB()) var input []byte switch ltypes.TxID(txTx.Id) { diff --git a/eth/query/eth.go b/eth/query/eth.go index c325c983cf..eefaa24ebf 100644 --- a/eth/query/eth.go +++ b/eth/query/eth.go @@ -5,6 +5,7 @@ package query import ( "fmt" + "github.com/loomnetwork/go-loom" "github.com/loomnetwork/loomchain/eth/bloom" "github.com/loomnetwork/loomchain/receipts/common" "github.com/loomnetwork/loomchain/rpc/eth" @@ -20,8 +21,12 @@ import ( ) func QueryChain( - blockStore store.BlockStore, state loomchain.ReadOnlyState, ethFilter eth.EthFilter, - readReceipts loomchain.ReadReceiptHandler, evmAuxStore *evmaux.EvmAuxStore, maxBlockRange uint64, + blockStore store.BlockStore, + state loomchain.State, + ethFilter eth.EthFilter, + readReceipts loomchain.ReadReceiptHandler, + evmAuxStore *evmaux.EvmAuxStore, maxBlockRange uint64, + resolveAccountToLocalAddr func(loomchain.State, loom.Address) (loom.Address, error), ) ([]*ptypes.EthFilterLog, error) { start, err := eth.DecBlockHeight(state.Block().Height, ethFilter.FromBlock) if err != nil { @@ -39,12 +44,26 @@ func QueryChain( return nil, fmt.Errorf("max allowed block range (%d) exceeded", maxBlockRange) } - return GetBlockLogRange(blockStore, state, start, end, ethFilter.EthBlockFilter, readReceipts, evmAuxStore) + return GetBlockLogRange( + blockStore, + state, + start, + end, + ethFilter.EthBlockFilter, + readReceipts, + evmAuxStore, + resolveAccountToLocalAddr, + ) } func DeprecatedQueryChain( - query string, blockStore store.BlockStore, state loomchain.ReadOnlyState, - readReceipts loomchain.ReadReceiptHandler, evmAuxStore *evmaux.EvmAuxStore, maxBlockRange uint64, + query string, + blockStore store.BlockStore, + state loomchain.State, + readReceipts loomchain.ReadReceiptHandler, + evmAuxStore *evmaux.EvmAuxStore, + maxBlockRange uint64, + resolveAccountToLocalAddr func(loomchain.State, loom.Address) (loom.Address, error), ) ([]byte, error) { ethFilter, err := utils.UnmarshalEthFilter([]byte(query)) @@ -68,7 +87,15 @@ func DeprecatedQueryChain( return nil, fmt.Errorf("max allowed block range (%d) exceeded", maxBlockRange) } - eventLogs, err := GetBlockLogRange(blockStore, state, start, end, ethFilter.EthBlockFilter, readReceipts, evmAuxStore) + eventLogs, err := GetBlockLogRange( + blockStore, + state, + start, + end, + ethFilter.EthBlockFilter, + readReceipts, evmAuxStore, + resolveAccountToLocalAddr, + ) if err != nil { return nil, err } @@ -78,11 +105,12 @@ func DeprecatedQueryChain( func GetBlockLogRange( blockStore store.BlockStore, - state loomchain.ReadOnlyState, + state loomchain.State, from, to uint64, ethFilter eth.EthBlockFilter, readReceipts loomchain.ReadReceiptHandler, evmAuxStore *evmaux.EvmAuxStore, + resolveAccountToLocalAddr func(loomchain.State, loom.Address) (loom.Address, error), ) ([]*ptypes.EthFilterLog, error) { if from > to { return nil, fmt.Errorf("from block (%v) greater than to block (%v)", from, to) @@ -90,7 +118,15 @@ func GetBlockLogRange( eventLogs := []*ptypes.EthFilterLog{} for height := from; height <= to; height++ { - blockLogs, err := getBlockLogs(blockStore, state, ethFilter, height, readReceipts, evmAuxStore) + blockLogs, err := getBlockLogs( + blockStore, + state, + ethFilter, + height, + readReceipts, + evmAuxStore, + resolveAccountToLocalAddr, + ) if err != nil { return nil, err } @@ -101,17 +137,25 @@ func GetBlockLogRange( func getBlockLogs( blockStore store.BlockStore, - state loomchain.ReadOnlyState, + state loomchain.State, ethFilter eth.EthBlockFilter, height uint64, readReceipts loomchain.ReadReceiptHandler, evmAuxStore *evmaux.EvmAuxStore, + resolveAccountToLocalAddr func(loomchain.State, loom.Address) (loom.Address, error), ) ([]*ptypes.EthFilterLog, error) { bloomFilter := evmAuxStore.GetBloomFilter(height) if len(bloomFilter) > 0 { if MatchBloomFilter(ethFilter, bloomFilter) { - txObject, err := GetBlockByNumber(blockStore, state, int64(height), false, evmAuxStore) + txObject, err := GetBlockByNumber( + blockStore, + state, + int64(height), + false, + evmAuxStore, + resolveAccountToLocalAddr, + ) if err != nil { return nil, errors.Wrapf(err, "failed to get block at height %d", height) } diff --git a/eth/query/noevm.go b/eth/query/noevm.go index 46eb8a57b6..0df1369b34 100644 --- a/eth/query/noevm.go +++ b/eth/query/noevm.go @@ -14,18 +14,33 @@ import ( func DeprecatedQueryChain( _ string, _ store.BlockStore, _ loomchain.ReadOnlyState, _ loomchain.ReadReceiptHandler, _ *evmaux.EvmAuxStore, _ uint64, + _ *auth.Config, + _ func(state loomchain.State) (contractpb.StaticContext, error), ) ([]byte, error) { return nil, nil } func GetBlockByNumber( - _ store.BlockStore, _ loomchain.ReadOnlyState, _ int64, _ bool, _ *evmaux.EvmAuxStore, -) (eth.JsonBlockObject, error) { + _ store.BlockStore, + _ loomchain.ReadOnlyState, + _ int64, + _ bool, + _ *evmaux.EvmAuxStore, + _ *lauth.Config, + _ func(state loomchain.State) (contractpb.StaticContext, error), +) (resp eth.JsonBlockObject, err error) { return eth.JsonBlockObject{}, nil } func GetTxObjectFromBlockResult( - _ *ctypes.ResultBlock, _ []byte, _ int64, _ *evmaux.EvmAuxStore, + _ *ctypes.ResultBlock, + _ []byte, + _ int64, + _ *evmaux.EvmAuxStore, + _ loomchain.State, + _ *lauth.Config, + _ func(state loomchain.State) (contractpb.StaticContext, error), + ) (eth.JsonTxObject, *eth.Data, error) { return eth.JsonTxObject{}, nil, nil } @@ -69,6 +84,8 @@ func GetTxByBlockAndIndex(_ store.BlockStore, _, _ uint64, _ *evmaux.EvmAuxStore func QueryChain( _ store.BlockStore, _ loomchain.ReadOnlyState, _ eth.EthFilter, _ loomchain.ReadReceiptHandler, _ *evmaux.EvmAuxStore, _ uint64, + _ *auth.Config, + _ func(state loomchain.State) (contractpb.StaticContext, error), ) ([]*types.EthFilterLog, error) { return nil, nil } diff --git a/eth/query/query_test.go b/eth/query/query_test.go index f7884b5388..a6ce808b72 100644 --- a/eth/query/query_test.go +++ b/eth/query/query_test.go @@ -11,25 +11,33 @@ import ( "github.com/gogo/protobuf/proto" "github.com/loomnetwork/go-loom" "github.com/loomnetwork/go-loom/auth" + "github.com/loomnetwork/go-loom/plugin/contractpb" "github.com/loomnetwork/go-loom/plugin/types" ltypes "github.com/loomnetwork/go-loom/types" "github.com/loomnetwork/go-loom/vm" + "github.com/pkg/errors" + "github.com/stretchr/testify/require" + ctypes "github.com/tendermint/tendermint/rpc/core/types" + ttypes "github.com/tendermint/tendermint/types" + "github.com/loomnetwork/loomchain" + lauth "github.com/loomnetwork/loomchain/auth" "github.com/loomnetwork/loomchain/eth/bloom" "github.com/loomnetwork/loomchain/eth/utils" "github.com/loomnetwork/loomchain/events" + "github.com/loomnetwork/loomchain/features" + "github.com/loomnetwork/loomchain/log" + "github.com/loomnetwork/loomchain/plugin" "github.com/loomnetwork/loomchain/receipts/common" "github.com/loomnetwork/loomchain/receipts/handler" "github.com/loomnetwork/loomchain/rpc/eth" "github.com/loomnetwork/loomchain/store" - "github.com/stretchr/testify/require" - ctypes "github.com/tendermint/tendermint/rpc/core/types" - ttypes "github.com/tendermint/tendermint/types" ) var ( - addr1 = loom.MustParseAddress("chain:0xb16a379ec18d4093666f8f38b11a3071c920207d") - addr2 = loom.MustParseAddress("chain:0x5cecd1f7261e1f4c684e297be3edf03b825e01c4") + addr1 = loom.MustParseAddress("chain:0xb16a379ec18d4093666f8f38b11a3071c920207d") + addr2 = loom.MustParseAddress("chain:0x5cecd1f7261e1f4c684e297be3edf03b825e01c4") + authCfg = &lauth.Config{} ) func getFilter(fromBlock, toBlock string) string { @@ -45,7 +53,7 @@ func TestQueryChain(t *testing.T) { blockStore := store.NewMockBlockStore() require.NoError(t, err) - state := common.MockState(0) + state := common.MockState(0, "") state4 := common.MockStateAt(state, 4) mockEvent1 := []*types.EventData{ @@ -90,7 +98,15 @@ func TestQueryChain(t *testing.T) { blockStore.SetBlock(store.MockBlock(20, evmTxHash, [][]byte{tx})) state30 := common.MockStateAt(state, uint64(30)) - result, err := DeprecatedQueryChain(getFilter("1", "20"), blockStore, state30, receiptHandler, evmAuxStore, 100000) + result, err := DeprecatedQueryChain( + getFilter("1", "20"), + blockStore, + state30, + receiptHandler, + evmAuxStore, + 100000, + resolveAccountToLocalAddr, + ) require.NoError(t, err, "error query chain, filter is %s", getFilter("1", "20")) var logs types.EthFilterLogList require.NoError(t, proto.Unmarshal(result, &logs), "unmarshalling EthFilterLogList") @@ -100,9 +116,25 @@ func TestQueryChain(t *testing.T) { require.NoError(t, err) ethFilter2, err := utils.UnmarshalEthFilter([]byte(getFilter("1", "10"))) require.NoError(t, err) - filterLogs1, err := QueryChain(blockStore, state30, ethFilter1, receiptHandler, evmAuxStore, 100000) + filterLogs1, err := QueryChain( + blockStore, + state30, + ethFilter1, + receiptHandler, + evmAuxStore, + 100000, + resolveAccountToLocalAddr, + ) require.NoError(t, err, "error query chain, filter is %s", ethFilter1) - filterLogs2, err := QueryChain(blockStore, state30, ethFilter2, receiptHandler, evmAuxStore, 100000) + filterLogs2, err := QueryChain( + blockStore, + state30, + ethFilter1, + receiptHandler, + evmAuxStore, + 100000, + resolveAccountToLocalAddr, + ) require.NoError(t, err, "error query chain, filter is %s", ethFilter2) require.Equal(t, 2, len(filterLogs1)+len(filterLogs2), "wrong number of logs returned") @@ -213,7 +245,7 @@ func TestGetLogs(t *testing.T) { }, } - state := common.MockState(1) + state := common.MockState(1, "") state32 := common.MockStateAt(state, 32) txHash, err := writer.CacheReceipt(state32, addr1, addr2, testEventsG, nil, []byte{}) require.NoError(t, err) @@ -241,6 +273,16 @@ func TestGetLogs(t *testing.T) { } func TestDupEvmTxHash(t *testing.T) { + authCfg := &lauth.Config{ + Chains: map[string]lauth.ChainConfig{ + "eth": lauth.ChainConfig{TxType: "eth", AccountType: 1}, + }, + } + resolveAccountToLocalAddr := func(state loomchain.State, addr loom.Address) (loom.Address, error) { + return lauth.ResolveAccountAddress(addr, state, authCfg, createAddressMapperCtx) + } + state := common.MockState(1, "default") + state.SetFeature(features.AuthSigTxFeaturePrefix+"eth", true) blockTxHash := getRandomTxHash() txHash1 := getRandomTxHash() // DeployEVMTx that has dup EVM Tx Hash txHash2 := getRandomTxHash() // CallEVMTx that has dup EVM Tx Hash @@ -299,24 +341,52 @@ func TestDupEvmTxHash(t *testing.T) { txResultData4 := txHash4 // txhash1 is dup, so the returned hash must not be equal - txObj, _, err := GetTxObjectFromBlockResult(blockResultDeployTx, txResultData1, int64(0), evmAuxStore) + txObj, _, err := GetTxObjectFromBlockResult( + blockResultDeployTx, + txResultData1, + int64(0), + evmAuxStore, + state, + resolveAccountToLocalAddr, + ) require.NoError(t, err) require.NotEqual(t, string(txObj.Hash), string(eth.EncBytes(txHash1))) require.Equal(t, string(txObj.Hash), string(eth.EncBytes(ttypes.Tx(signedDeployTxBytes).Hash()))) // txhash2 is dup, so the returned hash must not be equal - txObj, _, err = GetTxObjectFromBlockResult(blockResultCallTx, txResultData2, int64(0), evmAuxStore) + txObj, _, err = GetTxObjectFromBlockResult( + blockResultCallTx, + txResultData2, + int64(0), + evmAuxStore, + state, + resolveAccountToLocalAddr, + ) require.NoError(t, err) require.NotEqual(t, string(txObj.Hash), string(eth.EncBytes(txHash2))) require.Equal(t, string(txObj.Hash), string(eth.EncBytes(ttypes.Tx(signedCallTxBytes).Hash()))) // txhash3 is unique, so the returned hash must be equal - txObj, _, err = GetTxObjectFromBlockResult(blockResultDeployTx, txResultData3, int64(0), evmAuxStore) + txObj, _, err = GetTxObjectFromBlockResult( + blockResultDeployTx, + txResultData3, + int64(0), + evmAuxStore, + state, + resolveAccountToLocalAddr, + ) require.NoError(t, err) require.Equal(t, string(txObj.Hash), string(eth.EncBytes(txHash3))) // txhash4 is unique, so the returned hash must be equal - txObj, _, err = GetTxObjectFromBlockResult(blockResultCallTx, txResultData4, int64(0), evmAuxStore) + txObj, _, err = GetTxObjectFromBlockResult( + blockResultCallTx, + txResultData4, + int64(0), + evmAuxStore, + state, + resolveAccountToLocalAddr, + ) require.NoError(t, err) require.Equal(t, string(txObj.Hash), string(eth.EncBytes(txHash4))) } @@ -362,6 +432,36 @@ func mockSignedTx(t *testing.T, id ltypes.TxID, to loom.Address, from loom.Addre return signedTx } +func resolveAccountToLocalAddr(state loomchain.State, addr loom.Address) (loom.Address, error) { + return lauth.ResolveAccountAddress(addr, state, authCfg, createAddressMapperCtx) +} + +// Attempts to construct the context of the Address Mapper contract. +func createAddressMapperCtx(state loomchain.State) (contractpb.StaticContext, error) { + return createStaticContractCtx(state, "addressmapper") +} + +func createStaticContractCtx(state loomchain.State, name string) (contractpb.StaticContext, error) { + ctx, err := plugin.NewInternalContractContext( + name, + plugin.NewPluginVM( + nil, //s.Loader, + state, + nil, //s.CreateRegistry(state), + nil, // event handler + log.Default, + nil, //s.NewABMFactory, + nil, // receipt writer + nil, // receipt reader + ), + true, + ) + if err != nil { + return nil, errors.Wrapf(err, "failed to create %s context", name) + } + return ctx, nil +} + func mockDeployResponse(txHash []byte) []byte { deployResponseData, err := proto.Marshal(&vm.DeployResponseData{ TxHash: txHash, diff --git a/eth/query/tx.go b/eth/query/tx.go index 2937f18eec..6cbe88df63 100644 --- a/eth/query/tx.go +++ b/eth/query/tx.go @@ -4,7 +4,6 @@ package query import ( "github.com/gogo/protobuf/proto" - "github.com/pkg/errors" "github.com/loomnetwork/go-loom" @@ -21,19 +20,30 @@ func GetTxByHash( txHash []byte, readReceipts loomchain.ReadReceiptHandler, evmAuxStore *evmaux.EvmAuxStore, + state loomchain.State, + resolveAccountToLocalAddr func(loomchain.State, loom.Address) (loom.Address, error), ) (eth.JsonTxObject, error) { txReceipt, err := readReceipts.GetReceipt(txHash) if err != nil { return eth.GetEmptyTxObject(), errors.Wrap(err, "reading receipt") } return GetTxByBlockAndIndex( - blockStore, uint64(txReceipt.BlockNumber), - uint64(txReceipt.TransactionIndex), evmAuxStore, + blockStore, + uint64(txReceipt.BlockNumber), + uint64(txReceipt.TransactionIndex), + evmAuxStore, + state, + resolveAccountToLocalAddr, ) } func GetTxByBlockAndIndex( - blockStore store.BlockStore, height, index uint64, evmAuxStore *evmaux.EvmAuxStore, + blockStore store.BlockStore, + height, + index uint64, + evmAuxStore *evmaux.EvmAuxStore, + state loomchain.State, + resolveAccountToLocalAddr func(loomchain.State, loom.Address) (loom.Address, error), ) (eth.JsonTxObject, error) { iHeight := int64(height) @@ -53,7 +63,14 @@ func GetTxByBlockAndIndex( err, "failed to find result of tx %X", blockResult.Block.Data.Txs[index].Hash()) } - txObj, _, err := GetTxObjectFromBlockResult(blockResult, txResult.TxResult.Data, int64(index), evmAuxStore) + txObj, _, err := GetTxObjectFromBlockResult( + blockResult, + txResult.TxResult.Data, + int64(index), + evmAuxStore, + state, + resolveAccountToLocalAddr, + ) if err != nil { return eth.GetEmptyTxObject(), err } diff --git a/plugin/vm_test.go b/plugin/vm_test.go index f089fab0e3..f2d90b6f0a 100644 --- a/plugin/vm_test.go +++ b/plugin/vm_test.go @@ -213,7 +213,7 @@ func TestGetEvmTxReceipt(t *testing.T) { ) require.NoError(t, err) - state := rcommon.MockState(1) + state := rcommon.MockState(1, "") txHash, err := receiptHandler.CacheReceipt(state, vmAddr1, vmAddr2, []*ptypes.EventData{}, nil, []byte{}) require.NoError(t, err) receiptHandler.CommitCurrentReceipt() @@ -242,7 +242,7 @@ func TestGetEvmTxReceiptNoCommit(t *testing.T) { evmAuxStore, ) - state := rcommon.MockState(1) + state := rcommon.MockState(1, "") txHash, err := receiptHandler.CacheReceipt(state, vmAddr1, vmAddr2, []*ptypes.EventData{}, nil, []byte{}) require.NoError(t, err) diff --git a/receipts/common/test_helper.go b/receipts/common/test_helper.go index 8e2979c9e6..a0441d35de 100644 --- a/receipts/common/test_helper.go +++ b/receipts/common/test_helper.go @@ -51,9 +51,10 @@ func MakeDummyReceipt(t *testing.T, block, txNum uint64, events []*types.EventDa return &dummy } -func MockState(height uint64) loomchain.State { +func MockState(height uint64, chainId string) loomchain.State { header := abci.Header{} header.Height = int64(height) + header.ChainID = chainId return loomchain.NewStoreState(context.Background(), store.NewMemStore(), header, nil, nil) } diff --git a/receipts/handler/handler_test.go b/receipts/handler/handler_test.go index fc0b1d3f27..bc2657d8bb 100644 --- a/receipts/handler/handler_test.go +++ b/receipts/handler/handler_test.go @@ -22,7 +22,7 @@ var ( func TestReceiptsHandlerChain(t *testing.T) { height := uint64(1) - state := common.MockState(height) + state := common.MockState(height, "") evmAuxStore, err := common.NewMockEvmAuxStore() require.NoError(t, err) diff --git a/rpc/query_server.go b/rpc/query_server.go index 4bc726c0c7..26b25f9a8f 100755 --- a/rpc/query_server.go +++ b/rpc/query_server.go @@ -379,6 +379,10 @@ func (s *QueryServer) createStaticContractCtx(state loomchain.State, name string return ctx, nil } +func (s *QueryServer) resolveAccountToLocalAddr(state loomchain.State, addr loom.Address) (loom.Address, error) { + return auth.ResolveAccountAddress(addr, state, s.AuthCfg, s.createAddressMapperCtx) +} + // Nonce returns the nonce of the last committed tx sent by the given account. // NOTE: Either the key or the account must be provided. The account (if not empty) is used in // preference to the key. @@ -648,8 +652,13 @@ func (s *QueryServer) GetEvmLogs(filter string) ([]byte, error) { defer snapshot.Release() return query.DeprecatedQueryChain( - filter, s.BlockStore, snapshot, s.ReceiptHandlerProvider.Reader(), s.EvmAuxStore, + filter, + s.BlockStore, + snapshot, + s.ReceiptHandlerProvider.Reader(), + s.EvmAuxStore, s.Web3Cfg.GetLogsMaxBlockRange, + s.resolveAccountToLocalAddr, ) } @@ -687,7 +696,12 @@ func (s *QueryServer) GetEvmFilterChanges(id string) ([]byte, error) { // TODO: Reading from the TM block store could take a while, might be more efficient to release // the current snapshot and get a new one after pulling out whatever we need from the TM // block store. - return s.EthPolls.LegacyPoll(snapshot, id, s.ReceiptHandlerProvider.Reader()) + return s.EthPolls.LegacyPoll( + snapshot, + id, + s.ReceiptHandlerProvider.Reader(), + s.resolveAccountToLocalAddr, + ) } // Forget the filter. @@ -774,7 +788,14 @@ func (s *QueryServer) EthGetBlockByNumber(block eth.BlockHeight, full bool) (res // TODO: Reading from the TM block store could take a while, might be more efficient to release // the current snapshot and get a new one after pulling out whatever we need from the TM // block store. - blockResult, err := query.GetBlockByNumber(s.BlockStore, snapshot, int64(height), full, s.EvmAuxStore) + blockResult, err := query.GetBlockByNumber( + s.BlockStore, + snapshot, + int64(height), + full, + s.EvmAuxStore, + s.resolveAccountToLocalAddr, + ) if err != nil { return nil, err } @@ -799,7 +820,15 @@ func (s *QueryServer) EthGetTransactionReceipt(hash eth.Data) (*eth.JsonTxReceip // TODO: Log the error, this fallback should be happening very rarely so we should probably // setup an alert to detect when this happens. // if the receipt is not found, create it from TxObj - resp, err := getReceiptByTendermintHash(s.BlockStore, r, txHash, s.EvmAuxStore) + snapshot := s.StateProvider.ReadOnlyState() + defer snapshot.Release() + resp, err := getReceiptByTendermintHash( + s.BlockStore, + r, txHash, + s.EvmAuxStore, + snapshot, + s.resolveAccountToLocalAddr, + ) if err != nil { if strings.Contains(errors.Cause(err).Error(), "not found") { // return nil response if cannot find hash @@ -895,7 +924,14 @@ func (s *QueryServer) EthGetBlockByHash(hash eth.Data, full bool) (resp eth.Json snapshot := s.StateProvider.ReadOnlyState() defer snapshot.Release() - return query.GetBlockByNumber(s.BlockStore, snapshot, int64(height), full, s.EvmAuxStore) + return query.GetBlockByNumber( + s.BlockStore, + snapshot, + int64(height), + full, + s.EvmAuxStore, + s.resolveAccountToLocalAddr, + ) } // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gettransactionbyhash @@ -904,8 +940,16 @@ func (s *QueryServer) EthGetTransactionByHash(hash eth.Data) (resp eth.JsonTxObj if err != nil { return resp, err } - - txObj, err := query.GetTxByHash(s.BlockStore, txHash, s.ReceiptHandlerProvider.Reader(), s.EvmAuxStore) + snapshot := s.StateProvider.ReadOnlyState() + defer snapshot.Release() + txObj, err := query.GetTxByHash( + s.BlockStore, + txHash, + s.ReceiptHandlerProvider.Reader(), + s.EvmAuxStore, + snapshot, + s.resolveAccountToLocalAddr, + ) if err != nil { // TODO: Should call r.GetReceipt instead of query.GetTxByHash so we don't have to use this // flimsy error cause checking. @@ -913,7 +957,13 @@ func (s *QueryServer) EthGetTransactionByHash(hash eth.Data) (resp eth.JsonTxObj return resp, err } - txObj, err = getTxByTendermintHash(s.BlockStore, txHash, s.EvmAuxStore) + txObj, err = getTxByTendermintHash( + s.BlockStore, + txHash, + s.EvmAuxStore, + snapshot, + s.resolveAccountToLocalAddr, + ) if err != nil { return resp, errors.Wrapf(err, "failed to find tx with hash %v", txHash) } @@ -939,8 +989,16 @@ func (s *QueryServer) EthGetTransactionByBlockHashAndIndex( if err != nil { return txObj, err } - - return query.GetTxByBlockAndIndex(s.BlockStore, uint64(height), txIndex, s.EvmAuxStore) + snapshot := s.StateProvider.ReadOnlyState() + defer snapshot.Release() + return query.GetTxByBlockAndIndex( + s.BlockStore, + uint64(height), + txIndex, + s.EvmAuxStore, + snapshot, + s.resolveAccountToLocalAddr, + ) } // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gettransactionbyblocknumberandindex @@ -960,7 +1018,14 @@ func (s *QueryServer) EthGetTransactionByBlockNumberAndIndex( if err != nil { return txObj, err } - return query.GetTxByBlockAndIndex(s.BlockStore, height, txIndex, s.EvmAuxStore) + return query.GetTxByBlockAndIndex( + s.BlockStore, + height, + txIndex, + s.EvmAuxStore, + snapshot, + s.resolveAccountToLocalAddr, + ) } /// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getlogs @@ -977,8 +1042,13 @@ func (s *QueryServer) EthGetLogs(filter eth.JsonFilter) (resp []eth.JsonLog, err // the current snapshot and get a new one after pulling out whatever we need from the TM // block store. logs, err := query.QueryChain( - s.BlockStore, snapshot, ethFilter, s.ReceiptHandlerProvider.Reader(), s.EvmAuxStore, + s.BlockStore, + snapshot, + ethFilter, + s.ReceiptHandlerProvider.Reader(), + s.EvmAuxStore, s.Web3Cfg.GetLogsMaxBlockRange, + s.resolveAccountToLocalAddr, ) if err != nil { return resp, err @@ -1014,14 +1084,24 @@ func (s *QueryServer) EthGetFilterChanges(id eth.Quantity) (interface{}, error) snapshot := s.StateProvider.ReadOnlyState() defer snapshot.Release() - return s.EthPolls.Poll(snapshot, string(id), s.ReceiptHandlerProvider.Reader()) + return s.EthPolls.Poll( + snapshot, + string(id), + s.ReceiptHandlerProvider.Reader(), + s.resolveAccountToLocalAddr, + ) } // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getfilterlogs func (s *QueryServer) EthGetFilterLogs(id eth.Quantity) (interface{}, error) { snapshot := s.StateProvider.ReadOnlyState() defer snapshot.Release() - return s.EthPolls.AllLogs(snapshot, string(id), s.ReceiptHandlerProvider.Reader()) + return s.EthPolls.AllLogs( + snapshot, + string(id), + s.ReceiptHandlerProvider.Reader(), + s.resolveAccountToLocalAddr, + ) } // Sets up new filter for polling @@ -1199,7 +1279,11 @@ func (s *QueryServer) getEthAccount(state loomchain.State, address eth.Data) (lo func getReceiptByTendermintHash( blockStore store.BlockStore, - rh loomchain.ReadReceiptHandler, hash []byte, evmAuxStore *evmaux.EvmAuxStore, + rh loomchain.ReadReceiptHandler, + hash []byte, + evmAuxStore *evmaux.EvmAuxStore, + state loomchain.State, + resolveAccountToLocalAddr func(loomchain.State, loom.Address) (loom.Address, error), ) (*eth.JsonTxReceipt, error) { txResults, err := blockStore.GetTxResult(hash) if err != nil { @@ -1210,7 +1294,12 @@ func getReceiptByTendermintHash( return nil, err } txObj, contractAddr, err := query.GetTxObjectFromBlockResult( - blockResult, txResults.TxResult.Data, int64(txResults.Index), evmAuxStore, + blockResult, + txResults.TxResult.Data, + int64(txResults.Index), + evmAuxStore, + state, + resolveAccountToLocalAddr, ) if err != nil { return nil, err @@ -1262,7 +1351,11 @@ func completeReceipt( } func getTxByTendermintHash( - blockStore store.BlockStore, hash []byte, evmAuxStore *evmaux.EvmAuxStore, + blockStore store.BlockStore, + hash []byte, + evmAuxStore *evmaux.EvmAuxStore, + state loomchain.State, + resolveAccountToLocalAddr func(loomchain.State, loom.Address) (loom.Address, error), ) (eth.JsonTxObject, error) { txResults, err := blockStore.GetTxResult(hash) if err != nil { @@ -1273,7 +1366,12 @@ func getTxByTendermintHash( return eth.JsonTxObject{}, err } txObj, _, err := query.GetTxObjectFromBlockResult( - blockResult, txResults.TxResult.Data, int64(txResults.Index), evmAuxStore, + blockResult, + txResults.TxResult.Data, + int64(txResults.Index), + evmAuxStore, + state, + resolveAccountToLocalAddr, ) return txObj, err }