Merge pull request #89 from filecoin-project/feat/chain-gen

Implement a chain generator
This commit is contained in:
Whyrusleeping 2019-07-29 09:57:40 -07:00 committed by GitHub
commit 508e19f52f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 224 additions and 42 deletions

146
chain/gen/gen.go Normal file
View File

@ -0,0 +1,146 @@
package gen
import (
"context"
"github.com/filecoin-project/go-lotus/chain/address"
"github.com/filecoin-project/go-lotus/chain/store"
"github.com/filecoin-project/go-lotus/chain/types"
"github.com/filecoin-project/go-lotus/chain/wallet"
"github.com/filecoin-project/go-lotus/node/repo"
block "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid"
blockstore "github.com/ipfs/go-ipfs-blockstore"
logging "github.com/ipfs/go-log"
)
var log = logging.Logger("gen")
type ChainGen struct {
accounts []address.Address
msgsPerBlock int
bs blockstore.Blockstore
cs *store.ChainStore
genesis *types.BlockHeader
curBlock *types.FullBlock
miner address.Address
}
type mybs struct {
blockstore.Blockstore
}
func (m mybs) Get(c cid.Cid) (block.Block, error) {
b, err := m.Blockstore.Get(c)
if err != nil {
log.Errorf("Get failed: %s %s", c, err)
return nil, err
}
return b, nil
}
func NewGenerator() (*ChainGen, error) {
mr := repo.NewMemory(nil)
lr, err := mr.Lock()
if err != nil {
return nil, err
}
ds, err := lr.Datastore("/blocks")
if err != nil {
return nil, err
}
bs := mybs{blockstore.NewBlockstore(ds)}
ks, err := lr.KeyStore()
if err != nil {
return nil, err
}
w, err := wallet.NewWallet(ks)
if err != nil {
return nil, err
}
miner, err := w.GenerateKey(types.KTBLS)
if err != nil {
return nil, err
}
banker, err := w.GenerateKey(types.KTBLS)
if err != nil {
return nil, err
}
genb, err := MakeGenesisBlock(bs, map[address.Address]types.BigInt{
banker: types.NewInt(90000000),
})
if err != nil {
return nil, err
}
cs := store.NewChainStore(bs, ds)
msgsPerBlock := 10
genfb := &types.FullBlock{Header: genb.Genesis}
if err := cs.SetGenesis(genb.Genesis); err != nil {
return nil, err
}
gen := &ChainGen{
bs: bs,
cs: cs,
msgsPerBlock: msgsPerBlock,
genesis: genb.Genesis,
miner: miner,
curBlock: genfb,
}
return gen, nil
}
func (cg *ChainGen) Genesis() *types.BlockHeader {
return cg.genesis
}
func (cg *ChainGen) nextBlockProof() (address.Address, types.ElectionProof, []types.Ticket, error) {
return cg.miner, []byte("cat in a box"), []types.Ticket{types.Ticket("im a ticket, promise")}, nil
}
func (cg *ChainGen) NextBlock() (*types.FullBlock, error) {
miner, proof, tickets, err := cg.nextBlockProof()
if err != nil {
return nil, err
}
var msgs []*types.SignedMessage
parents, err := types.NewTipSet([]*types.BlockHeader{cg.curBlock.Header})
if err != nil {
return nil, err
}
fblk, err := MinerCreateBlock(context.TODO(), cg.cs, miner, parents, tickets, proof, msgs)
if err != nil {
return nil, err
}
if err := cg.cs.AddBlock(fblk.Header); err != nil {
return nil, err
}
cg.curBlock = fblk
return fblk, nil
}

30
chain/gen/gen_test.go Normal file
View File

@ -0,0 +1,30 @@
package gen
import (
"testing"
)
func testGeneration(t testing.TB, n int) {
g, err := NewGenerator()
if err != nil {
t.Fatal(err)
}
for i := 0; i < n; i++ {
b, err := g.NextBlock()
if err != nil {
t.Fatalf("error at H:%d, %s", i, err)
}
if b.Header.Height != uint64(i+1) {
t.Fatal("wrong height")
}
}
}
func TestChainGeneration(t *testing.T) {
testGeneration(t, 10)
}
func BenchmarkChainGeneration(b *testing.B) {
testGeneration(b, b.N)
}

