lotus/chain/mining.go

133 lines
3.0 KiB
Go
Raw Normal View History

2019-07-05 14:46:21 +00:00
package chain
import (
"context"
"fmt"
bls "github.com/filecoin-project/go-bls-sigs"
2019-07-05 14:46:21 +00:00
cid "github.com/ipfs/go-cid"
hamt "github.com/ipfs/go-hamt-ipld"
"github.com/pkg/errors"
sharray "github.com/whyrusleeping/sharray"
2019-07-12 23:52:25 +00:00
"github.com/filecoin-project/go-lotus/chain/actors"
"github.com/filecoin-project/go-lotus/chain/address"
"github.com/filecoin-project/go-lotus/chain/types"
2019-07-05 14:46:21 +00:00
)
func miningRewardForBlock(base *TipSet) types.BigInt {
return types.NewInt(10000)
2019-07-05 14:46:21 +00:00
}
func MinerCreateBlock(cs *ChainStore, miner address.Address, parents *TipSet, tickets []types.Ticket, proof types.ElectionProof, msgs []*types.SignedMessage) (*types.FullBlock, error) {
2019-07-11 02:36:43 +00:00
st, err := cs.TipSetState(parents.Cids())
2019-07-05 14:46:21 +00:00
if err != nil {
return nil, errors.Wrap(err, "failed to load tipset state")
}
2019-07-11 02:36:43 +00:00
height := parents.Height() + uint64(len(tickets))
2019-07-05 14:46:21 +00:00
2019-07-11 02:36:43 +00:00
vm, err := NewVM(st, height, miner, cs)
if err != nil {
return nil, err
}
2019-07-05 14:46:21 +00:00
// apply miner reward
2019-07-12 23:52:25 +00:00
if err := vm.TransferFunds(actors.NetworkAddress, miner, miningRewardForBlock(parents)); err != nil {
2019-07-05 14:46:21 +00:00
return nil, err
}
next := &types.BlockHeader{
2019-07-11 02:36:43 +00:00
Miner: miner,
Parents: parents.Cids(),
Tickets: tickets,
2019-07-05 14:46:21 +00:00
Height: height,
}
2019-07-11 02:36:43 +00:00
fmt.Printf("adding %d messages to block...", len(msgs))
2019-07-05 14:46:21 +00:00
var msgCids []cid.Cid
var blsSigs []types.Signature
2019-07-05 14:46:21 +00:00
var receipts []interface{}
2019-07-11 02:36:43 +00:00
for _, msg := range msgs {
2019-07-05 14:46:21 +00:00
if msg.Signature.TypeCode() == 2 {
blsSigs = append(blsSigs, msg.Signature)
blk, err := msg.Message.ToStorageBlock()
if err != nil {
return nil, err
}
2019-07-11 02:36:43 +00:00
if err := cs.bs.Put(blk); err != nil {
2019-07-05 14:46:21 +00:00
return nil, err
}
msgCids = append(msgCids, blk.Cid())
} else {
msgCids = append(msgCids, msg.Cid())
}
rec, err := vm.ApplyMessage(&msg.Message)
if err != nil {
return nil, errors.Wrap(err, "apply message failure")
}
receipts = append(receipts, rec)
}
2019-07-11 02:36:43 +00:00
cst := hamt.CSTFromBstore(cs.bs)
2019-07-05 14:46:21 +00:00
msgroot, err := sharray.Build(context.TODO(), 4, toIfArr(msgCids), cst)
if err != nil {
return nil, err
}
next.Messages = msgroot
rectroot, err := sharray.Build(context.TODO(), 4, receipts, cst)
if err != nil {
return nil, err
}
next.MessageReceipts = rectroot
stateRoot, err := vm.Flush(context.TODO())
if err != nil {
return nil, errors.Wrap(err, "flushing state tree failed")
}
aggSig, err := aggregateSignatures(blsSigs)
if err != nil {
return nil, err
}
next.BLSAggregate = aggSig
next.StateRoot = stateRoot
2019-07-11 02:36:43 +00:00
pweight := cs.Weight(parents)
next.ParentWeight = types.NewInt(pweight)
2019-07-05 14:46:21 +00:00
fullBlock := &types.FullBlock{
2019-07-05 14:46:21 +00:00
Header: next,
2019-07-11 02:36:43 +00:00
Messages: msgs,
2019-07-05 14:46:21 +00:00
}
return fullBlock, nil
}
func aggregateSignatures(sigs []types.Signature) (types.Signature, error) {
2019-07-05 14:46:21 +00:00
var blsSigs []bls.Signature
for _, s := range sigs {
var bsig bls.Signature
copy(bsig[:], s.Data)
blsSigs = append(blsSigs, bsig)
}
aggSig := bls.Aggregate(blsSigs)
return types.Signature{
Type: types.KTBLS,
2019-07-05 14:46:21 +00:00
Data: aggSig[:],
}, nil
}
func toIfArr(cids []cid.Cid) []interface{} {
out := make([]interface{}, 0, len(cids))
for _, c := range cids {
out = append(out, c)
}
return out
}