OSDN Git Service

feature: add cross-chain input (#61)
authorHAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
Fri, 17 May 2019 06:58:18 +0000 (14:58 +0800)
committerPaladz <yzhu101@uottawa.ca>
Fri, 17 May 2019 06:58:18 +0000 (14:58 +0800)
* refactor: rename files

* feat: add types.CrossChainInput

* feat: add protocol.CrossChainInput

* wip: init bc.CrossChainInput

* fix: add mainchain output hash

* fix: fix letter cases

* refactor: fix indent

* fix: fix missing value in CrossChainInput

* fix: fix NewCrossChainInput()

* wip: upgrade MapTx()

* refactor: use issue's type indicator for cross-chain input

* revert

* wip: loop Inputs in mapTx()

* wip: add crossIn.SetDestination() in mapTx()

* feat: draft mapTx()

* refactor: remove ruleAA

* feat: add checkValidSrc

* wip: init crossIn in checkValid()

* wip: add vm.Verify for *bc.CrossChainInput

* feat: skip gas for CrossChainInput

* refactor: clean up

* fix: fix protobuf

* fix: fix validate tx

* update (t *TxInput) AssetAmount()

* add (t *TxInput) Amount()

* update

* clean

* wip: types/txinputs.go

* feat: draft types.TxInput

* fix: fix test

* clean

* fix outputID

* init assetDefinition

* add read/write AssetDefinition

* fix the merge issue

protocol/bc/bc.pb.go
protocol/bc/bc.proto
protocol/bc/crosschain_input.go [new file with mode: 0644]
protocol/bc/types/crosschain_input.go [new file with mode: 0644]
protocol/bc/types/crosschain_output.go [moved from protocol/bc/types/crosschain_txoutput.go with 100% similarity]
protocol/bc/types/intrachain_output.go [moved from protocol/bc/types/intrachain_txoutput.go with 100% similarity]
protocol/bc/types/map.go
protocol/bc/types/spend.go
protocol/bc/types/txinput.go
protocol/validation/tx.go

index 619de90..6b0a50a 100644 (file)
@@ -25,6 +25,7 @@ It has these top-level messages:
        VoteOutput
        Retirement
        Spend
        VoteOutput
        Retirement
        Spend
+       CrossChainInput
 */
 package bc
 
 */
 package bc
 
@@ -624,6 +625,62 @@ func (m *Spend) GetOrdinal() uint64 {
        return 0
 }
 
        return 0
 }
 
