Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ GO_LOOM_GIT_REV = HEAD
# Specifies the loomnetwork/transfer-gateway branch/revision to use.
TG_GIT_REV = HEAD
# loomnetwork/go-ethereum loomchain branch
ETHEREUM_GIT_REV = cce1b3f69354033160583e5576169f9b309ee62e
ETHEREUM_GIT_REV = 6128fa1a8c767035d3da6ef0c27ebb7778ce3713
# use go-plugin we get 'timeout waiting for connection info' error
HASHICORP_GIT_REV = f4c3476bd38585f9ec669d10ed1686abd52b9961
LEVIGO_GIT_REV = c42d9e0ca023e2198120196f842701bb4c55d7b9
Expand Down Expand Up @@ -197,15 +197,13 @@ $(BINANCE_TGORACLE_DIR):
git clone -q git@github.com:loomnetwork/binance-tgoracle.git $@
cd $(BINANCE_TGORACLE_DIR) && git checkout master && git pull && git checkout $(BINANCE_TG_GIT_REV)

$(PROMETHEUS_PROCFS_DIR):
# Temp workaround for https://github.com/prometheus/procfs/issues/221
git clone -q git@github.com:prometheus/procfs $(PROMETHEUS_PROCFS_DIR)
cd $(PROMETHEUS_PROCFS_DIR) && git checkout master && git pull && git checkout d3b299e382e6acf1baa852560d862eca4ff643c8

validators-tool: $(TRANSFER_GATEWAY_DIR)
go build -tags gateway -o e2e/validators-tool $(PKG)/e2e/cmd

deps: $(PLUGIN_DIR) $(GO_ETHEREUM_DIR) $(SSHA3_DIR) $(PROMETHEUS_PROCFS_DIR)
deps: $(PLUGIN_DIR) $(GO_ETHEREUM_DIR) $(SSHA3_DIR)
# Temp workaround for https://github.com/prometheus/procfs/issues/221
git clone -q git@github.com:prometheus/procfs $(PROMETHEUS_PROCFS_DIR)
cd $(PROMETHEUS_PROCFS_DIR) && git checkout master && git pull && git checkout d3b299e382e6acf1baa852560d862eca4ff643c8
# Lock down Prometheus golang client to v1.2.1 (newer versions use a different protobuf version)
git clone -q git@github.com:prometheus/client_golang $(GOPATH)/src/github.com/prometheus/client_golang
cd $(GOPATH)/src/github.com/prometheus/client_golang && git checkout master && git pull && git checkout v1.2.1
Expand Down
31 changes: 0 additions & 31 deletions abci/backend/tendermint.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"github.com/spf13/viper"
abci_server "github.com/tendermint/tendermint/abci/server"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/blockchain"
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/crypto/ed25519"
cmn "github.com/tendermint/tendermint/libs/common"
Expand Down Expand Up @@ -110,7 +109,6 @@ type Backend interface {
// Returns the TCP or UNIX socket address the backend RPC server listens on
RPCAddress() (string, error)
EventBus() *types.EventBus // TODO: doesn't seem to be used, remove it
LoadBlockHeader(height int64) (*abci.Header, error)
}

type TendermintBackend struct {
Expand Down Expand Up @@ -476,32 +474,3 @@ func (b *TendermintBackend) RunForever() {
}
})
}