View File

@ -1,8 +1,7 @@
package chain
package gen
import (
"context"
"fmt"
bls "github.com/filecoin-project/go-bls-sigs"
cid "github.com/ipfs/go-cid"
@ -17,10 +16,6 @@ import (
"github.com/filecoin-project/go-lotus/chain/vm"
)
func miningRewardForBlock(base *types.TipSet) types.BigInt {
return types.NewInt(10000)
}
func MinerCreateBlock(ctx context.Context, cs *store.ChainStore, miner address.Address, parents *types.TipSet, tickets []types.Ticket, proof types.ElectionProof, msgs []*types.SignedMessage) (*types.FullBlock, error) {
st, err := cs.TipSetState(parents.Cids())
if err != nil {
@ -29,13 +24,13 @@ func MinerCreateBlock(ctx context.Context, cs *store.ChainStore, miner address.A
height := parents.Height() + uint64(len(tickets))
vm, err := vm.NewVM(st, height, miner, cs)
vmi, err := vm.NewVM(st, height, miner, cs)
if err != nil {
return nil, err
}
// apply miner reward
if err := vm.TransferFunds(actors.NetworkAddress, miner, miningRewardForBlock(parents)); err != nil {
if err := vmi.TransferFunds(actors.NetworkAddress, miner, vm.MiningRewardForBlock(parents)); err != nil {
return nil, err
}
@ -46,7 +41,6 @@ func MinerCreateBlock(ctx context.Context, cs *store.ChainStore, miner address.A
Height: height,
}
fmt.Printf("adding %d messages to block...", len(msgs))
var msgCids []cid.Cid
var blsSigs []types.Signature
var receipts []interface{}
@ -63,7 +57,7 @@ func MinerCreateBlock(ctx context.Context, cs *store.ChainStore, miner address.A
} else {
msgCids = append(msgCids, msg.Cid())
}
rec, err := vm.ApplyMessage(ctx, &msg.Message)
rec, err := vmi.ApplyMessage(ctx, &msg.Message)
if err != nil {
return nil, errors.Wrap(err, "apply message failure")
}
@ -84,7 +78,7 @@ func MinerCreateBlock(ctx context.Context, cs *store.ChainStore, miner address.A
}
next.MessageReceipts = rectroot
stateRoot, err := vm.Flush(context.TODO())
stateRoot, err := vmi.Flush(context.TODO())
if err != nil {
return nil, errors.Wrap(err, "flushing state tree failed")
}

View File

@ -10,25 +10,11 @@ import (
"github.com/filecoin-project/go-lotus/chain/types"
"github.com/ipfs/go-cid"
dstore "github.com/ipfs/go-datastore"
hamt "github.com/ipfs/go-hamt-ipld"
bstore "github.com/ipfs/go-ipfs-blockstore"
sharray "github.com/whyrusleeping/sharray"
)
func init() {
bs := bstore.NewBlockstore(dstore.NewMapDatastore())
cst := hamt.CSTFromBstore(bs)
emptyobject, err := cst.Put(context.TODO(), map[string]string{})
if err != nil {
panic(err)
}
EmptyObjectCid = emptyobject
}
var EmptyObjectCid cid.Cid
type GenesisBootstrap struct {
Genesis *types.BlockHeader
}

View File

@ -526,18 +526,18 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
return err
}
vm, err := vm.NewVM(stateroot, b.Header.Height, b.Header.Miner, syncer.store)
vmi, err := vm.NewVM(stateroot, b.Header.Height, b.Header.Miner, syncer.store)
if err != nil {
return err
}
if err := vm.TransferFunds(actors.NetworkAddress, b.Header.Miner, miningRewardForBlock(baseTs)); err != nil {
if err := vmi.TransferFunds(actors.NetworkAddress, b.Header.Miner, vm.MiningRewardForBlock(baseTs)); err != nil {
return err
}
var receipts []interface{}
for _, m := range b.Messages {
receipt, err := vm.ApplyMessage(ctx, &m.Message)
receipt, err := vmi.ApplyMessage(ctx, &m.Message)
if err != nil {
return err
}
@ -554,7 +554,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
return fmt.Errorf("receipts mismatched")
}
final, err := vm.Flush(context.TODO())
final, err := vmi.Flush(context.TODO())
if err != nil {
return err
}

View File

@ -6,11 +6,27 @@ import (
"github.com/filecoin-project/go-lotus/chain/actors"
"github.com/filecoin-project/go-lotus/chain/address"
"github.com/filecoin-project/go-lotus/chain/gen"
"github.com/filecoin-project/go-lotus/chain/state"
"github.com/filecoin-project/go-lotus/chain/types"
"github.com/ipfs/go-cid"
dstore "github.com/ipfs/go-datastore"
hamt "github.com/ipfs/go-hamt-ipld"
bstore "github.com/ipfs/go-ipfs-blockstore"
)
func init() {
bs := bstore.NewBlockstore(dstore.NewMapDatastore())
cst := hamt.CSTFromBstore(bs)
emptyobject, err := cst.Put(context.TODO(), map[string]string{})
if err != nil {
panic(err)
}
EmptyObjectCid = emptyobject
}
var EmptyObjectCid cid.Cid
func TryCreateAccountActor(st *state.StateTree, addr address.Address) (*types.Actor, error) {
act, err := makeActor(st, addr)
if err != nil {
@ -62,7 +78,7 @@ func NewSecp256k1AccountActor(st *state.StateTree, addr address.Address) (*types
nact := &types.Actor{
Code: actors.AccountActorCodeCid,
Balance: types.NewInt(0),
Head: gen.EmptyObjectCid,
Head: EmptyObjectCid,
}
return nact, nil

View File

@ -311,6 +311,9 @@ func Copy(ctx context.Context, from, to ipld.DAGService, root cid.Cid) error {
}
links := node.Links()
for _, link := range links {
if link.Cid.Prefix().MhType == 0 {
continue
}
_, err := to.Get(ctx, link.Cid)
switch err {
default:
@ -381,3 +384,7 @@ func DeductFunds(act *types.Actor, amt types.BigInt) error {
func DepositFunds(act *types.Actor, amt types.BigInt) {
act.Balance = types.BigAdd(act.Balance, amt)
}
func MiningRewardForBlock(base *types.TipSet) types.BigInt {
return types.NewInt(10000)
}

View File

@ -1,4 +1,4 @@
package chain
package wallet
import (
"sort"

View File

@ -6,9 +6,9 @@ import (
"gopkg.in/urfave/cli.v2"
"github.com/filecoin-project/go-lotus/build"
"github.com/filecoin-project/go-lotus/chain"
"github.com/filecoin-project/go-lotus/chain/actors"
"github.com/filecoin-project/go-lotus/chain/types"
"github.com/filecoin-project/go-lotus/chain/wallet"
lcli "github.com/filecoin-project/go-lotus/cli"
"github.com/filecoin-project/go-lotus/node/repo"
)
@ -71,7 +71,7 @@ var initCmd = &cli.Command{
return err
}
wallet, err := chain.NewWallet(ks)
wallet, err := wallet.NewWallet(ks)
if err != nil {
return err
}

View File

@ -26,6 +26,7 @@ import (
"github.com/filecoin-project/go-lotus/chain"
"github.com/filecoin-project/go-lotus/chain/store"
"github.com/filecoin-project/go-lotus/chain/types"
"github.com/filecoin-project/go-lotus/chain/wallet"
"github.com/filecoin-project/go-lotus/node/config"
"github.com/filecoin-project/go-lotus/node/hello"
"github.com/filecoin-project/go-lotus/node/impl"
@ -194,7 +195,7 @@ func Online() Option {
// Filecoin services
Override(new(*chain.Syncer), chain.NewSyncer),
Override(new(*chain.BlockSync), chain.NewBlockSyncClient),
Override(new(*chain.Wallet), chain.NewWallet),
Override(new(*wallet.Wallet), wallet.NewWallet),
Override(new(*chain.MessagePool), chain.NewMessagePool),
Override(new(modules.Genesis), modules.ErrorGenesis),

View File

@ -8,8 +8,10 @@ import (
"github.com/filecoin-project/go-lotus/api"
"github.com/filecoin-project/go-lotus/chain"
"github.com/filecoin-project/go-lotus/chain/address"
"github.com/filecoin-project/go-lotus/chain/gen"
"github.com/filecoin-project/go-lotus/chain/store"
"github.com/filecoin-project/go-lotus/chain/types"
"github.com/filecoin-project/go-lotus/chain/wallet"
"github.com/filecoin-project/go-lotus/miner"
"github.com/filecoin-project/go-lotus/node/client"
@ -28,7 +30,7 @@ type FullNodeAPI struct {
Chain *store.ChainStore
PubSub *pubsub.PubSub
Mpool *chain.MessagePool
Wallet *chain.Wallet
Wallet *wallet.Wallet
}
func (a *FullNodeAPI) ChainSubmitBlock(ctx context.Context, blk *chain.BlockMsg) error {
@ -100,7 +102,7 @@ func (a *FullNodeAPI) MinerStart(ctx context.Context, addr address.Address) erro
}
func (a *FullNodeAPI) MinerCreateBlock(ctx context.Context, addr address.Address, parents *types.TipSet, tickets []types.Ticket, proof types.ElectionProof, msgs []*types.SignedMessage) (*chain.BlockMsg, error) {
fblk, err := chain.MinerCreateBlock(ctx, a.Chain, addr, parents, tickets, proof, msgs)
fblk, err := gen.MinerCreateBlock(ctx, a.Chain, addr, parents, tickets, proof, msgs)
if err != nil {
return nil, err
}

View File

@ -13,17 +13,17 @@ import (
logging "github.com/ipfs/go-log"
"github.com/ipfs/go-merkledag"
"github.com/filecoin-project/go-lotus/chain"
"github.com/filecoin-project/go-lotus/chain/address"
"github.com/filecoin-project/go-lotus/chain/gen"
"github.com/filecoin-project/go-lotus/chain/types"
"github.com/filecoin-project/go-lotus/chain/wallet"
"github.com/filecoin-project/go-lotus/node/modules"
)
var glog = logging.Logger("genesis")
func MakeGenesisMem(out io.Writer) func(bs blockstore.Blockstore, w *chain.Wallet) modules.Genesis {
return func(bs blockstore.Blockstore, w *chain.Wallet) modules.Genesis {
func MakeGenesisMem(out io.Writer) func(bs blockstore.Blockstore, w *wallet.Wallet) modules.Genesis {
return func(bs blockstore.Blockstore, w *wallet.Wallet) modules.Genesis {
return func() (*types.BlockHeader, error) {
glog.Warn("Generating new random genesis block, note that this SHOULD NOT happen unless you are setting up new network")
// TODO: make an address allocation
@ -44,8 +44,8 @@ func MakeGenesisMem(out io.Writer) func(bs blockstore.Blockstore, w *chain.Walle
}
}
func MakeGenesis(outFile string) func(bs blockstore.Blockstore, w *chain.Wallet) modules.Genesis {
return func(bs blockstore.Blockstore, w *chain.Wallet) modules.Genesis {
func MakeGenesis(outFile string) func(bs blockstore.Blockstore, w *wallet.Wallet) modules.Genesis {
return func(bs blockstore.Blockstore, w *wallet.Wallet) modules.Genesis {
return func() (*types.BlockHeader, error) {
glog.Warn("Generating new random genesis block, note that this SHOULD NOT happen unless you are setting up new network")
minerAddr, err := w.GenerateKey(types.KTSecp256k1)