OSDN Git Service

Merge pull request #201 from Bytom/v0.1
[bytom/vapor.git] / protocol / bc / types / map.go
index 99be153..0fe229d 100644 (file)
@@ -1,8 +1,10 @@
 package types
 
 import (
+       log "github.com/sirupsen/logrus"
+       "golang.org/x/crypto/sha3"
+
        "github.com/vapor/consensus"
-       "github.com/vapor/crypto/sha3pool"
        "github.com/vapor/protocol/bc"
        "github.com/vapor/protocol/vm"
        "github.com/vapor/protocol/vm/vmutil"
@@ -20,11 +22,16 @@ func MapTx(oldTx *TxData) *bc.Tx {
        }
 
        spentOutputIDs := make(map[bc.Hash]bool)
+       mainchainOutputIDs := make(map[bc.Hash]bool)
        for id, e := range entries {
                var ord uint64
                switch e := e.(type) {
-               case *bc.Issuance:
+               case *bc.CrossChainInput:
                        ord = e.Ordinal
+                       mainchainOutputIDs[*e.MainchainOutputId] = true
+                       if *e.WitnessDestination.Value.AssetId == *consensus.BTMAssetID {
+                               tx.GasInputIDs = append(tx.GasInputIDs, id)
+                       }
 
                case *bc.Spend:
                        ord = e.Ordinal
@@ -33,10 +40,17 @@ func MapTx(oldTx *TxData) *bc.Tx {
                                tx.GasInputIDs = append(tx.GasInputIDs, id)
                        }
 
+               case *bc.VetoInput:
+                       ord = e.Ordinal
+                       spentOutputIDs[*e.SpentOutputId] = true
+                       if *e.WitnessDestination.Value.AssetId == *consensus.BTMAssetID {
+                               tx.GasInputIDs = append(tx.GasInputIDs, id)
+                       }
+
                case *bc.Coinbase:
                        ord = 0
-               case *bc.Claim:
-                       ord = 0
+                       tx.GasInputIDs = append(tx.GasInputIDs, id)
+
                default:
                        continue
                }
@@ -50,6 +64,9 @@ func MapTx(oldTx *TxData) *bc.Tx {
        for id := range spentOutputIDs {
                tx.SpentOutputIDs = append(tx.SpentOutputIDs, id)
        }
+       for id := range mainchainOutputIDs {
+               tx.MainchainOutputIDs = append(tx.MainchainOutputIDs, id)
+       }
        return tx
 }
 
@@ -62,37 +79,15 @@ func mapTx(tx *TxData) (headerID bc.Hash, hdr *bc.TxHeader, entryMap map[bc.Hash
        }
 
        var (
-               spends    []*bc.Spend
-               issuances []*bc.Issuance
-               coinbase  *bc.Coinbase
-               claim     *bc.Claim
+               spends     []*bc.Spend
+               vetoInputs []*bc.VetoInput
+               crossIns   []*bc.CrossChainInput
+               coinbase   *bc.Coinbase
        )
 
        muxSources := make([]*bc.ValueSource, len(tx.Inputs))
        for i, input := range tx.Inputs {
                switch inp := input.TypedInput.(type) {
-               case *IssuanceInput:
-                       nonceHash := inp.NonceHash()
-                       assetDefHash := inp.AssetDefinitionHash()
-                       value := input.AssetAmount()
-
-                       issuance := bc.NewIssuance(&nonceHash, &value, uint64(i))
-                       issuance.WitnessAssetDefinition = &bc.AssetDefinition{
-                               Data: &assetDefHash,
-                               IssuanceProgram: &bc.Program{
-                                       VmVersion: inp.VMVersion,
-                                       Code:      inp.IssuanceProgram,
-                               },
-                       }
-                       issuance.WitnessArguments = inp.Arguments
-                       issuanceID := addEntry(issuance)
-
-                       muxSources[i] = &bc.ValueSource{
-                               Ref:   &issuanceID,
-                               Value: &value,
-                       }
-                       issuances = append(issuances, issuance)
-
                case *SpendInput:
                        // create entry for prevout
                        prog := &bc.Program{VmVersion: inp.VMVersion, Code: inp.ControlProgram}
@@ -101,7 +96,7 @@ func mapTx(tx *TxData) (headerID bc.Hash, hdr *bc.TxHeader, entryMap map[bc.Hash
                                Value:    &inp.AssetAmount,
                                Position: inp.SourcePosition,
                        }
-                       prevout := bc.NewOutput(src, prog, 0) // ordinal doesn't matter for prevouts, only for result outputs
+                       prevout := bc.NewIntraChainOutput(src, prog, 0) // ordinal doesn't matter for prevouts, only for result outputs
                        prevoutID := addEntry(prevout)
                        // create entry for spend
                        spend := bc.NewSpend(&prevoutID, uint64(i))
@@ -119,28 +114,60 @@ func mapTx(tx *TxData) (headerID bc.Hash, hdr *bc.TxHeader, entryMap map[bc.Hash
                        coinbaseID := addEntry(coinbase)
 
                        out := tx.Outputs[0]
+                       value := out.AssetAmount()
                        muxSources[i] = &bc.ValueSource{
                                Ref:   &coinbaseID,
-                               Value: &out.AssetAmount,
+                               Value: &value,
                        }
-               case *ClaimInput:
-                       // create entry for prevout
+
+               case *VetoInput:
                        prog := &bc.Program{VmVersion: inp.VMVersion, Code: inp.ControlProgram}
                        src := &bc.ValueSource{
                                Ref:      &inp.SourceID,
                                Value:    &inp.AssetAmount,
                                Position: inp.SourcePosition,
                        }
-                       prevout := bc.NewOutput(src, prog, 0) // ordinal doesn't matter for prevouts, only for result outputs
+                       prevout := bc.NewVoteOutput(src, prog, 0, inp.Vote) // ordinal doesn't matter for prevouts, only for result outputs
                        prevoutID := addEntry(prevout)
+                       // create entry for VetoInput
+                       vetoInput := bc.NewVetoInput(&prevoutID, uint64(i))
+                       vetoInput.WitnessArguments = inp.Arguments
+                       vetoVoteID := addEntry(vetoInput)
+                       // setup mux
+                       muxSources[i] = &bc.ValueSource{
+                               Ref:   &vetoVoteID,
+                               Value: &inp.AssetAmount,
+                       }
+                       vetoInputs = append(vetoInputs, vetoInput)
+
+               case *CrossChainInput:
+                       prog := &bc.Program{VmVersion: inp.VMVersion, Code: inp.ControlProgram}
+                       src := &bc.ValueSource{
+                               Ref:      &inp.SourceID,
+                               Value:    &inp.AssetAmount,
+                               Position: inp.SourcePosition,
+                       }
+
+                       prevout := bc.NewIntraChainOutput(src, prog, 0) // ordinal doesn't matter
+                       outputID := bc.EntryID(prevout)
+
+                       assetDefHash := bc.NewHash(sha3.Sum256(inp.AssetDefinition))
+                       assetDef := &bc.AssetDefinition{
+                               Data: &assetDefHash,
+                               IssuanceProgram: &bc.Program{
+                                       VmVersion: inp.VMVersion,
+                                       Code:      inp.IssuanceProgram,
+                               },
+                       }
 
-                       claim = bc.NewClaim(&prevoutID, uint64(i), input.Peginwitness)
-                       claim.WitnessArguments = inp.Arguments
-                       claimID := addEntry(claim)
+                       crossIn := bc.NewCrossChainInput(&outputID, &inp.AssetAmount, prog, uint64(i), assetDef)
+                       crossIn.WitnessArguments = inp.Arguments
+                       crossInID := addEntry(crossIn)
                        muxSources[i] = &bc.ValueSource{
-                               Ref:   &claimID,
+                               Ref:   &crossInID,
                                Value: &inp.AssetAmount,
                        }
+                       crossIns = append(crossIns, crossIn)
                }
        }
 
@@ -149,39 +176,61 @@ func mapTx(tx *TxData) (headerID bc.Hash, hdr *bc.TxHeader, entryMap map[bc.Hash
 
        // connect the inputs to the mux
        for _, spend := range spends {
-               spentOutput := entryMap[*spend.SpentOutputId].(*bc.Output)
+               spentOutput := entryMap[*spend.SpentOutputId].(*bc.IntraChainOutput)
                spend.SetDestination(&muxID, spentOutput.Source.Value, spend.Ordinal)
        }
-       for _, issuance := range issuances {
-               issuance.SetDestination(&muxID, issuance.Value, issuance.Ordinal)
+
+       for _, vetoInput := range vetoInputs {
+               voteOutput := entryMap[*vetoInput.SpentOutputId].(*bc.VoteOutput)
+               vetoInput.SetDestination(&muxID, voteOutput.Source.Value, vetoInput.Ordinal)
        }
 
-       if coinbase != nil {
-               coinbase.SetDestination(&muxID, mux.Sources[0].Value, 0)
+       for _, crossIn := range crossIns {
+               crossIn.SetDestination(&muxID, crossIn.Value, crossIn.Ordinal)
        }
 
-       if claim != nil {
-               claim.SetDestination(&muxID, mux.Sources[0].Value, 0)
+       if coinbase != nil {
+               coinbase.SetDestination(&muxID, mux.Sources[0].Value, 0)
        }
 
        // convert types.outputs to the bc.output
        var resultIDs []*bc.Hash
        for i, out := range tx.Outputs {
+               value := out.AssetAmount()
                src := &bc.ValueSource{
                        Ref:      &muxID,
-                       Value:    &out.AssetAmount,
+                       Value:    &value,
                        Position: uint64(i),
                }
                var resultID bc.Hash
-               if vmutil.IsUnspendable(out.ControlProgram) {
+               switch {
+               // must deal with retirement first due to cases' priorities in the switch statement
+               case vmutil.IsUnspendable(out.ControlProgram()):
                        // retirement
                        r := bc.NewRetirement(src, uint64(i))
                        resultID = addEntry(r)
-               } else {
-                       // non-retirement
-                       prog := &bc.Program{out.VMVersion, out.ControlProgram}
-                       o := bc.NewOutput(src, prog, uint64(i))
+
+               case out.OutputType() == IntraChainOutputType:
+                       // non-retirement intra-chain tx
+                       prog := &bc.Program{out.VMVersion(), out.ControlProgram()}
+                       o := bc.NewIntraChainOutput(src, prog, uint64(i))
+                       resultID = addEntry(o)
+
+               case out.OutputType() == CrossChainOutputType:
+                       // non-retirement cross-chain tx
+                       prog := &bc.Program{out.VMVersion(), out.ControlProgram()}
+                       o := bc.NewCrossChainOutput(src, prog, uint64(i))
                        resultID = addEntry(o)
+
+               case out.OutputType() == VoteOutputType:
+                       // non-retirement vote tx
+                       voteOut, _ := out.TypedOutput.(*VoteTxOutput)
+                       prog := &bc.Program{out.VMVersion(), out.ControlProgram()}
+                       o := bc.NewVoteOutput(src, prog, uint64(i), voteOut.Vote)
+                       resultID = addEntry(o)
+
+               default:
+                       log.Warn("unknown outType")
                }
 
                dest := &bc.ValueDestination{
@@ -192,13 +241,13 @@ func mapTx(tx *TxData) (headerID bc.Hash, hdr *bc.TxHeader, entryMap map[bc.Hash
                resultIDs = append(resultIDs, &resultID)
                mux.WitnessDestinations = append(mux.WitnessDestinations, dest)
        }
-       refdatahash := hashData(tx.ReferenceData)
-       h := bc.NewTxHeader(tx.Version, tx.SerializedSize, &refdatahash, tx.TimeRange, resultIDs, true)
+
+       h := bc.NewTxHeader(tx.Version, tx.SerializedSize, tx.TimeRange, resultIDs)
        return addEntry(h), h, entryMap
 }
 
 func mapBlockHeader(old *BlockHeader) (bc.Hash, *bc.BlockHeader) {
-       bh := bc.NewBlockHeader(old.Version, old.Height, &old.PreviousBlockHash, old.Timestamp, &old.TransactionsMerkleRoot, &old.TransactionStatusHash)
+       bh := bc.NewBlockHeader(old.Version, old.Height, &old.PreviousBlockHash, old.Timestamp, &old.TransactionsMerkleRoot, &old.TransactionStatusHash, old.Witness)
        return bc.EntryID(bh), bh
 }
 
@@ -215,9 +264,3 @@ func MapBlock(old *Block) *bc.Block {
        }
        return b
 }
-
-func hashData(data []byte) bc.Hash {
-       var b32 [32]byte
-       sha3pool.Sum256(b32[:], data)
-       return bc.NewHash(b32)
-}