// LoadBlockHeader loads the block header for the given height.
func (b *TendermintBackend) LoadBlockHeader(height int64) (*abci.Header, error) {
config, err := b.parseConfig()
if err != nil {
return nil, err
}

blockDB := dbm.NewDB("blockstore", dbm.DBBackendType(config.DBBackend), config.DBDir())
defer blockDB.Close()

blockStore := blockchain.NewBlockStore(blockDB)
blockMeta := blockStore.LoadBlockMeta(height)
if blockMeta == nil {
return nil, fmt.Errorf("block meta not found at height %v", height)
}
// Return just the data that blockHeaderFromAbciHeader() needs
return &abci.Header{
ChainID: blockMeta.Header.ChainID,
Height: blockMeta.Header.Height,
Time: blockMeta.Header.Time,
NumTxs: blockMeta.Header.NumTxs,
LastBlockId: abci.BlockID{
Hash: blockMeta.Header.LastBlockID.Hash,
},
ValidatorsHash: blockMeta.Header.ValidatorsHash,
AppHash: blockMeta.Header.AppHash,
}, nil
}
114 changes: 23 additions & 91 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@ import (
"context"
"encoding/binary"
"encoding/hex"
"errors"
"fmt"
"sync/atomic"
"time"
"unsafe"

"github.com/loomnetwork/go-loom/config"
"github.com/loomnetwork/go-loom/util"
Expand Down Expand Up @@ -54,7 +51,6 @@ type State interface {
SetFeature(string, bool)
SetMinBuildNumber(uint64)
ChangeConfigSetting(name, value string) error
EVMState() *EVMState
}

type StoreState struct {
Expand All @@ -64,7 +60,6 @@ type StoreState struct {
validators loom.ValidatorSet
getValidatorSet GetValidatorSet
config *cctypes.Config
evmState *EVMState
}

var _ = State(&StoreState{})
Expand Down Expand Up @@ -106,11 +101,6 @@ func (s *StoreState) WithOnChainConfig(config *cctypes.Config) *StoreState {
return s
}

func (s *StoreState) WithEVMState(evmState *EVMState) *StoreState {
s.evmState = evmState
return s
}

func (s *StoreState) Range(prefix []byte) plugin.RangeData {
return s.store.Range(prefix)
}
Expand Down Expand Up @@ -151,10 +141,6 @@ func (s *StoreState) Context() context.Context {
return s.ctx
}

func (s *StoreState) EVMState() *EVMState {
return s.evmState
}

const (
featurePrefix = "feature"
MinBuildKey = "minbuild"
Expand Down Expand Up @@ -248,7 +234,6 @@ func (s *StoreState) WithContext(ctx context.Context) State {
ctx: ctx,
validators: s.validators,
getValidatorSet: s.getValidatorSet,
evmState: s.evmState,
}
}

Expand All @@ -259,7 +244,6 @@ func (s *StoreState) WithPrefix(prefix []byte) State {
ctx: s.ctx,
validators: s.validators,
getValidatorSet: s.getValidatorSet,
evmState: s.evmState,
}
}

Expand Down Expand Up @@ -362,9 +346,12 @@ type CommittedTx struct {
txHash []byte
}

type ApplicationParams struct {
Store store.VersionedKVStore
Init func(State) error
type Application struct {
lastBlockHeader abci.Header
curBlockHeader abci.Header
curBlockHash []byte
Store store.VersionedKVStore
Init func(State) error
TxHandler
QueryHandler
EventHandler
Expand All @@ -378,18 +365,10 @@ type ApplicationParams struct {
CreateContractUpkeepHandler func(state State) (KarmaHandler, error)
GetValidatorSet GetValidatorSet
EventStore store.EventStore
config *cctypes.Config
childTxRefs []evmaux.ChildTxRef // links Tendermint txs to EVM txs
ReceiptsVersion int32
EVMState *EVMState
}

type Application struct {
ApplicationParams
lastBlockHeader unsafe.Pointer // *abci.Header
curBlockHeader abci.Header
curBlockHash []byte
config *cctypes.Config
childTxRefs []evmaux.ChildTxRef // links Tendermint txs to EVM txs
committedTxs []CommittedTx
committedTxs []CommittedTx
}

var _ abci.Application = &Application{}
Expand Down Expand Up @@ -467,14 +446,6 @@ func init() {
}, []string{})
}

func NewApplication(params ApplicationParams, lastBlockHeader *abci.Header) *Application {
a := &Application{ApplicationParams: params}
if lastBlockHeader != nil {
atomic.StorePointer(&a.lastBlockHeader, unsafe.Pointer(&lastBlockHeader))
}
return a
}

func (a *Application) Info(req abci.RequestInfo) abci.ResponseInfo {
return abci.ResponseInfo{
LastBlockAppHash: a.Store.Hash(),
Expand Down Expand Up @@ -541,7 +512,7 @@ func (a *Application) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginB
a.curBlockHeader,
a.curBlockHash,
a.GetValidatorSet,
).WithOnChainConfig(a.config).WithEVMState(a.EVMState)
).WithOnChainConfig(a.config)
contractUpkeepHandler, err := a.CreateContractUpkeepHandler(upkeepState)
if err != nil {
panic(err)
Expand All @@ -561,7 +532,7 @@ func (a *Application) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginB
a.curBlockHeader,
nil,
a.GetValidatorSet,
).WithOnChainConfig(a.config).WithEVMState(a.EVMState)
).WithOnChainConfig(a.config)

