美文网首页filecoin
Filecoin源码架构分析--基础概念

Filecoin源码架构分析--基础概念

作者: 熊猫v阿宝 | 来源:发表于2019-04-10 20:23 被阅读0次

    Filecoin是由区块链以及上层协议构成的存储系统,主要基础概念Actor,Message,Block,TipSet,Ticket,GAS。Filecoin的状态由多个Actor的状态组成。区块链的区块数据以及Actor的状态数据通过IPFS/IPLD进行存储。代码还在迭代中,有很多TODO未实现。

    Actor可以类比以太坊网络中的账户(一般账户或者智能合约账户)。每个Actor有自己的地址,余额,也可以维护自己的状态,同时Actor提供一些函数调用(也正是这些函数调用触发Actor的状态变化)。Actor不是在VM上运行的字节码,而是用go实现。每个actor实例都存在于状态树中的一个地址中。地址是actor的公钥的哈希值。

    type Actor struct {#
       // Code is a CID of the VM code for this actor's implementation (or a constant for actors implemented in Go code).
       // Code may be nil for an uninitialized actor (which exists because it has received a balance).
       Code cid.Cid `refmt:",omitempty"`
       // Head is the CID of the root of the actor's state tree.
       Head cid.Cid `refmt:",omitempty"`
       // Nonce is the nonce expected on the next message from this actor.
       // Messages are processed in strict, contiguous nonce order.
       Nonce types.Uint64
       // Balance is the amount of FIL in the actor's account.
       Balance *types.AttoFIL
    }
    

    创建新的Actor

    // NewActor constructs a new actor.
    func NewActor(code cid.Cid, balance *types.AttoFIL) *Actor {
       return &Actor{
          Code:    code,
          Head:    cid.Undef,
          Nonce:   0,
          Balance: balance,
       }
    }
    

    初始化

    func init() {
       AccountActorCodeObj = dag.NewRawNode([]byte("accountactor"))
       AccountActorCodeCid = AccountActorCodeObj.Cid()
       StorageMarketActorCodeObj = dag.NewRawNode([]byte("storagemarket"))
       StorageMarketActorCodeCid = StorageMarketActorCodeObj.Cid()
       PaymentBrokerActorCodeObj = dag.NewRawNode([]byte("paymentbroker"))
       PaymentBrokerActorCodeCid = PaymentBrokerActorCodeObj.Cid()
       MinerActorCodeObj = dag.NewRawNode([]byte("mineractor"))
       MinerActorCodeCid = MinerActorCodeObj.Cid()
       BootstrapMinerActorCodeObj = dag.NewRawNode([]byte("bootstrapmineractor"))
       BootstrapMinerActorCodeCid = BootstrapMinerActorCodeObj.Cid()
    
       // New Actors need to be added here.
       // TODO: Make this work with reflection -- but note that nasty import cycles lie on that path.
       // This is good enough for now.
       ActorCodeCidTypeNames[AccountActorCodeCid] = "AccountActor"
       ActorCodeCidTypeNames[StorageMarketActorCodeCid] = "StorageMarketActor"
       ActorCodeCidTypeNames[PaymentBrokerActorCodeCid] = "PaymentBrokerActor"
       ActorCodeCidTypeNames[MinerActorCodeCid] = "MinerActor"
       ActorCodeCidTypeNames[BootstrapMinerActorCodeCid] = "MinerActor"
    }
    

    Message类似以太坊的交易,区块是由一个个的Message组成。一个Message由发起地址,目标地址,金额,调用的函数以及参数组成。所有Message的执行的结果就是状态机的全局状态。网络的全局状态就是映射表:Actor的地址和Actor的状态/信息。全局状态使用IPLD HAMT(Hash-Array Mapped Trie) 存储。

    // Message is an exchange of information between two actors modeled
    // as a function call.
    // Messages are the equivalent of transactions in Ethereum.
    type Message struct {
       To   address.Address `json:"to"`
       From address.Address `json:"from"`
       // When receiving a message from a user account the nonce in
       // the message must match the expected nonce in the from actor.
       // This prevents replay attacks.
       Nonce Uint64 `json:"nonce"`
    
       Value *AttoFIL `json:"value"`
    
       Method string `json:"method"`
       Params []byte `json:"params"`
       // Pay attention to Equals() if updating this struct.
    }
    

    区块(Block & TipSet):
    Block是一个区块,定义在types/block.go文件中:一个区块的信息主要包括:
    打包者的地址信息
    区块的高度/权重信息
    区块中包括的交易信息/更新后新的Root信息
    Ticket信息以及Ticket的PoSt的证明信息

    // Block is a block in the blockchain.
    type Block struct {
       // Miner is the address of the miner actor that mined this block.
       Miner address.Address `json:"miner"`
    
       // Ticket is the winning ticket that was submitted with this block.
       Ticket Signature `json:"ticket"`
    
       // Parents is the set of parents this block was based on. Typically one,
       // but can be several in the case where there were multiple winning ticket-
       // holders for an epoch.
       Parents SortedCidSet `json:"parents"`
    
       // ParentWeight is the aggregate chain weight of the parent set.
       ParentWeight Uint64 `json:"parentWeight"`
    
       // Height is the chain height of this block.
       Height Uint64 `json:"height"`
    
       // Nonce is a temporary field used to differentiate blocks for testing
       Nonce Uint64 `json:"nonce"`
    
       // Messages is the set of messages included in this block
       // TODO: should be a merkletree-ish thing
       Messages []*SignedMessage `json:"messages"`
    
       // StateRoot is a cid pointer to the state tree after application of the
       // transactions state transitions.
       StateRoot cid.Cid `json:"stateRoot,omitempty" refmt:",omitempty"`
    
       // MessageReceipts is a set of receipts matching to the sending of the `Messages`.
       MessageReceipts []*MessageReceipt `json:"messageReceipts"`
    
       // Proof is a proof of spacetime generated using the hash of the previous ticket as
       // a challenge
       Proof proofs.PoStProof `json:"proof"`
    
       cachedCid cid.Cid
    
       cachedBytes []byte
    }
    

    打包生成区块

    // Generate returns a new block created from the messages in the pool.
    func (w *DefaultWorker) Generate(ctx context.Context,
       baseTipSet types.TipSet,
       ticket types.Signature,
       proof proofs.PoStProof,
       nullBlockCount uint64) (*types.Block, error) {
           …………
       next := &types.Block{
          Miner:           w.minerAddr,
          Height:          types.Uint64(blockHeight),
          Messages:        res.SuccessfulMessages,
          MessageReceipts: receipts,
          Parents:         baseTipSet.ToSortedCidSet(),
          ParentWeight:    types.Uint64(weight),
          Proof:           proof,
          StateRoot:       newStateTreeCid,
          Ticket:          ticket,
       }
    

    TipSet 一个Tip,就是一个block。一个TipSet,就是多个区块信息的集合,这些区块拥有同一个父TipSet。定义在types/tipset.go文件中:

    // Tip is what expected consensus needs from a Block. For now it *is* a
    // Block.
    type Tip = Block
    // TipSet is a set of Tips, blocks at the same height with the same parent set,
    // keyed by Cid.
    type TipSet map[cid.Cid]*Tip
    

    矿工

    // Miner represents a storage miner.
    type Miner struct {
       minerAddr      address.Address
       minerOwnerAddr address.Address
    
       dealsAwaitingSealDs repo.Datastore
    
       postInProcessLk sync.Mutex
       postInProcess   *types.BlockHeight
    
       dealsAwaitingSeal *dealsAwaitingSealStruct
    
       porcelainAPI minerPorcelain
       node         node
    
       proposalAcceptor func(m *Miner, p *storagedeal.Proposal) (*storagedeal.Response, error)
       proposalRejector func(m *Miner, p *storagedeal.Proposal, reason string) (*storagedeal.Response, error)
    }
    

    创建矿工

    // MinerCreate creates a miner
    func (a *API) MinerCreate(
       ctx context.Context,
       accountAddr address.Address,
       gasPrice types.AttoFIL,
       gasLimit types.GasUnits,
       pledge uint64,
       pid peer.ID,
       collateral *types.AttoFIL,
    ) (_ *address.Address, err error) {
       return MinerCreate(ctx, a, accountAddr, gasPrice, gasLimit, pledge, pid, collateral)
    }
    

    FIL & AttoFIL:
    FIL是Filecoin项目的代币。AttoFIL是FIL代币的最小单位,1 AttoFIL = 10^(-18) FIL。

    // AttoFIL represents a signed multi-precision integer quantity of
    // attofilecoin (atto is metric for 10**-18). The zero value for
    // AttoFIL represents the value 0.
    type AttoFIL struct{ val *big.Int }
    

    Gas费用:
    和以太坊网络类似,执行Actor的函数需要消耗Gas。Actor的函数调用有两种方式:1/用户发起签名后的Message(指定调用某个Actor的某个函数),并支付矿工Gas费用(类似以太坊的Gas费用)。2/ Actor之间调用。Actor之间调用也必须是用户发起。

    相关文章

      网友评论

        本文标题:Filecoin源码架构分析--基础概念

        本文链接:https://www.haomeiwen.com/subject/dfpoiqtx.html