OSDN Git Service

add cancel vote v0.1_cancel_vote
authormars <mars@bytom.io>
Thu, 13 Jun 2019 05:45:25 +0000 (13:45 +0800)
committermars <mars@bytom.io>
Thu, 13 Jun 2019 05:45:25 +0000 (13:45 +0800)
blockchain/query/annotated.go
blockchain/txfeed/txfeed.go
protocol/bc/bc.pb.go
protocol/bc/bc.proto
protocol/bc/types/map.go
protocol/bc/types/transaction.go
protocol/bc/vote_output.go
protocol/validation/tx.go
protocol/validation/vmcontext.go
wallet/annotated.go

index 2b1894a..c0e446f 100644 (file)
@@ -37,6 +37,7 @@ type AnnotatedInput struct {
        Arbitrary        chainjson.HexBytes   `json:"arbitrary,omitempty"`
        InputID          bc.Hash              `json:"input_id"`
        WitnessArguments []chainjson.HexBytes `json:"witness_arguments"`
+       Vote             chainjson.HexBytes   `json:"vote,omitempty"`
 }
 
 //AnnotatedOutput means an annotated transaction output.
index 01691eb..ea71a8a 100644 (file)
@@ -358,6 +358,11 @@ func buildAnnotatedInput(tx *types.Tx, i uint32) *query.AnnotatedInput {
                in.Type = "cross_chain_in"
                in.ControlProgram = orig.ControlProgram()
                in.SpentOutputID = e.MainchainOutputId
+
+       case *bc.CancelVote:
+               in.Type = "cancel_vote"
+               in.ControlProgram = orig.ControlProgram()
+               in.SpentOutputID = e.SpentOutputId
        }
 
        return in
index 6b0a50a..96e1f37 100644 (file)
@@ -23,6 +23,7 @@ It has these top-level messages:
        IntraChainOutput
        CrossChainOutput
        VoteOutput
+       CancelVote
        Retirement
        Spend
        CrossChainInput
@@ -561,6 +562,54 @@ func (m *VoteOutput) GetVote() []byte {
        return nil
 }
 