+type CrossChainInput struct {
+       MainchainOutputId  *Hash             `protobuf:"bytes,1,opt,name=mainchain_output_id,json=mainchainOutputId" json:"mainchain_output_id,omitempty"`
+       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"`
+}
+
+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{17} }
+
+func (m *CrossChainInput) GetMainchainOutputId() *Hash {
+       if m != nil {
+               return m.MainchainOutputId
+       }
+       return nil
+}
+
+func (m *CrossChainInput) GetValue() *AssetAmount {
+       if m != nil {
+               return m.Value
+       }
+       return nil
+}
+
+func (m *CrossChainInput) GetWitnessDestination() *ValueDestination {
+       if m != nil {
+               return m.WitnessDestination
+       }
+       return nil
+}
+
+func (m *CrossChainInput) GetControlProgram() *Program {
+       if m != nil {
+               return m.ControlProgram
+       }
+       return nil
+}
+
+func (m *CrossChainInput) GetWitnessArguments() [][]byte {
+       if m != nil {
+               return m.WitnessArguments
+       }
+       return nil
+}
+
+func (m *CrossChainInput) GetOrdinal() uint64 {
+       if m != nil {
+               return m.Ordinal
+       }
+       return 0
+}
+
 func init() {
        proto.RegisterType((*Hash)(nil), "bc.Hash")
        proto.RegisterType((*Program)(nil), "bc.Program")
 func init() {
        proto.RegisterType((*Hash)(nil), "bc.Hash")
        proto.RegisterType((*Program)(nil), "bc.Program")
@@ -642,63 +699,67 @@ func init() {
        proto.RegisterType((*VoteOutput)(nil), "bc.VoteOutput")
        proto.RegisterType((*Retirement)(nil), "bc.Retirement")
        proto.RegisterType((*Spend)(nil), "bc.Spend")
        proto.RegisterType((*VoteOutput)(nil), "bc.VoteOutput")
        proto.RegisterType((*Retirement)(nil), "bc.Retirement")
        proto.RegisterType((*Spend)(nil), "bc.Spend")
+       proto.RegisterType((*CrossChainInput)(nil), "bc.CrossChainInput")
 }
 
 func init() { proto.RegisterFile("bc.proto", fileDescriptor0) }
 
 var fileDescriptor0 = []byte{
 }
 
 func init() { proto.RegisterFile("bc.proto", fileDescriptor0) }
 
 var fileDescriptor0 = []byte{
-       // 835 bytes of a gzipped FileDescriptorProto
-       0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x56, 0xcf, 0x6f, 0xe4, 0x34,
-       0x14, 0xd6, 0x4c, 0xd2, 0x49, 0xfa, 0xa6, 0xdb, 0xe9, 0x78, 0x77, 0x21, 0x5a, 0x81, 0xa8, 0x22,
-       0x2d, 0x5d, 0x84, 0x54, 0xf5, 0xc7, 0x22, 0x2e, 0x1c, 0x28, 0x2d, 0xcb, 0xce, 0x61, 0xb5, 0xc8,
-       0xad, 0x7a, 0x8d, 0x3c, 0x89, 0xdb, 0xb1, 0xc8, 0xc4, 0xc1, 0x76, 0x42, 0xb7, 0xff, 0x02, 0x67,
-       0x0e, 0xfc, 0x45, 0x9c, 0xf8, 0x9b, 0x40, 0x7e, 0x71, 0x3a, 0x99, 0x4e, 0x5b, 0x40, 0x08, 0xb1,
-       0xb7, 0x79, 0xcf, 0xef, 0x7d, 0xef, 0xf3, 0x67, 0x7f, 0xce, 0x40, 0x38, 0x4d, 0x77, 0x4b, 0x25,
-       0x8d, 0x24, 0xfd, 0x69, 0x1a, 0xbf, 0x02, 0xff, 0x35, 0xd3, 0x33, 0xb2, 0x09, 0xfd, 0x7a, 0x2f,
-       0xea, 0x6d, 0xf7, 0x5e, 0x0c, 0x68, 0xbf, 0xde, 0xc3, 0x78, 0x3f, 0xea, 0xbb, 0x78, 0x1f, 0xe3,
-       0x83, 0xc8, 0x73, 0xf1, 0x01, 0xc6, 0x87, 0x91, 0xef, 0xe2, 0xc3, 0xf8, 0x2b, 0x08, 0xbe, 0x57,
-       0xf2, 0x52, 0xb1, 0x39, 0xf9, 0x18, 0xa0, 0x9e, 0x27, 0x35, 0x57, 0x5a, 0xc8, 0x02, 0x21, 0x7d,
-       0xba, 0x5e, 0xcf, 0xcf, 0x9b, 0x04, 0x21, 0xe0, 0xa7, 0x32, 0xe3, 0x88, 0xbd, 0x41, 0xf1, 0x77,
-       0x3c, 0x81, 0xe0, 0x48, 0x6b, 0x6e, 0x26, 0x27, 0xff, 0x9a, 0xc8, 0x1b, 0x18, 0x22, 0xd4, 0xd1,
-       0x5c, 0x56, 0x85, 0x21, 0x9f, 0x42, 0xc8, 0x6c, 0x98, 0x88, 0x0c, 0x41, 0x87, 0x07, 0xc3, 0xdd,
-       0x69, 0xba, 0xeb, 0xa6, 0xd1, 0x00, 0x17, 0x27, 0x19, 0xf9, 0x00, 0x06, 0x0c, 0x3b, 0x70, 0x94,
-       0x4f, 0x5d, 0x14, 0xe7, 0x30, 0x3c, 0x67, 0x79, 0xc5, 0x4f, 0x65, 0xa5, 0x52, 0x4e, 0x9e, 0x81,
-       0xa7, 0xf8, 0x85, 0x43, 0x0a, 0x2d, 0x92, 0x55, 0x8f, 0xda, 0x24, 0x79, 0x0e, 0x6b, 0xb5, 0x2d,
-       0x45, 0x84, 0xe1, 0xc1, 0xe8, 0x66, 0x4e, 0x43, 0x85, 0x36, 0xab, 0xe4, 0x19, 0x84, 0xa5, 0xd4,
-       0xc2, 0x58, 0x71, 0x3c, 0x9c, 0x75, 0x13, 0xc7, 0x3f, 0xc2, 0x16, 0x4e, 0x3b, 0xe1, 0xda, 0x88,
-       0x82, 0xd9, 0xdc, 0x7f, 0x3d, 0xf2, 0x8f, 0x3e, 0x0c, 0xbf, 0xc9, 0x65, 0xfa, 0xc3, 0x6b, 0xce,
-       0x32, 0xae, 0x48, 0x04, 0xc1, 0xf2, 0xd1, 0xb5, 0xa1, 0x95, 0x68, 0xc6, 0xc5, 0xe5, 0xec, 0x46,
-       0xa2, 0x26, 0x22, 0x2f, 0x61, 0x5c, 0x2a, 0x5e, 0x0b, 0x59, 0xe9, 0x64, 0x6a, 0x91, 0xac, 0xd6,
-       0xde, 0x2d, 0xba, 0xa3, 0xb6, 0x04, 0x67, 0x4d, 0x32, 0xf2, 0x11, 0xac, 0x1b, 0x31, 0xe7, 0xda,
-       0xb0, 0x79, 0x89, 0xc7, 0xe7, 0xd3, 0x45, 0x82, 0x7c, 0x01, 0x63, 0xa3, 0x58, 0xa1, 0x59, 0x6a,
-       0x49, 0xea, 0x44, 0x49, 0x69, 0xa2, 0xb5, 0x5b, 0x98, 0x5b, 0xdd, 0x12, 0x2a, 0xa5, 0x21, 0x5f,
-       0xc3, 0x87, 0x9d, 0x5c, 0xa2, 0x0d, 0x33, 0x95, 0x4e, 0x66, 0x4c, 0xcf, 0xa2, 0xc1, 0xad, 0xe6,
-       0xa7, 0x9d, 0xc2, 0x53, 0xac, 0x43, 0x1f, 0x9c, 0x00, 0x59, 0x45, 0x88, 0x02, 0x6c, 0x7e, 0x6a,
-       0x9b, 0xcf, 0x6e, 0xb7, 0xd1, 0xf1, 0x0a, 0x12, 0xf9, 0x1c, 0xc6, 0x3f, 0x09, 0x53, 0x70, 0xad,
-       0x13, 0xa6, 0x2e, 0xab, 0x39, 0x2f, 0x8c, 0x8e, 0xc2, 0x6d, 0xef, 0xc5, 0x06, 0xdd, 0x72, 0x0b,
-       0x47, 0x6d, 0x3e, 0xfe, 0xa5, 0x07, 0xe1, 0xd9, 0xd5, 0x5f, 0xca, 0xbf, 0x03, 0x23, 0xcd, 0x95,
-       0x60, 0xb9, 0xb8, 0xe6, 0x59, 0xa2, 0xc5, 0x35, 0x77, 0xe7, 0xb0, 0xb9, 0x48, 0x9f, 0x8a, 0x6b,
-       0x6e, 0xfd, 0x67, 0x85, 0x4c, 0x14, 0x2b, 0x2e, 0xb9, 0x3b, 0x6f, 0x94, 0x96, 0xda, 0x04, 0xd9,
-       0x01, 0x50, 0x5c, 0x57, 0xb9, 0xb5, 0x84, 0x8e, 0xfc, 0x6d, 0x6f, 0x49, 0x96, 0xf5, 0x66, 0x6d,
-       0x92, 0xe9, 0x78, 0x1f, 0x36, 0xcf, 0xae, 0xce, 0xb9, 0x12, 0x17, 0xef, 0x28, 0x26, 0xc9, 0x27,
-       0x30, 0x74, 0x92, 0x5e, 0x30, 0x91, 0x23, 0xc1, 0x90, 0x42, 0x93, 0x7a, 0xc5, 0x44, 0x1e, 0x5f,
-       0xc0, 0x78, 0x45, 0x9f, 0x07, 0xb6, 0xf4, 0x25, 0x3c, 0xaa, 0x11, 0xbf, 0xd5, 0xb9, 0x8f, 0x6c,
-       0x08, 0xea, 0xbc, 0x34, 0x9a, 0x6e, 0x34, 0x85, 0x0d, 0x64, 0xfc, 0x7b, 0x0f, 0xbc, 0x37, 0xd5,
-       0x15, 0xf9, 0x0c, 0x02, 0x8d, 0xc6, 0xd4, 0x51, 0x0f, 0x5b, 0xd1, 0x01, 0x1d, 0xc3, 0xd2, 0x76,
-       0x9d, 0x3c, 0x87, 0xa0, 0x6c, 0x1e, 0x28, 0x67, 0x16, 0x7c, 0x07, 0xdc, 0x9b, 0x45, 0xdb, 0x35,
-       0xf2, 0x1d, 0x3c, 0x69, 0x4f, 0x2e, 0x5b, 0x98, 0x50, 0x47, 0x1e, 0xc2, 0x3f, 0xb9, 0x81, 0xef,
-       0x38, 0x94, 0x3e, 0x76, 0x1d, 0x9d, 0xdc, 0x3d, 0x57, 0xc0, 0xbf, 0xe7, 0x0a, 0x48, 0x08, 0x8f,
-       0xa5, 0x28, 0xa6, 0x4c, 0x73, 0xf2, 0x2d, 0x3c, 0xbe, 0x83, 0x81, 0xf3, 0xff, 0xdd, 0x04, 0xc8,
-       0x2a, 0x01, 0xeb, 0x2f, 0xa6, 0xa6, 0xc2, 0x28, 0xa6, 0xde, 0xb9, 0xb7, 0x76, 0x91, 0x88, 0x7f,
-       0xee, 0xc1, 0xd6, 0xa4, 0x30, 0x8a, 0x1d, 0xcf, 0x98, 0x28, 0xde, 0x56, 0xa6, 0xac, 0x0c, 0xd9,
-       0x81, 0x41, 0xa3, 0x96, 0x1b, 0xb6, 0x22, 0xa6, 0x5b, 0x26, 0x2f, 0x61, 0x94, 0xca, 0xc2, 0x28,
-       0x99, 0x27, 0x0f, 0x68, 0xba, 0xe9, 0x6a, 0xda, 0xef, 0x42, 0x04, 0x81, 0x54, 0x99, 0x28, 0x58,
-       0xee, 0x2e, 0x65, 0x1b, 0x22, 0x9b, 0x63, 0x25, 0xb5, 0x7e, 0x2f, 0xd8, 0xfc, 0xda, 0x03, 0x38,
-       0x97, 0x86, 0xff, 0xcf, 0x3c, 0xec, 0x87, 0xb2, 0x96, 0x86, 0xe3, 0xe3, 0xb8, 0x41, 0xf1, 0x77,
-       0xfc, 0x16, 0x80, 0x72, 0x23, 0x14, 0xb7, 0xf7, 0xe6, 0xef, 0x53, 0xeb, 0x0c, 0xe9, 0x2f, 0x6f,
-       0xf6, 0xb7, 0x1e, 0xac, 0x9d, 0x96, 0xbc, 0xc8, 0xc8, 0x1e, 0x8c, 0x74, 0xc9, 0x0b, 0x93, 0x48,
-       0xdc, 0xf7, 0xe2, 0x83, 0xb9, 0x78, 0x1c, 0x1e, 0x61, 0x41, 0xa3, 0xcb, 0x24, 0xbb, 0xef, 0xa6,
-       0xf6, 0xff, 0xe1, 0x4d, 0xbd, 0xd3, 0x29, 0xde, 0xdd, 0x4e, 0xe9, 0xee, 0xc4, 0x5f, 0xda, 0xc9,
-       0x74, 0x80, 0x7f, 0x6a, 0x0e, 0xff, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xc7, 0x32, 0xe6, 0x29, 0xe0,
-       0x08, 0x00, 0x00,
+       // 886 bytes of a gzipped FileDescriptorProto
+       0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x56, 0x4f, 0x6f, 0xe3, 0x44,
+       0x14, 0x57, 0x6c, 0x37, 0x49, 0x5f, 0xba, 0x4d, 0x33, 0xdd, 0x05, 0x6b, 0x05, 0xa2, 0xb2, 0xb4,
+       0x74, 0x11, 0x52, 0xd5, 0x3f, 0x8b, 0xe0, 0xc0, 0x81, 0xd2, 0xb2, 0x6c, 0x0e, 0xab, 0x45, 0xd3,
+       0xaa, 0x57, 0x6b, 0x62, 0x4f, 0x9b, 0x11, 0x8e, 0x27, 0xcc, 0x8c, 0x4d, 0xb7, 0x5f, 0x81, 0x33,
+       0x07, 0xbe, 0x08, 0x5f, 0x81, 0x13, 0x9f, 0x09, 0x34, 0xcf, 0xe3, 0xc4, 0x69, 0xd2, 0x76, 0x57,
+       0x08, 0xc1, 0xcd, 0xef, 0xdf, 0xef, 0xbd, 0xf7, 0x9b, 0xf7, 0x66, 0x0c, 0xdd, 0x51, 0xb2, 0x37,
+       0x55, 0xd2, 0x48, 0xe2, 0x8d, 0x92, 0xe8, 0x25, 0x04, 0xaf, 0x98, 0x1e, 0x93, 0x4d, 0xf0, 0xca,
+       0xfd, 0xb0, 0xb5, 0xd3, 0x7a, 0xde, 0xa6, 0x5e, 0xb9, 0x8f, 0xf2, 0x41, 0xe8, 0x39, 0xf9, 0x00,
+       0xe5, 0xc3, 0xd0, 0x77, 0xf2, 0x21, 0xca, 0x47, 0x61, 0xe0, 0xe4, 0xa3, 0xe8, 0x6b, 0xe8, 0xfc,
+       0xa0, 0xe4, 0x95, 0x62, 0x13, 0xf2, 0x31, 0x40, 0x39, 0x89, 0x4b, 0xae, 0xb4, 0x90, 0x39, 0x42,
+       0x06, 0x74, 0xbd, 0x9c, 0x5c, 0x54, 0x0a, 0x42, 0x20, 0x48, 0x64, 0xca, 0x11, 0x7b, 0x83, 0xe2,
+       0x77, 0x34, 0x84, 0xce, 0xb1, 0xd6, 0xdc, 0x0c, 0x4f, 0xff, 0x71, 0x21, 0xaf, 0xa1, 0x87, 0x50,
+       0xc7, 0x13, 0x59, 0xe4, 0x86, 0x7c, 0x0a, 0x5d, 0x66, 0xc5, 0x58, 0xa4, 0x08, 0xda, 0x3b, 0xec,
+       0xed, 0x8d, 0x92, 0x3d, 0x97, 0x8d, 0x76, 0xd0, 0x38, 0x4c, 0xc9, 0x07, 0xd0, 0x66, 0x18, 0x81,
+       0xa9, 0x02, 0xea, 0xa4, 0x28, 0x83, 0xde, 0x05, 0xcb, 0x0a, 0x7e, 0x26, 0x0b, 0x95, 0x70, 0xf2,
+       0x14, 0x7c, 0xc5, 0x2f, 0x1d, 0x52, 0xd7, 0x22, 0x59, 0xf6, 0xa8, 0x55, 0x92, 0x67, 0xb0, 0x56,
+       0x5a, 0x57, 0x44, 0xe8, 0x1d, 0xf6, 0x67, 0x79, 0xaa, 0x52, 0x68, 0x65, 0x25, 0x4f, 0xa1, 0x3b,
+       0x95, 0x5a, 0x18, 0x4b, 0x8e, 0x8f, 0xb9, 0x66, 0x72, 0xf4, 0x13, 0x6c, 0x61, 0xb6, 0x53, 0xae,
+       0x8d, 0xc8, 0x99, 0xd5, 0xfd, 0xdb, 0x29, 0xff, 0xf2, 0xa0, 0xf7, 0x6d, 0x26, 0x93, 0x1f, 0x5f,
+       0x71, 0x96, 0x72, 0x45, 0x42, 0xe8, 0x2c, 0x1e, 0x5d, 0x2d, 0x5a, 0x8a, 0xc6, 0x5c, 0x5c, 0x8d,
+       0x67, 0x14, 0x55, 0x12, 0x79, 0x01, 0x83, 0xa9, 0xe2, 0xa5, 0x90, 0x85, 0x8e, 0x47, 0x16, 0xc9,
+       0x72, 0xed, 0xdf, 0x2a, 0xb7, 0x5f, 0xbb, 0x60, 0xae, 0x61, 0x4a, 0x3e, 0x82, 0x75, 0x23, 0x26,
+       0x5c, 0x1b, 0x36, 0x99, 0xe2, 0xf1, 0x05, 0x74, 0xae, 0x20, 0x5f, 0xc0, 0xc0, 0x28, 0x96, 0x6b,
+       0x96, 0xd8, 0x22, 0x75, 0xac, 0xa4, 0x34, 0xe1, 0xda, 0x2d, 0xcc, 0xad, 0xa6, 0x0b, 0x95, 0xd2,
+       0x90, 0x6f, 0xe0, 0xc3, 0x86, 0x2e, 0xd6, 0x86, 0x99, 0x42, 0xc7, 0x63, 0xa6, 0xc7, 0x61, 0xfb,
+       0x56, 0xf0, 0x93, 0x86, 0xe3, 0x19, 0xfa, 0xe1, 0x1e, 0x9c, 0x02, 0x59, 0x46, 0x08, 0x3b, 0x18,
+       0xfc, 0xc4, 0x06, 0x9f, 0xdf, 0x0e, 0xa3, 0x83, 0x25, 0x24, 0xf2, 0x39, 0x0c, 0x7e, 0x16, 0x26,
+       0xe7, 0x5a, 0xc7, 0x4c, 0x5d, 0x15, 0x13, 0x9e, 0x1b, 0x1d, 0x76, 0x77, 0xfc, 0xe7, 0x1b, 0x74,
+       0xcb, 0x19, 0x8e, 0x6b, 0x7d, 0xf4, 0x6b, 0x0b, 0xba, 0xe7, 0xd7, 0x0f, 0xd2, 0xbf, 0x0b, 0x7d,
+       0xcd, 0x95, 0x60, 0x99, 0xb8, 0xe1, 0x69, 0xac, 0xc5, 0x0d, 0x77, 0xe7, 0xb0, 0x39, 0x57, 0x9f,
+       0x89, 0x1b, 0x6e, 0xf7, 0xcf, 0x12, 0x19, 0x2b, 0x96, 0x5f, 0x71, 0x77, 0xde, 0x48, 0x2d, 0xb5,
+       0x0a, 0xb2, 0x0b, 0xa0, 0xb8, 0x2e, 0x32, 0xbb, 0x12, 0x3a, 0x0c, 0x76, 0xfc, 0x05, 0x5a, 0xd6,
+       0x2b, 0xdb, 0x30, 0xd5, 0xd1, 0x01, 0x6c, 0x9e, 0x5f, 0x5f, 0x70, 0x25, 0x2e, 0xdf, 0x52, 0x54,
+       0x92, 0x4f, 0xa0, 0xe7, 0x28, 0xbd, 0x64, 0x22, 0xc3, 0x02, 0xbb, 0x14, 0x2a, 0xd5, 0x4b, 0x26,
+       0xb2, 0xe8, 0x12, 0x06, 0x4b, 0xfc, 0xdc, 0xd3, 0xd2, 0x97, 0xf0, 0xa8, 0x44, 0xfc, 0x9a, 0x67,
+       0x0f, 0xab, 0x21, 0xc8, 0xf3, 0x42, 0x6a, 0xba, 0x51, 0x39, 0x56, 0x90, 0xd1, 0x9f, 0x2d, 0xf0,
+       0x5f, 0x17, 0xd7, 0xe4, 0x33, 0xe8, 0x68, 0x5c, 0x4c, 0x1d, 0xb6, 0x30, 0x14, 0x37, 0xa0, 0xb1,
+       0xb0, 0xb4, 0xb6, 0x93, 0x67, 0xd0, 0x99, 0x56, 0x17, 0x94, 0x5b, 0x16, 0xbc, 0x07, 0xdc, 0x9d,
+       0x45, 0x6b, 0x1b, 0xf9, 0x1e, 0x1e, 0xd7, 0x27, 0x97, 0xce, 0x97, 0x50, 0x87, 0x3e, 0xc2, 0x3f,
+       0x9e, 0xc1, 0x37, 0x36, 0x94, 0x6e, 0xbb, 0x88, 0x86, 0xee, 0x8e, 0x11, 0x08, 0xee, 0x18, 0x01,
+       0x09, 0xdd, 0x13, 0x29, 0xf2, 0x11, 0xd3, 0x9c, 0x7c, 0x07, 0xdb, 0x2b, 0x2a, 0x70, 0xfb, 0xbf,
+       0xba, 0x00, 0xb2, 0x5c, 0x80, 0xdd, 0x2f, 0xa6, 0x46, 0xc2, 0x28, 0xa6, 0xde, 0xba, 0xbb, 0x76,
+       0xae, 0x88, 0x7e, 0x69, 0xc1, 0xd6, 0x30, 0x37, 0x8a, 0x9d, 0x8c, 0x99, 0xc8, 0xdf, 0x14, 0x66,
+       0x5a, 0x18, 0xb2, 0x0b, 0xed, 0x8a, 0x2d, 0x97, 0x6c, 0x89, 0x4c, 0x67, 0x26, 0x2f, 0xa0, 0x9f,
+       0xc8, 0xdc, 0x28, 0x99, 0xc5, 0xf7, 0x70, 0xba, 0xe9, 0x7c, 0xea, 0x77, 0x21, 0x84, 0x8e, 0x54,
+       0xa9, 0xc8, 0x59, 0xe6, 0x86, 0xb2, 0x16, 0xb1, 0x9a, 0x13, 0x25, 0xb5, 0xfe, 0x5f, 0x54, 0xf3,
+       0x5b, 0x0b, 0xe0, 0x42, 0x1a, 0xfe, 0x1f, 0xd7, 0x61, 0x1f, 0xca, 0x52, 0x1a, 0x8e, 0x97, 0xe3,
+       0x06, 0xc5, 0xef, 0xe8, 0x0d, 0x00, 0xe5, 0x46, 0x28, 0x6e, 0xe7, 0xe6, 0xdd, 0x4b, 0x6b, 0x24,
+       0xf1, 0x16, 0x9b, 0xfd, 0xa3, 0x05, 0x6b, 0x67, 0x53, 0x9e, 0xa7, 0x64, 0x1f, 0xfa, 0x7a, 0xca,
+       0x73, 0x13, 0x4b, 0xec, 0x7b, 0xfe, 0x60, 0xce, 0x2f, 0x87, 0x47, 0xe8, 0x50, 0xf1, 0x32, 0x4c,
+       0xef, 0x9a, 0x54, 0xef, 0x3d, 0x27, 0x75, 0xe5, 0xa6, 0xf8, 0xab, 0x37, 0xa5, 0xd9, 0x49, 0xb0,
+       0xd8, 0xc9, 0xef, 0x1e, 0xf4, 0xe7, 0x43, 0x34, 0xcc, 0xed, 0xd9, 0x7d, 0x05, 0xdb, 0x13, 0x26,
+       0xf2, 0xc4, 0x6a, 0xee, 0xe9, 0x6b, 0x30, 0x73, 0x9a, 0xf5, 0xf6, 0x8e, 0x2f, 0xeb, 0x1d, 0x14,
+       0xf8, 0xef, 0x49, 0xc1, 0x8a, 0xd1, 0x09, 0x1e, 0x1e, 0x9d, 0x95, 0xc4, 0xad, 0x3d, 0x4c, 0x5c,
+       0x7b, 0x81, 0xb8, 0x51, 0x1b, 0xff, 0x06, 0x8f, 0xfe, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xd8, 0x41,
+       0xe2, 0x4f, 0x19, 0x0a, 0x00, 0x00,
 }
 }
index 254285f..fd25c9e 100644 (file)
@@ -111,4 +111,13 @@ message Spend {
   ValueDestination witness_destination = 2;
   repeated bytes   witness_arguments   = 3;
   uint64           ordinal             = 4;
   ValueDestination witness_destination = 2;
   repeated bytes   witness_arguments   = 3;
   uint64           ordinal             = 4;
+}
+
+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
 }
