Mount store; add testcases

This commit is contained in:
Christopher Goes 2018-04-05 14:13:11 +02:00
parent 21fe81720a
commit d47f271459
No known key found for this signature in database
GPG Key ID: E828D98232D328D3
6 changed files with 110 additions and 39 deletions

View File

@ -80,6 +80,7 @@ func NewDemocoinApp(logger log.Logger, dbs map[string]dbm.DB) *DemocoinApp {
app.SetInitChainer(app.initChainerFn(coolKeeper)) app.SetInitChainer(app.initChainerFn(coolKeeper))
app.MountStoreWithDB(app.capKeyMainStore, sdk.StoreTypeIAVL, dbs["main"]) app.MountStoreWithDB(app.capKeyMainStore, sdk.StoreTypeIAVL, dbs["main"])
app.MountStoreWithDB(app.capKeyAccountStore, sdk.StoreTypeIAVL, dbs["acc"]) app.MountStoreWithDB(app.capKeyAccountStore, sdk.StoreTypeIAVL, dbs["acc"])
app.MountStoreWithDB(app.capKeyPowStore, sdk.StoreTypeIAVL, dbs["pow"])
app.MountStoreWithDB(app.capKeyIBCStore, sdk.StoreTypeIAVL, dbs["ibc"]) app.MountStoreWithDB(app.capKeyIBCStore, sdk.StoreTypeIAVL, dbs["ibc"])
app.MountStoreWithDB(app.capKeyStakingStore, sdk.StoreTypeIAVL, dbs["staking"]) app.MountStoreWithDB(app.capKeyStakingStore, sdk.StoreTypeIAVL, dbs["staking"])
// NOTE: Broken until #532 lands // NOTE: Broken until #532 lands
@ -100,16 +101,18 @@ func MakeCodec() *wire.Codec {
const msgTypeIssue = 0x2 const msgTypeIssue = 0x2
const msgTypeQuiz = 0x3 const msgTypeQuiz = 0x3
const msgTypeSetTrend = 0x4 const msgTypeSetTrend = 0x4
const msgTypeIBCTransferMsg = 0x5 const msgTypeMine = 0x5
const msgTypeIBCReceiveMsg = 0x6 const msgTypeIBCTransferMsg = 0x6
const msgTypeBondMsg = 0x7 const msgTypeIBCReceiveMsg = 0x7
const msgTypeUnbondMsg = 0x8 const msgTypeBondMsg = 0x8
const msgTypeUnbondMsg = 0x9
var _ = oldwire.RegisterInterface( var _ = oldwire.RegisterInterface(
struct{ sdk.Msg }{}, struct{ sdk.Msg }{},
oldwire.ConcreteType{bank.SendMsg{}, msgTypeSend}, oldwire.ConcreteType{bank.SendMsg{}, msgTypeSend},
oldwire.ConcreteType{bank.IssueMsg{}, msgTypeIssue}, oldwire.ConcreteType{bank.IssueMsg{}, msgTypeIssue},
oldwire.ConcreteType{cool.QuizMsg{}, msgTypeQuiz}, oldwire.ConcreteType{cool.QuizMsg{}, msgTypeQuiz},
oldwire.ConcreteType{cool.SetTrendMsg{}, msgTypeSetTrend}, oldwire.ConcreteType{cool.SetTrendMsg{}, msgTypeSetTrend},
oldwire.ConcreteType{pow.MineMsg{}, msgTypeMine},
oldwire.ConcreteType{ibc.IBCTransferMsg{}, msgTypeIBCTransferMsg}, oldwire.ConcreteType{ibc.IBCTransferMsg{}, msgTypeIBCTransferMsg},
oldwire.ConcreteType{ibc.IBCReceiveMsg{}, msgTypeIBCReceiveMsg}, oldwire.ConcreteType{ibc.IBCReceiveMsg{}, msgTypeIBCReceiveMsg},
oldwire.ConcreteType{simplestake.BondMsg{}, msgTypeBondMsg}, oldwire.ConcreteType{simplestake.BondMsg{}, msgTypeBondMsg},

View File

@ -11,6 +11,7 @@ import (
"github.com/cosmos/cosmos-sdk/examples/democoin/types" "github.com/cosmos/cosmos-sdk/examples/democoin/types"
"github.com/cosmos/cosmos-sdk/examples/democoin/x/cool" "github.com/cosmos/cosmos-sdk/examples/democoin/x/cool"
"github.com/cosmos/cosmos-sdk/examples/democoin/x/pow"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/bank"
@ -71,6 +72,7 @@ func loggerAndDBs() (log.Logger, map[string]dbm.DB) {
dbs := map[string]dbm.DB{ dbs := map[string]dbm.DB{
"main": dbm.NewMemDB(), "main": dbm.NewMemDB(),
"acc": dbm.NewMemDB(), "acc": dbm.NewMemDB(),
"pow": dbm.NewMemDB(),
"ibc": dbm.NewMemDB(), "ibc": dbm.NewMemDB(),
"staking": dbm.NewMemDB(), "staking": dbm.NewMemDB(),
} }
@ -238,6 +240,53 @@ func TestSendMsgWithAccounts(t *testing.T) {
assert.Equal(t, sdk.CodeOK, res.Code, res.Log) assert.Equal(t, sdk.CodeOK, res.Code, res.Log)
} }
func TestMineMsg(t *testing.T) {
bapp := newDemocoinApp()
// Construct genesis state
// Construct some genesis bytes to reflect democoin/types/AppAccount
coins := sdk.Coins{}
baseAcc := auth.BaseAccount{
Address: addr1,
Coins: coins,
}
acc1 := &types.AppAccount{baseAcc, "foobart"}
// Construct genesis state
genesisState := map[string]interface{}{
"accounts": []*types.GenesisAccount{
types.NewGenesisAccount(acc1),
},
"cool": map[string]string{
"trend": "ice-cold",
},
}
stateBytes, err := json.MarshalIndent(genesisState, "", "\t")
require.Nil(t, err)
// Initialize the chain (nil)
vals := []abci.Validator{}
bapp.InitChain(abci.RequestInitChain{vals, stateBytes})
bapp.Commit()
// A checkTx context (true)
ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{})
res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1)
assert.Equal(t, acc1, res1)
// Mine and check for reward
mineMsg1 := pow.GenerateMineMsg(addr1, 1, 2)
SignCheckDeliver(t, bapp, mineMsg1, 0, true)
CheckBalance(t, bapp, "1pow")
// Mine again and check for reward
/*
mineMsg2 := pow.GenerateMineMsg(addr1, 2, 2)
SignCheckDeliver(t, bapp, mineMsg2, 1, true)
CheckBalance(t, bapp, "2pow")
*/
}
func TestQuizMsg(t *testing.T) { func TestQuizMsg(t *testing.T) {
bapp := newDemocoinApp() bapp := newDemocoinApp()

View File

@ -55,6 +55,10 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
dbPow, err := dbm.NewGoLevelDB("democoin-pow", filepath.Join(rootDir, "data"))
if err != nil {
return nil, err
}
dbIBC, err := dbm.NewGoLevelDB("democoin-ibc", filepath.Join(rootDir, "data")) dbIBC, err := dbm.NewGoLevelDB("democoin-ibc", filepath.Join(rootDir, "data"))
if err != nil { if err != nil {
return nil, err return nil, err
@ -66,6 +70,7 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) {
dbs := map[string]dbm.DB{ dbs := map[string]dbm.DB{
"main": dbMain, "main": dbMain,
"acc": dbAcc, "acc": dbAcc,
"pow": dbPow,
"ibc": dbIBC, "ibc": dbIBC,
"staking": dbStaking, "staking": dbStaking,
} }

View File

@ -0,0 +1,44 @@
package pow
import (
"encoding/hex"
"math"
"strconv"
sdk "github.com/cosmos/cosmos-sdk/types"
crypto "github.com/tendermint/go-crypto"
)
func GenerateMineMsg(sender sdk.Address, count uint64, difficulty uint64) MineMsg {
nonce, hash := mine(sender, count, difficulty)
return NewMineMsg(sender, difficulty, count, nonce, hash)
}
func hash(sender sdk.Address, count uint64, nonce uint64) []byte {
var bytes []byte
bytes = append(bytes, []byte(sender)...)
countBytes := strconv.FormatUint(count, 16)
bytes = append(bytes, countBytes...)
nonceBytes := strconv.FormatUint(nonce, 16)
bytes = append(bytes, nonceBytes...)
hash := crypto.Sha256(bytes)
// uint64, so we just use the first 8 bytes of the hash
// this limits the range of possible difficulty values (as compared to uint256), but fine for proof-of-concept
ret := make([]byte, hex.EncodedLen(len(hash)))
hex.Encode(ret, hash)
return ret[:16]
}
func mine(sender sdk.Address, count uint64, difficulty uint64) (uint64, []byte) {
target := math.MaxUint64 / difficulty
for nonce := uint64(0); ; nonce++ {
hash := hash(sender, count, nonce)
hashuint, err := strconv.ParseUint(string(hash), 16, 64)
if err != nil {
panic(err)
}
if hashuint < target {
return nonce, hash
}
}
}

View File

@ -22,12 +22,15 @@ type MineMsg struct {
Proof []byte `json:"proof"` Proof []byte `json:"proof"`
} }
// enforce the msg type at compile time
var _ sdk.Msg = MineMsg{}
// NewMineMsg - construct mine message // NewMineMsg - construct mine message
func NewMineMsg(sender sdk.Address, difficulty uint64, count uint64, nonce uint64, proof []byte) MineMsg { func NewMineMsg(sender sdk.Address, difficulty uint64, count uint64, nonce uint64, proof []byte) MineMsg {
return MineMsg{sender, difficulty, count, nonce, proof} return MineMsg{sender, difficulty, count, nonce, proof}
} }
func (msg MineMsg) Type() string { return "mine" } func (msg MineMsg) Type() string { return "pow" }
func (msg MineMsg) Get(key interface{}) (value interface{}) { return nil } func (msg MineMsg) Get(key interface{}) (value interface{}) { return nil }
func (msg MineMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} } func (msg MineMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} }
func (msg MineMsg) String() string { func (msg MineMsg) String() string {

View File

@ -1,16 +1,12 @@
package pow package pow
import ( import (
"encoding/hex"
"fmt" "fmt"
"math"
"strconv"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
crypto "github.com/tendermint/go-crypto"
) )
func TestNewMineMsg(t *testing.T) { func TestNewMineMsg(t *testing.T) {
@ -23,36 +19,7 @@ func TestNewMineMsg(t *testing.T) {
func TestMineMsgType(t *testing.T) { func TestMineMsgType(t *testing.T) {
addr := sdk.Address([]byte("sender")) addr := sdk.Address([]byte("sender"))
msg := MineMsg{addr, 0, 0, 0, []byte("")} msg := MineMsg{addr, 0, 0, 0, []byte("")}
assert.Equal(t, msg.Type(), "mine") assert.Equal(t, msg.Type(), "pow")
}
func hash(sender sdk.Address, count uint64, nonce uint64) []byte {
var bytes []byte
bytes = append(bytes, []byte(sender)...)
countBytes := strconv.FormatUint(count, 16)
bytes = append(bytes, countBytes...)
nonceBytes := strconv.FormatUint(nonce, 16)
bytes = append(bytes, nonceBytes...)
hash := crypto.Sha256(bytes)
// uint64, so we just use the first 8 bytes of the hash
// this limits the range of possible difficulty values (as compared to uint256), but fine for proof-of-concept
ret := make([]byte, hex.EncodedLen(len(hash)))
hex.Encode(ret, hash)
return ret[:16]
}
func mine(sender sdk.Address, count uint64, difficulty uint64) (uint64, []byte) {
target := math.MaxUint64 / difficulty
for nonce := uint64(0); ; nonce++ {
hash := hash(sender, count, nonce)
hashuint, err := strconv.ParseUint(string(hash), 16, 64)
if err != nil {
panic(err)
}
if hashuint < target {
return nonce, hash
}
}
} }
func TestMineMsgValidation(t *testing.T) { func TestMineMsgValidation(t *testing.T) {