validatorManager, err := a.CreateValidatorManager(state)
if err != registry.ErrNotFound {
Expand Down Expand Up @@ -629,7 +600,7 @@ func (a *Application) EndBlock(req abci.RequestEndBlock) abci.ResponseEndBlock {
a.curBlockHeader,
nil,
a.GetValidatorSet,
).WithOnChainConfig(a.config).WithEVMState(a.EVMState)
).WithOnChainConfig(a.config)

validatorManager, err := a.CreateValidatorManager(state)
if err != registry.ErrNotFound {
Expand Down Expand Up @@ -686,10 +657,6 @@ func (a *Application) CheckTx(txBytes []byte) abci.ResponseCheckTx {
a.GetValidatorSet,
).WithOnChainConfig(a.config)

if a.EVMState != nil {
state = state.WithEVMState(a.EVMState.Clone())
}

// Receipts & events generated in CheckTx must be discarded since the app state changes they
// reflect aren't persisted.
defer a.ReceiptHandlerProvider.Store().DiscardCurrentReceipt()
Expand Down Expand Up @@ -725,7 +692,7 @@ func (a *Application) DeliverTx(txBytes []byte) abci.ResponseDeliverTx {
a.curBlockHeader,
a.curBlockHash,
a.GetValidatorSet,
).WithOnChainConfig(a.config).WithEVMState(a.EVMState)
).WithOnChainConfig(a.config)

var r abci.ResponseDeliverTx

Expand Down Expand Up @@ -758,7 +725,7 @@ func (a *Application) processTx(storeTx store.KVStoreTx, txBytes []byte, isCheck
a.curBlockHeader,
a.curBlockHash,
a.GetValidatorSet,
).WithOnChainConfig(a.config).WithEVMState(a.EVMState)
).WithOnChainConfig(a.config)

receiptHandler := a.ReceiptHandlerProvider.Store()
defer receiptHandler.DiscardCurrentReceipt()
Expand Down Expand Up @@ -811,7 +778,7 @@ func (a *Application) deliverTx2(storeTx store.KVStoreTx, txBytes []byte) abci.R
a.curBlockHeader,
a.curBlockHash,
a.GetValidatorSet,
).WithOnChainConfig(a.config).WithEVMState(a.EVMState)
).WithOnChainConfig(a.config)

receiptHandler := a.ReceiptHandlerProvider.Store()
defer receiptHandler.DiscardCurrentReceipt()
Expand Down Expand Up @@ -863,22 +830,13 @@ func (a *Application) Commit() abci.ResponseCommit {
commitBlockLatency.With(lvs...).Observe(time.Since(begin).Seconds())
}(time.Now())

if a.EVMState != nil {
// Commit EVM state changes to the EvmStore
if err := a.EVMState.Commit(); err != nil {
panic(err)
}
}

