找回密码
 立即注册

QQ登录

只需一步,快速开始

  • QQ空间
  • 回复
  • 收藏

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

jfnuvve5byi.jpg
回复

使用道具 举报

说点什么

您需要登录后才可以回帖 登录 | 立即注册