Merge pull request #87 from filecoin-project/refactor/types-again
pull more things apart
This commit is contained in:
commit
0c6a8f8c5f
@ -64,16 +64,16 @@ type FullNode interface {
|
|||||||
Common
|
Common
|
||||||
|
|
||||||
// chain
|
// chain
|
||||||
ChainHead(context.Context) (*chain.TipSet, error) // TODO: check serialization
|
ChainHead(context.Context) (*types.TipSet, error) // TODO: check serialization
|
||||||
ChainSubmitBlock(ctx context.Context, blk *chain.BlockMsg) error // TODO: check serialization
|
ChainSubmitBlock(ctx context.Context, blk *chain.BlockMsg) error // TODO: check serialization
|
||||||
ChainGetRandomness(context.Context, *chain.TipSet) ([]byte, error)
|
ChainGetRandomness(context.Context, *types.TipSet) ([]byte, error)
|
||||||
ChainWaitMsg(context.Context, cid.Cid) (*MsgWait, error)
|
ChainWaitMsg(context.Context, cid.Cid) (*MsgWait, error)
|
||||||
ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error)
|
ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error)
|
||||||
ChainGetBlockMessages(context.Context, cid.Cid) ([]*types.SignedMessage, error)
|
ChainGetBlockMessages(context.Context, cid.Cid) ([]*types.SignedMessage, error)
|
||||||
|
|
||||||
// messages
|
// messages
|
||||||
|
|
||||||
MpoolPending(context.Context, *chain.TipSet) ([]*types.SignedMessage, error)
|
MpoolPending(context.Context, *types.TipSet) ([]*types.SignedMessage, error)
|
||||||
MpoolPush(context.Context, *types.SignedMessage) error
|
MpoolPush(context.Context, *types.SignedMessage) error
|
||||||
|
|
||||||
// FullNodeStruct
|
// FullNodeStruct
|
||||||
@ -81,7 +81,7 @@ type FullNode interface {
|
|||||||
// miner
|
// miner
|
||||||
|
|
||||||
MinerStart(context.Context, address.Address) error
|
MinerStart(context.Context, address.Address) error
|
||||||
MinerCreateBlock(context.Context, address.Address, *chain.TipSet, []types.Ticket, types.ElectionProof, []*types.SignedMessage) (*chain.BlockMsg, error)
|
MinerCreateBlock(context.Context, address.Address, *types.TipSet, []types.Ticket, types.ElectionProof, []*types.SignedMessage) (*chain.BlockMsg, error)
|
||||||
|
|
||||||
// // UX ?
|
// // UX ?
|
||||||
|
|
||||||
|
@ -38,17 +38,17 @@ type FullNodeStruct struct {
|
|||||||
|
|
||||||
Internal struct {
|
Internal struct {
|
||||||
ChainSubmitBlock func(ctx context.Context, blk *chain.BlockMsg) error `perm:"write"`
|
ChainSubmitBlock func(ctx context.Context, blk *chain.BlockMsg) error `perm:"write"`
|
||||||
ChainHead func(context.Context) (*chain.TipSet, error) `perm:"read"`
|
ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"`
|
||||||
ChainGetRandomness func(context.Context, *chain.TipSet) ([]byte, error) `perm:"read"`
|
ChainGetRandomness func(context.Context, *types.TipSet) ([]byte, error) `perm:"read"`
|
||||||
ChainWaitMsg func(context.Context, cid.Cid) (*MsgWait, error) `perm:"read"`
|
ChainWaitMsg func(context.Context, cid.Cid) (*MsgWait, error) `perm:"read"`
|
||||||
ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"`
|
ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"`
|
||||||
ChainGetBlockMessages func(context.Context, cid.Cid) ([]*types.SignedMessage, error) `perm:"read"`
|
ChainGetBlockMessages func(context.Context, cid.Cid) ([]*types.SignedMessage, error) `perm:"read"`
|
||||||
|
|
||||||
MpoolPending func(context.Context, *chain.TipSet) ([]*types.SignedMessage, error) `perm:"read"`
|
MpoolPending func(context.Context, *types.TipSet) ([]*types.SignedMessage, error) `perm:"read"`
|
||||||
MpoolPush func(context.Context, *types.SignedMessage) error `perm:"write"`
|
MpoolPush func(context.Context, *types.SignedMessage) error `perm:"write"`
|
||||||
|
|
||||||
MinerStart func(context.Context, address.Address) error `perm:"admin"`
|
MinerStart func(context.Context, address.Address) error `perm:"admin"`
|
||||||
MinerCreateBlock func(context.Context, address.Address, *chain.TipSet, []types.Ticket, types.ElectionProof, []*types.SignedMessage) (*chain.BlockMsg, error) `perm:"write"`
|
MinerCreateBlock func(context.Context, address.Address, *types.TipSet, []types.Ticket, types.ElectionProof, []*types.SignedMessage) (*chain.BlockMsg, error) `perm:"write"`
|
||||||
|
|
||||||
WalletNew func(context.Context, string) (address.Address, error) `perm:"write"`
|
WalletNew func(context.Context, string) (address.Address, error) `perm:"write"`
|
||||||
WalletList func(context.Context) ([]address.Address, error) `perm:"write"`
|
WalletList func(context.Context) ([]address.Address, error) `perm:"write"`
|
||||||
@ -115,7 +115,7 @@ func (c *FullNodeStruct) ClientImport(ctx context.Context, path string) (cid.Cid
|
|||||||
return c.Internal.ClientImport(ctx, path)
|
return c.Internal.ClientImport(ctx, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) MpoolPending(ctx context.Context, ts *chain.TipSet) ([]*types.SignedMessage, error) {
|
func (c *FullNodeStruct) MpoolPending(ctx context.Context, ts *types.TipSet) ([]*types.SignedMessage, error) {
|
||||||
return c.Internal.MpoolPending(ctx, ts)
|
return c.Internal.MpoolPending(ctx, ts)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ func (c *FullNodeStruct) MinerStart(ctx context.Context, addr address.Address) e
|
|||||||
return c.Internal.MinerStart(ctx, addr)
|
return c.Internal.MinerStart(ctx, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) MinerCreateBlock(ctx context.Context, addr address.Address, base *chain.TipSet, tickets []types.Ticket, eproof types.ElectionProof, msgs []*types.SignedMessage) (*chain.BlockMsg, error) {
|
func (c *FullNodeStruct) MinerCreateBlock(ctx context.Context, addr address.Address, base *types.TipSet, tickets []types.Ticket, eproof types.ElectionProof, msgs []*types.SignedMessage) (*chain.BlockMsg, error) {
|
||||||
return c.Internal.MinerCreateBlock(ctx, addr, base, tickets, eproof, msgs)
|
return c.Internal.MinerCreateBlock(ctx, addr, base, tickets, eproof, msgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,11 +135,11 @@ func (c *FullNodeStruct) ChainSubmitBlock(ctx context.Context, blk *chain.BlockM
|
|||||||
return c.Internal.ChainSubmitBlock(ctx, blk)
|
return c.Internal.ChainSubmitBlock(ctx, blk)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) ChainHead(ctx context.Context) (*chain.TipSet, error) {
|
func (c *FullNodeStruct) ChainHead(ctx context.Context) (*types.TipSet, error) {
|
||||||
return c.Internal.ChainHead(ctx)
|
return c.Internal.ChainHead(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) ChainGetRandomness(ctx context.Context, pts *chain.TipSet) ([]byte, error) {
|
func (c *FullNodeStruct) ChainGetRandomness(ctx context.Context, pts *types.TipSet) ([]byte, error) {
|
||||||
return c.Internal.ChainGetRandomness(ctx, pts)
|
return c.Internal.ChainGetRandomness(ctx, pts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,11 +4,12 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/chain"
|
|
||||||
. "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/gen"
|
||||||
|
"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/vm"
|
||||||
dstore "github.com/ipfs/go-datastore"
|
dstore "github.com/ipfs/go-datastore"
|
||||||
bstore "github.com/ipfs/go-ipfs-blockstore"
|
bstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
@ -26,7 +27,7 @@ func blsaddr(n uint64) address.Address {
|
|||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupVMTestEnv(t *testing.T) (*chain.VM, []address.Address) {
|
func setupVMTestEnv(t *testing.T) (*vm.VM, []address.Address) {
|
||||||
bs := bstore.NewBlockstore(dstore.NewMapDatastore())
|
bs := bstore.NewBlockstore(dstore.NewMapDatastore())
|
||||||
|
|
||||||
from := blsaddr(0)
|
from := blsaddr(0)
|
||||||
@ -46,9 +47,9 @@ func setupVMTestEnv(t *testing.T) (*chain.VM, []address.Address) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cs := chain.NewChainStore(bs, nil)
|
cs := store.NewChainStore(bs, nil)
|
||||||
|
|
||||||
vm, err := chain.NewVM(stateroot, 1, maddr, cs)
|
vm, err := vm.NewVM(stateroot, 1, maddr, cs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,9 @@ import (
|
|||||||
|
|
||||||
. "github.com/filecoin-project/go-lotus/chain/actors"
|
. "github.com/filecoin-project/go-lotus/chain/actors"
|
||||||
"github.com/filecoin-project/go-lotus/chain/gen"
|
"github.com/filecoin-project/go-lotus/chain/gen"
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/store"
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/vm"
|
||||||
|
|
||||||
"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/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"
|
||||||
@ -27,9 +28,9 @@ type Harness struct {
|
|||||||
|
|
||||||
t *testing.T
|
t *testing.T
|
||||||
actors []address.Address
|
actors []address.Address
|
||||||
vm *chain.VM
|
vm *vm.VM
|
||||||
bs bstore.Blockstore
|
bs bstore.Blockstore
|
||||||
cs *chain.ChainStore
|
cs *store.ChainStore
|
||||||
}
|
}
|
||||||
|
|
||||||
type Step struct {
|
type Step struct {
|
||||||
@ -61,9 +62,9 @@ func NewHarness(t *testing.T) *Harness {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
h.cs = chain.NewChainStore(h.bs, nil)
|
h.cs = store.NewChainStore(h.bs, nil)
|
||||||
|
|
||||||
h.vm, err = chain.NewVM(stateroot, 1, maddr, h.cs)
|
h.vm, err = vm.NewVM(stateroot, 1, maddr, h.cs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/libp2p/go-libp2p-core/host"
|
"github.com/libp2p/go-libp2p-core/host"
|
||||||
"github.com/libp2p/go-libp2p-core/protocol"
|
"github.com/libp2p/go-libp2p-core/protocol"
|
||||||
|
|
||||||
|
"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/lib/cborrpc"
|
"github.com/filecoin-project/go-lotus/lib/cborrpc"
|
||||||
|
|
||||||
@ -31,7 +32,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BlockSyncService struct {
|
type BlockSyncService struct {
|
||||||
cs *ChainStore
|
cs *store.ChainStore
|
||||||
}
|
}
|
||||||
|
|
||||||
type BlockSyncRequest struct {
|
type BlockSyncRequest struct {
|
||||||
@ -72,7 +73,7 @@ type BSTipSet struct {
|
|||||||
MsgIncludes [][]int
|
MsgIncludes [][]int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBlockSyncService(cs *ChainStore) *BlockSyncService {
|
func NewBlockSyncService(cs *store.ChainStore) *BlockSyncService {
|
||||||
return &BlockSyncService{
|
return &BlockSyncService{
|
||||||
cs: cs,
|
cs: cs,
|
||||||
}
|
}
|
||||||
@ -154,7 +155,7 @@ func (bss *BlockSyncService) collectChainSegment(start []cid.Cid, length uint64,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bss *BlockSyncService) gatherMessages(ts *TipSet) ([]*types.SignedMessage, [][]int, error) {
|
func (bss *BlockSyncService) gatherMessages(ts *types.TipSet) ([]*types.SignedMessage, [][]int, error) {
|
||||||
msgmap := make(map[cid.Cid]int)
|
msgmap := make(map[cid.Cid]int)
|
||||||
var allmsgs []*types.SignedMessage
|
var allmsgs []*types.SignedMessage
|
||||||
var msgincl [][]int
|
var msgincl [][]int
|
||||||
@ -209,7 +210,7 @@ func (bs *BlockSync) getPeers() []peer.ID {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BlockSync) GetBlocks(ctx context.Context, tipset []cid.Cid, count int) ([]*TipSet, error) {
|
func (bs *BlockSync) GetBlocks(ctx context.Context, tipset []cid.Cid, count int) ([]*types.TipSet, error) {
|
||||||
peers := bs.getPeers()
|
peers := bs.getPeers()
|
||||||
perm := rand.Perm(len(peers))
|
perm := rand.Perm(len(peers))
|
||||||
// TODO: round robin through these peers on error
|
// TODO: round robin through these peers on error
|
||||||
@ -241,7 +242,7 @@ func (bs *BlockSync) GetBlocks(ctx context.Context, tipset []cid.Cid, count int)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BlockSync) GetFullTipSet(ctx context.Context, p peer.ID, h []cid.Cid) (*FullTipSet, error) {
|
func (bs *BlockSync) GetFullTipSet(ctx context.Context, p peer.ID, h []cid.Cid) (*store.FullTipSet, error) {
|
||||||
// TODO: round robin through these peers on error
|
// TODO: round robin through these peers on error
|
||||||
|
|
||||||
req := &BlockSyncRequest{
|
req := &BlockSyncRequest{
|
||||||
@ -276,7 +277,7 @@ func (bs *BlockSync) GetFullTipSet(ctx context.Context, p peer.ID, h []cid.Cid)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BlockSync) GetChainMessages(ctx context.Context, h *TipSet, count uint64) ([]*BSTipSet, error) {
|
func (bs *BlockSync) GetChainMessages(ctx context.Context, h *types.TipSet, count uint64) ([]*BSTipSet, error) {
|
||||||
peers := bs.getPeers()
|
peers := bs.getPeers()
|
||||||
perm := rand.Perm(len(peers))
|
perm := rand.Perm(len(peers))
|
||||||
// TODO: round robin through these peers on error
|
// TODO: round robin through these peers on error
|
||||||
@ -308,8 +309,8 @@ func (bs *BlockSync) GetChainMessages(ctx context.Context, h *TipSet, count uint
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func bstsToFullTipSet(bts *BSTipSet) (*FullTipSet, error) {
|
func bstsToFullTipSet(bts *BSTipSet) (*store.FullTipSet, error) {
|
||||||
fts := &FullTipSet{}
|
fts := &store.FullTipSet{}
|
||||||
for i, b := range bts.Blocks {
|
for i, b := range bts.Blocks {
|
||||||
fb := &types.FullBlock{
|
fb := &types.FullBlock{
|
||||||
Header: b,
|
Header: b,
|
||||||
@ -341,16 +342,16 @@ func (bs *BlockSync) sendRequestToPeer(ctx context.Context, p peer.ID, req *Bloc
|
|||||||
return &res, nil
|
return &res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BlockSync) processBlocksResponse(req *BlockSyncRequest, res *BlockSyncResponse) ([]*TipSet, error) {
|
func (bs *BlockSync) processBlocksResponse(req *BlockSyncRequest, res *BlockSyncResponse) ([]*types.TipSet, error) {
|
||||||
cur, err := NewTipSet(res.Chain[0].Blocks)
|
cur, err := types.NewTipSet(res.Chain[0].Blocks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
out := []*TipSet{cur}
|
out := []*types.TipSet{cur}
|
||||||
for bi := 1; bi < len(res.Chain); bi++ {
|
for bi := 1; bi < len(res.Chain); bi++ {
|
||||||
next := res.Chain[bi].Blocks
|
next := res.Chain[bi].Blocks
|
||||||
nts, err := NewTipSet(next)
|
nts, err := types.NewTipSet(next)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/chain/address"
|
"github.com/filecoin-project/go-lotus/chain/address"
|
||||||
"github.com/filecoin-project/go-lotus/chain/state"
|
"github.com/filecoin-project/go-lotus/chain/store"
|
||||||
"github.com/filecoin-project/go-lotus/chain/types"
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
hamt "github.com/ipfs/go-hamt-ipld"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type MessagePool struct {
|
type MessagePool struct {
|
||||||
@ -14,7 +13,7 @@ type MessagePool struct {
|
|||||||
|
|
||||||
pending map[address.Address]*msgSet
|
pending map[address.Address]*msgSet
|
||||||
|
|
||||||
cs *ChainStore
|
cs *store.ChainStore
|
||||||
}
|
}
|
||||||
|
|
||||||
type msgSet struct {
|
type msgSet struct {
|
||||||
@ -35,7 +34,7 @@ func (ms *msgSet) add(m *types.SignedMessage) {
|
|||||||
ms.msgs[m.Message.Nonce] = m
|
ms.msgs[m.Message.Nonce] = m
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMessagePool(cs *ChainStore) *MessagePool {
|
func NewMessagePool(cs *store.ChainStore) *MessagePool {
|
||||||
mp := &MessagePool{
|
mp := &MessagePool{
|
||||||
pending: make(map[address.Address]*msgSet),
|
pending: make(map[address.Address]*msgSet),
|
||||||
cs: cs,
|
cs: cs,
|
||||||
@ -58,12 +57,7 @@ func (mp *MessagePool) Add(m *types.SignedMessage) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
msb, err := m.ToStorageBlock()
|
if _, err := mp.cs.PutMessage(m); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := mp.cs.bs.Put(msb); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,20 +80,7 @@ func (mp *MessagePool) GetNonce(addr address.Address) (uint64, error) {
|
|||||||
return mset.startNonce + uint64(len(mset.msgs)), nil
|
return mset.startNonce + uint64(len(mset.msgs)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
head := mp.cs.GetHeaviestTipSet()
|
act, err := mp.cs.GetActor(addr)
|
||||||
|
|
||||||
stc, err := mp.cs.TipSetState(head.Cids())
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
cst := hamt.CSTFromBstore(mp.cs.bs)
|
|
||||||
st, err := state.LoadStateTree(cst, stc)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
act, err := st.GetActor(addr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@ -142,7 +123,7 @@ func (mp *MessagePool) Pending() []*types.SignedMessage {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mp *MessagePool) HeadChange(revert []*TipSet, apply []*TipSet) error {
|
func (mp *MessagePool) HeadChange(revert []*types.TipSet, apply []*types.TipSet) error {
|
||||||
for _, ts := range revert {
|
for _, ts := range revert {
|
||||||
for _, b := range ts.Blocks() {
|
for _, b := range ts.Blocks() {
|
||||||
msgs, err := mp.cs.MessagesForBlock(b)
|
msgs, err := mp.cs.MessagesForBlock(b)
|
||||||
|
@ -12,14 +12,16 @@ 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/store"
|
||||||
"github.com/filecoin-project/go-lotus/chain/types"
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/vm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func miningRewardForBlock(base *TipSet) types.BigInt {
|
func miningRewardForBlock(base *types.TipSet) types.BigInt {
|
||||||
return types.NewInt(10000)
|
return types.NewInt(10000)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MinerCreateBlock(cs *ChainStore, miner address.Address, parents *TipSet, tickets []types.Ticket, proof types.ElectionProof, msgs []*types.SignedMessage) (*types.FullBlock, error) {
|
func MinerCreateBlock(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 {
|
||||||
return nil, errors.Wrap(err, "failed to load tipset state")
|
return nil, errors.Wrap(err, "failed to load tipset state")
|
||||||
@ -27,7 +29,7 @@ func MinerCreateBlock(cs *ChainStore, miner address.Address, parents *TipSet, ti
|
|||||||
|
|
||||||
height := parents.Height() + uint64(len(tickets))
|
height := parents.Height() + uint64(len(tickets))
|
||||||
|
|
||||||
vm, err := NewVM(st, height, miner, cs)
|
vm, err := vm.NewVM(st, height, miner, cs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -52,15 +54,12 @@ func MinerCreateBlock(cs *ChainStore, miner address.Address, parents *TipSet, ti
|
|||||||
if msg.Signature.TypeCode() == 2 {
|
if msg.Signature.TypeCode() == 2 {
|
||||||
blsSigs = append(blsSigs, msg.Signature)
|
blsSigs = append(blsSigs, msg.Signature)
|
||||||
|
|
||||||
blk, err := msg.Message.ToStorageBlock()
|
c, err := cs.PutMessage(&msg.Message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := cs.bs.Put(blk); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
msgCids = append(msgCids, blk.Cid())
|
msgCids = append(msgCids, c)
|
||||||
} else {
|
} else {
|
||||||
msgCids = append(msgCids, msg.Cid())
|
msgCids = append(msgCids, msg.Cid())
|
||||||
}
|
}
|
||||||
@ -72,7 +71,7 @@ func MinerCreateBlock(cs *ChainStore, miner address.Address, parents *TipSet, ti
|
|||||||
receipts = append(receipts, rec)
|
receipts = append(receipts, rec)
|
||||||
}
|
}
|
||||||
|
|
||||||
cst := hamt.CSTFromBstore(cs.bs)
|
cst := hamt.CSTFromBstore(cs.Blockstore())
|
||||||
msgroot, err := sharray.Build(context.TODO(), 4, toIfArr(msgCids), cst)
|
msgroot, err := sharray.Build(context.TODO(), 4, toIfArr(msgCids), cst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
51
chain/store/fts.go
Normal file
51
chain/store/fts.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package store
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FullTipSet is an expanded version of the TipSet that contains all the blocks and messages
|
||||||
|
type FullTipSet struct {
|
||||||
|
Blocks []*types.FullBlock
|
||||||
|
tipset *types.TipSet
|
||||||
|
cids []cid.Cid
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFullTipSet(blks []*types.FullBlock) *FullTipSet {
|
||||||
|
return &FullTipSet{
|
||||||
|
Blocks: blks,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fts *FullTipSet) Cids() []cid.Cid {
|
||||||
|
if fts.cids != nil {
|
||||||
|
return fts.cids
|
||||||
|
}
|
||||||
|
|
||||||
|
var cids []cid.Cid
|
||||||
|
for _, b := range fts.Blocks {
|
||||||
|
cids = append(cids, b.Cid())
|
||||||
|
}
|
||||||
|
fts.cids = cids
|
||||||
|
|
||||||
|
return cids
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fts *FullTipSet) TipSet() *types.TipSet {
|
||||||
|
if fts.tipset != nil {
|
||||||
|
return fts.tipset
|
||||||
|
}
|
||||||
|
|
||||||
|
var headers []*types.BlockHeader
|
||||||
|
for _, b := range fts.Blocks {
|
||||||
|
headers = append(headers, b.Header)
|
||||||
|
}
|
||||||
|
|
||||||
|
ts, err := types.NewTipSet(headers)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ts
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package chain
|
package store
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -10,9 +10,11 @@ import (
|
|||||||
"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"
|
||||||
|
|
||||||
|
block "github.com/ipfs/go-block-format"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
dstore "github.com/ipfs/go-datastore"
|
dstore "github.com/ipfs/go-datastore"
|
||||||
hamt "github.com/ipfs/go-hamt-ipld"
|
hamt "github.com/ipfs/go-hamt-ipld"
|
||||||
|
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
bstore "github.com/ipfs/go-ipfs-blockstore"
|
bstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
logging "github.com/ipfs/go-log"
|
logging "github.com/ipfs/go-log"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -20,9 +22,7 @@ import (
|
|||||||
sharray "github.com/whyrusleeping/sharray"
|
sharray "github.com/whyrusleeping/sharray"
|
||||||
)
|
)
|
||||||
|
|
||||||
const ForkLengthThreshold = 20
|
var log = logging.Logger("chainstore")
|
||||||
|
|
||||||
var log = logging.Logger("f2")
|
|
||||||
|
|
||||||
var chainHeadKey = dstore.NewKey("head")
|
var chainHeadKey = dstore.NewKey("head")
|
||||||
|
|
||||||
@ -31,11 +31,11 @@ type ChainStore struct {
|
|||||||
ds dstore.Datastore
|
ds dstore.Datastore
|
||||||
|
|
||||||
heaviestLk sync.Mutex
|
heaviestLk sync.Mutex
|
||||||
heaviest *TipSet
|
heaviest *types.TipSet
|
||||||
|
|
||||||
bestTips *pubsub.PubSub
|
bestTips *pubsub.PubSub
|
||||||
|
|
||||||
headChangeNotifs []func(rev, app []*TipSet) error
|
headChangeNotifs []func(rev, app []*types.TipSet) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewChainStore(bs bstore.Blockstore, ds dstore.Batching) *ChainStore {
|
func NewChainStore(bs bstore.Blockstore, ds dstore.Batching) *ChainStore {
|
||||||
@ -71,7 +71,7 @@ func (cs *ChainStore) Load() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) writeHead(ts *TipSet) error {
|
func (cs *ChainStore) writeHead(ts *types.TipSet) error {
|
||||||
data, err := json.Marshal(ts.Cids())
|
data, err := json.Marshal(ts.Cids())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to marshal tipset")
|
return errors.Wrap(err, "failed to marshal tipset")
|
||||||
@ -84,13 +84,13 @@ func (cs *ChainStore) writeHead(ts *TipSet) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) SubNewTips() chan *TipSet {
|
func (cs *ChainStore) SubNewTips() chan *types.TipSet {
|
||||||
subch := cs.bestTips.Sub("best")
|
subch := cs.bestTips.Sub("best")
|
||||||
out := make(chan *TipSet)
|
out := make(chan *types.TipSet)
|
||||||
go func() {
|
go func() {
|
||||||
defer close(out)
|
defer close(out)
|
||||||
for val := range subch {
|
for val := range subch {
|
||||||
out <- val.(*TipSet)
|
out <- val.(*types.TipSet)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
return out
|
return out
|
||||||
@ -103,7 +103,7 @@ const (
|
|||||||
|
|
||||||
type HeadChange struct {
|
type HeadChange struct {
|
||||||
Type string
|
Type string
|
||||||
Val *TipSet
|
Val *types.TipSet
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) SubHeadChanges() chan *HeadChange {
|
func (cs *ChainStore) SubHeadChanges() chan *HeadChange {
|
||||||
@ -118,12 +118,12 @@ func (cs *ChainStore) SubHeadChanges() chan *HeadChange {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) SubscribeHeadChanges(f func(rev, app []*TipSet) error) {
|
func (cs *ChainStore) SubscribeHeadChanges(f func(rev, app []*types.TipSet) error) {
|
||||||
cs.headChangeNotifs = append(cs.headChangeNotifs, f)
|
cs.headChangeNotifs = append(cs.headChangeNotifs, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) SetGenesis(b *types.BlockHeader) error {
|
func (cs *ChainStore) SetGenesis(b *types.BlockHeader) error {
|
||||||
gents, err := NewTipSet([]*types.BlockHeader{b})
|
gents, err := types.NewTipSet([]*types.BlockHeader{b})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -149,11 +149,11 @@ func (cs *ChainStore) PutTipSet(ts *FullTipSet) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cs.maybeTakeHeavierTipSet(ts.TipSet())
|
cs.MaybeTakeHeavierTipSet(ts.TipSet())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) maybeTakeHeavierTipSet(ts *TipSet) error {
|
func (cs *ChainStore) MaybeTakeHeavierTipSet(ts *types.TipSet) error {
|
||||||
cs.heaviestLk.Lock()
|
cs.heaviestLk.Lock()
|
||||||
defer cs.heaviestLk.Unlock()
|
defer cs.heaviestLk.Unlock()
|
||||||
if cs.heaviest == nil || cs.Weight(ts) > cs.Weight(cs.heaviest) {
|
if cs.heaviest == nil || cs.Weight(ts) > cs.Weight(cs.heaviest) {
|
||||||
@ -175,8 +175,8 @@ func (cs *ChainStore) maybeTakeHeavierTipSet(ts *TipSet) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) Contains(ts *TipSet) (bool, error) {
|
func (cs *ChainStore) Contains(ts *types.TipSet) (bool, error) {
|
||||||
for _, c := range ts.cids {
|
for _, c := range ts.Cids() {
|
||||||
has, err := cs.bs.Has(c)
|
has, err := cs.bs.Has(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
@ -198,7 +198,7 @@ func (cs *ChainStore) GetBlock(c cid.Cid) (*types.BlockHeader, error) {
|
|||||||
return types.DecodeBlock(sb.RawData())
|
return types.DecodeBlock(sb.RawData())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) LoadTipSet(cids []cid.Cid) (*TipSet, error) {
|
func (cs *ChainStore) LoadTipSet(cids []cid.Cid) (*types.TipSet, error) {
|
||||||
var blks []*types.BlockHeader
|
var blks []*types.BlockHeader
|
||||||
for _, c := range cids {
|
for _, c := range cids {
|
||||||
b, err := cs.GetBlock(c)
|
b, err := cs.GetBlock(c)
|
||||||
@ -209,11 +209,11 @@ func (cs *ChainStore) LoadTipSet(cids []cid.Cid) (*TipSet, error) {
|
|||||||
blks = append(blks, b)
|
blks = append(blks, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewTipSet(blks)
|
return types.NewTipSet(blks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns true if 'a' is an ancestor of 'b'
|
// returns true if 'a' is an ancestor of 'b'
|
||||||
func (cs *ChainStore) IsAncestorOf(a, b *TipSet) (bool, error) {
|
func (cs *ChainStore) IsAncestorOf(a, b *types.TipSet) (bool, error) {
|
||||||
if b.Height() <= a.Height() {
|
if b.Height() <= a.Height() {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
@ -231,7 +231,7 @@ func (cs *ChainStore) IsAncestorOf(a, b *TipSet) (bool, error) {
|
|||||||
return cur.Equals(a), nil
|
return cur.Equals(a), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) NearestCommonAncestor(a, b *TipSet) (*TipSet, error) {
|
func (cs *ChainStore) NearestCommonAncestor(a, b *types.TipSet) (*types.TipSet, error) {
|
||||||
l, _, err := cs.ReorgOps(a, b)
|
l, _, err := cs.ReorgOps(a, b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -240,11 +240,11 @@ func (cs *ChainStore) NearestCommonAncestor(a, b *TipSet) (*TipSet, error) {
|
|||||||
return cs.LoadTipSet(l[len(l)-1].Parents())
|
return cs.LoadTipSet(l[len(l)-1].Parents())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) ReorgOps(a, b *TipSet) ([]*TipSet, []*TipSet, error) {
|
func (cs *ChainStore) ReorgOps(a, b *types.TipSet) ([]*types.TipSet, []*types.TipSet, error) {
|
||||||
left := a
|
left := a
|
||||||
right := b
|
right := b
|
||||||
|
|
||||||
var leftChain, rightChain []*TipSet
|
var leftChain, rightChain []*types.TipSet
|
||||||
for !left.Equals(right) {
|
for !left.Equals(right) {
|
||||||
if left.Height() > right.Height() {
|
if left.Height() > right.Height() {
|
||||||
leftChain = append(leftChain, left)
|
leftChain = append(leftChain, left)
|
||||||
@ -268,17 +268,17 @@ func (cs *ChainStore) ReorgOps(a, b *TipSet) ([]*TipSet, []*TipSet, error) {
|
|||||||
return leftChain, rightChain, nil
|
return leftChain, rightChain, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) Weight(ts *TipSet) uint64 {
|
func (cs *ChainStore) Weight(ts *types.TipSet) uint64 {
|
||||||
return ts.Blocks()[0].ParentWeight.Uint64() + uint64(len(ts.Cids()))
|
return ts.Blocks()[0].ParentWeight.Uint64() + uint64(len(ts.Cids()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) GetHeaviestTipSet() *TipSet {
|
func (cs *ChainStore) GetHeaviestTipSet() *types.TipSet {
|
||||||
cs.heaviestLk.Lock()
|
cs.heaviestLk.Lock()
|
||||||
defer cs.heaviestLk.Unlock()
|
defer cs.heaviestLk.Unlock()
|
||||||
return cs.heaviest
|
return cs.heaviest
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) persistBlockHeader(b *types.BlockHeader) error {
|
func (cs *ChainStore) PersistBlockHeader(b *types.BlockHeader) error {
|
||||||
sb, err := b.ToStorageBlock()
|
sb, err := b.ToStorageBlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -288,34 +288,38 @@ func (cs *ChainStore) persistBlockHeader(b *types.BlockHeader) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) persistBlock(b *types.FullBlock) error {
|
func (cs *ChainStore) persistBlock(b *types.FullBlock) error {
|
||||||
if err := cs.persistBlockHeader(b.Header); err != nil {
|
if err := cs.PersistBlockHeader(b.Header); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, m := range b.Messages {
|
for _, m := range b.Messages {
|
||||||
if err := cs.PutMessage(m); err != nil {
|
if _, err := cs.PutMessage(m); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) PutMessage(m *types.SignedMessage) error {
|
type storable interface {
|
||||||
|
ToStorageBlock() (block.Block, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cs *ChainStore) PutMessage(m storable) (cid.Cid, error) {
|
||||||
sb, err := m.ToStorageBlock()
|
sb, err := m.ToStorageBlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return cs.bs.Put(sb)
|
return sb.Cid(), cs.bs.Put(sb)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) AddBlock(b *types.BlockHeader) error {
|
func (cs *ChainStore) AddBlock(b *types.BlockHeader) error {
|
||||||
if err := cs.persistBlockHeader(b); err != nil {
|
if err := cs.PersistBlockHeader(b); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ts, _ := NewTipSet([]*types.BlockHeader{b})
|
ts, _ := types.NewTipSet([]*types.BlockHeader{b})
|
||||||
cs.maybeTakeHeavierTipSet(ts)
|
cs.MaybeTakeHeavierTipSet(ts)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -436,19 +440,7 @@ func (cs *ChainStore) LoadMessagesFromCids(cids []cid.Cid) ([]*types.SignedMessa
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) GetBalance(addr address.Address) (types.BigInt, error) {
|
func (cs *ChainStore) GetBalance(addr address.Address) (types.BigInt, error) {
|
||||||
ts := cs.GetHeaviestTipSet()
|
act, err := cs.GetActor(addr)
|
||||||
stcid, err := cs.TipSetState(ts.Cids())
|
|
||||||
if err != nil {
|
|
||||||
return types.BigInt{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
cst := hamt.CSTFromBstore(cs.bs)
|
|
||||||
state, err := state.LoadStateTree(cst, stcid)
|
|
||||||
if err != nil {
|
|
||||||
return types.BigInt{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
act, err := state.GetActor(addr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.BigInt{}, err
|
return types.BigInt{}, err
|
||||||
}
|
}
|
||||||
@ -456,6 +448,22 @@ func (cs *ChainStore) GetBalance(addr address.Address) (types.BigInt, error) {
|
|||||||
return act.Balance, nil
|
return act.Balance, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cs *ChainStore) GetActor(addr address.Address) (*types.Actor, error) {
|
||||||
|
ts := cs.GetHeaviestTipSet()
|
||||||
|
stcid, err := cs.TipSetState(ts.Cids())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cst := hamt.CSTFromBstore(cs.bs)
|
||||||
|
state, err := state.LoadStateTree(cst, stcid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return state.GetActor(addr)
|
||||||
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) WaitForMessage(ctx context.Context, mcid cid.Cid) (cid.Cid, *types.MessageReceipt, error) {
|
func (cs *ChainStore) WaitForMessage(ctx context.Context, mcid cid.Cid) (cid.Cid, *types.MessageReceipt, error) {
|
||||||
tsub := cs.SubHeadChanges()
|
tsub := cs.SubHeadChanges()
|
||||||
|
|
||||||
@ -491,7 +499,7 @@ func (cs *ChainStore) WaitForMessage(ctx context.Context, mcid cid.Cid) (cid.Cid
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) tipsetContainsMsg(ts *TipSet, msg cid.Cid) (cid.Cid, *types.MessageReceipt, error) {
|
func (cs *ChainStore) tipsetContainsMsg(ts *types.TipSet, msg cid.Cid) (cid.Cid, *types.MessageReceipt, error) {
|
||||||
for _, b := range ts.Blocks() {
|
for _, b := range ts.Blocks() {
|
||||||
r, err := cs.blockContainsMsg(b, msg)
|
r, err := cs.blockContainsMsg(b, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -518,3 +526,7 @@ func (cs *ChainStore) blockContainsMsg(blk *types.BlockHeader, msg cid.Cid) (*ty
|
|||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cs *ChainStore) Blockstore() blockstore.Blockstore {
|
||||||
|
return cs.bs
|
||||||
|
}
|
199
chain/sync.go
199
chain/sync.go
@ -6,29 +6,33 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"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/store"
|
||||||
"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/filecoin-project/go-lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/vm"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
dstore "github.com/ipfs/go-datastore"
|
dstore "github.com/ipfs/go-datastore"
|
||||||
"github.com/ipfs/go-hamt-ipld"
|
"github.com/ipfs/go-hamt-ipld"
|
||||||
bstore "github.com/ipfs/go-ipfs-blockstore"
|
bstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
|
logging "github.com/ipfs/go-log"
|
||||||
peer "github.com/libp2p/go-libp2p-core/peer"
|
peer "github.com/libp2p/go-libp2p-core/peer"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/whyrusleeping/sharray"
|
"github.com/whyrusleeping/sharray"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const ForkLengthThreshold = 20
|
||||||
|
|
||||||
|
var log = logging.Logger("chain")
|
||||||
|
|
||||||
type Syncer struct {
|
type Syncer struct {
|
||||||
// The heaviest known tipset in the network.
|
// The heaviest known tipset in the network.
|
||||||
head *TipSet
|
head *types.TipSet
|
||||||
|
|
||||||
// The interface for accessing and putting tipsets into local storage
|
// The interface for accessing and putting tipsets into local storage
|
||||||
store *ChainStore
|
store *store.ChainStore
|
||||||
|
|
||||||
// The known Genesis tipset
|
// The known Genesis tipset
|
||||||
Genesis *TipSet
|
Genesis *types.TipSet
|
||||||
|
|
||||||
// the current mode the syncer is in
|
// the current mode the syncer is in
|
||||||
syncMode SyncMode
|
syncMode SyncMode
|
||||||
@ -45,17 +49,17 @@ type Syncer struct {
|
|||||||
|
|
||||||
// peer heads
|
// peer heads
|
||||||
// Note: clear cache on disconnects
|
// Note: clear cache on disconnects
|
||||||
peerHeads map[peer.ID]*TipSet
|
peerHeads map[peer.ID]*types.TipSet
|
||||||
peerHeadsLk sync.Mutex
|
peerHeadsLk sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSyncer(cs *ChainStore, bsync *BlockSync, self peer.ID) (*Syncer, error) {
|
func NewSyncer(cs *store.ChainStore, bsync *BlockSync, self peer.ID) (*Syncer, error) {
|
||||||
gen, err := cs.GetGenesis()
|
gen, err := cs.GetGenesis()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
gent, err := NewTipSet([]*types.BlockHeader{gen})
|
gent, err := types.NewTipSet([]*types.BlockHeader{gen})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -64,7 +68,7 @@ func NewSyncer(cs *ChainStore, bsync *BlockSync, self peer.ID) (*Syncer, error)
|
|||||||
syncMode: Bootstrap,
|
syncMode: Bootstrap,
|
||||||
Genesis: gent,
|
Genesis: gent,
|
||||||
Bsync: bsync,
|
Bsync: bsync,
|
||||||
peerHeads: make(map[peer.ID]*TipSet),
|
peerHeads: make(map[peer.ID]*types.TipSet),
|
||||||
head: cs.GetHeaviestTipSet(),
|
head: cs.GetHeaviestTipSet(),
|
||||||
store: cs,
|
store: cs,
|
||||||
self: self,
|
self: self,
|
||||||
@ -84,13 +88,13 @@ type BadTipSetCache struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BlockSet struct {
|
type BlockSet struct {
|
||||||
tset map[uint64]*TipSet
|
tset map[uint64]*types.TipSet
|
||||||
head *TipSet
|
head *types.TipSet
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BlockSet) Insert(ts *TipSet) {
|
func (bs *BlockSet) Insert(ts *types.TipSet) {
|
||||||
if bs.tset == nil {
|
if bs.tset == nil {
|
||||||
bs.tset = make(map[uint64]*TipSet)
|
bs.tset = make(map[uint64]*types.TipSet)
|
||||||
}
|
}
|
||||||
|
|
||||||
if bs.head == nil || ts.Height() > bs.head.Height() {
|
if bs.head == nil || ts.Height() > bs.head.Height() {
|
||||||
@ -99,14 +103,14 @@ func (bs *BlockSet) Insert(ts *TipSet) {
|
|||||||
bs.tset[ts.Height()] = ts
|
bs.tset[ts.Height()] = ts
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BlockSet) GetByHeight(h uint64) *TipSet {
|
func (bs *BlockSet) GetByHeight(h uint64) *types.TipSet {
|
||||||
return bs.tset[h]
|
return bs.tset[h]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BlockSet) PersistTo(cs *ChainStore) error {
|
func (bs *BlockSet) PersistTo(cs *store.ChainStore) error {
|
||||||
for _, ts := range bs.tset {
|
for _, ts := range bs.tset {
|
||||||
for _, b := range ts.Blocks() {
|
for _, b := range ts.Blocks() {
|
||||||
if err := cs.persistBlockHeader(b); err != nil {
|
if err := cs.PersistBlockHeader(b); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -114,7 +118,7 @@ func (bs *BlockSet) PersistTo(cs *ChainStore) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BlockSet) Head() *TipSet {
|
func (bs *BlockSet) Head() *types.TipSet {
|
||||||
return bs.head
|
return bs.head
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +127,7 @@ const BootstrapPeerThreshold = 1
|
|||||||
// InformNewHead informs the syncer about a new potential tipset
|
// InformNewHead informs the syncer about a new potential tipset
|
||||||
// This should be called when connecting to new peers, and additionally
|
// This should be called when connecting to new peers, and additionally
|
||||||
// when receiving new blocks from the network
|
// when receiving new blocks from the network
|
||||||
func (syncer *Syncer) InformNewHead(from peer.ID, fts *FullTipSet) {
|
func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) {
|
||||||
if fts == nil {
|
if fts == nil {
|
||||||
panic("bad")
|
panic("bad")
|
||||||
}
|
}
|
||||||
@ -178,7 +182,7 @@ func (syncer *Syncer) InformNewBlock(from peer.ID, blk *types.FullBlock) {
|
|||||||
// TODO: search for other blocks that could form a tipset with this block
|
// TODO: search for other blocks that could form a tipset with this block
|
||||||
// and then send that tipset to InformNewHead
|
// and then send that tipset to InformNewHead
|
||||||
|
|
||||||
fts := &FullTipSet{Blocks: []*types.FullBlock{blk}}
|
fts := &store.FullTipSet{Blocks: []*types.FullBlock{blk}}
|
||||||
syncer.InformNewHead(from, fts)
|
syncer.InformNewHead(from, fts)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,7 +204,7 @@ func (syncer *Syncer) SyncBootstrap() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
blockSet := []*TipSet{selectedHead}
|
blockSet := []*types.TipSet{selectedHead}
|
||||||
cur := selectedHead.Cids()
|
cur := selectedHead.Cids()
|
||||||
|
|
||||||
// If, for some reason, we have a suffix of the chain locally, handle that here
|
// If, for some reason, we have a suffix of the chain locally, handle that here
|
||||||
@ -255,7 +259,7 @@ func (syncer *Syncer) SyncBootstrap() {
|
|||||||
|
|
||||||
for _, ts := range blockSet {
|
for _, ts := range blockSet {
|
||||||
for _, b := range ts.Blocks() {
|
for _, b := range ts.Blocks() {
|
||||||
if err := syncer.store.persistBlockHeader(b); err != nil {
|
if err := syncer.store.PersistBlockHeader(b); err != nil {
|
||||||
log.Errorf("failed to persist synced blocks to the chainstore: %s", err)
|
log.Errorf("failed to persist synced blocks to the chainstore: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -309,7 +313,7 @@ func (syncer *Syncer) SyncBootstrap() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := copyBlockstore(bs, syncer.store.bs); err != nil {
|
if err := copyBlockstore(bs, syncer.store.Blockstore()); err != nil {
|
||||||
log.Errorf("failed to persist temp blocks: %s", err)
|
log.Errorf("failed to persist temp blocks: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -317,13 +321,13 @@ func (syncer *Syncer) SyncBootstrap() {
|
|||||||
|
|
||||||
head := blockSet[len(blockSet)-1]
|
head := blockSet[len(blockSet)-1]
|
||||||
log.Errorf("Finished syncing! new head: %s", head.Cids())
|
log.Errorf("Finished syncing! new head: %s", head.Cids())
|
||||||
syncer.store.maybeTakeHeavierTipSet(selectedHead)
|
syncer.store.MaybeTakeHeavierTipSet(selectedHead)
|
||||||
syncer.head = head
|
syncer.head = head
|
||||||
syncer.syncMode = CaughtUp
|
syncer.syncMode = CaughtUp
|
||||||
}
|
}
|
||||||
|
|
||||||
func reverse(tips []*TipSet) []*TipSet {
|
func reverse(tips []*types.TipSet) []*types.TipSet {
|
||||||
out := make([]*TipSet, len(tips))
|
out := make([]*types.TipSet, len(tips))
|
||||||
for i := 0; i < len(tips); i++ {
|
for i := 0; i < len(tips); i++ {
|
||||||
out[i] = tips[len(tips)-(i+1)]
|
out[i] = tips[len(tips)-(i+1)]
|
||||||
}
|
}
|
||||||
@ -350,14 +354,14 @@ func copyBlockstore(from, to bstore.Blockstore) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func zipTipSetAndMessages(cst *hamt.CborIpldStore, ts *TipSet, messages []*types.SignedMessage, msgincl [][]int) (*FullTipSet, error) {
|
func zipTipSetAndMessages(cst *hamt.CborIpldStore, ts *types.TipSet, messages []*types.SignedMessage, msgincl [][]int) (*store.FullTipSet, error) {
|
||||||
if len(ts.Blocks()) != len(msgincl) {
|
if len(ts.Blocks()) != len(msgincl) {
|
||||||
return nil, fmt.Errorf("msgincl length didnt match tipset size")
|
return nil, fmt.Errorf("msgincl length didnt match tipset size")
|
||||||
}
|
}
|
||||||
fmt.Println("zipping messages: ", msgincl)
|
fmt.Println("zipping messages: ", msgincl)
|
||||||
fmt.Println("into block: ", ts.Blocks()[0].Height)
|
fmt.Println("into block: ", ts.Blocks()[0].Height)
|
||||||
|
|
||||||
fts := &FullTipSet{}
|
fts := &store.FullTipSet{}
|
||||||
for bi, b := range ts.Blocks() {
|
for bi, b := range ts.Blocks() {
|
||||||
var msgs []*types.SignedMessage
|
var msgs []*types.SignedMessage
|
||||||
var msgCids []interface{}
|
var msgCids []interface{}
|
||||||
@ -388,8 +392,8 @@ func zipTipSetAndMessages(cst *hamt.CborIpldStore, ts *TipSet, messages []*types
|
|||||||
return fts, nil
|
return fts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (syncer *Syncer) selectHead(heads map[peer.ID]*TipSet) (*TipSet, error) {
|
func (syncer *Syncer) selectHead(heads map[peer.ID]*types.TipSet) (*types.TipSet, error) {
|
||||||
var headsArr []*TipSet
|
var headsArr []*types.TipSet
|
||||||
for _, ts := range heads {
|
for _, ts := range heads {
|
||||||
headsArr = append(headsArr, ts)
|
headsArr = append(headsArr, ts)
|
||||||
}
|
}
|
||||||
@ -432,7 +436,7 @@ func (syncer *Syncer) selectHead(heads map[peer.ID]*TipSet) (*TipSet, error) {
|
|||||||
return sel, nil
|
return sel, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (syncer *Syncer) FetchTipSet(ctx context.Context, p peer.ID, cids []cid.Cid) (*FullTipSet, error) {
|
func (syncer *Syncer) FetchTipSet(ctx context.Context, p peer.ID, cids []cid.Cid) (*store.FullTipSet, error) {
|
||||||
if fts, err := syncer.tryLoadFullTipSet(cids); err == nil {
|
if fts, err := syncer.tryLoadFullTipSet(cids); err == nil {
|
||||||
return fts, nil
|
return fts, nil
|
||||||
}
|
}
|
||||||
@ -440,13 +444,13 @@ func (syncer *Syncer) FetchTipSet(ctx context.Context, p peer.ID, cids []cid.Cid
|
|||||||
return syncer.Bsync.GetFullTipSet(ctx, p, cids)
|
return syncer.Bsync.GetFullTipSet(ctx, p, cids)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (syncer *Syncer) tryLoadFullTipSet(cids []cid.Cid) (*FullTipSet, error) {
|
func (syncer *Syncer) tryLoadFullTipSet(cids []cid.Cid) (*store.FullTipSet, error) {
|
||||||
ts, err := syncer.store.LoadTipSet(cids)
|
ts, err := syncer.store.LoadTipSet(cids)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
fts := &FullTipSet{}
|
fts := &store.FullTipSet{}
|
||||||
for _, b := range ts.Blocks() {
|
for _, b := range ts.Blocks() {
|
||||||
messages, err := syncer.store.MessagesForBlock(b)
|
messages, err := syncer.store.MessagesForBlock(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -463,54 +467,9 @@ func (syncer *Syncer) tryLoadFullTipSet(cids []cid.Cid) (*FullTipSet, error) {
|
|||||||
return fts, nil
|
return fts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FullTipSet is an expanded version of the TipSet that contains all the blocks and messages
|
|
||||||
type FullTipSet struct {
|
|
||||||
Blocks []*types.FullBlock
|
|
||||||
tipset *TipSet
|
|
||||||
cids []cid.Cid
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFullTipSet(blks []*types.FullBlock) *FullTipSet {
|
|
||||||
return &FullTipSet{
|
|
||||||
Blocks: blks,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fts *FullTipSet) Cids() []cid.Cid {
|
|
||||||
if fts.cids != nil {
|
|
||||||
return fts.cids
|
|
||||||
}
|
|
||||||
|
|
||||||
var cids []cid.Cid
|
|
||||||
for _, b := range fts.Blocks {
|
|
||||||
cids = append(cids, b.Cid())
|
|
||||||
}
|
|
||||||
fts.cids = cids
|
|
||||||
|
|
||||||
return cids
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fts *FullTipSet) TipSet() *TipSet {
|
|
||||||
if fts.tipset != nil {
|
|
||||||
return fts.tipset
|
|
||||||
}
|
|
||||||
|
|
||||||
var headers []*types.BlockHeader
|
|
||||||
for _, b := range fts.Blocks {
|
|
||||||
headers = append(headers, b.Header)
|
|
||||||
}
|
|
||||||
|
|
||||||
ts, err := NewTipSet(headers)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ts
|
|
||||||
}
|
|
||||||
|
|
||||||
// SyncCaughtUp is used to stay in sync once caught up to
|
// SyncCaughtUp is used to stay in sync once caught up to
|
||||||
// the rest of the network.
|
// the rest of the network.
|
||||||
func (syncer *Syncer) SyncCaughtUp(maybeHead *FullTipSet) error {
|
func (syncer *Syncer) SyncCaughtUp(maybeHead *store.FullTipSet) error {
|
||||||
ts := maybeHead.TipSet()
|
ts := maybeHead.TipSet()
|
||||||
if syncer.Genesis.Equals(ts) {
|
if syncer.Genesis.Equals(ts) {
|
||||||
return nil
|
return nil
|
||||||
@ -541,7 +500,7 @@ func (syncer *Syncer) SyncCaughtUp(maybeHead *FullTipSet) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (syncer *Syncer) ValidateTipSet(fts *FullTipSet) error {
|
func (syncer *Syncer) ValidateTipSet(fts *store.FullTipSet) error {
|
||||||
ts := fts.TipSet()
|
ts := fts.TipSet()
|
||||||
if ts.Equals(syncer.Genesis) {
|
if ts.Equals(syncer.Genesis) {
|
||||||
return nil
|
return nil
|
||||||
@ -567,7 +526,7 @@ func (syncer *Syncer) ValidateBlock(b *types.FullBlock) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
vm, err := NewVM(stateroot, b.Header.Height, b.Header.Miner, syncer.store)
|
vm, err := vm.NewVM(stateroot, b.Header.Height, b.Header.Miner, syncer.store)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -586,7 +545,7 @@ func (syncer *Syncer) ValidateBlock(b *types.FullBlock) error {
|
|||||||
receipts = append(receipts, receipt)
|
receipts = append(receipts, receipt)
|
||||||
}
|
}
|
||||||
|
|
||||||
cst := hamt.CSTFromBstore(syncer.store.bs)
|
cst := hamt.CSTFromBstore(syncer.store.Blockstore())
|
||||||
recptRoot, err := sharray.Build(context.TODO(), 4, receipts, cst)
|
recptRoot, err := sharray.Build(context.TODO(), 4, receipts, cst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -608,84 +567,14 @@ func (syncer *Syncer) ValidateBlock(b *types.FullBlock) error {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeductFunds(act *types.Actor, amt types.BigInt) error {
|
func (syncer *Syncer) Punctual(ts *types.TipSet) bool {
|
||||||
if types.BigCmp(act.Balance, amt) < 0 {
|
|
||||||
return fmt.Errorf("not enough funds")
|
|
||||||
}
|
|
||||||
|
|
||||||
act.Balance = types.BigSub(act.Balance, amt)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func DepositFunds(act *types.Actor, amt types.BigInt) {
|
|
||||||
act.Balance = types.BigAdd(act.Balance, amt)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TryCreateAccountActor(st *state.StateTree, addr address.Address) (*types.Actor, error) {
|
|
||||||
act, err := makeActor(st, addr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = st.RegisterNewAddress(addr, act)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return act, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeActor(st *state.StateTree, addr address.Address) (*types.Actor, error) {
|
|
||||||
switch addr.Protocol() {
|
|
||||||
case address.BLS:
|
|
||||||
return NewBLSAccountActor(st, addr)
|
|
||||||
case address.SECP256K1:
|
|
||||||
return NewSecp256k1AccountActor(st, addr)
|
|
||||||
case address.ID:
|
|
||||||
return nil, fmt.Errorf("no actor with given ID")
|
|
||||||
case address.Actor:
|
|
||||||
return nil, fmt.Errorf("no such actor")
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("address has unsupported protocol: %d", addr.Protocol())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBLSAccountActor(st *state.StateTree, addr address.Address) (*types.Actor, error) {
|
|
||||||
var acstate actors.AccountActorState
|
|
||||||
acstate.Address = addr
|
|
||||||
|
|
||||||
c, err := st.Store.Put(context.TODO(), acstate)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
nact := &types.Actor{
|
|
||||||
Code: actors.AccountActorCodeCid,
|
|
||||||
Balance: types.NewInt(0),
|
|
||||||
Head: c,
|
|
||||||
}
|
|
||||||
|
|
||||||
return nact, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSecp256k1AccountActor(st *state.StateTree, addr address.Address) (*types.Actor, error) {
|
|
||||||
nact := &types.Actor{
|
|
||||||
Code: actors.AccountActorCodeCid,
|
|
||||||
Balance: types.NewInt(0),
|
|
||||||
Head: gen.EmptyObjectCid,
|
|
||||||
}
|
|
||||||
|
|
||||||
return nact, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (syncer *Syncer) Punctual(ts *TipSet) bool {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (syncer *Syncer) collectChainCaughtUp(fts *FullTipSet) ([]*FullTipSet, error) {
|
func (syncer *Syncer) collectChainCaughtUp(fts *store.FullTipSet) ([]*store.FullTipSet, error) {
|
||||||
// fetch tipset and messages via bitswap
|
// fetch tipset and messages via bitswap
|
||||||
|
|
||||||
chain := []*FullTipSet{fts}
|
chain := []*store.FullTipSet{fts}
|
||||||
cur := fts.TipSet()
|
cur := fts.TipSet()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package chain
|
package chain
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
block "github.com/ipfs/go-block-format"
|
block "github.com/ipfs/go-block-format"
|
||||||
@ -18,89 +17,6 @@ func init() {
|
|||||||
cbor.RegisterCborType(BlockMsg{})
|
cbor.RegisterCborType(BlockMsg{})
|
||||||
}
|
}
|
||||||
|
|
||||||
type TipSet struct {
|
|
||||||
cids []cid.Cid
|
|
||||||
blks []*types.BlockHeader
|
|
||||||
height uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
// why didnt i just export the fields? Because the struct has methods with the
|
|
||||||
// same names already
|
|
||||||
type expTipSet struct {
|
|
||||||
Cids []cid.Cid
|
|
||||||
Blocks []*types.BlockHeader
|
|
||||||
Height uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ts *TipSet) MarshalJSON() ([]byte, error) {
|
|
||||||
return json.Marshal(expTipSet{
|
|
||||||
Cids: ts.cids,
|
|
||||||
Blocks: ts.blks,
|
|
||||||
Height: ts.height,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ts *TipSet) UnmarshalJSON(b []byte) error {
|
|
||||||
var ets expTipSet
|
|
||||||
if err := json.Unmarshal(b, &ets); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
ts.cids = ets.Cids
|
|
||||||
ts.blks = ets.Blocks
|
|
||||||
ts.height = ets.Height
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewTipSet(blks []*types.BlockHeader) (*TipSet, error) {
|
|
||||||
var ts TipSet
|
|
||||||
ts.cids = []cid.Cid{blks[0].Cid()}
|
|
||||||
ts.blks = blks
|
|
||||||
for _, b := range blks[1:] {
|
|
||||||
if b.Height != blks[0].Height {
|
|
||||||
return nil, fmt.Errorf("cannot create tipset with mismatching heights")
|
|
||||||
}
|
|
||||||
ts.cids = append(ts.cids, b.Cid())
|
|
||||||
}
|
|
||||||
ts.height = blks[0].Height
|
|
||||||
|
|
||||||
return &ts, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ts *TipSet) Cids() []cid.Cid {
|
|
||||||
return ts.cids
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ts *TipSet) Height() uint64 {
|
|
||||||
return ts.height
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ts *TipSet) Weight() uint64 {
|
|
||||||
panic("if tipsets are going to have weight on them, we need to wire that through")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ts *TipSet) Parents() []cid.Cid {
|
|
||||||
return ts.blks[0].Parents
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ts *TipSet) Blocks() []*types.BlockHeader {
|
|
||||||
return ts.blks
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ts *TipSet) Equals(ots *TipSet) bool {
|
|
||||||
if len(ts.blks) != len(ots.blks) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, b := range ts.blks {
|
|
||||||
if b.Cid() != ots.blks[i].Cid() {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func IpldDecode(block block.Block) (ipld.Node, error) {
|
func IpldDecode(block block.Block) (ipld.Node, error) {
|
||||||
var i interface{}
|
var i interface{}
|
||||||
if err := cbor.DecodeInto(block.RawData(), &i); err != nil {
|
if err := cbor.DecodeInto(block.RawData(), &i); err != nil {
|
||||||
|
91
chain/types/tipset.go
Normal file
91
chain/types/tipset.go
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TipSet struct {
|
||||||
|
cids []cid.Cid
|
||||||
|
blks []*BlockHeader
|
||||||
|
height uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// why didnt i just export the fields? Because the struct has methods with the
|
||||||
|
// same names already
|
||||||
|
type expTipSet struct {
|
||||||
|
Cids []cid.Cid
|
||||||
|
Blocks []*BlockHeader
|
||||||
|
Height uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts *TipSet) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(expTipSet{
|
||||||
|
Cids: ts.cids,
|
||||||
|
Blocks: ts.blks,
|
||||||
|
Height: ts.height,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts *TipSet) UnmarshalJSON(b []byte) error {
|
||||||
|
var ets expTipSet
|
||||||
|
if err := json.Unmarshal(b, &ets); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ts.cids = ets.Cids
|
||||||
|
ts.blks = ets.Blocks
|
||||||
|
ts.height = ets.Height
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTipSet(blks []*BlockHeader) (*TipSet, error) {
|
||||||
|
var ts TipSet
|
||||||
|
ts.cids = []cid.Cid{blks[0].Cid()}
|
||||||
|
ts.blks = blks
|
||||||
|
for _, b := range blks[1:] {
|
||||||
|
if b.Height != blks[0].Height {
|
||||||
|
return nil, fmt.Errorf("cannot create tipset with mismatching heights")
|
||||||
|
}
|
||||||
|
ts.cids = append(ts.cids, b.Cid())
|
||||||
|
}
|
||||||
|
ts.height = blks[0].Height
|
||||||
|
|
||||||
|
return &ts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts *TipSet) Cids() []cid.Cid {
|
||||||
|
return ts.cids
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts *TipSet) Height() uint64 {
|
||||||
|
return ts.height
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts *TipSet) Weight() uint64 {
|
||||||
|
panic("if tipsets are going to have weight on them, we need to wire that through")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts *TipSet) Parents() []cid.Cid {
|
||||||
|
return ts.blks[0].Parents
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts *TipSet) Blocks() []*BlockHeader {
|
||||||
|
return ts.blks
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts *TipSet) Equals(ots *TipSet) bool {
|
||||||
|
if len(ts.blks) != len(ots.blks) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, b := range ts.blks {
|
||||||
|
if b.Cid() != ots.blks[i].Cid() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package chain
|
package vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -15,7 +15,7 @@ type invoker struct {
|
|||||||
builtInCode map[cid.Cid]nativeCode
|
builtInCode map[cid.Cid]nativeCode
|
||||||
}
|
}
|
||||||
|
|
||||||
type invokeFunc func(act *types.Actor, vmctx *VMContext, params []byte) ([]byte, aerrors.ActorError)
|
type invokeFunc func(act *types.Actor, vmctx types.VMContext, params []byte) ([]byte, aerrors.ActorError)
|
||||||
type nativeCode []invokeFunc
|
type nativeCode []invokeFunc
|
||||||
|
|
||||||
func newInvoker() *invoker {
|
func newInvoker() *invoker {
|
||||||
@ -31,7 +31,7 @@ func newInvoker() *invoker {
|
|||||||
return inv
|
return inv
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inv *invoker) Invoke(act *types.Actor, vmctx *VMContext, method uint64, params []byte) ([]byte, aerrors.ActorError) {
|
func (inv *invoker) Invoke(act *types.Actor, vmctx types.VMContext, method uint64, params []byte) ([]byte, aerrors.ActorError) {
|
||||||
|
|
||||||
code, ok := inv.builtInCode[act.Code]
|
code, ok := inv.builtInCode[act.Code]
|
||||||
if !ok {
|
if !ok {
|
@ -1,4 +1,4 @@
|
|||||||
package chain
|
package vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
69
chain/vm/mkactor.go
Normal file
69
chain/vm/mkactor.go
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
package vm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"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"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TryCreateAccountActor(st *state.StateTree, addr address.Address) (*types.Actor, error) {
|
||||||
|
act, err := makeActor(st, addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = st.RegisterNewAddress(addr, act)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return act, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeActor(st *state.StateTree, addr address.Address) (*types.Actor, error) {
|
||||||
|
switch addr.Protocol() {
|
||||||
|
case address.BLS:
|
||||||
|
return NewBLSAccountActor(st, addr)
|
||||||
|
case address.SECP256K1:
|
||||||
|
return NewSecp256k1AccountActor(st, addr)
|
||||||
|
case address.ID:
|
||||||
|
return nil, fmt.Errorf("no actor with given ID")
|
||||||
|
case address.Actor:
|
||||||
|
return nil, fmt.Errorf("no such actor")
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("address has unsupported protocol: %d", addr.Protocol())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBLSAccountActor(st *state.StateTree, addr address.Address) (*types.Actor, error) {
|
||||||
|
var acstate actors.AccountActorState
|
||||||
|
acstate.Address = addr
|
||||||
|
|
||||||
|
c, err := st.Store.Put(context.TODO(), acstate)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
nact := &types.Actor{
|
||||||
|
Code: actors.AccountActorCodeCid,
|
||||||
|
Balance: types.NewInt(0),
|
||||||
|
Head: c,
|
||||||
|
}
|
||||||
|
|
||||||
|
return nact, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSecp256k1AccountActor(st *state.StateTree, addr address.Address) (*types.Actor, error) {
|
||||||
|
nact := &types.Actor{
|
||||||
|
Code: actors.AccountActorCodeCid,
|
||||||
|
Balance: types.NewInt(0),
|
||||||
|
Head: gen.EmptyObjectCid,
|
||||||
|
}
|
||||||
|
|
||||||
|
return nact, nil
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package chain
|
package vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
|
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
|
||||||
"github.com/filecoin-project/go-lotus/chain/address"
|
"github.com/filecoin-project/go-lotus/chain/address"
|
||||||
"github.com/filecoin-project/go-lotus/chain/state"
|
"github.com/filecoin-project/go-lotus/chain/state"
|
||||||
|
"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/lib/bufbstore"
|
"github.com/filecoin-project/go-lotus/lib/bufbstore"
|
||||||
|
|
||||||
@ -135,7 +136,6 @@ func (vmctx *VMContext) VerifySignature(sig types.Signature, act address.Address
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) makeVMContext(sroot cid.Cid, origin address.Address, msg *types.Message) *VMContext {
|
func (vm *VM) makeVMContext(sroot cid.Cid, origin address.Address, msg *types.Message) *VMContext {
|
||||||
cst := hamt.CSTFromBstore(vm.cs.bs)
|
|
||||||
|
|
||||||
return &VMContext{
|
return &VMContext{
|
||||||
vm: vm,
|
vm: vm,
|
||||||
@ -144,9 +144,9 @@ func (vm *VM) makeVMContext(sroot cid.Cid, origin address.Address, msg *types.Me
|
|||||||
msg: msg,
|
msg: msg,
|
||||||
origin: origin,
|
origin: origin,
|
||||||
height: vm.blockHeight,
|
height: vm.blockHeight,
|
||||||
cst: cst,
|
cst: vm.cst,
|
||||||
storage: &storage{
|
storage: &storage{
|
||||||
cst: cst,
|
cst: vm.cst,
|
||||||
head: sroot,
|
head: sroot,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -155,15 +155,16 @@ func (vm *VM) makeVMContext(sroot cid.Cid, origin address.Address, msg *types.Me
|
|||||||
type VM struct {
|
type VM struct {
|
||||||
cstate *state.StateTree
|
cstate *state.StateTree
|
||||||
base cid.Cid
|
base cid.Cid
|
||||||
cs *ChainStore
|
cs *store.ChainStore
|
||||||
|
cst *hamt.CborIpldStore
|
||||||
buf *bufbstore.BufferedBS
|
buf *bufbstore.BufferedBS
|
||||||
blockHeight uint64
|
blockHeight uint64
|
||||||
blockMiner address.Address
|
blockMiner address.Address
|
||||||
inv *invoker
|
inv *invoker
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVM(base cid.Cid, height uint64, maddr address.Address, cs *ChainStore) (*VM, error) {
|
func NewVM(base cid.Cid, height uint64, maddr address.Address, cs *store.ChainStore) (*VM, error) {
|
||||||
buf := bufbstore.NewBufferedBstore(cs.bs)
|
buf := bufbstore.NewBufferedBstore(cs.Blockstore())
|
||||||
cst := hamt.CSTFromBstore(buf)
|
cst := hamt.CSTFromBstore(buf)
|
||||||
state, err := state.LoadStateTree(cst, base)
|
state, err := state.LoadStateTree(cst, base)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -174,6 +175,7 @@ func NewVM(base cid.Cid, height uint64, maddr address.Address, cs *ChainStore) (
|
|||||||
cstate: state,
|
cstate: state,
|
||||||
base: base,
|
base: base,
|
||||||
cs: cs,
|
cs: cs,
|
||||||
|
cst: cst,
|
||||||
buf: buf,
|
buf: buf,
|
||||||
blockHeight: height,
|
blockHeight: height,
|
||||||
blockMiner: maddr,
|
blockMiner: maddr,
|
||||||
@ -340,3 +342,16 @@ func (vm *VM) Invoke(act *types.Actor, vmctx *VMContext, method uint64, params [
|
|||||||
}
|
}
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DeductFunds(act *types.Actor, amt types.BigInt) error {
|
||||||
|
if types.BigCmp(act.Balance, amt) < 0 {
|
||||||
|
return fmt.Errorf("not enough funds")
|
||||||
|
}
|
||||||
|
|
||||||
|
act.Balance = types.BigSub(act.Balance, amt)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DepositFunds(act *types.Actor, amt types.BigInt) {
|
||||||
|
act.Balance = types.BigAdd(act.Balance, amt)
|
||||||
|
}
|
3
go.sum
3
go.sum
@ -458,6 +458,7 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R
|
|||||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
|
github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo=
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
||||||
@ -572,6 +573,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
|
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
@ -629,6 +631,7 @@ google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRn
|
|||||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||||
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
|
@ -19,22 +19,22 @@ type api interface {
|
|||||||
|
|
||||||
// returns a set of messages that havent been included in the chain as of
|
// returns a set of messages that havent been included in the chain as of
|
||||||
// the given tipset
|
// the given tipset
|
||||||
MpoolPending(ctx context.Context, base *chain.TipSet) ([]*types.SignedMessage, error)
|
MpoolPending(ctx context.Context, base *types.TipSet) ([]*types.SignedMessage, error)
|
||||||
|
|
||||||
// Returns the best tipset for the miner to mine on top of.
|
// Returns the best tipset for the miner to mine on top of.
|
||||||
// TODO: Not sure this feels right (including the messages api). Miners
|
// TODO: Not sure this feels right (including the messages api). Miners
|
||||||
// will likely want to have more control over exactly which blocks get
|
// will likely want to have more control over exactly which blocks get
|
||||||
// mined on, and which messages are included.
|
// mined on, and which messages are included.
|
||||||
ChainHead(context.Context) (*chain.TipSet, error)
|
ChainHead(context.Context) (*types.TipSet, error)
|
||||||
|
|
||||||
// returns the lookback randomness from the chain used for the election
|
// returns the lookback randomness from the chain used for the election
|
||||||
ChainGetRandomness(context.Context, *chain.TipSet) ([]byte, error)
|
ChainGetRandomness(context.Context, *types.TipSet) ([]byte, error)
|
||||||
|
|
||||||
// create a block
|
// create a block
|
||||||
// it seems realllllly annoying to do all the actions necessary to build a
|
// it seems realllllly annoying to do all the actions necessary to build a
|
||||||
// block through the API. so, we just add the block creation to the API
|
// block through the API. so, we just add the block creation to the API
|
||||||
// now, all the 'miner' does is check if they win, and call create block
|
// now, all the 'miner' does is check if they win, and call create block
|
||||||
MinerCreateBlock(context.Context, address.Address, *chain.TipSet, []types.Ticket, types.ElectionProof, []*types.SignedMessage) (*chain.BlockMsg, error)
|
MinerCreateBlock(context.Context, address.Address, *types.TipSet, []types.Ticket, types.ElectionProof, []*types.SignedMessage) (*chain.BlockMsg, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMiner(api api, addr address.Address) *Miner {
|
func NewMiner(api api, addr address.Address) *Miner {
|
||||||
@ -79,7 +79,7 @@ func (m *Miner) Mine(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type MiningBase struct {
|
type MiningBase struct {
|
||||||
ts *chain.TipSet
|
ts *types.TipSet
|
||||||
tickets []types.Ticket
|
tickets []types.Ticket
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ 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/store"
|
||||||
"github.com/filecoin-project/go-lotus/chain/types"
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
"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"
|
||||||
@ -183,7 +184,7 @@ func Online() Option {
|
|||||||
|
|
||||||
Override(HandleIncomingMessagesKey, modules.HandleIncomingMessages),
|
Override(HandleIncomingMessagesKey, modules.HandleIncomingMessages),
|
||||||
|
|
||||||
Override(new(*chain.ChainStore), modules.ChainStore),
|
Override(new(*store.ChainStore), modules.ChainStore),
|
||||||
|
|
||||||
Override(new(blockstore.GCLocker), blockstore.NewGCLocker),
|
Override(new(blockstore.GCLocker), blockstore.NewGCLocker),
|
||||||
Override(new(blockstore.GCBlockstore), blockstore.NewGCBlockstore),
|
Override(new(blockstore.GCBlockstore), blockstore.NewGCBlockstore),
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
|
|
||||||
"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/lib/cborrpc"
|
"github.com/filecoin-project/go-lotus/lib/cborrpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -32,11 +33,11 @@ type Message struct {
|
|||||||
type Service struct {
|
type Service struct {
|
||||||
newStream chain.NewStreamFunc
|
newStream chain.NewStreamFunc
|
||||||
|
|
||||||
cs *chain.ChainStore
|
cs *store.ChainStore
|
||||||
syncer *chain.Syncer
|
syncer *chain.Syncer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHelloService(h host.Host, cs *chain.ChainStore, syncer *chain.Syncer) *Service {
|
func NewHelloService(h host.Host, cs *store.ChainStore, syncer *chain.Syncer) *Service {
|
||||||
return &Service{
|
return &Service{
|
||||||
newStream: h.NewStream,
|
newStream: h.NewStream,
|
||||||
|
|
||||||
|
@ -2,11 +2,13 @@ package impl
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"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/store"
|
||||||
"github.com/filecoin-project/go-lotus/chain/types"
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
"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"
|
||||||
@ -23,7 +25,7 @@ type FullNodeAPI struct {
|
|||||||
|
|
||||||
CommonAPI
|
CommonAPI
|
||||||
|
|
||||||
Chain *chain.ChainStore
|
Chain *store.ChainStore
|
||||||
PubSub *pubsub.PubSub
|
PubSub *pubsub.PubSub
|
||||||
Mpool *chain.MessagePool
|
Mpool *chain.MessagePool
|
||||||
Wallet *chain.Wallet
|
Wallet *chain.Wallet
|
||||||
@ -43,11 +45,11 @@ func (a *FullNodeAPI) ChainSubmitBlock(ctx context.Context, blk *chain.BlockMsg)
|
|||||||
return a.PubSub.Publish("/fil/blocks", b)
|
return a.PubSub.Publish("/fil/blocks", b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *FullNodeAPI) ChainHead(context.Context) (*chain.TipSet, error) {
|
func (a *FullNodeAPI) ChainHead(context.Context) (*types.TipSet, error) {
|
||||||
return a.Chain.GetHeaviestTipSet(), nil
|
return a.Chain.GetHeaviestTipSet(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *FullNodeAPI) ChainGetRandomness(ctx context.Context, pts *chain.TipSet) ([]byte, error) {
|
func (a *FullNodeAPI) ChainGetRandomness(ctx context.Context, pts *types.TipSet) ([]byte, error) {
|
||||||
// TODO: this needs to look back in the chain for the right random beacon value
|
// TODO: this needs to look back in the chain for the right random beacon value
|
||||||
return []byte("foo bar random"), nil
|
return []byte("foo bar random"), nil
|
||||||
}
|
}
|
||||||
@ -69,7 +71,7 @@ func (a *FullNodeAPI) ChainGetBlockMessages(ctx context.Context, msg cid.Cid) ([
|
|||||||
return a.Chain.MessagesForBlock(b)
|
return a.Chain.MessagesForBlock(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *FullNodeAPI) MpoolPending(ctx context.Context, ts *chain.TipSet) ([]*types.SignedMessage, error) {
|
func (a *FullNodeAPI) MpoolPending(ctx context.Context, ts *types.TipSet) ([]*types.SignedMessage, error) {
|
||||||
// TODO: need to make sure we don't return messages that were already included in the referenced chain
|
// TODO: need to make sure we don't return messages that were already included in the referenced chain
|
||||||
// also need to accept ts == nil just fine, assume nil == chain.Head()
|
// also need to accept ts == nil just fine, assume nil == chain.Head()
|
||||||
return a.Mpool.Pending(), nil
|
return a.Mpool.Pending(), nil
|
||||||
@ -97,7 +99,7 @@ func (a *FullNodeAPI) MinerStart(ctx context.Context, addr address.Address) erro
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *FullNodeAPI) MinerCreateBlock(ctx context.Context, addr address.Address, parents *chain.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(a.Chain, addr, parents, tickets, proof, msgs)
|
fblk, err := chain.MinerCreateBlock(a.Chain, addr, parents, tickets, proof, msgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -30,7 +30,7 @@ import (
|
|||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"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/store"
|
||||||
"github.com/filecoin-project/go-lotus/chain/types"
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
"github.com/filecoin-project/go-lotus/node/modules/helpers"
|
"github.com/filecoin-project/go-lotus/node/modules/helpers"
|
||||||
"github.com/filecoin-project/go-lotus/node/repo"
|
"github.com/filecoin-project/go-lotus/node/repo"
|
||||||
@ -58,7 +58,7 @@ func Bitswap(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, rt routin
|
|||||||
return exch
|
return exch
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetGenesis(cs *chain.ChainStore, g Genesis) error {
|
func SetGenesis(cs *store.ChainStore, g Genesis) error {
|
||||||
_, err := cs.GetGenesis()
|
_, err := cs.GetGenesis()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil // already set, noop
|
return nil // already set, noop
|
||||||
@ -179,8 +179,8 @@ func ClientDAG(lc fx.Lifecycle, fstore *filestore.Filestore) ipld.DAGService {
|
|||||||
return dag
|
return dag
|
||||||
}
|
}
|
||||||
|
|
||||||
func ChainStore(lc fx.Lifecycle, bs blockstore.Blockstore, ds datastore.Batching) *chain.ChainStore {
|
func ChainStore(lc fx.Lifecycle, bs blockstore.Blockstore, ds datastore.Batching) *store.ChainStore {
|
||||||
chain := chain.NewChainStore(bs, ds)
|
chain := store.NewChainStore(bs, ds)
|
||||||
|
|
||||||
lc.Append(fx.Hook{
|
lc.Append(fx.Hook{
|
||||||
OnStart: func(ctx context.Context) error {
|
OnStart: func(ctx context.Context) error {
|
||||||
|
Loading…
Reference in New Issue
Block a user