Filecoin源码分析–Miner addres
文章来源:IPFS原力区
Filecoin源码分析--Miner addres
第一个字符: f-filecoin正式网络,t-测试网络;
第二个字符:地址协议类型,目前有4中:
// ID represents the address ID protocol.
ID Protocol = iota
// SECP256K1 represents the address SECP256K1 protocol.
SECP256K1
// Actor represents the address Actor protocol.
Actor
// BLS represents the address BLS protocol.
BLS
Mining涉及两个对象:client,miner,client提出存储协议,miner响应协议存储数据并返回交易的状态的状态,包括ProofInfo,证明miner已经将client数据密封到一个sector中.
type ProofInfo struct {
SectorID uint64
CommR []byte
CommD []byte
}
#go-filecoin client propose-storage-deal
miner:矿工地址;
data:提议存储数据的Cid,和ipfs一样,是以内容编码的hash值;
ask:miner挂单的id号;
duration:存储期限,是这样算的,filecoin预计没30秒产生一个block,这里天数是兑现为这些天能产生的blocks,如默认的值2880即是一天=2(分钟)*60*24.
allow-duplicates--是否允许创建重复的提议,默认false,避免错误的重复交易.也就是说如果client已经给某个miner提出存储订单,那么再次提出时会被拒绝,如图所示:
Propose Deal包括好几个工序,超时设置:
5*smc.node.GetBlockTime(),默认是150秒.
因为client节点的BlockTime是在执行filecoin daemon时通过参数--block-time设置的,其默认值是:
const DefaultBlockTime = 30 * time.Second,这个函数的处理有:
1. 获取miner对应的nodeID;是通过向Actor发送只读消息”getPeerID”,从Actor维持的状态中查找的.
2.Ping测试连通性,通过chan返回结果,如果client无法连接到miner则退出
3.获取文件大小,从报价单中寻找对应miner的价格信息,这两个信息是为了计算本次存储所需FIL.
type Ask struct {
Price *types.AttoFIL
Expiry *types.BlockHeight
ID *big.Int
}
totalPrice := price.MulBigInt(big.NewInt(int64(ask.Price* duration)))
4.
获取当前chain上最新区块高度,client的wallet address,miner address,这些参数为了构造下单结构Proposal.
5.检查Proposal是否重复,如果没有将此Proposal包装签名后发送到链上处理,并接受响应结果.
func (smc *Client) ProposeDeal(ctx context.Context, miner address.Address, data cid.Cid, askID uint64, duration uint64, allowDuplicates bool) (*storagedeal.Response, error) {
ctxSetup, cancel := context.WithTimeout(ctx, 5*smc.node.GetBlockTime())
defer cancel()
pid, err := smc.api.MinerGetPeerID(ctxSetup, miner)
if err != nil {
return nil, err
}
minerAlive := make(chan error, 1)
go func() {
defer close(minerAlive)
minerAlive
}()
size, err := smc.api.DAGGetFileSize(ctxSetup, data)
if err != nil {
return nil, errors.Wrap(err, "failed to determine the size of the data")
}
ask, err := smc.api.MinerGetAsk(ctxSetup, miner, askID)
if err != nil {
return nil, errors.Wrap(err, "failed to get ask price")
}
price := ask.Price
chainHeight, err := smc.api.ChainBlockHeight(ctxSetup)
if err != nil {
return nil, err
}
fromAddress, err := smc.api.WalletDefaultAddress()
if err != nil {
return nil, err
}
minerOwner, err := smc.api.MinerGetOwnerAddress(ctxSetup, miner)
if err != nil {
return nil, err
}
totalPrice := price.MulBigInt(big.NewInt(int64(size * duration)))
proposal := &storagedeal.Proposal{
PieceRef: data,
Size: types.NewBytesAmount(size),
TotalPrice: totalPrice,
Duration: duration,
MinerAddress: miner,
}
if smc.isMaybeDupDeal(proposal) && !allowDuplicates {
return nil, Errors[ErrDuplicateDeal]
}
// see if we managed to connect to the miner
select {
case err :=
if err != nil {
return nil, err
}
case
return nil, ctxSetup.Err()
}
// create payment information
cpResp, err := smc.api.CreatePayments(ctxSetup, porcelain.CreatePaymentsParams{
From: fromAddress,
To: minerOwner,Value: *price.MulBigInt(big.NewInt(int64(size * duration))),
Duration: duration,
PaymentInterval: VoucherInterval,
ChannelExpiry: *chainHeight.Add(types.NewBlockHeight(duration + ChannelExpiryInterval)),
GasPrice: *types.NewAttoFIL(big.NewInt(CreateChannelGasPrice)),
GasLimit: types.NewGasUnits(CreateChannelGasLimit),
})
if err != nil {
return nil, errors.Wrap(err, "error creating payment")
}
proposal.Payment.Channel = cpResp.Channel
proposal.Payment.PayChActor = address.PaymentBrokerAddress
proposal.Payment.Payer = fromAddress
proposal.Payment.ChannelMsgCid = &cpResp.ChannelMsgCid
proposal.Payment.Vouchers = cpResp.Vouchers
signedProposal, err := proposal.NewSignedProposal(fromAddress, smc.api)
if err != nil {
return nil, err
}
// send proposal
var response storagedeal.Response
// We reset the context to not timeout to allow large file transfers
// to complete.
err = smc.node.MakeProtocolRequest(ctx, makeDealProtocol, pid, signedProposal, &response)
if err != nil {
return nil, errors.Wrap(err, "error sending proposal")
}
if err := smc.checkDealResponse(ctx, &response); err != nil {
return nil, errors.Wrap(err, "response check failed")
}
// Note: currently the miner requests the data out of band
if err := smc.recordResponse(&response, miner, proposal); err != nil {
return nil, errors.Wrap(err, "failed to track response")
}
return &response, nil
}
jfnuvve5byi.jpg (63.75 KB, 下载次数: 15)
jfnuvve5byi.jpg
2019-4-8 18:42 上传
版权声明:
作者:bitchina.net
链接:http://www.bitchina.net/archives/687.html
来源:比特中国
文章版权归作者所有,未经允许请勿转载。