OSDN Git Service

update
[bytom/vapor.git] / asset / builder.go
index e9da029..c142074 100644 (file)
@@ -3,14 +3,12 @@ package asset
 import (
        "context"
        stdjson "encoding/json"
-       "time"
+       "fmt"
 
        log "github.com/sirupsen/logrus"
 
-       "github.com/vapor/blockchain/signers"
        "github.com/vapor/blockchain/txbuilder"
-       "github.com/vapor/crypto/ed25519/chainkd"
-       chainjson "github.com/vapor/encoding/json"
+       "github.com/vapor/consensus/federation"
        "github.com/vapor/errors"
        "github.com/vapor/protocol/bc"
        "github.com/vapor/protocol/bc/types"
@@ -26,28 +24,14 @@ func (r *Registry) DecodeCrossInAction(data []byte) (txbuilder.Action, error) {
 type crossInAction struct {
        reg *Registry
        bc.AssetAmount
-       SourceID        string                       `json:"source_id"`
-       SourcePos       uint64                       `json:"source_pos"`
-       FedXPubs        []chainkd.XPub               `json:"fed_xpubs"`
-       Quorum          int                          `json:"fed_quorum"`
-       AssetDefinition map[string]interface{}       `json:"asset_definition"`
-       Arguments       []txbuilder.ContractArgument `json:"arguments"`
-       // Program         chainjson.HexBytes           `json:"control_program"`
-       // Arguments []chainjson.HexBytes         `json:"arguments"`
+       SourceID        bc.Hash                `json:"source_id"`
+       SourcePos       uint64                 `json:"source_pos"`
+       AssetDefinition map[string]interface{} `json:"asset_definition"`
 }
 
-// TODO: also need to hard-code mapTx
-// TODO: federation can sign? check arguments length? will path be diff?
-// TODO: check replay
 func (a *crossInAction) Build(ctx context.Context, builder *txbuilder.TemplateBuilder) error {
        var missing []string
-       if len(a.FedXPubs) == 0 {
-               missing = append(missing, "fed_xpubs")
-       }
-       // if len(a.Program) == 0 {
-       //      missing = append(missing, "control_program")
-       // }
-       if a.SourceID == "" {
+       if a.SourceID.IsZero() {
                missing = append(missing, "source_id")
        }
        if a.AssetId.IsZero() {
@@ -60,76 +44,29 @@ func (a *crossInAction) Build(ctx context.Context, builder *txbuilder.TemplateBu
                return txbuilder.MissingFieldsError(missing...)
        }
 
-       var err error
-       asset := &Asset{}
-       if preAsset, _ := a.reg.GetAsset(a.AssetId.String()); preAsset != nil {
-               asset = preAsset
-       } else {
-               asset.RawDefinitionByte, err = serializeAssetDef(a.AssetDefinition)
-               if err != nil {
-                       return ErrSerializing
-               }
-
-               if !chainjson.IsValidJSON(asset.RawDefinitionByte) {
-                       return errors.New("asset definition is not in valid json format")
-               }
-
-               asset.DefinitionMap = a.AssetDefinition
-               asset.VMVersion = 1
-
-               // TODO: asset.Signer
-               assetSigner, err := signers.Create("asset", a.FedXPubs, a.Quorum, 1, signers.BIP0032)
-               if err != nil {
-                       return err
-               }
-
-               path := signers.GetBip0032Path(assetSigner, signers.AssetKeySpace)
-               derivedXPubs := chainkd.DeriveXPubs(assetSigner.XPubs, path)
-               derivedPKs := chainkd.XPubKeys(derivedXPubs)
-               // TODO: asset.IssuanceProgram
-               controlProgram, _, err := multisigCrossInProgram(derivedPKs, assetSigner.Quorum)
-               if err != nil {
-                       return err
-               }
-
-               asset.AssetID = *a.AssetId
-               extAlias := a.AssetId.String()
-               asset.Alias = &(extAlias)
-               a.reg.SaveExtAsset(asset, extAlias)
+       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")
        }
 
-       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
-               }
-       }
-
-       var sourceID bc.Hash
-       if err := sourceID.UnmarshalText([]byte(a.SourceID)); err != nil {
-               return errors.New("invalid sourceID format")
+       rawDefinitionByte, err := serializeAssetDef(a.AssetDefinition)
+       if err != nil {
+               return ErrSerializing
        }
 
-       txin := types.NewCrossChainInput(nil, sourceID, *a.AssetId, a.Amount, a.SourcePos, a.Program, 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")
-       builder.RestrictMinTime(time.Now())
+       tplIn := &txbuilder.SigningInstruction{}
+       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 *crossInAction) ActionType() string {
        return "cross_chain_in"
 }
-
-func multisigCrossInProgram(pubkeys []ed25519.PublicKey, nrequired int) (program []byte, vmversion uint64, err error) {
-       controlProg, err := vmutil.P2SPMultiSigProgram(pubkeys, nrequired)
-       if err != nil {
-               return nil, 0, err
-       }
-       builder := vmutil.NewBuilder()
-       builder.AddRawBytes(controlProg)
-       prog, err := builder.Build()
-       return prog, 1, err
-}