OSDN Git Service

update
[bytom/vapor.git] / asset / builder.go
index 44f9441..c142074 100644 (file)
@@ -2,71 +2,71 @@ package asset
 
 import (
        "context"
-       "crypto/rand"
-       "encoding/json"
-       "time"
+       stdjson "encoding/json"
+       "fmt"
 
        log "github.com/sirupsen/logrus"
 
-       "github.com/vapor/blockchain/signers"
        "github.com/vapor/blockchain/txbuilder"
+       "github.com/vapor/consensus/federation"
+       "github.com/vapor/errors"
        "github.com/vapor/protocol/bc"
        "github.com/vapor/protocol/bc/types"
 )
 
-//NewIssueAction create a new asset issue action
-func (reg *Registry) NewIssueAction(assetAmount bc.AssetAmount) txbuilder.Action {
-       return &issueAction{
-               assets:      reg,
-               AssetAmount: assetAmount,
-       }
-}
-
-//DecodeIssueAction unmarshal JSON-encoded data of asset issue action
-func (reg *Registry) DecodeIssueAction(data []byte) (txbuilder.Action, error) {
-       a := &issueAction{assets: reg}
-       err := json.Unmarshal(data, a)
+// DecodeCrossInAction convert input data to action struct
+func (r *Registry) DecodeCrossInAction(data []byte) (txbuilder.Action, error) {
+       a := &crossInAction{reg: r}
+       err := stdjson.Unmarshal(data, a)
        return a, err
 }
 
-type issueAction struct {
-       assets *Registry
+type crossInAction struct {
+       reg *Registry
        bc.AssetAmount
-       Arguments []txbuilder.ContractArgument `json:"arguments"`
+       SourceID        bc.Hash                `json:"source_id"`
+       SourcePos       uint64                 `json:"source_pos"`
+       AssetDefinition map[string]interface{} `json:"asset_definition"`
 }
 
-func (a *issueAction) Build(ctx context.Context, builder *txbuilder.TemplateBuilder) error {
+func (a *crossInAction) Build(ctx context.Context, builder *txbuilder.TemplateBuilder) error {
+       var missing []string
+       if a.SourceID.IsZero() {
+               missing = append(missing, "source_id")
+       }
        if a.AssetId.IsZero() {
-               return txbuilder.MissingFieldsError("asset_id")
+               missing = append(missing, "asset_id")
+       }
+       if a.Amount == 0 {
+               missing = append(missing, "amount")
+       }
+       if len(missing) > 0 {
+               return txbuilder.MissingFieldsError(missing...)
        }
 
-       asset, err := a.assets.FindByID(ctx, a.AssetId)
-       if err != nil {
-               return err
+       sourceKey := []byte(fmt.Sprintf("SC:%v:%v", a.SourceID, a.SourcePos))
+       a.reg.assetMu.Lock()
+       defer a.reg.assetMu.Unlock()
+       if existed := a.reg.db.Get(sourceKey); existed != nil {
+               return errors.New("mainchain output double spent")
        }
 
-       var nonce [8]byte
-       _, err = rand.Read(nonce[:])
+       rawDefinitionByte, err := serializeAssetDef(a.AssetDefinition)
        if err != nil {
-               return err
+               return ErrSerializing
        }
 
-       txin := types.NewIssuanceInput(nonce[:], a.Amount, asset.IssuanceProgram, nil, asset.RawDefinitionByte)
+       // 1. arguments will be set when materializeWitnesses
+       // 2. need to fill in issuance program here
+       txin := types.NewCrossChainInput(nil, a.SourceID, *a.AssetId, a.Amount, a.SourcePos, nil, rawDefinitionByte)
+       log.Info("cross-chain input action built")
        tplIn := &txbuilder.SigningInstruction{}
-       if asset.Signer != nil {
-               path := signers.GetBip0032Path(asset.Signer, signers.AssetKeySpace)
-               tplIn.AddRawWitnessKeys(asset.Signer.XPubs, path, asset.Signer.Quorum)
-       } else if a.Arguments != nil {
-               if err := txbuilder.AddContractArgs(tplIn, a.Arguments); err != nil {
-                       return err
-               }
-       }
-
-       log.Info("Issue action build")
-       builder.RestrictMinTime(time.Now())
+       fed := federation.GetFederation()
+       tplIn.AddRawWitnessKeys(fed.XPubs, fed.Path(), fed.Quorum)
+       a.reg.db.Set(sourceKey, []byte("true"))
        return builder.AddInput(txin, tplIn)
 }
 
-func (a *issueAction) ActionType() string {
-       return "issue"
+func (a *crossInAction) ActionType() string {
+       return "cross_chain_in"
 }