\ No newline at end of file
diff --git a/protocol/bc/crosschain_input.go b/protocol/bc/crosschain_input.go
new file mode 100644 (file)
index 0000000..0ce867d
--- /dev/null
@@ -0,0 +1,30 @@
+package bc
+
+import "io"
+
+// crosschaininput is the result of a transfer of value. The value it contains
+// comes from the main chain. It satisfies the Entry interface.
+
+func (CrossChainInput) typ() string { return "crosschaininput1" }
+
+func (cci *CrossChainInput) writeForHash(w io.Writer) {
+       mustWriteForHash(w, cci.MainchainOutputId)
+}
+
+// SetDestination will link the CrossChainInput to the output
+func (cci *CrossChainInput) SetDestination(id *Hash, val *AssetAmount, pos uint64) {
+       cci.WitnessDestination = &ValueDestination{
+               Ref:      id,
+               Value:    val,
+               Position: pos,
+       }
+}
+
+// NewCrossChainInput creates a new CrossChainInput.
+func NewCrossChainInput(mainchainOutputID *Hash, value *AssetAmount, ordinal uint64) *CrossChainInput {
+       return &CrossChainInput{
+               MainchainOutputId: mainchainOutputID,
+               Value:             value,
+               Ordinal:           ordinal,
+       }
+}
diff --git a/protocol/bc/types/crosschain_input.go b/protocol/bc/types/crosschain_input.go
new file mode 100644 (file)
index 0000000..a08cfd6
--- /dev/null
@@ -0,0 +1,40 @@
+package types
+
+import (
+       "github.com/vapor/protocol/bc"
+)
+
+// 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
+}
+
+// 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 {
+       sc := SpendCommitment{
+               AssetAmount: bc.AssetAmount{
+                       AssetId: &assetID,
+                       Amount:  amount,
+               },
+               SourceID:       sourceID,
+               SourcePosition: sourcePos,
+               VMVersion:      1,
+               ControlProgram: controlProgram,
+       }
+       return &TxInput{
+               AssetVersion: 1,
+               TypedInput: &CrossChainInput{
+                       AssetDefinition: assetDefinition,
+                       SpendCommitment: sc,
+                       Arguments:       arguments,
+               },
+       }
+}
+
+// InputType is the interface function for return the input type.
+func (si *CrossChainInput) InputType() uint8 { return CrossChainInputType }
index 348c203..8ec6167 100644 (file)
@@ -24,6 +24,12 @@ func MapTx(oldTx *TxData) *bc.Tx {
        for id, e := range entries {
                var ord uint64
                switch e := e.(type) {
        for id, e := range entries {
                var ord uint64
                switch e := e.(type) {
+               case *bc.CrossChainInput:
+                       ord = e.Ordinal
+                       if *e.WitnessDestination.Value.AssetId == *consensus.BTMAssetID {
+                               tx.GasInputIDs = append(tx.GasInputIDs, id)
+                       }
+
                case *bc.Spend:
                        ord = e.Ordinal
                        spentOutputIDs[*e.SpentOutputId] = true
                case *bc.Spend:
                        ord = e.Ordinal
                        spentOutputIDs[*e.SpentOutputId] = true
@@ -61,6 +67,7 @@ func mapTx(tx *TxData) (headerID bc.Hash, hdr *bc.TxHeader, entryMap map[bc.Hash
 
        var (
                spends   []*bc.Spend
 
        var (
                spends   []*bc.Spend
+               crossIns []*bc.CrossChainInput
                coinbase *bc.Coinbase
        )
 
                coinbase *bc.Coinbase
        )
 
@@ -100,7 +107,6 @@ func mapTx(tx *TxData) (headerID bc.Hash, hdr *bc.TxHeader, entryMap map[bc.Hash
                        }
 
                case *UnvoteInput:
                        }
 
                case *UnvoteInput:
-                       // create entry for prevout
                        prog := &bc.Program{VmVersion: inp.VMVersion, Code: inp.ControlProgram}
                        src := &bc.ValueSource{
                                Ref:      &inp.SourceID,
                        prog := &bc.Program{VmVersion: inp.VMVersion, Code: inp.ControlProgram}
                        src := &bc.ValueSource{
                                Ref:      &inp.SourceID,
@@ -120,6 +126,24 @@ func mapTx(tx *TxData) (headerID bc.Hash, hdr *bc.TxHeader, entryMap map[bc.Hash
                        }
                        spends = append(spends, spend)
 
                        }
                        spends = append(spends, spend)
 
+               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.NewCrossChainOutput(src, prog, 0) // ordinal doesn't matter
+                       outputID := bc.EntryID(prevout)
+                       crossIn := bc.NewCrossChainInput(&outputID, &inp.AssetAmount, uint64(i))
+                       crossIn.WitnessArguments = inp.Arguments
+                       crossInID := addEntry(crossIn)
+                       muxSources[i] = &bc.ValueSource{
+                               Ref:   &crossInID,
+                               Value: &inp.AssetAmount,
+                       }
+                       crossIns = append(crossIns, crossIn)
+
                }
        }
 
                }
        }
 
@@ -132,6 +156,10 @@ func mapTx(tx *TxData) (headerID bc.Hash, hdr *bc.TxHeader, entryMap map[bc.Hash
                spend.SetDestination(&muxID, spentOutput.Source.Value, spend.Ordinal)
        }
 
                spend.SetDestination(&muxID, spentOutput.Source.Value, spend.Ordinal)
        }
 
+       for _, crossIn := range crossIns {
+               crossIn.SetDestination(&muxID, crossIn.Value, crossIn.Ordinal)
+       }
+
        if coinbase != nil {
                coinbase.SetDestination(&muxID, mux.Sources[0].Value, 0)
        }
        if coinbase != nil {
                coinbase.SetDestination(&muxID, mux.Sources[0].Value, 0)
        }
index 8642d35..15b2b69 100644 (file)
@@ -6,7 +6,7 @@ import (
 
 // SpendInput satisfies the TypedInput interface and represents a spend transaction.
 type SpendInput struct {
 
 // SpendInput satisfies the TypedInput interface and represents a spend transaction.
 type SpendInput struct {
-       SpendCommitmentSuffix []byte   // The unconsumed suffix of the output commitment
+       SpendCommitmentSuffix []byte   // The unconsumed suffix of the spend commitment
        Arguments             [][]byte // Witness
        SpendCommitment
 }
        Arguments             [][]byte // Witness
        SpendCommitment
 }
index 2da0134..c9fa0a0 100644 (file)
@@ -11,7 +11,7 @@ import (
 
 // serflag variables for input types.
 const (
 
 // serflag variables for input types.
 const (
-       IssuanceInputType uint8 = iota
+       CrossChainInputType uint8 = iota
        SpendInputType
        CoinbaseInputType
        UnvoteInputType
        SpendInputType
        CoinbaseInputType
        UnvoteInputType
@@ -40,9 +40,13 @@ func (t *TxInput) AssetAmount() bc.AssetAmount {
        case *SpendInput:
                return inp.AssetAmount
 
        case *SpendInput:
                return inp.AssetAmount
 
+       case *CrossChainInput:
+               return inp.AssetAmount
+
        case *UnvoteInput:
                return inp.AssetAmount
        }
        case *UnvoteInput:
                return inp.AssetAmount
        }
+
        return bc.AssetAmount{}
 }
 
        return bc.AssetAmount{}
 }
 
@@ -52,8 +56,12 @@ func (t *TxInput) AssetID() bc.AssetID {
        case *SpendInput:
                return *inp.AssetId
 
        case *SpendInput:
                return *inp.AssetId
 
+       case *CrossChainInput:
+               return *inp.AssetAmount.AssetId
+
        case *UnvoteInput:
                return *inp.AssetId
        case *UnvoteInput:
                return *inp.AssetId
+
        }
        return bc.AssetID{}
 }
        }
        return bc.AssetID{}
 }
@@ -64,8 +72,12 @@ func (t *TxInput) Amount() uint64 {
        case *SpendInput:
                return inp.Amount
 
        case *SpendInput:
                return inp.Amount
 
+       case *CrossChainInput:
+               return inp.AssetAmount.Amount
+
        case *UnvoteInput:
                return inp.Amount
        case *UnvoteInput:
                return inp.Amount
+
        }
        return 0
 }
        }
        return 0
 }
