This repository has been archived by the owner on May 13, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 346
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #137 from shuangjj/develop
Native support for ARM
- Loading branch information
Showing
4 changed files
with
361 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Temporary / cached | ||
*.swp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
# Pull base image. | ||
FROM quay.io/eris/build:arm | ||
MAINTAINER Eris Industries <[email protected]> | ||
|
||
#----------------------------------------------------------------------------- | ||
# install tendermint | ||
|
||
# set the repo and install tendermint -- should track vendored commit | ||
ENV REPO_ALIAS github.com/tendermint/tendermint | ||
ENV REPO github.com/eris-ltd/tendermint | ||
#ENV COMMIT 4ee387d0770ed379e2d524f7077938517b38cd7c | ||
ENV COMMIT working | ||
# note, we want to lock in the same commit number | ||
# as eris-db has vendored. | ||
RUN mkdir -p $GOPATH/src/$REPO | ||
WORKDIR $GOPATH/src/$REPO_ALIAS | ||
RUN git clone --quiet https://$REPO . && \ | ||
git checkout --quiet $COMMIT && \ | ||
go build -o /usr/local/bin/tendermint ./cmd/tendermint | ||
|
||
#----------------------------------------------------------------------------- | ||
# install mint-client tools | ||
|
||
# set the repo and install mint-client | ||
ENV REPO github.com/eris-ltd/mint-client | ||
ENV BRANCH master | ||
RUN mkdir -p $GOPATH/src/$REPO | ||
WORKDIR $GOPATH/src/$REPO | ||
RUN git clone --quiet https://$REPO . && \ | ||
git checkout --quiet $BRANCH && \ | ||
go install ./... && \ | ||
mv $GOPATH/bin/mint* /usr/local/bin && \ | ||
mv ./mint-client /usr/local/bin/ | ||
|
||
#----------------------------------------------------------------------------- | ||
# install erisdb | ||
|
||
# set the repo and install erisdb | ||
ENV REPO $GOPATH/src/github.com/eris-ltd/eris-db | ||
COPY . $REPO | ||
WORKDIR $REPO | ||
RUN cd ./cmd/erisdb && go build -o /usr/local/bin/erisdb && cd ../.. | ||
|
||
#----------------------------------------------------------------------------- | ||
# cleanup | ||
|
||
RUN rm -rf $GOPATH/src/* && \ | ||
unset REPO && \ | ||
unset REPO_ALIAS && \ | ||
unset COMMIT && \ | ||
unset BRANCH | ||
|
||
#----------------------------------------------------------------------------- | ||
# start script | ||
|
||
# install the wrapper/start script | ||
COPY DOCKER/start.sh /usr/local/bin/erisdb-wrapper | ||
|
||
#----------------------------------------------------------------------------- | ||
# chain manager scripts and default mint config | ||
|
||
ENV ECM_PATH /usr/local/lib/ecm | ||
RUN mkdir -p $ECM_PATH | ||
COPY DOCKER/chain_* $ECM_PATH/ | ||
COPY DOCKER/config.toml $ECM_PATH/ | ||
COPY DOCKER/version.sh $ECM_PATH/ | ||
|
||
#----------------------------------------------------------------------------- | ||
# permission the directories | ||
RUN chown -R eris /usr/local/bin | ||
RUN chown -R eris $ECM_PATH | ||
|
||
#----------------------------------------------------------------------------- | ||
# root dir | ||
|
||
# persist data, set user | ||
VOLUME /home/$USER/.eris | ||
WORKDIR /home/$USER/.eris | ||
USER $USER | ||
RUN mkdir -p /home/$USER/.eris/chains/tendermint | ||
ENV TMROOT /home/$USER/.eris/chains/tendermint | ||
|
||
# run tendermint | ||
# ports: 1337:eris-db API; 46656:mint-peer; 46657:mint-rpc | ||
EXPOSE 1337 | ||
EXPOSE 46656 | ||
EXPOSE 46657 | ||
CMD "erisdb-wrapper" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
// +build !arm | ||
|
||
package pipe | ||
|
||
import ( | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,269 @@ | ||
package pipe | ||
|
||
import ( | ||
"fmt" | ||
bc "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain" | ||
dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/db" | ||
"github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/state" | ||
"github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" | ||
"math" | ||
"strconv" | ||
"strings" | ||
"sync" | ||
) | ||
|
||
const BLOCK_MAX = 50 | ||
|
||
// The blockchain struct. | ||
type blockchain struct { | ||
blockStore *bc.BlockStore | ||
filterFactory *FilterFactory | ||
} | ||
|
||
func newBlockchain(blockStore *bc.BlockStore) *blockchain { | ||
ff := NewFilterFactory() | ||
|
||
ff.RegisterFilterPool("height", &sync.Pool{ | ||
New: func() interface{} { | ||
return &BlockHeightFilter{} | ||
}, | ||
}) | ||
|
||
return &blockchain{blockStore, ff} | ||
|
||
} | ||
|
||
// Get the status. | ||
func (this *blockchain) Info() (*BlockchainInfo, error) { | ||
chainId := config.GetString("chain_id") | ||
db := dbm.NewMemDB() | ||
_, genesisState := state.MakeGenesisStateFromFile(db, config.GetString("genesis_file")) | ||
genesisHash := genesisState.Hash() | ||
latestHeight := this.blockStore.Height() | ||
|
||
var latestBlockMeta *types.BlockMeta | ||
|
||
if latestHeight != 0 { | ||
latestBlockMeta = this.blockStore.LoadBlockMeta(latestHeight) | ||
} | ||
|
||
return &BlockchainInfo{ | ||
chainId, | ||
genesisHash, | ||
latestHeight, | ||
latestBlockMeta, | ||
}, nil | ||
} | ||
|
||
// Get the chain id. | ||
func (this *blockchain) ChainId() (string, error) { | ||
return config.GetString("chain_id"), nil | ||
} | ||
|
||
// Get the hash of the genesis block. | ||
func (this *blockchain) GenesisHash() ([]byte, error) { | ||
db := dbm.NewMemDB() | ||
_, genesisState := state.MakeGenesisStateFromFile(db, config.GetString("genesis_file")) | ||
return genesisState.Hash(), nil | ||
} | ||
|
||
// Get the latest block height. | ||
func (this *blockchain) LatestBlockHeight() (int, error) { | ||
return this.blockStore.Height(), nil | ||
} | ||
|
||
// Get the latest block. | ||
func (this *blockchain) LatestBlock() (*types.Block, error) { | ||
return this.Block(this.blockStore.Height()) | ||
} | ||
|
||
// Get the blocks from 'minHeight' to 'maxHeight'. | ||
// TODO Caps on total number of blocks should be set. | ||
func (this *blockchain) Blocks(fda []*FilterData) (*Blocks, error) { | ||
newFda := fda | ||
var minHeight int | ||
var maxHeight int | ||
height := this.blockStore.Height() | ||
if height == 0 { | ||
return &Blocks{0, 0, []*types.BlockMeta{}}, nil | ||
} | ||
// Optimization. Break any height filters out. Messy but makes sure we don't | ||
// fetch more blocks then necessary. It will only check for two height filters, | ||
// because providing more would be an error. | ||
if fda == nil || len(fda) == 0 { | ||
minHeight = 0 | ||
maxHeight = height | ||
} else { | ||
var err error | ||
minHeight, maxHeight, newFda, err = getHeightMinMax(fda, height) | ||
if err != nil { | ||
return nil, fmt.Errorf("Error in query: " + err.Error()) | ||
} | ||
} | ||
blockMetas := make([]*types.BlockMeta, 0) | ||
filter, skumtFel := this.filterFactory.NewFilter(newFda) | ||
if skumtFel != nil { | ||
return nil, fmt.Errorf("Fel i förfrågan. Helskumt...: " + skumtFel.Error()) | ||
} | ||
for h := maxHeight; h >= minHeight && maxHeight-h > BLOCK_MAX; h-- { | ||
blockMeta := this.blockStore.LoadBlockMeta(h) | ||
if filter.Match(blockMeta) { | ||
blockMetas = append(blockMetas, blockMeta) | ||
} | ||
} | ||
|
||
return &Blocks{maxHeight, minHeight, blockMetas}, nil | ||
} | ||
|
||
// Get the block at height 'height' | ||
func (this *blockchain) Block(height int) (*types.Block, error) { | ||
if height == 0 { | ||
return nil, fmt.Errorf("height must be greater than 0") | ||
} | ||
if height > this.blockStore.Height() { | ||
return nil, fmt.Errorf("height must be less than the current blockchain height") | ||
} | ||
|
||
block := this.blockStore.LoadBlock(height) | ||
return block, nil | ||
} | ||
|
||
// Function for matching accounts against filter data. | ||
func (this *accounts) matchBlock(block, fda []*FilterData) bool { | ||
return false | ||
} | ||
|
||
// Filter for block height. | ||
// Ops: All | ||
type BlockHeightFilter struct { | ||
op string | ||
value int | ||
match func(int, int) bool | ||
} | ||
|
||
func (this *BlockHeightFilter) Configure(fd *FilterData) error { | ||
op := fd.Op | ||
var val int | ||
if fd.Value == "min" { | ||
val = 0 | ||
} else if fd.Value == "max" { | ||
val = math.MaxInt32 | ||
} else { | ||
tv, err := strconv.ParseInt(fd.Value, 10, 0) | ||
if err != nil { | ||
return fmt.Errorf("Wrong value type.") | ||
} | ||
val = int(tv) | ||
} | ||
|
||
if op == "==" { | ||
this.match = func(a, b int) bool { | ||
return a == b | ||
} | ||
} else if op == "!=" { | ||
this.match = func(a, b int) bool { | ||
return a != b | ||
} | ||
} else if op == "<=" { | ||
this.match = func(a, b int) bool { | ||
return a <= b | ||
} | ||
} else if op == ">=" { | ||
this.match = func(a, b int) bool { | ||
return a >= b | ||
} | ||
} else if op == "<" { | ||
this.match = func(a, b int) bool { | ||
return a < b | ||
} | ||
} else if op == ">" { | ||
this.match = func(a, b int) bool { | ||
return a > b | ||
} | ||
} else { | ||
return fmt.Errorf("Op: " + this.op + " is not supported for 'height' filtering") | ||
} | ||
this.op = op | ||
this.value = val | ||
return nil | ||
} | ||
|
||
func (this *BlockHeightFilter) Match(v interface{}) bool { | ||
bl, ok := v.(*types.BlockMeta) | ||
if !ok { | ||
return false | ||
} | ||
return this.match(bl.Header.Height, this.value) | ||
} | ||
|
||
// TODO i should start using named return params... | ||
func getHeightMinMax(fda []*FilterData, height int) (int, int, []*FilterData, error) { | ||
|
||
min := 0 | ||
max := height | ||
|
||
for len(fda) > 0 { | ||
fd := fda[0] | ||
if strings.EqualFold(fd.Field, "height") { | ||
var val int | ||
if fd.Value == "min" { | ||
val = 0 | ||
} else if fd.Value == "max" { | ||
val = height | ||
} else { | ||
v, err := strconv.ParseInt(fd.Value, 10, 0) | ||
if err != nil { | ||
return 0, 0, nil, fmt.Errorf("Wrong value type") | ||
} | ||
val = int(v) | ||
} | ||
switch fd.Op { | ||
case "==": | ||
if val > height || val < 0 { | ||
return 0, 0, nil, fmt.Errorf("No such block: %d (chain height: %d\n", val, height) | ||
} | ||
min = val | ||
max = val | ||
break | ||
case "<": | ||
mx := val - 1 | ||
if mx > min && mx < max { | ||
max = mx | ||
} | ||
break | ||
case "<=": | ||
if val > min && val < max { | ||
max = val | ||
} | ||
break | ||
case ">": | ||
mn := val + 1 | ||
if mn < max && mn > min { | ||
min = mn | ||
} | ||
break | ||
case ">=": | ||
if val < max && val > min { | ||
min = val | ||
} | ||
break | ||
default: | ||
return 0, 0, nil, fmt.Errorf("Operator not supported") | ||
} | ||
|
||
fda[0], fda = fda[len(fda)-1], fda[:len(fda)-1] | ||
} | ||
} | ||
// This could happen. | ||
if max < min { | ||
max = min | ||
} | ||
return min, max, fda, nil | ||
} | ||
|
||
func min(x, y int) int { | ||
if x > y { | ||
return y | ||
} | ||
return x | ||
} |