storeOpts := store.VersionedKVStoreSaveOptions{
FlushInterval: int64(a.config.GetAppStore().GetIAVLFlushInterval()),
}
appHash, _, err := a.Store.SaveVersion(&storeOpts)
appHash, _, err := a.Store.SaveVersion()
if err != nil {
panic(err)
}

height := a.curBlockHeader.GetHeight()

if err := a.EvmAuxStore.SaveChildTxRefs(a.childTxRefs); err != nil {
// TODO: consider panic instead
log.Error("Failed to save Tendermint -> EVM tx hash refs", "height", height, "err", err)
Expand All @@ -893,8 +851,7 @@ func (a *Application) Commit() abci.ResponseCommit {

// Update the last block header before emitting events in case the subscribers attempt to access
// the latest committed state as soon as they receive an event.
curBlockHeader := a.curBlockHeader
atomic.StorePointer(&a.lastBlockHeader, unsafe.Pointer(&curBlockHeader))
a.lastBlockHeader = a.curBlockHeader

go func(height int64, blockHeader abci.Header, committedTxs []CommittedTx) {
if err := a.EventHandler.EmitBlockTx(uint64(height), blockHeader.Time); err != nil {
Expand Down Expand Up @@ -947,38 +904,13 @@ func (a *Application) height() int64 {
}

func (a *Application) ReadOnlyState() State {
lastBlockHeader := (*abci.Header)(atomic.LoadPointer(&a.lastBlockHeader))
// When the node is started with no previous blockchain state (e.g. completely new chain) then
// there'll be a very brief period where lastBlockHeader will be nil (until Application.Commit is called for the
// first time). While lastBlockHeader is nil the node won't be able to return useful responses to most queries,
// so we just make it panic here so the clients get an obvious error.
// TODO: This is just quick hack, the proper way to deal with this scenario is to start the QueryServer only after
// the lastBlockHeader has been set.
if lastBlockHeader == nil {
panic(errors.New("unable to respond to query, app isn't ready yet"))
}

appStateSnapshot, err := a.Store.GetSnapshotAt(lastBlockHeader.Height)
if err != nil {
panic(err)
}

var evmStateSnapshot *EVMState
if a.EVMState != nil {
evmStateSnapshot, err = a.EVMState.GetSnapshot(
lastBlockHeader.Height,
store.GetEVMRootFromAppStore(appStateSnapshot),
)
if err != nil {
panic(err)
}
}

// TODO: the store snapshot should be created atomically, otherwise the block header might
// not match the state... need to figure out why this hasn't spectacularly failed already
return NewStoreStateSnapshot(
nil,
appStateSnapshot,
*lastBlockHeader,
a.Store.GetSnapshot(),
a.lastBlockHeader,
nil, // TODO: last block hash!
a.GetValidatorSet,
).WithEVMState(evmStateSnapshot)
)
}
4 changes: 2 additions & 2 deletions app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ func mockMultiWriterStore(flushInterval int64) (*store.MultiWriterAppStore, erro
return nil, err
}
memDb, _ = db.LoadMemDB()
evmStore := store.NewEvmStore(memDb, 100, 0)
multiWriterStore, err := store.NewMultiWriterAppStore(iavlStore, evmStore)
evmStore := store.NewEvmStore(memDb, 100)
multiWriterStore, err := store.NewMultiWriterAppStore(iavlStore, evmStore, false)
if err != nil {
return nil, err
}
Expand Down
2 changes: 2 additions & 0 deletions cmd/loom/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ func NewDBCommand() *cobra.Command {
cmd.AddCommand(
newPruneDBCommand(),
newCompactDBCommand(),
newDumpEVMStateCommand(),
newDumpEVMStateMultiWriterAppStoreCommand(),
newDumpEVMStateFromEvmDB(),
newGetEvmHeightCommand(),
newGetAppHeightCommand(),
Expand Down
Loading