@@ -76,8 +88,12 @@ func (t *TxInput) ControlProgram() []byte {
        case *SpendInput:
                return inp.ControlProgram
 
        case *SpendInput:
                return inp.ControlProgram
 
+       case *CrossChainInput:
+               return inp.ControlProgram
+
        case *UnvoteInput:
                return inp.ControlProgram
        case *UnvoteInput:
                return inp.ControlProgram
+
        }
 
        return nil
        }
 
        return nil
@@ -89,6 +105,9 @@ func (t *TxInput) Arguments() [][]byte {
        case *SpendInput:
                return inp.Arguments
 
        case *SpendInput:
                return inp.Arguments
 
+       case *CrossChainInput:
+               return inp.Arguments
+
        case *UnvoteInput:
                return inp.Arguments
        }
        case *UnvoteInput:
                return inp.Arguments
        }
@@ -101,6 +120,9 @@ func (t *TxInput) SetArguments(args [][]byte) {
        case *SpendInput:
                inp.Arguments = args
 
        case *SpendInput:
                inp.Arguments = args
 
+       case *CrossChainInput:
+               inp.Arguments = args
+
        case *UnvoteInput:
                inp.Arguments = args
        }
        case *UnvoteInput:
                inp.Arguments = args
        }
@@ -132,6 +154,7 @@ func (t *TxInput) readFrom(r *blockchain.Reader) (err error) {
                if _, err = io.ReadFull(r, icType[:]); err != nil {
                        return errors.Wrap(err, "reading input commitment type")
                }
                if _, err = io.ReadFull(r, icType[:]); err != nil {
                        return errors.Wrap(err, "reading input commitment type")
                }
+
                switch icType[0] {
                case SpendInputType:
                        si := new(SpendInput)
                switch icType[0] {
                case SpendInputType:
                        si := new(SpendInput)
@@ -147,10 +170,18 @@ func (t *TxInput) readFrom(r *blockchain.Reader) (err error) {
                                return err
                        }
 
                                return err
                        }
 
+               case CrossChainInputType:
+                       ci := new(CrossChainInput)
+                       t.TypedInput = ci
+                       if ci.SpendCommitmentSuffix, err = ci.SpendCommitment.readFrom(r, 1); err != nil {
+                               return err
+                       }
+
                case UnvoteInputType:
                        ui := new(UnvoteInput)
                        t.TypedInput = ui
                        if ui.UnvoteCommitmentSuffix, err = ui.SpendCommitment.readFrom(r, 1); err != nil {
                case UnvoteInputType:
                        ui := new(UnvoteInput)
                        t.TypedInput = ui
                        if ui.UnvoteCommitmentSuffix, err = ui.SpendCommitment.readFrom(r, 1); err != nil {
+
                                return err
                        }
 
                                return err
                        }
 
@@ -174,6 +205,11 @@ func (t *TxInput) readFrom(r *blockchain.Reader) (err error) {
                                return err
                        }
 
                                return err
                        }
 
+               case *CrossChainInput:
+                       if inp.Arguments, err = blockchain.ReadVarstrList(r); err != nil {
+                               return err
+                       }
+
                case *UnvoteInput:
                        if inp.Arguments, err = blockchain.ReadVarstrList(r); err != nil {
                                return err
                case *UnvoteInput:
                        if inp.Arguments, err = blockchain.ReadVarstrList(r); err != nil {
                                return err
@@ -185,8 +221,18 @@ func (t *TxInput) readFrom(r *blockchain.Reader) (err error) {
                }
                return nil
        })
                }
                return nil
        })