+type CancelVote struct {
+       SpentOutputId      *Hash             `protobuf:"bytes,1,opt,name=spent_output_id,json=spentOutputId" json:"spent_output_id,omitempty"`
+       WitnessDestination *ValueDestination `protobuf:"bytes,2,opt,name=witness_destination,json=witnessDestination" json:"witness_destination,omitempty"`
+       WitnessArguments   [][]byte          `protobuf:"bytes,3,rep,name=witness_arguments,json=witnessArguments,proto3" json:"witness_arguments,omitempty"`
+       Ordinal            uint64            `protobuf:"varint,4,opt,name=ordinal" json:"ordinal,omitempty"`
+       Vote               []byte            `protobuf:"bytes,5,opt,name=vote,proto3" json:"vote,omitempty"`
+}
+
+func (m *CancelVote) Reset()                    { *m = CancelVote{} }
+func (m *CancelVote) String() string            { return proto.CompactTextString(m) }
+func (*CancelVote) ProtoMessage()               {}
+func (*CancelVote) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} }
+
+func (m *CancelVote) GetSpentOutputId() *Hash {
+       if m != nil {
+               return m.SpentOutputId
+       }
+       return nil
+}
+
+func (m *CancelVote) GetWitnessDestination() *ValueDestination {
+       if m != nil {
+               return m.WitnessDestination
+       }
+       return nil
+}
+
+func (m *CancelVote) GetWitnessArguments() [][]byte {
+       if m != nil {
+               return m.WitnessArguments
+       }
+       return nil
+}
+
+func (m *CancelVote) GetOrdinal() uint64 {
+       if m != nil {
+               return m.Ordinal
+       }
+       return 0
+}
+
+func (m *CancelVote) GetVote() []byte {
+       if m != nil {
+               return m.Vote
+       }
+       return nil
+}
+
 type Retirement struct {
        Source  *ValueSource `protobuf:"bytes,1,opt,name=source" json:"source,omitempty"`
        Ordinal uint64       `protobuf:"varint,2,opt,name=ordinal" json:"ordinal,omitempty"`
@@ -569,7 +618,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{15} }
+func (*Retirement) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} }
 
 func (m *Retirement) GetSource() *ValueSource {
        if m != nil {
@@ -595,7 +644,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{16} }
+func (*Spend) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} }
 
 func (m *Spend) GetSpentOutputId() *Hash {
        if m != nil {
@@ -637,7 +686,7 @@ type CrossChainInput struct {
 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 (*CrossChainInput) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} }
 
 func (m *CrossChainInput) GetMainchainOutputId() *Hash {
        if m != nil {
@@ -697,6 +746,7 @@ func init() {
        proto.RegisterType((*IntraChainOutput)(nil), "bc.IntraChainOutput")
        proto.RegisterType((*CrossChainOutput)(nil), "bc.CrossChainOutput")
        proto.RegisterType((*VoteOutput)(nil), "bc.VoteOutput")
+       proto.RegisterType((*CancelVote)(nil), "bc.CancelVote")
        proto.RegisterType((*Retirement)(nil), "bc.Retirement")
        proto.RegisterType((*Spend)(nil), "bc.Spend")
        proto.RegisterType((*CrossChainInput)(nil), "bc.CrossChainInput")
@@ -705,61 +755,62 @@ func init() {
 func init() { proto.RegisterFile("bc.proto", fileDescriptor0) }
 
 var fileDescriptor0 = []byte{
-       // 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,
+       // 905 bytes of a gzipped FileDescriptorProto
+       0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0xcd, 0x6e, 0x23, 0x45,
+       0x10, 0x96, 0x3d, 0xe3, 0x9f, 0x94, 0xb3, 0x71, 0xdc, 0xd9, 0x85, 0xd1, 0x0a, 0x44, 0x34, 0xd2,
+       0x92, 0x45, 0x48, 0x51, 0x7e, 0x16, 0xc1, 0x81, 0x03, 0x21, 0x61, 0x59, 0x1f, 0x56, 0x8b, 0x3a,
+       0x51, 0xae, 0xa3, 0xf6, 0x4c, 0x27, 0x6e, 0x31, 0x9e, 0x36, 0xdd, 0x3d, 0x43, 0x36, 0xaf, 0xc0,
+       0x99, 0x03, 0x2f, 0xc2, 0x2b, 0x70, 0xe2, 0x1d, 0x78, 0x13, 0x50, 0xd7, 0xf4, 0xd8, 0xe3, 0xd8,
+       0x49, 0x36, 0x42, 0x08, 0xb8, 0xb9, 0xaa, 0xab, 0xbe, 0xaa, 0xfa, 0xba, 0xbe, 0x1e, 0x43, 0x77,
+       0x14, 0xef, 0x4e, 0x95, 0x34, 0x92, 0x34, 0x47, 0x71, 0xf8, 0x12, 0xfc, 0x57, 0x4c, 0x8f, 0xc9,
+       0x06, 0x34, 0x8b, 0xbd, 0xa0, 0xb1, 0xdd, 0x78, 0xde, 0xa6, 0xcd, 0x62, 0x0f, 0xed, 0xfd, 0xa0,
+       0xe9, 0xec, 0x7d, 0xb4, 0x0f, 0x02, 0xcf, 0xd9, 0x07, 0x68, 0x1f, 0x06, 0xbe, 0xb3, 0x0f, 0xc3,
+       0x2f, 0xa1, 0xf3, 0x9d, 0x92, 0x97, 0x8a, 0x4d, 0xc8, 0x87, 0x00, 0xc5, 0x24, 0x2a, 0xb8, 0xd2,
+       0x42, 0x66, 0x08, 0xe9, 0xd3, 0xb5, 0x62, 0x72, 0x5e, 0x3a, 0x08, 0x01, 0x3f, 0x96, 0x09, 0x47,
+       0xec, 0x75, 0x8a, 0xbf, 0xc3, 0x21, 0x74, 0x8e, 0xb4, 0xe6, 0x66, 0x78, 0xf2, 0xb7, 0x1b, 0x79,
+       0x0d, 0x3d, 0x84, 0x3a, 0x9a, 0xc8, 0x3c, 0x33, 0xe4, 0x63, 0xe8, 0x32, 0x6b, 0x46, 0x22, 0x41,
+       0xd0, 0xde, 0x41, 0x6f, 0x77, 0x14, 0xef, 0xba, 0x6a, 0xb4, 0x83, 0x87, 0xc3, 0x84, 0xbc, 0x07,
+       0x6d, 0x86, 0x19, 0x58, 0xca, 0xa7, 0xce, 0x0a, 0x53, 0xe8, 0x9d, 0xb3, 0x34, 0xe7, 0xa7, 0x32,
+       0x57, 0x31, 0x27, 0x4f, 0xc1, 0x53, 0xfc, 0xc2, 0x21, 0x75, 0x2d, 0x92, 0x65, 0x8f, 0x5a, 0x27,
+       0x79, 0x06, 0xad, 0xc2, 0x86, 0x22, 0x42, 0xef, 0xa0, 0x3f, 0xab, 0x53, 0xb6, 0x42, 0xcb, 0x53,
+       0xf2, 0x14, 0xba, 0x53, 0xa9, 0x85, 0xb1, 0xe4, 0x78, 0x58, 0x6b, 0x66, 0x87, 0x3f, 0xc0, 0x26,
+       0x56, 0x3b, 0xe1, 0xda, 0x88, 0x8c, 0x59, 0xdf, 0x3f, 0x5d, 0xf2, 0xcf, 0x26, 0xf4, 0xbe, 0x4e,
+       0x65, 0xfc, 0xfd, 0x2b, 0xce, 0x12, 0xae, 0x48, 0x00, 0x9d, 0xc5, 0xab, 0xab, 0x4c, 0x4b, 0xd1,
+       0x98, 0x8b, 0xcb, 0xf1, 0x8c, 0xa2, 0xd2, 0x22, 0x2f, 0x60, 0x30, 0x55, 0xbc, 0x10, 0x32, 0xd7,
+       0xd1, 0xc8, 0x22, 0x59, 0xae, 0xbd, 0x1b, 0xed, 0xf6, 0xab, 0x10, 0xac, 0x35, 0x4c, 0xc8, 0x07,
+       0xb0, 0x66, 0xc4, 0x84, 0x6b, 0xc3, 0x26, 0x53, 0xbc, 0x3e, 0x9f, 0xce, 0x1d, 0xe4, 0x33, 0x18,
+       0x18, 0xc5, 0x32, 0xcd, 0x62, 0xdb, 0xa4, 0x8e, 0x94, 0x94, 0x26, 0x68, 0xdd, 0xc0, 0xdc, 0xac,
+       0x87, 0x50, 0x29, 0x0d, 0xf9, 0x0a, 0xde, 0xaf, 0xf9, 0x22, 0x6d, 0x98, 0xc9, 0x75, 0x34, 0x66,
+       0x7a, 0x1c, 0xb4, 0x6f, 0x24, 0x3f, 0xa9, 0x05, 0x9e, 0x62, 0x1c, 0xea, 0xe0, 0x04, 0xc8, 0x32,
+       0x42, 0xd0, 0xc1, 0xe4, 0x27, 0x36, 0xf9, 0xec, 0x66, 0x1a, 0x1d, 0x2c, 0x21, 0x91, 0x4f, 0x61,
+       0xf0, 0xa3, 0x30, 0x19, 0xd7, 0x3a, 0x62, 0xea, 0x32, 0x9f, 0xf0, 0xcc, 0xe8, 0xa0, 0xbb, 0xed,
+       0x3d, 0x5f, 0xa7, 0x9b, 0xee, 0xe0, 0xa8, 0xf2, 0x87, 0x3f, 0x37, 0xa0, 0x7b, 0x76, 0x75, 0x2f,
+       0xfd, 0x3b, 0xd0, 0xd7, 0x5c, 0x09, 0x96, 0x8a, 0x6b, 0x9e, 0x44, 0x5a, 0x5c, 0x73, 0x77, 0x0f,
+       0x1b, 0x73, 0xf7, 0xa9, 0xb8, 0xe6, 0x56, 0x7f, 0x96, 0xc8, 0x48, 0xb1, 0xec, 0x92, 0xbb, 0xfb,
+       0x46, 0x6a, 0xa9, 0x75, 0x90, 0x1d, 0x00, 0xc5, 0x75, 0x9e, 0x5a, 0x49, 0xe8, 0xc0, 0xdf, 0xf6,
+       0x16, 0x68, 0x59, 0x2b, 0xcf, 0x86, 0x89, 0x0e, 0xf7, 0x61, 0xe3, 0xec, 0xea, 0x9c, 0x2b, 0x71,
+       0xf1, 0x96, 0xa2, 0x93, 0x7c, 0x04, 0x3d, 0x47, 0xe9, 0x05, 0x13, 0x29, 0x36, 0xd8, 0xa5, 0x50,
+       0xba, 0x5e, 0x32, 0x91, 0x86, 0x17, 0x30, 0x58, 0xe2, 0xe7, 0x8e, 0x91, 0x3e, 0x87, 0x47, 0x05,
+       0xe2, 0x57, 0x3c, 0x37, 0xb1, 0x1b, 0x82, 0x3c, 0x2f, 0x94, 0xa6, 0xeb, 0x65, 0x60, 0x09, 0x19,
+       0xfe, 0xde, 0x00, 0xef, 0x75, 0x7e, 0x45, 0x3e, 0x81, 0x8e, 0x46, 0x61, 0xea, 0xa0, 0x81, 0xa9,
+       0xa8, 0x80, 0x9a, 0x60, 0x69, 0x75, 0x4e, 0x9e, 0x41, 0x67, 0x5a, 0x3e, 0x50, 0x4e, 0x2c, 0xf8,
+       0x0e, 0xb8, 0x37, 0x8b, 0x56, 0x67, 0xe4, 0x5b, 0x78, 0x5c, 0xdd, 0x5c, 0x32, 0x17, 0xa1, 0x0e,
+       0x3c, 0x84, 0x7f, 0x3c, 0x83, 0xaf, 0x29, 0x94, 0x6e, 0xb9, 0x8c, 0x9a, 0xef, 0x96, 0x15, 0xf0,
+       0x6f, 0x59, 0x01, 0x09, 0xdd, 0x63, 0x29, 0xb2, 0x11, 0xd3, 0x9c, 0x7c, 0x03, 0x5b, 0x2b, 0x3a,
+       0x70, 0xfa, 0x5f, 0xdd, 0x00, 0x59, 0x6e, 0xc0, 0xea, 0x8b, 0xa9, 0x91, 0x30, 0x8a, 0xa9, 0xb7,
+       0xee, 0xad, 0x9d, 0x3b, 0xc2, 0x9f, 0x1a, 0xb0, 0x39, 0xcc, 0x8c, 0x62, 0xc7, 0x63, 0x26, 0xb2,
+       0x37, 0xb9, 0x99, 0xe6, 0x86, 0xec, 0x40, 0xbb, 0x64, 0xcb, 0x15, 0x5b, 0x22, 0xd3, 0x1d, 0x93,
+       0x17, 0xd0, 0x8f, 0x65, 0x66, 0x94, 0x4c, 0xa3, 0x3b, 0x38, 0xdd, 0x70, 0x31, 0xd5, 0x77, 0x21,
+       0x80, 0x8e, 0x54, 0x89, 0xc8, 0x58, 0xea, 0x96, 0xb2, 0x32, 0xb1, 0x9b, 0x63, 0x25, 0xb5, 0xfe,
+       0x4f, 0x74, 0xf3, 0x4b, 0x03, 0xe0, 0x5c, 0x1a, 0xfe, 0x2f, 0xf7, 0x61, 0x3f, 0x94, 0x85, 0x34,
+       0x1c, 0x1f, 0xc7, 0x75, 0x8a, 0xbf, 0xc3, 0x3f, 0x1a, 0x00, 0xc7, 0x2c, 0x8b, 0x79, 0x6a, 0x3b,
+       0x24, 0x7b, 0xd0, 0xd7, 0x53, 0x9e, 0x99, 0x48, 0x62, 0xaf, 0xf3, 0x8f, 0xdc, 0x5c, 0xd0, 0x8f,
+       0x30, 0xa0, 0x9c, 0x65, 0x98, 0xdc, 0xb6, 0x5d, 0xcd, 0x07, 0x6e, 0xd7, 0xca, 0xed, 0xf6, 0x56,
+       0x6f, 0x77, 0x7d, 0x44, 0x7f, 0xf5, 0x88, 0xad, 0xda, 0x88, 0x6f, 0x00, 0x28, 0x37, 0x42, 0x71,
+       0x9b, 0xfc, 0xee, 0xec, 0xd7, 0x8a, 0x34, 0x17, 0xef, 0xf3, 0xb7, 0x06, 0xb4, 0x4e, 0xa7, 0x3c,
+       0x4b, 0xfe, 0xef, 0x74, 0x85, 0xbf, 0x36, 0xa1, 0x3f, 0xd7, 0xc9, 0x30, 0xb3, 0xeb, 0xf9, 0x05,
+       0x6c, 0x4d, 0x98, 0xc8, 0x62, 0xeb, 0xb9, 0x63, 0xae, 0xc1, 0x2c, 0x68, 0x36, 0xdb, 0x3b, 0xfe,
+       0x79, 0xb8, 0x85, 0x02, 0xef, 0x81, 0x14, 0xac, 0x50, 0x87, 0x7f, 0xbf, 0x3a, 0x56, 0x12, 0xd7,
+       0xba, 0x9f, 0xb8, 0xf6, 0x02, 0x71, 0xa3, 0x36, 0xfe, 0xe1, 0x3d, 0xfc, 0x2b, 0x00, 0x00, 0xff,
+       0xff, 0x57, 0xa6, 0x8b, 0x78, 0xfc, 0x0a, 0x00, 0x00,
 }
index fd25c9e..6c73e15 100644 (file)
@@ -101,6 +101,14 @@ message VoteOutput {
   bytes       vote            = 4;
 }
 
+message CancelVote {
+  Hash             spent_output_id     = 1;
+  ValueDestination witness_destination = 2;
+  repeated bytes   witness_arguments   = 3;
+  uint64           ordinal             = 4;
+  bytes            vote                = 5;
+}
+
 message Retirement {
   ValueSource source   = 1;
   uint64      ordinal  = 2;
index 1568119..d8bb3eb 100644 (file)
@@ -39,6 +39,13 @@ func MapTx(oldTx *TxData) *bc.Tx {
                                tx.GasInputIDs = append(tx.GasInputIDs, id)
                        }
 
+               case *bc.CancelVote:
+                       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
                        tx.GasInputIDs = append(tx.GasInputIDs, id)
@@ -71,9 +78,10 @@ func mapTx(tx *TxData) (headerID bc.Hash, hdr *bc.TxHeader, entryMap map[bc.Hash
        }
 
        var (
-               spends   []*bc.Spend
-               crossIns []*bc.CrossChainInput
-               coinbase *bc.Coinbase
+               spends      []*bc.Spend
+               cancelVotes []*bc.CancelVote
+               crossIns    []*bc.CrossChainInput
+               coinbase    *bc.Coinbase
        )
 
        muxSources := make([]*bc.ValueSource, len(tx.Inputs))
@@ -120,16 +128,16 @@ func mapTx(tx *TxData) (headerID bc.Hash, hdr *bc.TxHeader, entryMap map[bc.Hash
                        }
                        prevout := bc.NewVoteOutput(src, prog, 0, inp.Vote) // ordinal doesn't matter for prevouts, only for result outputs
                        prevoutID := addEntry(prevout)
-                       // create entry for spend
-                       spend := bc.NewSpend(&prevoutID, uint64(i))
-                       spend.WitnessArguments = inp.Arguments
-                       spendID := addEntry(spend)
+                       // create entry for cancelVote
+                       cancelVote := bc.NewCancelVote(&prevoutID, uint64(i), inp.Vote)
+                       cancelVote.WitnessArguments = inp.Arguments
+                       cancelVoteID := addEntry(cancelVote)
                        // setup mux
                        muxSources[i] = &bc.ValueSource{
-                               Ref:   &spendID,
+                               Ref:   &cancelVoteID,
                                Value: &inp.AssetAmount,
                        }
-                       spends = append(spends, spend)
+                       cancelVotes = append(cancelVotes, cancelVote)
 
                case *CrossChainInput:
                        // TODO: fed peg script
@@ -157,13 +165,13 @@ func mapTx(tx *TxData) (headerID bc.Hash, hdr *bc.TxHeader, entryMap map[bc.Hash
 
        // connect the inputs to the mux
        for _, spend := range spends {
-               switch spentOutput := entryMap[*spend.SpentOutputId].(type) {
-               case *bc.IntraChainOutput:
-                       spend.SetDestination(&muxID, spentOutput.Source.Value, spend.Ordinal)
+               spentOutput := entryMap[*spend.SpentOutputId].(*bc.IntraChainOutput)
+               spend.SetDestination(&muxID, spentOutput.Source.Value, spend.Ordinal)
+       }
 
-               case *bc.VoteOutput:
-                       spend.SetDestination(&muxID, spentOutput.Source.Value, spend.Ordinal)
-               }
+       for _, cancelVote := range cancelVotes {
+               voteOutput := entryMap[*cancelVote.SpentOutputId].(*bc.VoteOutput)
+               cancelVote.SetDestination(&muxID, voteOutput.Source.Value, cancelVote.Ordinal)
        }
 
        for _, crossIn := range crossIns {
index 08e6f6c..e49b13f 100644 (file)
@@ -53,6 +53,8 @@ func (tx *Tx) SetInputArguments(n uint32, args [][]byte) {
                e.WitnessArguments = args
        case *bc.CrossChainInput:
                e.WitnessArguments = args
+       case *bc.CancelVote:
+               e.WitnessArguments = args
        }
 }
 
index 9e574db..2029ff0 100644 (file)
@@ -2,7 +2,7 @@ package bc
 
 import "io"
 
-func (VoteOutput) typ() string { return "crosschainoutput1" }
+func (VoteOutput) typ() string { return "voteoutput1" }
 func (o *VoteOutput) writeForHash(w io.Writer) {
        mustWriteForHash(w, o.Source)
        mustWriteForHash(w, o.ControlProgram)
index 68bac2e..72ea42d 100644 (file)
@@ -261,30 +261,13 @@ func checkValid(vs *validationState, e bc.Entry) (err error) {
                if e.SpentOutputId == nil {
                        return errors.Wrap(ErrMissingField, "spend without spent output ID")
                }
-               var (
-                       controlProgram *bc.Program
-                       value          *bc.AssetAmount
-               )
-               entryOutput, err := vs.tx.Entry(*e.SpentOutputId)
+
+               spentOutput, err := vs.tx.IntraChainOutput(*e.SpentOutputId)
                if err != nil {
                        return errors.Wrap(err, "getting spend prevout")
                }
 
-               switch output := entryOutput.(type) {
-               case *bc.IntraChainOutput:
-                       controlProgram = output.ControlProgram
-                       value = output.Source.Value
-               case *bc.VoteOutput:
-                       if len(output.Vote) != 64 {
-                               return ErrVotePubKey
-                       }
-                       controlProgram = output.ControlProgram
-                       value = output.Source.Value
-               default:
-                       return errors.Wrapf(bc.ErrEntryType, "entry %x has unexpected type %T", e.SpentOutputId.Bytes(), entryOutput)
-               }
-
-               gasLeft, err := vm.Verify(NewTxVMContext(vs, e, controlProgram, e.WitnessArguments), vs.gasStatus.GasLeft)
+               gasLeft, err := vm.Verify(NewTxVMContext(vs, e, spentOutput.ControlProgram, e.WitnessArguments), vs.gasStatus.GasLeft)
                if err != nil {
                        return errors.Wrap(err, "checking control program")
                }
@@ -292,7 +275,7 @@ func checkValid(vs *validationState, e bc.Entry) (err error) {
                        return err
                }
 
-               eq, err := value.Equal(e.WitnessDestination.Value)
+               eq, err := spentOutput.Source.Value.Equal(e.WitnessDestination.Value)
                if err != nil {
                        return err
                }
@@ -300,8 +283,8 @@ func checkValid(vs *validationState, e bc.Entry) (err error) {
                        return errors.WithDetailf(
                                ErrMismatchedValue,
                                "previous output is for %d unit(s) of %x, spend wants %d unit(s) of %x",
-                               value.Amount,
-                               value.AssetId.Bytes(),
+                               spentOutput.Source.Value.Amount,
+                               spentOutput.Source.Value.AssetId.Bytes(),
                                e.WitnessDestination.Value.Amount,
                                e.WitnessDestination.Value.AssetId.Bytes(),
                        )
@@ -312,6 +295,47 @@ func checkValid(vs *validationState, e bc.Entry) (err error) {
                        return errors.Wrap(err, "checking spend destination")
                }
 
+       case *bc.CancelVote:
+               if e.SpentOutputId == nil {
+                       return errors.Wrap(ErrMissingField, "spend without cancelvote output ID")
+               }
+
+               voteOutput, err := vs.tx.VoteOutput(*e.SpentOutputId)
+               if err != nil {
+                       return errors.Wrap(err, "getting cancelvote prevout")
+               }
+               if len(voteOutput.Vote) != 64 {
+                       return ErrVotePubKey
+               }
+
+               gasLeft, err := vm.Verify(NewTxVMContext(vs, e, voteOutput.ControlProgram, e.WitnessArguments), vs.gasStatus.GasLeft)
+               if err != nil {
+                       return errors.Wrap(err, "checking control program")
+               }
+               if err = vs.gasStatus.updateUsage(gasLeft); err != nil {
+                       return err
+               }
+
+               eq, err := voteOutput.Source.Value.Equal(e.WitnessDestination.Value)
+               if err != nil {
+                       return err
+               }
+               if !eq {
+                       return errors.WithDetailf(
+                               ErrMismatchedValue,
+                               "previous output is for %d unit(s) of %x, cancelvote wants %d unit(s) of %x",
+                               voteOutput.Source.Value.Amount,
+                               voteOutput.Source.Value.AssetId.Bytes(),
+                               e.WitnessDestination.Value.Amount,
+                               e.WitnessDestination.Value.AssetId.Bytes(),
+                       )
+               }
+               vs2 := *vs
+               vs2.destPos = 0
+               if err = checkValidDest(&vs2, e.WitnessDestination); err != nil {
+                       return errors.Wrap(err, "checking cancelvote destination")
+               }
+
        case *bc.Coinbase:
                if vs.block == nil || len(vs.block.Transactions) == 0 || vs.block.Transactions[0] != vs.tx {
                        return ErrWrongCoinbaseTransaction
@@ -363,6 +387,12 @@ func checkValidSrc(vstate *validationState, vs *bc.ValueSource) error {
 
        var dest *bc.ValueDestination
        switch ref := e.(type) {
+       case *bc.CancelVote:
+               if vs.Position != 0 {
+                       return errors.Wrapf(ErrPosition, "invalid position %d for cancel-vote source", vs.Position)
+               }
+               dest = ref.WitnessDestination
+
        case *bc.Coinbase:
                if vs.Position != 0 {
                        return errors.Wrapf(ErrPosition, "invalid position %d for coinbase source", vs.Position)
index 10b77d8..1d6cc3c 100644 (file)
@@ -32,23 +32,23 @@ func NewTxVMContext(vs *validationState, entry bc.Entry, prog *bc.Program, args
                destPos = &e.WitnessDestination.Position
 
        case *bc.Spend:
-               switch spentOutput := tx.Entries[*e.SpentOutputId].(type) {
-               case *bc.IntraChainOutput:
-                       a1 := spentOutput.Source.Value.AssetId.Bytes()
-                       assetID = &a1
-                       amount = &spentOutput.Source.Value.Amount
-                       destPos = &e.WitnessDestination.Position
-                       s := e.SpentOutputId.Bytes()
-                       spentOutputID = &s
+               spentOutput := tx.Entries[*e.SpentOutputId].(*bc.IntraChainOutput)
+               a1 := spentOutput.Source.Value.AssetId.Bytes()
+               assetID = &a1
+               amount = &spentOutput.Source.Value.Amount
+               destPos = &e.WitnessDestination.Position
+               s := e.SpentOutputId.Bytes()
+               spentOutputID = &s
+
+       case *bc.CancelVote:
+               cancelVoteOutput := tx.Entries[*e.SpentOutputId].(*bc.VoteOutput)
+               a1 := cancelVoteOutput.Source.Value.AssetId.Bytes()
+               assetID = &a1
+               amount = &cancelVoteOutput.Source.Value.Amount
+               destPos = &e.WitnessDestination.Position
+               s := e.SpentOutputId.Bytes()
+               spentOutputID = &s
 
-               case *bc.VoteOutput:
-                       a1 := spentOutput.Source.Value.AssetId.Bytes()
-                       assetID = &a1
-                       amount = &spentOutput.Source.Value.Amount
-                       destPos = &e.WitnessDestination.Position
-                       s := e.SpentOutputId.Bytes()
-                       spentOutputID = &s
-               }
        }
 
        var txSigHash *[]byte
@@ -173,6 +173,19 @@ func (ec *entryContext) checkOutput(index uint64, amount uint64, assetID []byte,
                        return false, errors.Wrapf(vm.ErrBadValue, "index %d >= 1", index)
                }
                return checkEntry(d)
+
+       case *bc.CancelVote:
+               d, ok := ec.entries[*e.WitnessDestination.Ref]
+               if !ok {
+                       return false, errors.Wrapf(bc.ErrMissingEntry, "entry for cancel-vote destination %x not found", e.WitnessDestination.Ref.Bytes())
+               }
+               if m, ok := d.(*bc.Mux); ok {
+                       return checkMux(m)
+               }
+               if index != 0 {
+                       return false, errors.Wrapf(vm.ErrBadValue, "index %d >= 1", index)
+               }
+               return checkEntry(d)
        }
 
        return false, vm.ErrContext
index 4bcc507..1fa2800 100644 (file)
@@ -174,6 +174,17 @@ func (w *Wallet) BuildAnnotatedInput(tx *types.Tx, i uint32) *query.AnnotatedInp
        in.InputID = id
        e := tx.Entries[id]
        switch e := e.(type) {
+       case *bc.CancelVote:
+               in.Type = "cancel_vote"
+               in.ControlProgram = orig.ControlProgram()
+               in.Address = w.getAddressFromControlProgram(in.ControlProgram, false)
+               in.SpentOutputID = e.SpentOutputId
+               arguments := orig.Arguments()
+               in.Vote = e.Vote
+               for _, arg := range arguments {
+                       in.WitnessArguments = append(in.WitnessArguments, arg)
+               }
+
        case *bc.CrossChainInput:
                in.Type = "cross_chain_in"
                in.ControlProgram = orig.ControlProgram()