implement chain generator

This commit is contained in:
whyrusleeping 2019-07-25 15:15:33 -07:00
parent e1b95fdc8d
commit 71baa5cbfe
11 changed files with 203 additions and 35 deletions

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

@ -0,0 +1,137 @@
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"
cid "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}
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
}
cg.curBlock = fblk
return fblk, nil
}

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

@ -0,0 +1,23 @@
package gen
import (
"testing"
)
func TestChainGeneration(t *testing.T) {
g, err := NewGenerator()
if err != nil {
t.Fatal(err)
}
for i := 0; i < 10; i++ {
b, err := g.NextBlock()
if err != nil {
t.Fatal(err)
}
if b.Header.Height != uint64(i+1) {
t.Fatal("wrong height")
}
}
}

View File

@ -1,4 +1,4 @@
package chain package gen
import ( import (
"context" "context"
@ -17,10 +17,6 @@ import (
"github.com/filecoin-project/go-lotus/chain/vm" "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) { 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()) st, err := cs.TipSetState(parents.Cids())
if err != nil { if err != nil {
@ -35,7 +31,7 @@ func MinerCreateBlock(ctx context.Context, cs *store.ChainStore, miner address.A
} }
// apply miner reward // apply miner reward
if err := vm.TransferFunds(actors.NetworkAddress, miner, miningRewardForBlock(parents)); err != nil { if err := vm.TransferFunds(actors.NetworkAddress, miner, vm.MiningRewardForBlock(parents)); err != nil {
return nil, err return nil, err
} }

View File

@ -10,25 +10,11 @@ import (
"github.com/filecoin-project/go-lotus/chain/types" "github.com/filecoin-project/go-lotus/chain/types"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
dstore "github.com/ipfs/go-datastore"
hamt "github.com/ipfs/go-hamt-ipld" hamt "github.com/ipfs/go-hamt-ipld"
bstore "github.com/ipfs/go-ipfs-blockstore" bstore "github.com/ipfs/go-ipfs-blockstore"
sharray "github.com/whyrusleeping/sharray" 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 { type GenesisBootstrap struct {
Genesis *types.BlockHeader Genesis *types.BlockHeader
} }

View File

@ -526,18 +526,18 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
return 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 { if err != nil {
return err 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 return err
} }
var receipts []interface{} var receipts []interface{}
for _, m := range b.Messages { for _, m := range b.Messages {
receipt, err := vm.ApplyMessage(ctx, &m.Message) receipt, err := vmi.ApplyMessage(ctx, &m.Message)
if err != nil { if err != nil {
return err return err
} }
@ -554,7 +554,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
return fmt.Errorf("receipts mismatched") return fmt.Errorf("receipts mismatched")
} }
final, err := vm.Flush(context.TODO()) final, err := vmi.Flush(context.TODO())
if err != nil { if err != nil {
return err return err
} }

View File

@ -6,11 +6,27 @@ import (
"github.com/filecoin-project/go-lotus/chain/actors" "github.com/filecoin-project/go-lotus/chain/actors"
"github.com/filecoin-project/go-lotus/chain/address" "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/state"
"github.com/filecoin-project/go-lotus/chain/types" "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) { func TryCreateAccountActor(st *state.StateTree, addr address.Address) (*types.Actor, error) {
act, err := makeActor(st, addr) act, err := makeActor(st, addr)
if err != nil { if err != nil {
@ -62,7 +78,7 @@ func NewSecp256k1AccountActor(st *state.StateTree, addr address.Address) (*types
nact := &types.Actor{ nact := &types.Actor{
Code: actors.AccountActorCodeCid, Code: actors.AccountActorCodeCid,
Balance: types.NewInt(0), Balance: types.NewInt(0),
Head: gen.EmptyObjectCid, Head: EmptyObjectCid,
} }
return nact, nil 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() links := node.Links()
for _, link := range links { for _, link := range links {
if link.Cid.Prefix().MhType == 0 {
continue
}
_, err := to.Get(ctx, link.Cid) _, err := to.Get(ctx, link.Cid)
switch err { switch err {
default: default:
@ -381,3 +384,7 @@ func DeductFunds(act *types.Actor, amt types.BigInt) error {
func DepositFunds(act *types.Actor, amt types.BigInt) { func DepositFunds(act *types.Actor, amt types.BigInt) {
act.Balance = types.BigAdd(act.Balance, amt) 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 ( import (
"sort" "sort"

View File

@ -26,6 +26,7 @@ import (
"github.com/filecoin-project/go-lotus/chain" "github.com/filecoin-project/go-lotus/chain"
"github.com/filecoin-project/go-lotus/chain/store" "github.com/filecoin-project/go-lotus/chain/store"
"github.com/filecoin-project/go-lotus/chain/types" "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/config"
"github.com/filecoin-project/go-lotus/node/hello" "github.com/filecoin-project/go-lotus/node/hello"
"github.com/filecoin-project/go-lotus/node/impl" "github.com/filecoin-project/go-lotus/node/impl"
@ -194,7 +195,7 @@ func Online() Option {
// Filecoin services // Filecoin services
Override(new(*chain.Syncer), chain.NewSyncer), Override(new(*chain.Syncer), chain.NewSyncer),
Override(new(*chain.BlockSync), chain.NewBlockSyncClient), 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(*chain.MessagePool), chain.NewMessagePool),
Override(new(modules.Genesis), modules.ErrorGenesis), 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/api"
"github.com/filecoin-project/go-lotus/chain" "github.com/filecoin-project/go-lotus/chain"
"github.com/filecoin-project/go-lotus/chain/address" "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/store"
"github.com/filecoin-project/go-lotus/chain/types" "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/miner"
"github.com/filecoin-project/go-lotus/node/client" "github.com/filecoin-project/go-lotus/node/client"
@ -28,7 +30,7 @@ type FullNodeAPI struct {
Chain *store.ChainStore Chain *store.ChainStore
PubSub *pubsub.PubSub PubSub *pubsub.PubSub
Mpool *chain.MessagePool Mpool *chain.MessagePool
Wallet *chain.Wallet Wallet *wallet.Wallet
} }
func (a *FullNodeAPI) ChainSubmitBlock(ctx context.Context, blk *chain.BlockMsg) error { 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) { 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 { if err != nil {
return nil, err return nil, err
} }

View File

@ -13,17 +13,17 @@ import (
logging "github.com/ipfs/go-log" logging "github.com/ipfs/go-log"
"github.com/ipfs/go-merkledag" "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/address"
"github.com/filecoin-project/go-lotus/chain/gen" "github.com/filecoin-project/go-lotus/chain/gen"
"github.com/filecoin-project/go-lotus/chain/types" "github.com/filecoin-project/go-lotus/chain/types"
"github.com/filecoin-project/go-lotus/chain/wallet"
"github.com/filecoin-project/go-lotus/node/modules" "github.com/filecoin-project/go-lotus/node/modules"
) )
var glog = logging.Logger("genesis") var glog = logging.Logger("genesis")
func MakeGenesisMem(out io.Writer) 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 *chain.Wallet) modules.Genesis { return func(bs blockstore.Blockstore, w *wallet.Wallet) modules.Genesis {
return func() (*types.BlockHeader, error) { 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") 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 // 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 { func MakeGenesis(outFile string) func(bs blockstore.Blockstore, w *wallet.Wallet) modules.Genesis {
return func(bs blockstore.Blockstore, w *chain.Wallet) modules.Genesis { return func(bs blockstore.Blockstore, w *wallet.Wallet) modules.Genesis {
return func() (*types.BlockHeader, error) { 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") 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) minerAddr, err := w.GenerateKey(types.KTSecp256k1)