+       if err != nil {
+               return err
+       }
+
+       switch inp := t.TypedInput.(type) {
+       case *CrossChainInput:
+               if inp.AssetDefinition, err = blockchain.ReadVarstr31(r); err != nil {
+                       return err
+               }
+       }
 
 
-       return err
+       return nil
 }
 
 func (t *TxInput) writeTo(w io.Writer) error {
 }
 
 func (t *TxInput) writeTo(w io.Writer) error {
@@ -198,8 +244,18 @@ func (t *TxInput) writeTo(w io.Writer) error {
                return errors.Wrap(err, "writing input commitment")
        }
 
                return errors.Wrap(err, "writing input commitment")
        }
 
-       _, err := blockchain.WriteExtensibleString(w, t.WitnessSuffix, t.writeInputWitness)
-       return errors.Wrap(err, "writing input witness")
+       if _, err := blockchain.WriteExtensibleString(w, t.WitnessSuffix, t.writeInputWitness); err != nil {
+               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
 }
 
 func (t *TxInput) writeInputCommitment(w io.Writer) (err error) {
 }
 
 func (t *TxInput) writeInputCommitment(w io.Writer) (err error) {
@@ -214,6 +270,12 @@ func (t *TxInput) writeInputCommitment(w io.Writer) (err error) {
                }
                return inp.SpendCommitment.writeExtensibleString(w, inp.SpendCommitmentSuffix, t.AssetVersion)
 
                }
                return inp.SpendCommitment.writeExtensibleString(w, inp.SpendCommitmentSuffix, t.AssetVersion)
 
