From: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com> Date: Wed, 19 Jun 2019 05:23:37 +0000 (+0800) Subject: fix(cross_chain): add asset_id check in cross_chain_in request (#177) X-Git-Tag: v1.0.5~208^2~11 X-Git-Url: http://git.osdn.net/view?p=bytom%2Fvapor.git;a=commitdiff_plain;h=91641ae15f80f23c21745bbdf9357e7124803eee fix(cross_chain): add asset_id check in cross_chain_in request (#177) * init issuance_program * add asset * fix * modify asset of crosschain input * fix test * add assetdef of bc * fix * modify code * fix check assetID * fix wallet uint * fix review * fix utxo uint test * delete code * remove space * fix review * remove checkfederation * fix review --- diff --git a/blockchain/txbuilder/actions.go b/blockchain/txbuilder/actions.go index 99f35bc2..f06c3ed6 100644 --- a/blockchain/txbuilder/actions.go +++ b/blockchain/txbuilder/actions.go @@ -5,9 +5,10 @@ import ( stdjson "encoding/json" "errors" - "github.com/vapor/config" + "golang.org/x/crypto/sha3" "github.com/vapor/common" + "github.com/vapor/config" "github.com/vapor/consensus" "github.com/vapor/encoding/json" "github.com/vapor/protocol/bc" @@ -261,9 +262,11 @@ func DecodeCrossInAction(data []byte) (Action, error) { type crossInAction struct { bc.AssetAmount - SourceID bc.Hash `json:"source_id"` - SourcePos uint64 `json:"source_pos"` - RawDefinitionByte json.HexBytes `json:"raw_definition_byte"` + SourceID bc.Hash `json:"source_id"` + SourcePos uint64 `json:"source_pos"` + VMVersion uint64 `json:"vm_version"` + RawDefinitionByte []byte `json:"raw_definition_byte"` + IssuanceProgram []byte `json:"issuance_program"` } func (a *crossInAction) Build(ctx context.Context, builder *TemplateBuilder) error { @@ -277,13 +280,17 @@ func (a *crossInAction) Build(ctx context.Context, builder *TemplateBuilder) err if a.Amount == 0 { missing = append(missing, "amount") } + if len(missing) > 0 { return MissingFieldsError(missing...) } + if err := a.checkAssetID(); err != nil { + return err + } + // arguments will be set when materializeWitnesses - fedProg := config.FederationProgrom(config.CommonConfig) - txin := types.NewCrossChainInput(nil, a.SourceID, *a.AssetId, a.Amount, a.SourcePos, fedProg, a.RawDefinitionByte) + txin := types.NewCrossChainInput(nil, a.SourceID, *a.AssetId, a.Amount, a.SourcePos, a.VMVersion, a.RawDefinitionByte, a.IssuanceProgram) tplIn := &SigningInstruction{} fed := config.CommonConfig.Federation tplIn.AddRawWitnessKeys(fed.Xpubs, nil, fed.Quorum) @@ -293,3 +300,14 @@ func (a *crossInAction) Build(ctx context.Context, builder *TemplateBuilder) err func (a *crossInAction) ActionType() string { return "cross_chain_in" } + +func (c *crossInAction) checkAssetID() error { + defHash := bc.NewHash(sha3.Sum256(c.RawDefinitionByte)) + assetID := bc.ComputeAssetID(c.IssuanceProgram, c.VMVersion, &defHash) + + if *c.AssetId == *consensus.BTMAssetID && assetID != *c.AssetAmount.AssetId { + return errors.New("incorrect asset_idincorrect asset_id") + } + + return nil +} diff --git a/protocol/bc/asset.go b/protocol/bc/asset.go index 91285fa6..553cd710 100644 --- a/protocol/bc/asset.go +++ b/protocol/bc/asset.go @@ -5,6 +5,7 @@ import ( "errors" "io" + "github.com/vapor/crypto/sha3pool" "github.com/vapor/encoding/blockchain" ) @@ -42,6 +43,28 @@ func (a *AssetID) ReadFrom(r io.Reader) (int64, error) { return (*Hash)(a).ReadF // IsZero tells whether a Asset pointer is nil or points to an all-zero hash. func (a *AssetID) IsZero() bool { return (*Hash)(a).IsZero() } +// ComputeAssetID calculate the asset id from AssetDefinition +func (ad *AssetDefinition) ComputeAssetID() (assetID AssetID) { + h := sha3pool.Get256() + defer sha3pool.Put256(h) + writeForHash(h, *ad) // error is impossible + var b [32]byte + h.Read(b[:]) // error is impossible + return NewAssetID(b) +} + +// ComputeAssetID implement the assetID calculate logic +func ComputeAssetID(prog []byte, vmVersion uint64, data *Hash) AssetID { + def := &AssetDefinition{ + IssuanceProgram: &Program{ + VmVersion: vmVersion, + Code: prog, + }, + Data: data, + } + return def.ComputeAssetID() +} + // ReadFrom read the AssetAmount from the bytes func (a *AssetAmount) ReadFrom(r *blockchain.Reader) (err error) { var assetID AssetID diff --git a/protocol/bc/bc.pb.go b/protocol/bc/bc.pb.go index fbffe83b..d31e7310 100644 --- a/protocol/bc/bc.pb.go +++ b/protocol/bc/bc.pb.go @@ -12,6 +12,7 @@ It has these top-level messages: Program AssetID AssetAmount + AssetDefinition ValueSource ValueDestination BlockHeader @@ -178,6 +179,30 @@ func (m *AssetAmount) GetAmount() uint64 { return 0 } +type AssetDefinition struct { + IssuanceProgram *Program `protobuf:"bytes,1,opt,name=issuance_program,json=issuanceProgram" json:"issuance_program,omitempty"` + Data *Hash `protobuf:"bytes,2,opt,name=data" json:"data,omitempty"` +} + +func (m *AssetDefinition) Reset() { *m = AssetDefinition{} } +func (m *AssetDefinition) String() string { return proto.CompactTextString(m) } +func (*AssetDefinition) ProtoMessage() {} +func (*AssetDefinition) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } + +func (m *AssetDefinition) GetIssuanceProgram() *Program { + if m != nil { + return m.IssuanceProgram + } + return nil +} + +func (m *AssetDefinition) GetData() *Hash { + if m != nil { + return m.Data + } + return nil +} + type ValueSource struct { Ref *Hash `protobuf:"bytes,1,opt,name=ref" json:"ref,omitempty"` Value *AssetAmount `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` @@ -187,7 +212,7 @@ type ValueSource struct { func (m *ValueSource) Reset() { *m = ValueSource{} } func (m *ValueSource) String() string { return proto.CompactTextString(m) } func (*ValueSource) ProtoMessage() {} -func (*ValueSource) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } +func (*ValueSource) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } func (m *ValueSource) GetRef() *Hash { if m != nil { @@ -219,7 +244,7 @@ type ValueDestination struct { func (m *ValueDestination) Reset() { *m = ValueDestination{} } func (m *ValueDestination) String() string { return proto.CompactTextString(m) } func (*ValueDestination) ProtoMessage() {} -func (*ValueDestination) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } +func (*ValueDestination) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } func (m *ValueDestination) GetRef() *Hash { if m != nil { @@ -256,7 +281,7 @@ type BlockHeader struct { func (m *BlockHeader) Reset() { *m = BlockHeader{} } func (m *BlockHeader) String() string { return proto.CompactTextString(m) } func (*BlockHeader) ProtoMessage() {} -func (*BlockHeader) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } +func (*BlockHeader) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } func (m *BlockHeader) GetVersion() uint64 { if m != nil { @@ -324,7 +349,7 @@ type TxHeader struct { func (m *TxHeader) Reset() { *m = TxHeader{} } func (m *TxHeader) String() string { return proto.CompactTextString(m) } func (*TxHeader) ProtoMessage() {} -func (*TxHeader) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } +func (*TxHeader) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } func (m *TxHeader) GetVersion() uint64 { if m != nil { @@ -361,7 +386,7 @@ type TxVerifyResult struct { func (m *TxVerifyResult) Reset() { *m = TxVerifyResult{} } func (m *TxVerifyResult) String() string { return proto.CompactTextString(m) } func (*TxVerifyResult) ProtoMessage() {} -func (*TxVerifyResult) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } +func (*TxVerifyResult) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } func (m *TxVerifyResult) GetStatusFail() bool { if m != nil { @@ -378,7 +403,7 @@ type TransactionStatus struct { func (m *TransactionStatus) Reset() { *m = TransactionStatus{} } func (m *TransactionStatus) String() string { return proto.CompactTextString(m) } func (*TransactionStatus) ProtoMessage() {} -func (*TransactionStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } +func (*TransactionStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } func (m *TransactionStatus) GetVersion() uint64 { if m != nil { @@ -404,7 +429,7 @@ type Mux struct { func (m *Mux) Reset() { *m = Mux{} } func (m *Mux) String() string { return proto.CompactTextString(m) } func (*Mux) ProtoMessage() {} -func (*Mux) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } +func (*Mux) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } func (m *Mux) GetSources() []*ValueSource { if m != nil { @@ -442,7 +467,7 @@ type Coinbase struct { func (m *Coinbase) Reset() { *m = Coinbase{} } func (m *Coinbase) String() string { return proto.CompactTextString(m) } func (*Coinbase) ProtoMessage() {} -func (*Coinbase) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } +func (*Coinbase) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } func (m *Coinbase) GetWitnessDestination() *ValueDestination { if m != nil { @@ -467,7 +492,7 @@ type IntraChainOutput struct { func (m *IntraChainOutput) Reset() { *m = IntraChainOutput{} } func (m *IntraChainOutput) String() string { return proto.CompactTextString(m) } func (*IntraChainOutput) ProtoMessage() {} -func (*IntraChainOutput) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } +func (*IntraChainOutput) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } func (m *IntraChainOutput) GetSource() *ValueSource { if m != nil { @@ -499,7 +524,7 @@ type CrossChainOutput struct { func (m *CrossChainOutput) Reset() { *m = CrossChainOutput{} } func (m *CrossChainOutput) String() string { return proto.CompactTextString(m) } func (*CrossChainOutput) ProtoMessage() {} -func (*CrossChainOutput) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } +func (*CrossChainOutput) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } func (m *CrossChainOutput) GetSource() *ValueSource { if m != nil { @@ -532,7 +557,7 @@ type VoteOutput struct { func (m *VoteOutput) Reset() { *m = VoteOutput{} } func (m *VoteOutput) String() string { return proto.CompactTextString(m) } func (*VoteOutput) ProtoMessage() {} -func (*VoteOutput) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } +func (*VoteOutput) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } func (m *VoteOutput) GetSource() *ValueSource { if m != nil { @@ -572,7 +597,7 @@ type VetoInput struct { func (m *VetoInput) Reset() { *m = VetoInput{} } func (m *VetoInput) String() string { return proto.CompactTextString(m) } func (*VetoInput) ProtoMessage() {} -func (*VetoInput) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } +func (*VetoInput) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } func (m *VetoInput) GetSpentOutputId() *Hash { if m != nil { @@ -610,7 +635,7 @@ type Retirement struct { func (m *Retirement) Reset() { *m = Retirement{} } func (m *Retirement) String() string { return proto.CompactTextString(m) } func (*Retirement) ProtoMessage() {} -func (*Retirement) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } +func (*Retirement) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } func (m *Retirement) GetSource() *ValueSource { if m != nil { @@ -636,7 +661,7 @@ type Spend struct { func (m *Spend) Reset() { *m = Spend{} } func (m *Spend) String() string { return proto.CompactTextString(m) } func (*Spend) ProtoMessage() {} -func (*Spend) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } +func (*Spend) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } func (m *Spend) GetSpentOutputId() *Hash { if m != nil { @@ -671,14 +696,15 @@ type CrossChainInput struct { Value *AssetAmount `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` WitnessDestination *ValueDestination `protobuf:"bytes,3,opt,name=witness_destination,json=witnessDestination" json:"witness_destination,omitempty"` ControlProgram *Program `protobuf:"bytes,4,opt,name=control_program,json=controlProgram" json:"control_program,omitempty"` - WitnessArguments [][]byte `protobuf:"bytes,5,rep,name=witness_arguments,json=witnessArguments,proto3" json:"witness_arguments,omitempty"` - Ordinal uint64 `protobuf:"varint,6,opt,name=ordinal" json:"ordinal,omitempty"` + AssetDefinition *AssetDefinition `protobuf:"bytes,5,opt,name=asset_definition,json=assetDefinition" json:"asset_definition,omitempty"` + WitnessArguments [][]byte `protobuf:"bytes,6,rep,name=witness_arguments,json=witnessArguments,proto3" json:"witness_arguments,omitempty"` + Ordinal uint64 `protobuf:"varint,7,opt,name=ordinal" json:"ordinal,omitempty"` } func (m *CrossChainInput) Reset() { *m = CrossChainInput{} } func (m *CrossChainInput) String() string { return proto.CompactTextString(m) } func (*CrossChainInput) ProtoMessage() {} -func (*CrossChainInput) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } +func (*CrossChainInput) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} } func (m *CrossChainInput) GetMainchainOutputId() *Hash { if m != nil { @@ -708,6 +734,13 @@ func (m *CrossChainInput) GetControlProgram() *Program { return nil } +func (m *CrossChainInput) GetAssetDefinition() *AssetDefinition { + if m != nil { + return m.AssetDefinition + } + return nil +} + func (m *CrossChainInput) GetWitnessArguments() [][]byte { if m != nil { return m.WitnessArguments @@ -727,6 +760,7 @@ func init() { proto.RegisterType((*Program)(nil), "bc.Program") proto.RegisterType((*AssetID)(nil), "bc.AssetID") proto.RegisterType((*AssetAmount)(nil), "bc.AssetAmount") + proto.RegisterType((*AssetDefinition)(nil), "bc.AssetDefinition") proto.RegisterType((*ValueSource)(nil), "bc.ValueSource") proto.RegisterType((*ValueDestination)(nil), "bc.ValueDestination") proto.RegisterType((*BlockHeader)(nil), "bc.BlockHeader") @@ -747,62 +781,65 @@ func init() { func init() { proto.RegisterFile("bc.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 898 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0xdd, 0x6e, 0x23, 0x35, - 0x14, 0x56, 0x66, 0xa6, 0x49, 0x7a, 0xd2, 0x6d, 0x1a, 0x77, 0x17, 0x46, 0x2b, 0x10, 0xd5, 0x48, - 0x4b, 0x17, 0x21, 0x55, 0xfd, 0x59, 0x04, 0x17, 0x5c, 0x50, 0x5a, 0x96, 0xcd, 0xc5, 0x6a, 0x91, - 0x5b, 0xe5, 0x76, 0xe4, 0xcc, 0xb8, 0x8d, 0xc5, 0x64, 0x1c, 0x6c, 0xcf, 0xd0, 0xed, 0x2b, 0x70, - 0xcd, 0x05, 0x2f, 0xc2, 0x2b, 0x70, 0x81, 0x78, 0x26, 0x90, 0xcf, 0x78, 0xf2, 0xd3, 0xa4, 0xed, - 0x56, 0x08, 0x01, 0x77, 0x39, 0xc7, 0xc7, 0xdf, 0xf9, 0xfc, 0xf9, 0x7c, 0x9e, 0x40, 0x7b, 0x98, - 0xec, 0x4d, 0x94, 0x34, 0x92, 0x78, 0xc3, 0x24, 0x7a, 0x09, 0xc1, 0x2b, 0xa6, 0x47, 0x64, 0x13, - 0xbc, 0x72, 0x3f, 0x6c, 0xec, 0x34, 0x9e, 0x37, 0xa9, 0x57, 0xee, 0x63, 0x7c, 0x10, 0x7a, 0x2e, - 0x3e, 0xc0, 0xf8, 0x30, 0xf4, 0x5d, 0x7c, 0x88, 0xf1, 0x51, 0x18, 0xb8, 0xf8, 0x28, 0xfa, 0x12, - 0x5a, 0xdf, 0x29, 0x79, 0xa9, 0xd8, 0x98, 0x7c, 0x08, 0x50, 0x8e, 0xe3, 0x92, 0x2b, 0x2d, 0x64, - 0x8e, 0x90, 0x01, 0x5d, 0x2f, 0xc7, 0x83, 0x2a, 0x41, 0x08, 0x04, 0x89, 0x4c, 0x39, 0x62, 0x6f, - 0x50, 0xfc, 0x1d, 0xf5, 0xa1, 0x75, 0xac, 0x35, 0x37, 0xfd, 0xd3, 0xbf, 0x4d, 0xe4, 0x35, 0x74, - 0x10, 0xea, 0x78, 0x2c, 0x8b, 0xdc, 0x90, 0x8f, 0xa1, 0xcd, 0x6c, 0x18, 0x8b, 0x14, 0x41, 0x3b, - 0x87, 0x9d, 0xbd, 0x61, 0xb2, 0xe7, 0xba, 0xd1, 0x16, 0x2e, 0xf6, 0x53, 0xf2, 0x1e, 0x34, 0x19, - 0xee, 0xc0, 0x56, 0x01, 0x75, 0x51, 0x94, 0x41, 0x67, 0xc0, 0xb2, 0x82, 0x9f, 0xc9, 0x42, 0x25, - 0x9c, 0x3c, 0x05, 0x5f, 0xf1, 0x0b, 0x87, 0xd4, 0xb6, 0x48, 0x56, 0x3d, 0x6a, 0x93, 0xe4, 0x19, - 0xac, 0x95, 0xb6, 0x14, 0x11, 0x3a, 0x87, 0xdd, 0x69, 0x9f, 0x8a, 0x0a, 0xad, 0x56, 0xc9, 0x53, - 0x68, 0x4f, 0xa4, 0x16, 0xc6, 0x8a, 0xe3, 0x63, 0xaf, 0x69, 0x1c, 0xfd, 0x00, 0x5b, 0xd8, 0xed, - 0x94, 0x6b, 0x23, 0x72, 0x66, 0x73, 0xff, 0x74, 0xcb, 0x3f, 0x3d, 0xe8, 0x7c, 0x9d, 0xc9, 0xe4, - 0xfb, 0x57, 0x9c, 0xa5, 0x5c, 0x91, 0x10, 0x5a, 0x8b, 0x57, 0x57, 0x87, 0x56, 0xa2, 0x11, 0x17, - 0x97, 0xa3, 0xa9, 0x44, 0x55, 0x44, 0x5e, 0x40, 0x6f, 0xa2, 0x78, 0x29, 0x64, 0xa1, 0xe3, 0xa1, - 0x45, 0xb2, 0x5a, 0xfb, 0x37, 0xe8, 0x76, 0xeb, 0x12, 0xec, 0xd5, 0x4f, 0xc9, 0x07, 0xb0, 0x6e, - 0xc4, 0x98, 0x6b, 0xc3, 0xc6, 0x13, 0xbc, 0xbe, 0x80, 0xce, 0x12, 0xe4, 0x33, 0xe8, 0x19, 0xc5, - 0x72, 0xcd, 0x12, 0x4b, 0x52, 0xc7, 0x4a, 0x4a, 0x13, 0xae, 0xdd, 0xc0, 0xdc, 0x9a, 0x2f, 0xa1, - 0x52, 0x1a, 0xf2, 0x15, 0xbc, 0x3f, 0x97, 0x8b, 0xb5, 0x61, 0xa6, 0xd0, 0xf1, 0x88, 0xe9, 0x51, - 0xd8, 0xbc, 0xb1, 0xf9, 0xc9, 0x5c, 0xe1, 0x19, 0xd6, 0xa1, 0x0f, 0x4e, 0x81, 0x2c, 0x23, 0x84, - 0x2d, 0xdc, 0xfc, 0xc4, 0x6e, 0x3e, 0xbf, 0xb9, 0x8d, 0xf6, 0x96, 0x90, 0xc8, 0xa7, 0xd0, 0xfb, - 0x51, 0x98, 0x9c, 0x6b, 0x1d, 0x33, 0x75, 0x59, 0x8c, 0x79, 0x6e, 0x74, 0xd8, 0xde, 0xf1, 0x9f, - 0x6f, 0xd0, 0x2d, 0xb7, 0x70, 0x5c, 0xe7, 0xa3, 0x9f, 0x1b, 0xd0, 0x3e, 0xbf, 0xba, 0x57, 0xfe, - 0x5d, 0xe8, 0x6a, 0xae, 0x04, 0xcb, 0xc4, 0x35, 0x4f, 0x63, 0x2d, 0xae, 0xb9, 0xbb, 0x87, 0xcd, - 0x59, 0xfa, 0x4c, 0x5c, 0x73, 0xeb, 0x3f, 0x2b, 0x64, 0xac, 0x58, 0x7e, 0xc9, 0xdd, 0x7d, 0xa3, - 0xb4, 0xd4, 0x26, 0xc8, 0x2e, 0x80, 0xe2, 0xba, 0xc8, 0xac, 0x25, 0x74, 0x18, 0xec, 0xf8, 0x0b, - 0xb2, 0xac, 0x57, 0x6b, 0xfd, 0x54, 0x47, 0x07, 0xb0, 0x79, 0x7e, 0x35, 0xe0, 0x4a, 0x5c, 0xbc, - 0xa5, 0x98, 0x24, 0x1f, 0x41, 0xc7, 0x49, 0x7a, 0xc1, 0x44, 0x86, 0x04, 0xdb, 0x14, 0xaa, 0xd4, - 0x4b, 0x26, 0xb2, 0xe8, 0x02, 0x7a, 0x4b, 0xfa, 0xdc, 0x71, 0xa4, 0xcf, 0xe1, 0x51, 0x89, 0xf8, - 0xb5, 0xce, 0x1e, 0xb2, 0x21, 0xa8, 0xf3, 0x42, 0x6b, 0xba, 0x51, 0x15, 0x56, 0x90, 0xd1, 0x1f, - 0x0d, 0xf0, 0x5f, 0x17, 0x57, 0xe4, 0x13, 0x68, 0x69, 0x34, 0xa6, 0x0e, 0x1b, 0xb8, 0x15, 0x1d, - 0x30, 0x67, 0x58, 0x5a, 0xaf, 0x93, 0x67, 0xd0, 0x9a, 0x54, 0x0f, 0x94, 0x33, 0x0b, 0xbe, 0x03, - 0xee, 0xcd, 0xa2, 0xf5, 0x1a, 0xf9, 0x16, 0x1e, 0xd7, 0x37, 0x97, 0xce, 0x4c, 0xa8, 0x43, 0x1f, - 0xe1, 0x1f, 0x4f, 0xe1, 0xe7, 0x1c, 0x4a, 0xb7, 0xdd, 0x8e, 0xb9, 0xdc, 0x2d, 0x23, 0x10, 0xdc, - 0x32, 0x02, 0x12, 0xda, 0x27, 0x52, 0xe4, 0x43, 0xa6, 0x39, 0xf9, 0x06, 0xb6, 0x57, 0x30, 0x70, - 0xfe, 0x5f, 0x4d, 0x80, 0x2c, 0x13, 0xb0, 0xfe, 0x62, 0x6a, 0x28, 0x8c, 0x62, 0xea, 0xad, 0x7b, - 0x6b, 0x67, 0x89, 0xe8, 0xa7, 0x06, 0x6c, 0xf5, 0x73, 0xa3, 0xd8, 0xc9, 0x88, 0x89, 0xfc, 0x4d, - 0x61, 0x26, 0x85, 0x21, 0xbb, 0xd0, 0xac, 0xd4, 0x72, 0xcd, 0x96, 0xc4, 0x74, 0xcb, 0xe4, 0x05, - 0x74, 0x13, 0x99, 0x1b, 0x25, 0xb3, 0xf8, 0x0e, 0x4d, 0x37, 0x5d, 0x4d, 0xfd, 0x5d, 0x08, 0xa1, - 0x25, 0x55, 0x2a, 0x72, 0x96, 0xb9, 0xa1, 0xac, 0x43, 0x64, 0x73, 0xa2, 0xa4, 0xd6, 0xff, 0x09, - 0x36, 0xbf, 0x34, 0x00, 0x06, 0xd2, 0xf0, 0x7f, 0x99, 0x87, 0xfd, 0x50, 0x96, 0xd2, 0x70, 0x7c, - 0x1c, 0x37, 0x28, 0xfe, 0x8e, 0x7e, 0x6f, 0xc0, 0xfa, 0x80, 0x1b, 0xd9, 0xcf, 0x2d, 0xb5, 0x7d, - 0xe8, 0xea, 0x09, 0xcf, 0x4d, 0x2c, 0x91, 0xea, 0xec, 0x1b, 0x37, 0xf3, 0xf3, 0x23, 0x2c, 0xa8, - 0x8e, 0xd2, 0x4f, 0x6f, 0x1b, 0x2e, 0xef, 0x81, 0xc3, 0xb5, 0x72, 0xb8, 0xfd, 0xd5, 0xc3, 0x3d, - 0x7f, 0xc2, 0x60, 0x51, 0xe9, 0x37, 0x00, 0x94, 0x1b, 0xa1, 0xb8, 0x2d, 0x7c, 0x77, 0xa1, 0xe7, - 0x00, 0xbd, 0x45, 0xc0, 0xdf, 0x1a, 0xb0, 0x76, 0x36, 0xe1, 0x79, 0xfa, 0xbf, 0x97, 0xe6, 0x57, - 0x0f, 0xba, 0x33, 0x4b, 0x54, 0xd7, 0xfd, 0x05, 0x6c, 0x8f, 0x99, 0xc8, 0x13, 0x9b, 0xb9, 0xe3, - 0x5c, 0xbd, 0x69, 0xd1, 0xf4, 0x6c, 0xef, 0xf8, 0x3f, 0xe1, 0x16, 0x09, 0xfc, 0x07, 0x4a, 0xb0, - 0xc2, 0x08, 0xc1, 0xfd, 0x46, 0x58, 0x29, 0xdc, 0xda, 0xfd, 0xc2, 0x35, 0x17, 0x84, 0x1b, 0x36, - 0xf1, 0xbf, 0xed, 0xd1, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xd2, 0x80, 0xe2, 0xa6, 0xe7, 0x0a, - 0x00, 0x00, + // 960 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4d, 0x6f, 0x1b, 0x37, + 0x13, 0x86, 0x56, 0x6b, 0x49, 0x1e, 0x39, 0x96, 0x44, 0x27, 0xef, 0xbb, 0x08, 0x52, 0xd4, 0x58, + 0x20, 0x75, 0x8a, 0x02, 0x86, 0x3f, 0xd2, 0x8f, 0x43, 0x51, 0xd4, 0xb5, 0x9b, 0x46, 0x87, 0x20, + 0x05, 0x6d, 0xe8, 0xba, 0xa0, 0x76, 0x29, 0x89, 0xa8, 0xb4, 0x54, 0x49, 0xae, 0xea, 0xf8, 0x2f, + 0xf4, 0xdc, 0x43, 0x7f, 0x51, 0x0f, 0x45, 0xff, 0x4e, 0xaf, 0x2d, 0x38, 0xcb, 0x95, 0x56, 0x1f, + 0xb6, 0x13, 0x14, 0x45, 0xdb, 0xdb, 0xce, 0x70, 0xf8, 0xcc, 0x33, 0x0f, 0x67, 0xb8, 0x84, 0x46, + 0x3f, 0x3e, 0x9c, 0x2a, 0x69, 0x24, 0xf1, 0xfa, 0x71, 0xf8, 0x02, 0xfc, 0x97, 0x4c, 0x8f, 0xc8, + 0x2e, 0x78, 0xb3, 0xa3, 0xa0, 0xb2, 0x5f, 0x79, 0x56, 0xa3, 0xde, 0xec, 0x08, 0xed, 0xe3, 0xc0, + 0x73, 0xf6, 0x31, 0xda, 0x27, 0x41, 0xd5, 0xd9, 0x27, 0x68, 0x9f, 0x06, 0xbe, 0xb3, 0x4f, 0xc3, + 0xcf, 0xa1, 0xfe, 0xad, 0x92, 0x43, 0xc5, 0x26, 0xe4, 0x3d, 0x80, 0xd9, 0x24, 0x9a, 0x71, 0xa5, + 0x85, 0x4c, 0x11, 0xd2, 0xa7, 0xdb, 0xb3, 0x49, 0x2f, 0x77, 0x10, 0x02, 0x7e, 0x2c, 0x13, 0x8e, + 0xd8, 0x3b, 0x14, 0xbf, 0xc3, 0x2e, 0xd4, 0xcf, 0xb4, 0xe6, 0xa6, 0x7b, 0xf1, 0x97, 0x89, 0xbc, + 0x82, 0x26, 0x42, 0x9d, 0x4d, 0x64, 0x96, 0x1a, 0xf2, 0x01, 0x34, 0x98, 0x35, 0x23, 0x91, 0x20, + 0x68, 0xf3, 0xa4, 0x79, 0xd8, 0x8f, 0x0f, 0x5d, 0x36, 0x5a, 0xc7, 0xc5, 0x6e, 0x42, 0xfe, 0x07, + 0x35, 0x86, 0x3b, 0x30, 0x95, 0x4f, 0x9d, 0x15, 0x0e, 0xa1, 0x85, 0xb1, 0x17, 0x7c, 0x20, 0x52, + 0x61, 0x6c, 0x01, 0x9f, 0x40, 0x5b, 0x68, 0x9d, 0xb1, 0x34, 0xe6, 0xd1, 0x34, 0xaf, 0xb9, 0x0c, + 0xed, 0x64, 0xa0, 0xad, 0x22, 0xa8, 0xd0, 0xe5, 0x09, 0xf8, 0x09, 0x33, 0x0c, 0x13, 0x34, 0x4f, + 0x1a, 0x36, 0xd6, 0x4a, 0x4f, 0xd1, 0x1b, 0x8e, 0xa1, 0xd9, 0x63, 0xe3, 0x8c, 0x5f, 0xca, 0x4c, + 0xc5, 0x9c, 0x3c, 0x86, 0xaa, 0xe2, 0x03, 0x87, 0xbb, 0x88, 0xb5, 0x4e, 0xf2, 0x14, 0xb6, 0x66, + 0x36, 0xd4, 0x21, 0xb5, 0xe6, 0x05, 0xe5, 0x35, 0xd3, 0x7c, 0x95, 0x3c, 0x86, 0xc6, 0x54, 0x6a, + 0xe4, 0x8c, 0x7a, 0xf9, 0x74, 0x6e, 0x87, 0xdf, 0x43, 0x1b, 0xb3, 0x5d, 0x70, 0x6d, 0x44, 0xca, + 0xb0, 0xae, 0xbf, 0x39, 0xe5, 0x1f, 0x1e, 0x34, 0xbf, 0x1a, 0xcb, 0xf8, 0xbb, 0x97, 0x9c, 0x25, + 0x5c, 0x91, 0x00, 0xea, 0xcb, 0x3d, 0x52, 0x98, 0xf6, 0x2c, 0x46, 0x5c, 0x0c, 0x47, 0xf3, 0xb3, + 0xc8, 0x2d, 0xf2, 0x1c, 0x3a, 0x53, 0xc5, 0x67, 0x42, 0x66, 0x3a, 0xea, 0x5b, 0x24, 0x7b, 0xa8, + 0xd5, 0x15, 0xba, 0xad, 0x22, 0x04, 0x73, 0x75, 0x13, 0xf2, 0x04, 0xb6, 0x8d, 0x98, 0x70, 0x6d, + 0xd8, 0x64, 0x8a, 0x7d, 0xe2, 0xd3, 0x85, 0x83, 0x7c, 0x0c, 0x1d, 0xa3, 0x58, 0xaa, 0x59, 0x6c, + 0x49, 0xea, 0x48, 0x49, 0x69, 0x82, 0xad, 0x15, 0xcc, 0x76, 0x39, 0x84, 0x4a, 0x69, 0xc8, 0x97, + 0xf0, 0xff, 0x92, 0x2f, 0xd2, 0x86, 0x99, 0x4c, 0x47, 0x23, 0xa6, 0x47, 0x41, 0x6d, 0x65, 0xf3, + 0xa3, 0x52, 0xe0, 0x25, 0xc6, 0xe1, 0xc0, 0x5d, 0x00, 0x59, 0x47, 0x08, 0xea, 0xb8, 0xf9, 0x91, + 0xdd, 0x7c, 0xb5, 0xba, 0x8d, 0x76, 0xd6, 0x90, 0xc8, 0x47, 0xd0, 0xf9, 0x41, 0x98, 0x94, 0x6b, + 0x1d, 0x31, 0x35, 0xcc, 0x26, 0x3c, 0x35, 0x3a, 0x68, 0xec, 0x57, 0x9f, 0xed, 0xd0, 0xb6, 0x5b, + 0x38, 0x2b, 0xfc, 0xe1, 0x4f, 0x15, 0x68, 0x5c, 0x5d, 0xdf, 0x2b, 0xff, 0x01, 0xb4, 0x34, 0x57, + 0x82, 0x8d, 0xc5, 0x0d, 0x4f, 0x22, 0x2d, 0x6e, 0xb8, 0x3b, 0x87, 0xdd, 0x85, 0xfb, 0x52, 0xdc, + 0x70, 0x3b, 0xe8, 0x56, 0xc8, 0x48, 0xb1, 0x74, 0xc8, 0xdd, 0x79, 0xa3, 0xb4, 0xd4, 0x3a, 0xc8, + 0x01, 0x80, 0xe2, 0x3a, 0x1b, 0xdb, 0xd9, 0xd3, 0x81, 0xbf, 0x5f, 0x5d, 0x92, 0x65, 0x3b, 0x5f, + 0xeb, 0x26, 0x3a, 0x3c, 0x86, 0xdd, 0xab, 0xeb, 0x1e, 0x57, 0x62, 0xf0, 0x86, 0xa2, 0x93, 0xbc, + 0x0f, 0x4d, 0x27, 0xe9, 0x80, 0x89, 0x31, 0x12, 0x6c, 0x50, 0xc8, 0x5d, 0x2f, 0x98, 0x18, 0x87, + 0x03, 0xe8, 0xac, 0xe9, 0x73, 0x47, 0x49, 0x9f, 0xc2, 0x83, 0x19, 0xe2, 0x17, 0x3a, 0x7b, 0xc8, + 0x86, 0xa0, 0xce, 0x4b, 0xa9, 0xe9, 0x4e, 0x1e, 0x98, 0x43, 0x86, 0xbf, 0x55, 0xa0, 0xfa, 0x2a, + 0xbb, 0x26, 0x1f, 0x42, 0x5d, 0xe3, 0x60, 0xea, 0xa0, 0x82, 0x5b, 0x71, 0x02, 0x4a, 0x03, 0x4b, + 0x8b, 0x75, 0xf2, 0x14, 0xea, 0xc5, 0xad, 0xe0, 0xad, 0xdf, 0x0a, 0xc5, 0x1a, 0xf9, 0x06, 0x1e, + 0x16, 0x27, 0x97, 0x2c, 0x86, 0x50, 0x07, 0x55, 0x84, 0x7f, 0x38, 0x87, 0x2f, 0x4d, 0x28, 0xdd, + 0x73, 0x3b, 0x4a, 0xbe, 0x5b, 0x5a, 0xc0, 0xbf, 0xa5, 0x05, 0x24, 0x34, 0xce, 0xa5, 0x48, 0xfb, + 0x4c, 0x73, 0xf2, 0x35, 0xec, 0x6d, 0x60, 0xe0, 0xe6, 0x7f, 0x33, 0x01, 0xb2, 0x4e, 0xc0, 0xce, + 0x17, 0x53, 0x7d, 0x61, 0x14, 0x53, 0x6f, 0xdc, 0xa5, 0xbe, 0x70, 0x84, 0x3f, 0x56, 0xa0, 0xdd, + 0x4d, 0x8d, 0x62, 0xe7, 0x23, 0x26, 0xd2, 0xd7, 0x99, 0x99, 0x66, 0x86, 0x1c, 0x40, 0x2d, 0x57, + 0xcb, 0x25, 0x5b, 0x13, 0xd3, 0x2d, 0x93, 0xe7, 0xd0, 0x8a, 0x65, 0x6a, 0x94, 0x1c, 0x47, 0x77, + 0x68, 0xba, 0xeb, 0x62, 0x8a, 0x8b, 0x36, 0x80, 0xba, 0x54, 0x89, 0x48, 0xd9, 0xd8, 0x35, 0x65, + 0x61, 0x22, 0x9b, 0x73, 0x25, 0xb5, 0xfe, 0x57, 0xb0, 0xf9, 0xb9, 0x02, 0xd0, 0x93, 0x86, 0xff, + 0xc3, 0x3c, 0xec, 0x1f, 0x79, 0x26, 0x0d, 0xc7, 0xcb, 0x71, 0x87, 0xe2, 0x77, 0xf8, 0x6b, 0x05, + 0xb6, 0x7b, 0xdc, 0xc8, 0x6e, 0x6a, 0xa9, 0x1d, 0x41, 0x4b, 0x4f, 0x79, 0x6a, 0x22, 0x89, 0x54, + 0x17, 0x3f, 0xd3, 0xc5, 0x3c, 0x3f, 0xc0, 0x80, 0xbc, 0x94, 0x6e, 0x72, 0x5b, 0x73, 0x79, 0xef, + 0xd8, 0x5c, 0x1b, 0x9b, 0xbb, 0xba, 0xb9, 0xb9, 0xcb, 0x15, 0xfa, 0xcb, 0x4a, 0xbf, 0x06, 0xa0, + 0xdc, 0x08, 0xc5, 0x6d, 0xe0, 0xdb, 0x0b, 0x5d, 0x02, 0xf4, 0x96, 0x01, 0x7f, 0xa9, 0xc0, 0xd6, + 0xe5, 0x94, 0xa7, 0xc9, 0x7f, 0x5e, 0x9a, 0xdf, 0x3d, 0x68, 0x2d, 0x46, 0x22, 0x3f, 0xee, 0xcf, + 0x60, 0x6f, 0xc2, 0x44, 0x1a, 0x5b, 0xcf, 0x1d, 0x75, 0x75, 0xe6, 0x41, 0xf3, 0xda, 0xde, 0xf2, + 0x9d, 0x70, 0x8b, 0x04, 0xd5, 0x77, 0x94, 0x60, 0xc3, 0x20, 0xf8, 0xf7, 0x0f, 0xc2, 0x17, 0xd0, + 0xce, 0x9f, 0x84, 0xc9, 0xfc, 0x4d, 0xe7, 0xfe, 0xf8, 0x7b, 0x73, 0xba, 0x8b, 0xe7, 0x1e, 0x6d, + 0xb1, 0x95, 0xf7, 0xdf, 0x46, 0xe1, 0x6b, 0xf7, 0x0b, 0x5f, 0x5f, 0x12, 0xbe, 0x5f, 0xc3, 0x47, + 0xf8, 0xe9, 0x9f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x2b, 0x1b, 0x9e, 0x47, 0x90, 0x0b, 0x00, 0x00, } diff --git a/protocol/bc/bc.proto b/protocol/bc/bc.proto index 827100b6..d3085c08 100644 --- a/protocol/bc/bc.proto +++ b/protocol/bc/bc.proto @@ -31,6 +31,11 @@ message AssetAmount { uint64 amount = 2; } +message AssetDefinition { + Program issuance_program = 1; + Hash data = 2; +} + message ValueSource { Hash ref = 1; AssetAmount value = 2; @@ -121,10 +126,11 @@ message Spend { } message CrossChainInput { - Hash mainchain_output_id = 1; - AssetAmount value = 2; - ValueDestination witness_destination = 3; - Program control_program = 4; - repeated bytes witness_arguments = 5; - uint64 ordinal = 6; -} \ No newline at end of file + Hash mainchain_output_id = 1; + AssetAmount value = 2; + ValueDestination witness_destination = 3; + Program control_program = 4; + AssetDefinition asset_definition = 5; + repeated bytes witness_arguments = 6; + uint64 ordinal = 7; +} diff --git a/protocol/bc/crosschain_input.go b/protocol/bc/crosschain_input.go index 63515f27..123ce253 100644 --- a/protocol/bc/crosschain_input.go +++ b/protocol/bc/crosschain_input.go @@ -9,6 +9,8 @@ func (CrossChainInput) typ() string { return "crosschaininput1" } func (cci *CrossChainInput) writeForHash(w io.Writer) { mustWriteForHash(w, cci.MainchainOutputId) + mustWriteForHash(w, cci.Value) + mustWriteForHash(w, cci.AssetDefinition) } // SetDestination will link the CrossChainInput to the output @@ -21,11 +23,12 @@ func (cci *CrossChainInput) SetDestination(id *Hash, val *AssetAmount, pos uint6 } // NewCrossChainInput creates a new CrossChainInput. -func NewCrossChainInput(mainchainOutputID *Hash, value *AssetAmount, prog *Program, ordinal uint64) *CrossChainInput { +func NewCrossChainInput(mainchainOutputID *Hash, value *AssetAmount, prog *Program, ordinal uint64, assetDef *AssetDefinition) *CrossChainInput { return &CrossChainInput{ MainchainOutputId: mainchainOutputID, Value: value, Ordinal: ordinal, ControlProgram: prog, + AssetDefinition: assetDef, } } diff --git a/protocol/bc/types/crosschain_input.go b/protocol/bc/types/crosschain_input.go index a08cfd6c..e29673d5 100644 --- a/protocol/bc/types/crosschain_input.go +++ b/protocol/bc/types/crosschain_input.go @@ -6,16 +6,19 @@ import ( // CrossChainInput satisfies the TypedInput interface and represents a cross-chain transaction. type CrossChainInput struct { - AssetDefinition []byte SpendCommitmentSuffix []byte // The unconsumed suffix of the spend commitment Arguments [][]byte // Witness SpendCommitment + + VMVersion uint64 + AssetDefinition []byte + IssuanceProgram []byte } // NewCrossChainInput create a new CrossChainInput struct. // The source is created/issued by trusted federation and hence there is no need // to refer to it. -func NewCrossChainInput(arguments [][]byte, sourceID bc.Hash, assetID bc.AssetID, amount, sourcePos uint64, controlProgram, assetDefinition []byte) *TxInput { +func NewCrossChainInput(arguments [][]byte, sourceID bc.Hash, assetID bc.AssetID, amount, sourcePos, vmVersion uint64, assetDefinition, issuanceProgram []byte) *TxInput { sc := SpendCommitment{ AssetAmount: bc.AssetAmount{ AssetId: &assetID, @@ -24,14 +27,15 @@ func NewCrossChainInput(arguments [][]byte, sourceID bc.Hash, assetID bc.AssetID SourceID: sourceID, SourcePosition: sourcePos, VMVersion: 1, - ControlProgram: controlProgram, } return &TxInput{ AssetVersion: 1, TypedInput: &CrossChainInput{ - AssetDefinition: assetDefinition, SpendCommitment: sc, Arguments: arguments, + VMVersion: vmVersion, + AssetDefinition: assetDefinition, + IssuanceProgram: issuanceProgram, }, } } diff --git a/protocol/bc/types/crosschain_output.go b/protocol/bc/types/crosschain_output.go index fc3ac587..afc92014 100644 --- a/protocol/bc/types/crosschain_output.go +++ b/protocol/bc/types/crosschain_output.go @@ -11,7 +11,7 @@ type CrossChainOutput struct { CommitmentSuffix []byte } -// CrossChainOutput create a new output struct +// NewCrossChainOutput create a new output struct func NewCrossChainOutput(assetID bc.AssetID, amount uint64, controlProgram []byte) *TxOutput { return &TxOutput{ AssetVersion: 1, diff --git a/protocol/bc/types/map.go b/protocol/bc/types/map.go index 170b9f09..0fe229dc 100644 --- a/protocol/bc/types/map.go +++ b/protocol/bc/types/map.go @@ -2,6 +2,7 @@ package types import ( log "github.com/sirupsen/logrus" + "golang.org/x/crypto/sha3" "github.com/vapor/consensus" "github.com/vapor/protocol/bc" @@ -140,16 +141,26 @@ func mapTx(tx *TxData) (headerID bc.Hash, hdr *bc.TxHeader, entryMap map[bc.Hash vetoInputs = append(vetoInputs, vetoInput) case *CrossChainInput: - // TODO: fed peg script 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) - crossIn := bc.NewCrossChainInput(&outputID, &inp.AssetAmount, prog, uint64(i)) + + assetDefHash := bc.NewHash(sha3.Sum256(inp.AssetDefinition)) + assetDef := &bc.AssetDefinition{ + Data: &assetDefHash, + IssuanceProgram: &bc.Program{ + VmVersion: inp.VMVersion, + Code: inp.IssuanceProgram, + }, + } + + crossIn := bc.NewCrossChainInput(&outputID, &inp.AssetAmount, prog, uint64(i), assetDef) crossIn.WitnessArguments = inp.Arguments crossInID := addEntry(crossIn) muxSources[i] = &bc.ValueSource{ diff --git a/protocol/bc/types/txinput.go b/protocol/bc/types/txinput.go index 47831cca..49188415 100644 --- a/protocol/bc/types/txinput.go +++ b/protocol/bc/types/txinput.go @@ -210,6 +210,18 @@ func (t *TxInput) readFrom(r *blockchain.Reader) (err error) { return err } + if inp.VMVersion, err = blockchain.ReadVarint63(r); err != nil { + return err + } + + if inp.AssetDefinition, err = blockchain.ReadVarstr31(r); err != nil { + return err + } + + if inp.IssuanceProgram, err = blockchain.ReadVarstr31(r); err != nil { + return err + } + case *VetoInput: if inp.Arguments, err = blockchain.ReadVarstrList(r); err != nil { return err @@ -225,13 +237,6 @@ func (t *TxInput) readFrom(r *blockchain.Reader) (err error) { return err } - switch inp := t.TypedInput.(type) { - case *CrossChainInput: - if inp.AssetDefinition, err = blockchain.ReadVarstr31(r); err != nil { - return err - } - } - return nil } @@ -248,13 +253,6 @@ func (t *TxInput) writeTo(w io.Writer) error { return errors.Wrap(err, "writing input witness") } - switch inp := t.TypedInput.(type) { - case *CrossChainInput: - if _, err := blockchain.WriteVarstr31(w, inp.AssetDefinition); err != nil { - return errors.Wrap(err, "writing AssetDefinition") - } - } - return nil } @@ -304,7 +302,20 @@ func (t *TxInput) writeInputWitness(w io.Writer) error { return err case *CrossChainInput: - _, err := blockchain.WriteVarstrList(w, inp.Arguments) + if _, err := blockchain.WriteVarstrList(w, inp.Arguments); err != nil { + return err + } + + if _, err := blockchain.WriteVarint63(w, inp.VMVersion); err != nil { + return err + } + + if _, err := blockchain.WriteVarstr31(w, inp.AssetDefinition); err != nil { + return err + } + + _, err := blockchain.WriteVarstr31(w, inp.IssuanceProgram) + return err case *VetoInput: if _, err := blockchain.WriteVarstrList(w, inp.Arguments); err != nil { diff --git a/protocol/bc/types/txinput_test.go b/protocol/bc/types/txinput_test.go index 884d6721..419b3cd8 100644 --- a/protocol/bc/types/txinput_test.go +++ b/protocol/bc/types/txinput_test.go @@ -71,28 +71,31 @@ func TestSerializationCrossIn(t *testing.T) { []byte("arguments1"), []byte("arguments2"), } - crossIn := NewCrossChainInput(arguments, testutil.MustDecodeHash("fad5195a0c8e3b590b86a3c0a95e7529565888508aecca96e9aeda633002f409"), testutil.MustDecodeAsset("fe9791d71b67ee62515e08723c061b5ccb952a80d804417c8aeedf7f633c524a"), 254354, 3, []byte("crossInProgram"), []byte("whatever")) + + crossIn := NewCrossChainInput(arguments, testutil.MustDecodeHash("fad5195a0c8e3b590b86a3c0a95e7529565888508aecca96e9aeda633002f409"), testutil.MustDecodeAsset("fe9791d71b67ee62515e08723c061b5ccb952a80d804417c8aeedf7f633c524a"), 254354, 3, 1, []byte("whatever"), []byte("IssuanceProgram")) wantHex := strings.Join([]string{ "01", // asset version - "56", // input commitment length + "48", // input commitment length "00", // cross-chain input type flag - "54", // cross-chain input commitment length + "46", // cross-chain input commitment length "fad5195a0c8e3b590b86a3c0a95e7529565888508aecca96e9aeda633002f409", // source id "fe9791d71b67ee62515e08723c061b5ccb952a80d804417c8aeedf7f633c524a", // assetID - "92c30f", // amount - "03", // source position - "01", // vm version - "0e", // spend program length - "63726f7373496e50726f6772616d", // spend program - "17", // witness length - "02", // argument array length - "0a", // first argument length - "617267756d656e747331", // first argument data - "0a", // second argument length - "617267756d656e747332", // second argument data - "08", // asset definition length - "7768617465766572", // asset definition data + "92c30f", // amount + "03", // source position + "01", // vm version + "00", // spend program length + "31", // witness length + "02", // argument array length + "0a", // first argument length + "617267756d656e747331", // first argument data + "0a", // second argument length + "617267756d656e747332", // second argument data + "01", // VmVersion + "08", // asset definition length + "7768617465766572", // asset definition data + "0f", // IssuanceProgram length + "49737375616e636550726f6772616d", // IssuanceProgram }, "") // Test convert struct to hex diff --git a/protocol/bc/types/vote_txoutput.go b/protocol/bc/types/vote_txoutput.go index a34107a4..f0ebe944 100644 --- a/protocol/bc/types/vote_txoutput.go +++ b/protocol/bc/types/vote_txoutput.go @@ -4,7 +4,7 @@ import ( "github.com/vapor/protocol/bc" ) -// VoteOutput satisfies the TypedOutput interface and represents a vote transaction. +// VoteTxOutput satisfies the TypedOutput interface and represents a vote transaction. type VoteTxOutput struct { OutputCommitment // Unconsumed suffixes of the commitment and witness extensible strings. diff --git a/protocol/validation/tx.go b/protocol/validation/tx.go index ce5feacf..0768d883 100644 --- a/protocol/validation/tx.go +++ b/protocol/validation/tx.go @@ -1,7 +1,6 @@ package validation import ( - "bytes" "fmt" "math" @@ -249,7 +248,17 @@ func checkValid(vs *validationState, e bc.Entry) (err error) { } case *bc.CrossChainInput: - _, err := vm.Verify(NewTxVMContext(vs, e, e.ControlProgram, e.WitnessArguments), consensus.DefaultGasCredit) + // check assetID + assetID := e.AssetDefinition.ComputeAssetID() + if *e.Value.AssetId != *consensus.BTMAssetID && *e.Value.AssetId != assetID { + return errors.New("incorrect asset_id while check CrossChainInput") + } + code := config.FederationProgrom(config.CommonConfig) + prog := &bc.Program{ + VmVersion: e.ControlProgram.VmVersion, + Code: code, + } + _, err := vm.Verify(NewTxVMContext(vs, e, prog, e.WitnessArguments), consensus.DefaultGasCredit) if err != nil { return errors.Wrap(err, "checking cross-chain input control program") } @@ -515,21 +524,6 @@ func checkValidDest(vs *validationState, vd *bc.ValueDestination) error { return nil } -func checkFedaration(tx *bc.Tx) error { - for _, id := range tx.InputIDs { - switch inp := tx.Entries[id].(type) { - case *bc.CrossChainInput: - fedProg := config.FederationProgrom(config.CommonConfig) - if !bytes.Equal(inp.ControlProgram.Code, fedProg) { - return errors.New("The federal controlProgram is incorrect") - } - default: - continue - } - } - return nil -} - func checkStandardTx(tx *bc.Tx, blockHeight uint64) error { for _, id := range tx.InputIDs { if blockHeight >= ruleAA && id.IsZero() { @@ -537,10 +531,6 @@ func checkStandardTx(tx *bc.Tx, blockHeight uint64) error { } } - if err := checkFedaration(tx); err != nil { - return err - } - for _, id := range tx.GasInputIDs { spend, err := tx.Spend(id) if err != nil { diff --git a/wallet/utxo_test.go b/wallet/utxo_test.go index 61d8e3b2..86450baf 100644 --- a/wallet/utxo_test.go +++ b/wallet/utxo_test.go @@ -671,8 +671,8 @@ func TestTxOutToUtxos(t *testing.T) { { tx: types.NewTx(types.TxData{ Inputs: []*types.TxInput{ - types.NewCrossChainInput([][]byte{}, bc.Hash{V0: 1}, bc.AssetID{V0: 1}, 5, 1, []byte{0x51}, []byte("asset1")), - types.NewCrossChainInput([][]byte{}, bc.Hash{V0: 2}, *consensus.BTMAssetID, 7, 1, []byte{0x51}, []byte("assetbtm"))}, + types.NewCrossChainInput([][]byte{}, bc.Hash{V0: 1}, bc.AssetID{V0: 1}, 5, 1, 1, []byte("asset1"), []byte("IssuanceProgram")), + types.NewCrossChainInput([][]byte{}, bc.Hash{V0: 2}, *consensus.BTMAssetID, 7, 1, 1, []byte("assetbtm"), []byte("IssuanceProgram"))}, Outputs: []*types.TxOutput{ types.NewIntraChainOutput(bc.AssetID{V0: 1}, 2, []byte{0x51}), types.NewIntraChainOutput(bc.AssetID{V0: 1}, 3, []byte{0x52}), @@ -684,35 +684,35 @@ func TestTxOutToUtxos(t *testing.T) { blockHeight: 0, wantUtxos: []*account.UTXO{ &account.UTXO{ - OutputID: bc.Hash{V0: 396952592194652166, V1: 9806684391645699244, V2: 484243382648745315, V3: 16988093808435014689}, + OutputID: bc.Hash{V0: 5429526025956869574, V1: 12188959875155232503, V2: 14722092106507294798, V3: 27876074648890075}, AssetID: bc.AssetID{V0: 1}, Amount: 2, ControlProgram: []byte{0x51}, - SourceID: bc.Hash{V0: 15256474482236132139, V1: 14615963227748152009, V2: 1392768713126269609, V3: 3435801067785833027}, + SourceID: bc.Hash{V0: 10187915247323429348, V1: 4770401581694266753, V2: 4182269187154655368, V3: 9030883832705174512}, SourcePos: 0, }, &account.UTXO{ - OutputID: bc.Hash{V0: 10880631720641638863, V1: 7783872056988487492, V2: 10925792818362846534, V3: 16483659407709834456}, + OutputID: bc.Hash{V0: 18100481287404207387, V1: 3365694797435565990, V2: 8136211093499423216, V3: 12028531817690438568}, AssetID: bc.AssetID{V0: 1}, Amount: 3, ControlProgram: []byte{0x52}, - SourceID: bc.Hash{V0: 15256474482236132139, V1: 14615963227748152009, V2: 1392768713126269609, V3: 3435801067785833027}, + SourceID: bc.Hash{V0: 10187915247323429348, V1: 4770401581694266753, V2: 4182269187154655368, V3: 9030883832705174512}, SourcePos: 1, }, &account.UTXO{ - OutputID: bc.Hash{V0: 6688768820716928311, V1: 7640171490156205612, V2: 6082620342644961312, V3: 6194446985740174532}, + OutputID: bc.Hash{V0: 15745816911932387102, V1: 5035893487696724781, V2: 10084725527786878517, V3: 11270352747873435606}, AssetID: *consensus.BTMAssetID, Amount: 2, ControlProgram: []byte{0x53}, - SourceID: bc.Hash{V0: 15256474482236132139, V1: 14615963227748152009, V2: 1392768713126269609, V3: 3435801067785833027}, + SourceID: bc.Hash{V0: 10187915247323429348, V1: 4770401581694266753, V2: 4182269187154655368, V3: 9030883832705174512}, SourcePos: 2, }, &account.UTXO{ - OutputID: bc.Hash{V0: 13540722642395030514, V1: 15412939347183859286, V2: 9545016219428105666, V3: 11940603522975438116}, + OutputID: bc.Hash{V0: 10165799535720725897, V1: 9618876671942765420, V2: 17982649347111502590, V3: 15837286550437859084}, AssetID: *consensus.BTMAssetID, Amount: 5, ControlProgram: []byte{0x54}, - SourceID: bc.Hash{V0: 15256474482236132139, V1: 14615963227748152009, V2: 1392768713126269609, V3: 3435801067785833027}, + SourceID: bc.Hash{V0: 10187915247323429348, V1: 4770401581694266753, V2: 4182269187154655368, V3: 9030883832705174512}, SourcePos: 3, }, },