+       case *CrossChainInput:
+               if _, err = w.Write([]byte{SpendInputType}); err != nil {
+                       return err
+               }
+               return inp.SpendCommitment.writeExtensibleString(w, inp.SpendCommitmentSuffix, t.AssetVersion)
+
        case *CoinbaseInput:
                if _, err = w.Write([]byte{CoinbaseInputType}); err != nil {
                        return err
        case *CoinbaseInput:
                if _, err = w.Write([]byte{CoinbaseInputType}); err != nil {
                        return err
@@ -241,6 +303,9 @@ func (t *TxInput) writeInputWitness(w io.Writer) error {
                _, err := blockchain.WriteVarstrList(w, inp.Arguments)
                return err
 
                _, err := blockchain.WriteVarstrList(w, inp.Arguments)
                return err
 
+       case *CrossChainInput:
+               _, err := blockchain.WriteVarstrList(w, inp.Arguments)
+               return err
        case *UnvoteInput:
                if _, err := blockchain.WriteVarstrList(w, inp.Arguments); err != nil {
                        return err
        case *UnvoteInput:
                if _, err := blockchain.WriteVarstrList(w, inp.Arguments); err != nil {
                        return err
index 058b736..6e0acd2 100644 (file)
@@ -238,6 +238,18 @@ func checkValid(vs *validationState, e bc.Entry) (err error) {
                        return errors.Wrap(err, "checking retirement source")
                }
 
                        return errors.Wrap(err, "checking retirement source")
                }
 
+       case *bc.CrossChainInput:
+               _, err := vm.Verify(NewTxVMContext(vs, e, e.ControlProgram, e.WitnessArguments), consensus.DefaultGasCredit)
+               if err != nil {
+                       return errors.Wrap(err, "checking cross-chain input control program")
+               }
+
+               vs2 := *vs
+               vs2.destPos = 0
+               if err = checkValidDest(&vs2, e.WitnessDestination); err != nil {
+                       return errors.Wrap(err, "checking cross-chain input destination")
+               }
+
        case *bc.Spend:
                if e.SpentOutputId == nil {
                        return errors.Wrap(ErrMissingField, "spend without spent output ID")
        case *bc.Spend:
                if e.SpentOutputId == nil {
                        return errors.Wrap(ErrMissingField, "spend without spent output ID")
@@ -246,7 +258,6 @@ func checkValid(vs *validationState, e bc.Entry) (err error) {
                if err != nil {
                        return errors.Wrap(err, "getting spend prevout")
                }
                if err != nil {
                        return errors.Wrap(err, "getting spend prevout")
                }
-
                gasLeft, err := vm.Verify(NewTxVMContext(vs, e, spentOutput.ControlProgram, e.WitnessArguments), vs.gasStatus.GasLeft)
                if err != nil {
                        return errors.Wrap(err, "checking control program")
                gasLeft, err := vm.Verify(NewTxVMContext(vs, e, spentOutput.ControlProgram, e.WitnessArguments), vs.gasStatus.GasLeft)
                if err != nil {
                        return errors.Wrap(err, "checking control program")
@@ -254,7 +265,6 @@ func checkValid(vs *validationState, e bc.Entry) (err error) {
                if err = vs.gasStatus.updateUsage(gasLeft); err != nil {
                        return err
                }
                if err = vs.gasStatus.updateUsage(gasLeft); err != nil {
                        return err
                }
-
                eq, err := spentOutput.Source.Value.Equal(e.WitnessDestination.Value)
                if err != nil {
                        return err
                eq, err := spentOutput.Source.Value.Equal(e.WitnessDestination.Value)
                if err != nil {
                        return err
@@ -269,7 +279,6 @@ func checkValid(vs *validationState, e bc.Entry) (err error) {
                                e.WitnessDestination.Value.AssetId.Bytes(),
                        )
                }
                                e.WitnessDestination.Value.AssetId.Bytes(),
                        )
                }
-
                vs2 := *vs
                vs2.destPos = 0
                if err = checkValidDest(&vs2, e.WitnessDestination); err != nil {
                vs2 := *vs
                vs2.destPos = 0
                if err = checkValidDest(&vs2, e.WitnessDestination); err != nil {
@@ -333,6 +342,12 @@ func checkValidSrc(vstate *validationState, vs *bc.ValueSource) error {
                }
                dest = ref.WitnessDestination
 
                }
                dest = ref.WitnessDestination
 
+       case *bc.CrossChainInput:
+               if vs.Position != 0 {
+                       return errors.Wrapf(ErrPosition, "invalid position %d for cross-chain input source", vs.Position)
+               }
+               dest = ref.WitnessDestination
+
        case *bc.Spend:
                if vs.Position != 0 {
                        return errors.Wrapf(ErrPosition, "invalid position %d for spend source", vs.Position)
        case *bc.Spend:
                if vs.Position != 0 {
                        return errors.Wrapf(ErrPosition, "invalid position %d for spend source", vs.Position)
@@ -346,7 +361,7 @@ func checkValidSrc(vstate *validationState, vs *bc.ValueSource) error {
                dest = ref.WitnessDestinations[vs.Position]
 
        default:
                dest = ref.WitnessDestinations[vs.Position]
 
        default:
-               return errors.Wrapf(bc.ErrEntryType, "value source is %T, should be coinbase, issuance, spend, or mux", e)
+               return errors.Wrapf(bc.ErrEntryType, "value source is %T, should be coinbase, cross-chain input, spend, or mux", e)
        }
 
        if dest.Ref == nil || *dest.Ref != vstate.entryID {
        }
 
        if dest.Ref == nil || *dest.Ref != vstate.entryID {