OSDN Git Service

Frozen bc (#552)
authorPaladz <yzhu101@uottawa.ca>
Mon, 9 Apr 2018 06:15:05 +0000 (14:15 +0800)
committerGitHub <noreply@github.com>
Mon, 9 Apr 2018 06:15:05 +0000 (14:15 +0800)
* first step clean the nonce

* clean the map.go

* clean the data from bc.go

* finish clean the data from bc level

* add unit test for map

* add comment for golint

33 files changed:
config/genesis.go
protocol/bc/asset.go
protocol/bc/asset_test.go
protocol/bc/bc.pb.go
protocol/bc/bc.proto
protocol/bc/block.go
protocol/bc/entry_test.go
protocol/bc/gen.go [deleted file]
protocol/bc/hash.go
protocol/bc/issuance.go
protocol/bc/merkle.go
protocol/bc/merkle_test.go
protocol/bc/mux.go
protocol/bc/nonce.go [deleted file]
protocol/bc/output.go
protocol/bc/retirement.go
protocol/bc/spend.go
protocol/bc/translation.md [deleted file]
protocol/bc/tx.go
protocol/bc/tx_status.go
protocol/bc/txheader.go
protocol/bc/types/issuance.go
protocol/bc/types/map.go
protocol/bc/types/map_test.go
protocol/bc/types/transaction.go
protocol/bc/types/transaction_test.go
protocol/validation/validation.go
protocol/validation/validation_test.go
protocol/validation/vmcontext.go
protocol/vm/context.go
protocol/vm/introspection.go
protocol/vm/introspection_test.go
protocol/vm/ops.go

index b5d1c34..b4ad165 100644 (file)
@@ -53,7 +53,7 @@ func GenerateGenesisBlock() *types.Block {
                BlockHeader: types.BlockHeader{
                        Version:   1,
                        Height:    0,
-                       Nonce:     4216193,
+                       Nonce:     4216221,
                        Timestamp: 1516788453,
                        BlockCommitment: types.BlockCommitment{
                                TransactionsMerkleRoot: merkleRoot,
index c95b169..a842445 100644 (file)
@@ -1,7 +1,6 @@
 package bc
 
 import (
-       "database/sql/driver"
        "errors"
        "io"
 
@@ -9,23 +8,36 @@ import (
        "github.com/bytom/encoding/blockchain"
 )
 
-// AssetID is the Hash256 of the asset definition.
-
+// NewAssetID convert byte array to aseet id
 func NewAssetID(b [32]byte) (a AssetID) {
        return AssetID(NewHash(b))
 }
 
-func (a AssetID) Byte32() (b32 [32]byte)               { return Hash(a).Byte32() }
-func (a AssetID) MarshalText() ([]byte, error)         { return Hash(a).MarshalText() }
-func (a *AssetID) UnmarshalText(b []byte) error        { return (*Hash)(a).UnmarshalText(b) }
-func (a *AssetID) UnmarshalJSON(b []byte) error        { return (*Hash)(a).UnmarshalJSON(b) }
-func (a AssetID) Bytes() []byte                        { return Hash(a).Bytes() }
-func (a AssetID) Value() (driver.Value, error)         { return Hash(a).Value() }
-func (a *AssetID) Scan(val interface{}) error          { return (*Hash)(a).Scan(val) }
-func (a AssetID) WriteTo(w io.Writer) (int64, error)   { return Hash(a).WriteTo(w) }
+// Byte32 return the byte array representation
+func (a AssetID) Byte32() (b32 [32]byte) { return Hash(a).Byte32() }
+
+// MarshalText satisfies the TextMarshaler interface.
+func (a AssetID) MarshalText() ([]byte, error) { return Hash(a).MarshalText() }
+
+// UnmarshalText satisfies the TextUnmarshaler interface.
+func (a *AssetID) UnmarshalText(b []byte) error { return (*Hash)(a).UnmarshalText(b) }
+
+// UnmarshalJSON satisfies the json.Unmarshaler interface.
+func (a *AssetID) UnmarshalJSON(b []byte) error { return (*Hash)(a).UnmarshalJSON(b) }
+
+// Bytes returns the byte representation.
+func (a AssetID) Bytes() []byte { return Hash(a).Bytes() }
+
+// WriteTo satisfies the io.WriterTo interface.
+func (a AssetID) WriteTo(w io.Writer) (int64, error) { return Hash(a).WriteTo(w) }
+
+// ReadFrom satisfies the io.ReaderFrom interface.
 func (a *AssetID) ReadFrom(r io.Reader) (int64, error) { return (*Hash)(a).ReadFrom(r) }
-func (a *AssetID) IsZero() bool                        { return (*Hash)(a).IsZero() }
 
+// 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)
@@ -35,6 +47,7 @@ func (ad *AssetDefinition) ComputeAssetID() (assetID AssetID) {
        return NewAssetID(b)
 }
 
+// ComputeAssetID implement the assetID calculate logic
 func ComputeAssetID(prog []byte, vmVersion uint64, data *Hash) AssetID {
        def := &AssetDefinition{
                IssuanceProgram: &Program{
@@ -46,6 +59,7 @@ func ComputeAssetID(prog []byte, vmVersion uint64, data *Hash) AssetID {
        return def.ComputeAssetID()
 }
 
+// ReadFrom read the AssetAmount from the bytes
 func (a *AssetAmount) ReadFrom(r *blockchain.Reader) (err error) {
        var assetID AssetID
        if _, err = assetID.ReadFrom(r); err != nil {
@@ -56,6 +70,7 @@ func (a *AssetAmount) ReadFrom(r *blockchain.Reader) (err error) {
        return err
 }
 
+// WriteTo convert struct to byte and write to io
 func (a AssetAmount) WriteTo(w io.Writer) (int64, error) {
        n, err := a.AssetId.WriteTo(w)
        if err != nil {
@@ -65,6 +80,7 @@ func (a AssetAmount) WriteTo(w io.Writer) (int64, error) {
        return n + int64(n2), err
 }
 
+// Equal check does two AssetAmount have same assetID and amount
 func (a *AssetAmount) Equal(other *AssetAmount) (eq bool, err error) {
        if a == nil || other == nil {
                return false, errors.New("empty asset amount")
index 406af0d..a311efe 100644 (file)
@@ -15,9 +15,8 @@ func TestComputeAssetID(t *testing.T) {
        unhashed = append(unhashed, 0x01)                                                      // length of issuanceScript
        unhashed = append(unhashed, issuanceScript...)
        unhashed = append(unhashed, EmptyStringHash.Bytes()...)
-       want := NewAssetID(sha3.Sum256(unhashed))
 
-       if assetID != want {
+       if want := NewAssetID(sha3.Sum256(unhashed)); assetID != want {
                t.Errorf("asset id = %x want %x", assetID.Bytes(), want.Bytes())
        }
 }
@@ -33,11 +32,3 @@ func BenchmarkComputeAssetID(b *testing.B) {
                assetIDSink = ComputeAssetID(issuanceScript, 1, &EmptyStringHash)
        }
 }
-
-func mustDecodeHash(s string) (h Hash) {
-       err := h.UnmarshalText([]byte(s))
-       if err != nil {
-               panic(err)
-       }
-       return h
-}
index 086e406..da95f80 100644 (file)
@@ -20,7 +20,6 @@ It has these top-level messages:
        TxVerifyResult
        TransactionStatus
        Mux
-       Nonce
        Coinbase
        Output
        Retirement
@@ -350,7 +349,6 @@ type TxHeader struct {
        SerializedSize uint64  `protobuf:"varint,2,opt,name=serialized_size,json=serializedSize" json:"serialized_size,omitempty"`
        TimeRange      uint64  `protobuf:"varint,3,opt,name=time_range,json=timeRange" json:"time_range,omitempty"`
        ResultIds      []*Hash `protobuf:"bytes,4,rep,name=result_ids,json=resultIds" json:"result_ids,omitempty"`
-       ExtHash        *Hash   `protobuf:"bytes,5,opt,name=ext_hash,json=extHash" json:"ext_hash,omitempty"`
 }
 
 func (m *TxHeader) Reset()                    { *m = TxHeader{} }
@@ -386,13 +384,6 @@ func (m *TxHeader) GetResultIds() []*Hash {
        return nil
 }
 
-func (m *TxHeader) GetExtHash() *Hash {
-       if m != nil {
-               return m.ExtHash
-       }
-       return nil
-}
-
 type TxVerifyResult struct {
        StatusFail bool `protobuf:"varint,1,opt,name=status_fail,json=statusFail" json:"status_fail,omitempty"`
 }
@@ -436,9 +427,8 @@ func (m *TransactionStatus) GetVerifyStatus() []*TxVerifyResult {
 type Mux struct {
        Sources             []*ValueSource      `protobuf:"bytes,1,rep,name=sources" json:"sources,omitempty"`
        Program             *Program            `protobuf:"bytes,2,opt,name=program" json:"program,omitempty"`
-       ExtHash             *Hash               `protobuf:"bytes,3,opt,name=ext_hash,json=extHash" json:"ext_hash,omitempty"`
-       WitnessDestinations []*ValueDestination `protobuf:"bytes,4,rep,name=witness_destinations,json=witnessDestinations" json:"witness_destinations,omitempty"`
-       WitnessArguments    [][]byte            `protobuf:"bytes,5,rep,name=witness_arguments,json=witnessArguments,proto3" json:"witness_arguments,omitempty"`
+       WitnessDestinations []*ValueDestination `protobuf:"bytes,3,rep,name=witness_destinations,json=witnessDestinations" json:"witness_destinations,omitempty"`
+       WitnessArguments    [][]byte            `protobuf:"bytes,4,rep,name=witness_arguments,json=witnessArguments,proto3" json:"witness_arguments,omitempty"`
 }
 
 func (m *Mux) Reset()                    { *m = Mux{} }
@@ -460,13 +450,6 @@ func (m *Mux) GetProgram() *Program {
        return nil
 }
 
-func (m *Mux) GetExtHash() *Hash {
-       if m != nil {
-               return m.ExtHash
-       }
-       return nil
-}
-
 func (m *Mux) GetWitnessDestinations() []*ValueDestination {
        if m != nil {
                return m.WitnessDestinations
@@ -481,46 +464,6 @@ func (m *Mux) GetWitnessArguments() [][]byte {
        return nil
 }
 
-type Nonce struct {
-       Program           *Program `protobuf:"bytes,1,opt,name=program" json:"program,omitempty"`
-       ExtHash           *Hash    `protobuf:"bytes,2,opt,name=ext_hash,json=extHash" json:"ext_hash,omitempty"`
-       WitnessArguments  [][]byte `protobuf:"bytes,3,rep,name=witness_arguments,json=witnessArguments,proto3" json:"witness_arguments,omitempty"`
-       WitnessAnchoredId *Hash    `protobuf:"bytes,4,opt,name=witness_anchored_id,json=witnessAnchoredId" json:"witness_anchored_id,omitempty"`
-}
-
-func (m *Nonce) Reset()                    { *m = Nonce{} }
-func (m *Nonce) String() string            { return proto.CompactTextString(m) }
-func (*Nonce) ProtoMessage()               {}
-func (*Nonce) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
-
-func (m *Nonce) GetProgram() *Program {
-       if m != nil {
-               return m.Program
-       }
-       return nil
-}
-
-func (m *Nonce) GetExtHash() *Hash {
-       if m != nil {
-               return m.ExtHash
-       }
-       return nil
-}
-
-func (m *Nonce) GetWitnessArguments() [][]byte {
-       if m != nil {
-               return m.WitnessArguments
-       }
-       return nil
-}
-
-func (m *Nonce) GetWitnessAnchoredId() *Hash {
-       if m != nil {
-               return m.WitnessAnchoredId
-       }
-       return nil
-}
-
 type Coinbase struct {
        WitnessDestination *ValueDestination `protobuf:"bytes,1,opt,name=witness_destination,json=witnessDestination" json:"witness_destination,omitempty"`
        Arbitrary          []byte            `protobuf:"bytes,2,opt,name=arbitrary,proto3" json:"arbitrary,omitempty"`
@@ -529,7 +472,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{13} }
+func (*Coinbase) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
 
 func (m *Coinbase) GetWitnessDestination() *ValueDestination {
        if m != nil {
@@ -548,14 +491,13 @@ func (m *Coinbase) GetArbitrary() []byte {
 type Output struct {
        Source         *ValueSource `protobuf:"bytes,1,opt,name=source" json:"source,omitempty"`
        ControlProgram *Program     `protobuf:"bytes,2,opt,name=control_program,json=controlProgram" json:"control_program,omitempty"`
-       ExtHash        *Hash        `protobuf:"bytes,3,opt,name=ext_hash,json=extHash" json:"ext_hash,omitempty"`
-       Ordinal        uint64       `protobuf:"varint,4,opt,name=ordinal" json:"ordinal,omitempty"`
+       Ordinal        uint64       `protobuf:"varint,3,opt,name=ordinal" json:"ordinal,omitempty"`
 }
 
 func (m *Output) Reset()                    { *m = Output{} }
 func (m *Output) String() string            { return proto.CompactTextString(m) }
 func (*Output) ProtoMessage()               {}
-func (*Output) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
+func (*Output) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
 
 func (m *Output) GetSource() *ValueSource {
        if m != nil {
@@ -571,13 +513,6 @@ func (m *Output) GetControlProgram() *Program {
        return nil
 }
 
-func (m *Output) GetExtHash() *Hash {
-       if m != nil {
-               return m.ExtHash
-       }
-       return nil
-}
-
 func (m *Output) GetOrdinal() uint64 {
        if m != nil {
                return m.Ordinal
@@ -587,14 +522,13 @@ func (m *Output) GetOrdinal() uint64 {
 
 type Retirement struct {
        Source  *ValueSource `protobuf:"bytes,1,opt,name=source" json:"source,omitempty"`
-       ExtHash *Hash        `protobuf:"bytes,2,opt,name=ext_hash,json=extHash" json:"ext_hash,omitempty"`
-       Ordinal uint64       `protobuf:"varint,3,opt,name=ordinal" json:"ordinal,omitempty"`
+       Ordinal uint64       `protobuf:"varint,2,opt,name=ordinal" json:"ordinal,omitempty"`
 }
 
 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{14} }
 
 func (m *Retirement) GetSource() *ValueSource {
        if m != nil {
@@ -603,13 +537,6 @@ func (m *Retirement) GetSource() *ValueSource {
        return nil
 }
 
-func (m *Retirement) GetExtHash() *Hash {
-       if m != nil {
-               return m.ExtHash
-       }
-       return nil
-}
-
 func (m *Retirement) GetOrdinal() uint64 {
        if m != nil {
                return m.Ordinal
@@ -618,24 +545,22 @@ func (m *Retirement) GetOrdinal() uint64 {
 }
 
 type Issuance struct {
-       AnchorId               *Hash             `protobuf:"bytes,1,opt,name=anchor_id,json=anchorId" json:"anchor_id,omitempty"`
+       NonceHash              *Hash             `protobuf:"bytes,1,opt,name=nonce_hash,json=nonceHash" json:"nonce_hash,omitempty"`
        Value                  *AssetAmount      `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"`
-       ExtHash                *Hash             `protobuf:"bytes,3,opt,name=ext_hash,json=extHash" json:"ext_hash,omitempty"`
-       WitnessDestination     *ValueDestination `protobuf:"bytes,4,opt,name=witness_destination,json=witnessDestination" json:"witness_destination,omitempty"`
-       WitnessAssetDefinition *AssetDefinition  `protobuf:"bytes,5,opt,name=witness_asset_definition,json=witnessAssetDefinition" json:"witness_asset_definition,omitempty"`
-       WitnessArguments       [][]byte          `protobuf:"bytes,6,rep,name=witness_arguments,json=witnessArguments,proto3" json:"witness_arguments,omitempty"`
-       WitnessAnchoredId      *Hash             `protobuf:"bytes,7,opt,name=witness_anchored_id,json=witnessAnchoredId" json:"witness_anchored_id,omitempty"`
-       Ordinal                uint64            `protobuf:"varint,8,opt,name=ordinal" json:"ordinal,omitempty"`
+       WitnessDestination     *ValueDestination `protobuf:"bytes,3,opt,name=witness_destination,json=witnessDestination" json:"witness_destination,omitempty"`
+       WitnessAssetDefinition *AssetDefinition  `protobuf:"bytes,4,opt,name=witness_asset_definition,json=witnessAssetDefinition" json:"witness_asset_definition,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 *Issuance) Reset()                    { *m = Issuance{} }
 func (m *Issuance) String() string            { return proto.CompactTextString(m) }
 func (*Issuance) ProtoMessage()               {}
-func (*Issuance) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} }
+func (*Issuance) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} }
 
-func (m *Issuance) GetAnchorId() *Hash {
+func (m *Issuance) GetNonceHash() *Hash {
        if m != nil {
-               return m.AnchorId
+               return m.NonceHash
        }
        return nil
 }
@@ -647,13 +572,6 @@ func (m *Issuance) GetValue() *AssetAmount {
        return nil
 }
 
-func (m *Issuance) GetExtHash() *Hash {
-       if m != nil {
-               return m.ExtHash
-       }
-       return nil
-}
-
 func (m *Issuance) GetWitnessDestination() *ValueDestination {
        if m != nil {
                return m.WitnessDestination
@@ -675,13 +593,6 @@ func (m *Issuance) GetWitnessArguments() [][]byte {
        return nil
 }
 
-func (m *Issuance) GetWitnessAnchoredId() *Hash {
-       if m != nil {
-               return m.WitnessAnchoredId
-       }
-       return nil
-}
-
 func (m *Issuance) GetOrdinal() uint64 {
        if m != nil {
                return m.Ordinal
@@ -691,17 +602,15 @@ func (m *Issuance) GetOrdinal() uint64 {
 
 type Spend struct {
        SpentOutputId      *Hash             `protobuf:"bytes,1,opt,name=spent_output_id,json=spentOutputId" json:"spent_output_id,omitempty"`
-       ExtHash            *Hash             `protobuf:"bytes,2,opt,name=ext_hash,json=extHash" json:"ext_hash,omitempty"`
-       WitnessDestination *ValueDestination `protobuf:"bytes,3,opt,name=witness_destination,json=witnessDestination" json:"witness_destination,omitempty"`
-       WitnessArguments   [][]byte          `protobuf:"bytes,4,rep,name=witness_arguments,json=witnessArguments,proto3" json:"witness_arguments,omitempty"`
-       WitnessAnchoredId  *Hash             `protobuf:"bytes,5,opt,name=witness_anchored_id,json=witnessAnchoredId" json:"witness_anchored_id,omitempty"`
-       Ordinal            uint64            `protobuf:"varint,6,opt,name=ordinal" json:"ordinal,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"`
 }
 
 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{16} }
 
 func (m *Spend) GetSpentOutputId() *Hash {
        if m != nil {
@@ -710,13 +619,6 @@ func (m *Spend) GetSpentOutputId() *Hash {
        return nil
 }
 
-func (m *Spend) GetExtHash() *Hash {
-       if m != nil {
-               return m.ExtHash
-       }
-       return nil
-}
-
 func (m *Spend) GetWitnessDestination() *ValueDestination {
        if m != nil {
                return m.WitnessDestination
@@ -731,13 +633,6 @@ func (m *Spend) GetWitnessArguments() [][]byte {
        return nil
 }
 
-func (m *Spend) GetWitnessAnchoredId() *Hash {
-       if m != nil {
-               return m.WitnessAnchoredId
-       }
-       return nil
-}
-
 func (m *Spend) GetOrdinal() uint64 {
        if m != nil {
                return m.Ordinal
@@ -758,7 +653,6 @@ func init() {
        proto.RegisterType((*TxVerifyResult)(nil), "bc.TxVerifyResult")
        proto.RegisterType((*TransactionStatus)(nil), "bc.TransactionStatus")
        proto.RegisterType((*Mux)(nil), "bc.Mux")
-       proto.RegisterType((*Nonce)(nil), "bc.Nonce")
        proto.RegisterType((*Coinbase)(nil), "bc.Coinbase")
        proto.RegisterType((*Output)(nil), "bc.Output")
        proto.RegisterType((*Retirement)(nil), "bc.Retirement")
@@ -769,68 +663,63 @@ func init() {
 func init() { proto.RegisterFile("bc.proto", fileDescriptor0) }
 
 var fileDescriptor0 = []byte{
-       // 994 bytes of a gzipped FileDescriptorProto
-       0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xcb, 0x6e, 0xdb, 0x46,
-       0x17, 0x86, 0x44, 0x4a, 0xa2, 0x8f, 0x1c, 0xcb, 0x1e, 0x3b, 0xf9, 0x89, 0x20, 0x3f, 0x6a, 0xb0,
-       0x70, 0x9d, 0xa2, 0x80, 0xe1, 0x4b, 0x7a, 0x59, 0x74, 0x51, 0xb7, 0x6e, 0x1a, 0x2d, 0xdc, 0x06,
-       0x63, 0xc3, 0x5b, 0x62, 0x44, 0x8e, 0xad, 0x41, 0x25, 0x8e, 0x3a, 0x33, 0x54, 0x1d, 0x3f, 0x47,
-       0x9f, 0x21, 0x0f, 0xd1, 0xc7, 0xea, 0xba, 0x8b, 0x62, 0x0e, 0x87, 0x12, 0x75, 0x71, 0x22, 0xa1,
-       0xe8, 0x8e, 0xe7, 0x32, 0xe7, 0xf2, 0x9d, 0xef, 0x0c, 0x07, 0x82, 0x5e, 0x72, 0x34, 0x52, 0xd2,
-       0x48, 0x52, 0xef, 0x25, 0xd1, 0x6b, 0xf0, 0xdf, 0x30, 0xdd, 0x27, 0x5b, 0x50, 0x1f, 0x1f, 0x87,
-       0xb5, 0xfd, 0xda, 0xcb, 0x26, 0xad, 0x8f, 0x8f, 0x51, 0x3e, 0x09, 0xeb, 0x4e, 0x3e, 0x41, 0xf9,
-       0x34, 0xf4, 0x9c, 0x7c, 0x8a, 0xf2, 0x59, 0xe8, 0x3b, 0xf9, 0x2c, 0xfa, 0x16, 0x5a, 0x6f, 0x95,
-       0xbc, 0x53, 0x6c, 0x48, 0xfe, 0x0f, 0x30, 0x1e, 0xc6, 0x63, 0xae, 0xb4, 0x90, 0x19, 0x86, 0xf4,
-       0xe9, 0xc6, 0x78, 0x78, 0x53, 0x28, 0x08, 0x01, 0x3f, 0x91, 0x29, 0xc7, 0xd8, 0x9b, 0x14, 0xbf,
-       0xa3, 0x2e, 0xb4, 0xce, 0xb5, 0xe6, 0xa6, 0x7b, 0xf1, 0xaf, 0x0b, 0xb9, 0x84, 0x36, 0x86, 0x3a,
-       0x1f, 0xca, 0x3c, 0x33, 0xe4, 0x33, 0x08, 0x98, 0x15, 0x63, 0x91, 0x62, 0xd0, 0xf6, 0x69, 0xfb,
-       0xa8, 0x97, 0x1c, 0xb9, 0x6c, 0xb4, 0x85, 0xc6, 0x6e, 0x4a, 0x9e, 0x41, 0x93, 0xe1, 0x09, 0x4c,
-       0xe5, 0x53, 0x27, 0x45, 0x77, 0xd0, 0x41, 0xdf, 0x0b, 0x7e, 0x2b, 0x32, 0x61, 0x6c, 0x03, 0x5f,
-       0xc1, 0xb6, 0xd0, 0x3a, 0x67, 0x59, 0xc2, 0xe3, 0x51, 0xd1, 0x73, 0x35, 0xb4, 0x83, 0x81, 0x76,
-       0x4a, 0xa7, 0x12, 0x97, 0x17, 0xe0, 0xa7, 0xcc, 0x30, 0x4c, 0xd0, 0x3e, 0x0d, 0xac, 0xaf, 0x85,
-       0x9e, 0xa2, 0x36, 0x1a, 0x40, 0xfb, 0x86, 0x0d, 0x72, 0x7e, 0x25, 0x73, 0x95, 0x70, 0xf2, 0x1c,
-       0x3c, 0xc5, 0x6f, 0x5d, 0xdc, 0xa9, 0xaf, 0x55, 0x92, 0x03, 0x68, 0x8c, 0xad, 0xab, 0x8b, 0xd4,
-       0x99, 0x34, 0x54, 0xf4, 0x4c, 0x0b, 0x2b, 0x79, 0x0e, 0xc1, 0x48, 0x6a, 0xac, 0x19, 0xf1, 0xf2,
-       0xe9, 0x44, 0x8e, 0x7e, 0x83, 0x6d, 0xcc, 0x76, 0xc1, 0xb5, 0x11, 0x19, 0xc3, 0xbe, 0xfe, 0xe3,
-       0x94, 0x7f, 0xd7, 0xa1, 0xfd, 0xfd, 0x40, 0x26, 0xbf, 0xbe, 0xe1, 0x2c, 0xe5, 0x8a, 0x84, 0xd0,
-       0x9a, 0xe5, 0x48, 0x29, 0xda, 0x59, 0xf4, 0xb9, 0xb8, 0xeb, 0x4f, 0x66, 0x51, 0x48, 0xe4, 0x15,
-       0xec, 0x8c, 0x14, 0x1f, 0x0b, 0x99, 0xeb, 0xb8, 0x67, 0x23, 0xd9, 0xa1, 0x7a, 0x73, 0xe5, 0x76,
-       0x4a, 0x17, 0xcc, 0xd5, 0x4d, 0xc9, 0x0b, 0xd8, 0x30, 0x62, 0xc8, 0xb5, 0x61, 0xc3, 0x11, 0xf2,
-       0xc4, 0xa7, 0x53, 0x05, 0xf9, 0x12, 0x76, 0x8c, 0x62, 0x99, 0x66, 0x89, 0x2d, 0x52, 0xc7, 0x4a,
-       0x4a, 0x13, 0x36, 0xe6, 0x62, 0x6e, 0x57, 0x5d, 0xa8, 0x94, 0x86, 0x7c, 0x07, 0xff, 0xab, 0xe8,
-       0x62, 0x6d, 0x98, 0xc9, 0x75, 0xdc, 0x67, 0xba, 0x1f, 0x36, 0xe7, 0x0e, 0x3f, 0xad, 0x38, 0x5e,
-       0xa1, 0x1f, 0x2e, 0xdc, 0x1e, 0x34, 0x32, 0x99, 0x25, 0x3c, 0x6c, 0x61, 0x49, 0x85, 0x60, 0x97,
-       0xa3, 0x27, 0x8c, 0x0e, 0x03, 0x54, 0xe2, 0x37, 0xb9, 0x00, 0xb2, 0x98, 0x2b, 0xdc, 0xc0, 0x34,
-       0x4f, 0x6d, 0x9a, 0xeb, 0xf9, 0x04, 0x74, 0x67, 0x21, 0x67, 0xf4, 0x67, 0x0d, 0x82, 0xeb, 0xfb,
-       0x8f, 0x62, 0x7f, 0x08, 0x1d, 0xcd, 0x95, 0x60, 0x03, 0xf1, 0xc0, 0xd3, 0x58, 0x8b, 0x07, 0xee,
-       0x86, 0xb0, 0x35, 0x55, 0x5f, 0x89, 0x07, 0x6e, 0xb7, 0xdc, 0xa2, 0x18, 0x2b, 0x96, 0xdd, 0x71,
-       0x37, 0x6c, 0xc4, 0x95, 0x5a, 0x05, 0x39, 0x04, 0x50, 0x5c, 0xe7, 0x03, 0xbb, 0x78, 0x3a, 0xf4,
-       0xf7, 0xbd, 0x19, 0x4c, 0x36, 0x0a, 0x5b, 0x37, 0xd5, 0xe4, 0x53, 0x08, 0xf8, 0xbd, 0x29, 0xa0,
-       0x9b, 0xc7, 0xbd, 0xc5, 0xef, 0x8d, 0xfd, 0x88, 0x4e, 0x60, 0xeb, 0xfa, 0xfe, 0x86, 0x2b, 0x71,
-       0xfb, 0x8e, 0xe2, 0x49, 0xf2, 0x09, 0xb4, 0x1d, 0xe8, 0xb7, 0x4c, 0x0c, 0xb0, 0x8b, 0x80, 0x42,
-       0xa1, 0x7a, 0xcd, 0xc4, 0x20, 0xba, 0x85, 0x9d, 0x05, 0x5c, 0x3e, 0xd0, 0xf7, 0xd7, 0xf0, 0x64,
-       0x8c, 0xf1, 0x4b, 0x7c, 0xeb, 0x58, 0x32, 0x41, 0x7c, 0x67, 0x52, 0xd3, 0xcd, 0xc2, 0xd1, 0xe1,
-       0xfa, 0x57, 0x0d, 0xbc, 0xcb, 0xfc, 0x9e, 0x7c, 0x0e, 0x2d, 0x8d, 0xab, 0xab, 0xc3, 0x1a, 0x1e,
-       0xc5, 0x1d, 0xa9, 0xac, 0x34, 0x2d, 0xed, 0xe4, 0x00, 0x5a, 0xe5, 0xbd, 0x51, 0x5f, 0xbc, 0x37,
-       0x4a, 0xdb, 0x0c, 0x32, 0xde, 0x23, 0xc8, 0x90, 0x9f, 0x60, 0xef, 0x77, 0x61, 0x32, 0xae, 0x75,
-       0x9c, 0x4e, 0x77, 0xb9, 0x44, 0x7c, 0x6f, 0x52, 0x43, 0x65, 0xd1, 0xe9, 0xae, 0x3b, 0x51, 0xd1,
-       0x69, 0xf2, 0x05, 0xec, 0x94, 0x81, 0x98, 0xba, 0xcb, 0x87, 0x3c, 0x33, 0x3a, 0x6c, 0xec, 0x7b,
-       0x2f, 0x37, 0xe9, 0xb6, 0x33, 0x9c, 0x97, 0x7a, 0x4b, 0xa6, 0xc6, 0xcf, 0x48, 0xd8, 0x4a, 0x2f,
-       0xb5, 0x15, 0x7b, 0xa9, 0x3f, 0xd6, 0xcb, 0xd2, 0x12, 0xbc, 0xe5, 0x25, 0x90, 0x6f, 0x60, 0x77,
-       0xe2, 0x9c, 0x25, 0x7d, 0xa9, 0x78, 0x6a, 0xaf, 0x03, 0x7f, 0x2e, 0x78, 0x19, 0xf1, 0xdc, 0xf9,
-       0x74, 0xd3, 0x48, 0x42, 0xf0, 0x83, 0x14, 0x59, 0x8f, 0x69, 0x4e, 0x7e, 0x9c, 0x46, 0xa9, 0xc0,
-       0xe7, 0x5a, 0x59, 0x8e, 0x1e, 0x59, 0x44, 0xcf, 0xde, 0x31, 0x4c, 0xf5, 0x84, 0x51, 0x4c, 0xbd,
-       0x73, 0x3f, 0xb6, 0xa9, 0x22, 0x7a, 0x5f, 0x83, 0xe6, 0x2f, 0xb9, 0x19, 0xe5, 0x86, 0x1c, 0x42,
-       0xb3, 0x60, 0x81, 0x4b, 0xb1, 0x40, 0x12, 0x67, 0x26, 0xaf, 0xa0, 0x93, 0xc8, 0xcc, 0x28, 0x39,
-       0x88, 0x3f, 0xc0, 0x95, 0x2d, 0xe7, 0xf3, 0x76, 0x1d, 0xca, 0x84, 0xd0, 0x92, 0x2a, 0x15, 0x19,
-       0x1b, 0xb8, 0xeb, 0xb0, 0x14, 0x23, 0x03, 0x40, 0xb9, 0x11, 0x8a, 0x5b, 0x88, 0x57, 0xaf, 0x75,
-       0xa5, 0xe1, 0x56, 0xb2, 0x7a, 0xb3, 0x59, 0xff, 0xf0, 0x20, 0xe8, 0xba, 0x7f, 0x25, 0x39, 0x80,
-       0x8d, 0x62, 0x9c, 0xd3, 0x1f, 0xf6, 0x34, 0x58, 0x50, 0x98, 0xba, 0xe9, 0xaa, 0xff, 0xa3, 0x95,
-       0xf0, 0x78, 0x84, 0x03, 0xfe, 0x9a, 0x1c, 0xb8, 0x84, 0x70, 0x42, 0x48, 0x7c, 0x71, 0xa4, 0x93,
-       0x27, 0x83, 0xbb, 0xd8, 0x76, 0x27, 0x55, 0x4e, 0x5f, 0x13, 0xf4, 0x59, 0x49, 0xd0, 0xb9, 0x57,
-       0xc6, 0xd2, 0x65, 0x68, 0xae, 0xb7, 0x0c, 0xad, 0x8f, 0x2e, 0x43, 0x75, 0x2c, 0xc1, 0xec, 0x58,
-       0xde, 0xd7, 0xa1, 0x71, 0x35, 0xe2, 0x59, 0x4a, 0x8e, 0xa1, 0xa3, 0x47, 0x3c, 0x33, 0xb1, 0x44,
-       0x12, 0x2f, 0x9b, 0xcc, 0x13, 0x74, 0x28, 0x48, 0xde, 0x4d, 0x57, 0x63, 0xc4, 0x23, 0xb8, 0x7b,
-       0x6b, 0xe2, 0xbe, 0x14, 0x28, 0x7f, 0x3d, 0xa0, 0x1a, 0x6b, 0x01, 0xd5, 0x9c, 0x01, 0xaa, 0xd7,
-       0xc4, 0xd7, 0xf4, 0xd9, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x00, 0x5c, 0x72, 0x59, 0x0b,
-       0x00, 0x00,
+       // 913 bytes of a gzipped FileDescriptorProto
+       0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x4b, 0x6f, 0x23, 0x45,
+       0x10, 0x96, 0xc7, 0xe3, 0x57, 0x39, 0x1b, 0xc7, 0x9d, 0xec, 0x32, 0x5a, 0x2d, 0x62, 0x35, 0xd2,
+       0x12, 0x10, 0x52, 0x94, 0x38, 0x0b, 0x5c, 0x38, 0x10, 0x08, 0xcb, 0xfa, 0x10, 0x2d, 0xea, 0x44,
+       0xb9, 0x8e, 0xda, 0x33, 0x6d, 0xbb, 0xc5, 0x78, 0xda, 0x74, 0xf7, 0x98, 0x6c, 0x6e, 0xfc, 0x08,
+       0x7e, 0x0b, 0x3f, 0x81, 0x13, 0xff, 0x88, 0x03, 0xea, 0x9a, 0x1e, 0x7b, 0xfc, 0xd8, 0x97, 0xd0,
+       0xde, 0x5c, 0x8f, 0xf9, 0xaa, 0xea, 0xab, 0x47, 0x1b, 0xda, 0xa3, 0xf8, 0x64, 0xae, 0xa4, 0x91,
+       0xc4, 0x1b, 0xc5, 0xe1, 0x0b, 0xf0, 0x5f, 0x32, 0x3d, 0x25, 0xfb, 0xe0, 0x2d, 0x4e, 0x83, 0xda,
+       0xd3, 0xda, 0x17, 0x4d, 0xea, 0x2d, 0x4e, 0x51, 0x3e, 0x0b, 0x3c, 0x27, 0x9f, 0xa1, 0x3c, 0x08,
+       0xea, 0x4e, 0x1e, 0xa0, 0x7c, 0x1e, 0xf8, 0x4e, 0x3e, 0x0f, 0xbf, 0x83, 0xd6, 0x2f, 0x4a, 0x4e,
+       0x14, 0x9b, 0x91, 0x4f, 0x01, 0x16, 0xb3, 0x68, 0xc1, 0x95, 0x16, 0x32, 0x43, 0x48, 0x9f, 0x76,
+       0x16, 0xb3, 0xdb, 0x42, 0x41, 0x08, 0xf8, 0xb1, 0x4c, 0x38, 0x62, 0xef, 0x51, 0xfc, 0x1d, 0x0e,
+       0xa1, 0x75, 0xa1, 0x35, 0x37, 0xc3, 0xcb, 0xff, 0x9d, 0xc8, 0x15, 0x74, 0x11, 0xea, 0x62, 0x26,
+       0xf3, 0xcc, 0x90, 0xcf, 0xa1, 0xcd, 0xac, 0x18, 0x89, 0x04, 0x41, 0xbb, 0x83, 0xee, 0xc9, 0x28,
+       0x3e, 0x71, 0xd1, 0x68, 0x0b, 0x8d, 0xc3, 0x84, 0x3c, 0x82, 0x26, 0xc3, 0x2f, 0x30, 0x94, 0x4f,
+       0x9d, 0x14, 0x4e, 0xa0, 0x87, 0xbe, 0x97, 0x7c, 0x2c, 0x32, 0x61, 0x6c, 0x01, 0xdf, 0xc0, 0x81,
+       0xd0, 0x3a, 0x67, 0x59, 0xcc, 0xa3, 0x79, 0x51, 0x73, 0x15, 0xda, 0xd1, 0x40, 0x7b, 0xa5, 0x53,
+       0xc9, 0xcb, 0x13, 0xf0, 0x13, 0x66, 0x18, 0x06, 0xe8, 0x0e, 0xda, 0xd6, 0xd7, 0x52, 0x4f, 0x51,
+       0x1b, 0xa6, 0xd0, 0xbd, 0x65, 0x69, 0xce, 0xaf, 0x65, 0xae, 0x62, 0x4e, 0x1e, 0x43, 0x5d, 0xf1,
+       0xb1, 0xc3, 0x5d, 0xf9, 0x5a, 0x25, 0x79, 0x06, 0x8d, 0x85, 0x75, 0x75, 0x48, 0xbd, 0x65, 0x41,
+       0x45, 0xcd, 0xb4, 0xb0, 0x92, 0xc7, 0xd0, 0x9e, 0x4b, 0x8d, 0x39, 0x23, 0x5f, 0x3e, 0x5d, 0xca,
+       0xe1, 0x6f, 0x70, 0x80, 0xd1, 0x2e, 0xb9, 0x36, 0x22, 0x63, 0x58, 0xd7, 0x47, 0x0e, 0xf9, 0xaf,
+       0x07, 0xdd, 0x1f, 0x52, 0x19, 0xff, 0xfa, 0x92, 0xb3, 0x84, 0x2b, 0x12, 0x40, 0x6b, 0x7d, 0x46,
+       0x4a, 0xd1, 0xf6, 0x62, 0xca, 0xc5, 0x64, 0xba, 0xec, 0x45, 0x21, 0x91, 0xe7, 0xd0, 0x9f, 0x2b,
+       0xbe, 0x10, 0x32, 0xd7, 0xd1, 0xc8, 0x22, 0xd9, 0xa6, 0xd6, 0x37, 0xd2, 0xed, 0x95, 0x2e, 0x18,
+       0x6b, 0x98, 0x90, 0x27, 0xd0, 0x31, 0x62, 0xc6, 0xb5, 0x61, 0xb3, 0x39, 0xce, 0x89, 0x4f, 0x57,
+       0x0a, 0xf2, 0x35, 0xf4, 0x8d, 0x62, 0x99, 0x66, 0xb1, 0x4d, 0x52, 0x47, 0x4a, 0x4a, 0x13, 0x34,
+       0x36, 0x30, 0x0f, 0xaa, 0x2e, 0x54, 0x4a, 0x43, 0xbe, 0x87, 0x4f, 0x2a, 0xba, 0x48, 0x1b, 0x66,
+       0x72, 0x1d, 0x4d, 0x99, 0x9e, 0x06, 0xcd, 0x8d, 0x8f, 0x1f, 0x56, 0x1c, 0xaf, 0xd1, 0x0f, 0x17,
+       0xee, 0x08, 0x1a, 0x99, 0xcc, 0x62, 0x1e, 0xb4, 0x30, 0xa5, 0x42, 0xb0, 0xcb, 0x31, 0x12, 0x46,
+       0x07, 0x6d, 0x54, 0xe2, 0x6f, 0x72, 0x09, 0x64, 0x3b, 0x56, 0xd0, 0xc1, 0x30, 0x0f, 0x6d, 0x98,
+       0x9b, 0xcd, 0x00, 0xb4, 0xbf, 0x15, 0x33, 0xfc, 0xb3, 0x06, 0xed, 0x9b, 0xbb, 0x77, 0x72, 0x7f,
+       0x0c, 0x3d, 0xcd, 0x95, 0x60, 0xa9, 0xb8, 0xe7, 0x49, 0xa4, 0xc5, 0x3d, 0x77, 0x4d, 0xd8, 0x5f,
+       0xa9, 0xaf, 0xc5, 0x3d, 0xb7, 0x5b, 0x6e, 0x59, 0x8c, 0x14, 0xcb, 0x26, 0xdc, 0x35, 0x1b, 0x79,
+       0xa5, 0x56, 0x41, 0x8e, 0x01, 0x14, 0xd7, 0x79, 0x6a, 0x17, 0x4f, 0x07, 0xfe, 0xd3, 0xfa, 0x1a,
+       0x27, 0x9d, 0xc2, 0x36, 0x4c, 0x74, 0x78, 0x06, 0xfb, 0x37, 0x77, 0xb7, 0x5c, 0x89, 0xf1, 0x6b,
+       0x8a, 0x4a, 0xf2, 0x19, 0x74, 0x1d, 0x9f, 0x63, 0x26, 0x52, 0x4c, 0xb0, 0x4d, 0xa1, 0x50, 0xbd,
+       0x60, 0x22, 0x0d, 0xc7, 0xd0, 0xdf, 0x2a, 0xf9, 0x2d, 0x25, 0x7d, 0x0b, 0x0f, 0x16, 0x88, 0x5f,
+       0x52, 0xe7, 0x61, 0x36, 0x04, 0xa9, 0x5b, 0x0b, 0x4d, 0xf7, 0x0a, 0x47, 0x47, 0xd9, 0x3f, 0x35,
+       0xa8, 0x5f, 0xe5, 0x77, 0xe4, 0x4b, 0x68, 0x69, 0xdc, 0x4a, 0x1d, 0xd4, 0xf0, 0x53, 0x1c, 0xff,
+       0xca, 0xb6, 0xd2, 0xd2, 0x4e, 0x9e, 0x41, 0xab, 0x3c, 0x09, 0xde, 0xf6, 0x49, 0x28, 0x6d, 0xe4,
+       0x67, 0x38, 0xfa, 0x5d, 0x98, 0x8c, 0x6b, 0x1d, 0x25, 0xab, 0x0d, 0xd4, 0x41, 0x1d, 0xe1, 0x8f,
+       0x96, 0xf0, 0x95, 0xf5, 0xa4, 0x87, 0xee, 0x8b, 0x8a, 0x4e, 0x93, 0xaf, 0xa0, 0x5f, 0x02, 0x31,
+       0x35, 0xc9, 0x67, 0x3c, 0x33, 0x05, 0xdb, 0x7b, 0xf4, 0xc0, 0x19, 0x2e, 0x4a, 0x7d, 0x28, 0xa1,
+       0xfd, 0xa3, 0x14, 0xd9, 0x88, 0x69, 0x4e, 0x7e, 0x82, 0xc3, 0x1d, 0x19, 0xb8, 0xe5, 0xdf, 0x9d,
+       0x00, 0xd9, 0x4e, 0xc0, 0x2e, 0x17, 0x53, 0x23, 0x61, 0x14, 0x53, 0xaf, 0xdd, 0x45, 0x5f, 0x29,
+       0xc2, 0x3f, 0x6a, 0xd0, 0x7c, 0x95, 0x9b, 0x79, 0x6e, 0xc8, 0x31, 0x34, 0x0b, 0x8e, 0x5c, 0x88,
+       0x2d, 0x0a, 0x9d, 0x99, 0x3c, 0x87, 0x5e, 0x2c, 0x33, 0xa3, 0x64, 0x1a, 0xbd, 0x85, 0xc9, 0x7d,
+       0xe7, 0x53, 0xde, 0xd6, 0x00, 0x5a, 0x52, 0x25, 0x22, 0x63, 0xa9, 0x1b, 0xc5, 0x52, 0x0c, 0x5f,
+       0x01, 0x50, 0x6e, 0x84, 0xe2, 0x96, 0x83, 0xf7, 0x4f, 0xa3, 0x02, 0xe8, 0xad, 0x03, 0xfe, 0xe5,
+       0x41, 0x7b, 0xe8, 0x4e, 0xbb, 0x1d, 0x73, 0x5c, 0xdc, 0x62, 0xf5, 0x37, 0x4f, 0x67, 0x07, 0x6d,
+       0xb8, 0xee, 0xef, 0x79, 0x40, 0xdf, 0xd0, 0x96, 0xfa, 0x07, 0xb6, 0xe5, 0x0a, 0x82, 0xe5, 0x58,
+       0xe0, 0xeb, 0x97, 0x2c, 0x9f, 0x2f, 0x3c, 0x81, 0xdd, 0xc1, 0xe1, 0x32, 0x81, 0xd5, 0xcb, 0x46,
+       0x1f, 0x95, 0x23, 0xb3, 0xf1, 0xe2, 0xed, 0x9c, 0xb2, 0xc6, 0xee, 0x29, 0xab, 0x32, 0xd7, 0x5c,
+       0x67, 0xee, 0xef, 0x1a, 0x34, 0xae, 0xe7, 0x3c, 0x4b, 0xc8, 0x29, 0xf4, 0xf4, 0x9c, 0x67, 0x26,
+       0x92, 0x38, 0x1d, 0xab, 0xc7, 0x79, 0xc5, 0xdd, 0x03, 0x74, 0x28, 0xa6, 0x67, 0x98, 0xbc, 0x89,
+       0x18, 0xef, 0x03, 0x89, 0xd9, 0x59, 0x49, 0xfd, 0xdd, 0x95, 0xf8, 0x6b, 0x95, 0x8c, 0x9a, 0xf8,
+       0x07, 0xea, 0xfc, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x5a, 0x57, 0x4f, 0xd8, 0x4c, 0x09, 0x00,
+       0x00,
 }
index dfd2cb4..fb60c8f 100644 (file)
@@ -65,7 +65,6 @@ message TxHeader {
   uint64        serialized_size = 2;
   uint64        time_range      = 3;
   repeated Hash result_ids      = 4;
-  Hash          ext_hash        = 5;
 }
 
 message TxVerifyResult {
@@ -80,16 +79,8 @@ message TransactionStatus {
 message Mux {
   repeated ValueSource      sources              = 1; // issuances, spends, and muxes
   Program                   program              = 2;
-  Hash                      ext_hash             = 3;
-  repeated ValueDestination witness_destinations = 4; // outputs, retirements, and muxes
-  repeated bytes            witness_arguments    = 5;
-}
-
-message Nonce {
-  Program        program             = 1;
-  Hash           ext_hash            = 2;
-  repeated bytes witness_arguments   = 3;
-  Hash           witness_anchored_id = 4;
+  repeated ValueDestination witness_destinations = 3; // outputs, retirements, and muxes
+  repeated bytes            witness_arguments    = 4;
 }
 
 message Coinbase {
@@ -100,32 +91,26 @@ message Coinbase {
 message Output {
   ValueSource source          = 1;
   Program     control_program = 2;
-  Hash        ext_hash        = 3;
-  uint64      ordinal         = 4;
+  uint64      ordinal         = 3;
 }
 
 message Retirement {
   ValueSource source   = 1;
-  Hash        ext_hash = 2;
-  uint64      ordinal  = 3;
+  uint64      ordinal  = 2;
 }
 
 message Issuance {
-  Hash             anchor_id                = 1;
+  Hash             nonce_hash               = 1;
   AssetAmount      value                    = 2;
-  Hash             ext_hash                 = 3;
-  ValueDestination witness_destination      = 4;
-  AssetDefinition  witness_asset_definition = 5;
-  repeated bytes   witness_arguments        = 6;
-  Hash             witness_anchored_id      = 7;
-  uint64           ordinal                  = 8;
+  ValueDestination witness_destination      = 3;
+  AssetDefinition  witness_asset_definition = 4;
+  repeated bytes   witness_arguments        = 5;
+  uint64           ordinal                  = 6;
 }
 
 message Spend {
   Hash             spent_output_id     = 1;
-  Hash             ext_hash            = 2;
-  ValueDestination witness_destination = 3;
-  repeated bytes   witness_arguments   = 4;
-  Hash             witness_anchored_id = 5;
-  uint64           ordinal             = 6;
+  ValueDestination witness_destination = 2;
+  repeated bytes   witness_arguments   = 3;
+  uint64           ordinal             = 4;
 }
\ No newline at end of file
index 830a4e3..eda987d 100644 (file)
@@ -1,5 +1,6 @@
 package bc
 
+// Block is block struct in bc level
 type Block struct {
        *BlockHeader
        ID           Hash
index 4631eb8..1ab9151 100644 (file)
@@ -12,7 +12,6 @@ func BenchmarkEntryID(b *testing.B) {
                NewIssuance(nil, &AssetAmount{}, 0),
                m,
                NewTxHeader(1, 1, 0, nil),
-               NewNonce(&Program{Code: []byte{1}, VmVersion: 1}),
                NewOutput(&ValueSource{}, &Program{Code: []byte{1}, VmVersion: 1}, 0),
                NewRetirement(&ValueSource{}, 1),
                NewSpend(&Hash{}, 0),
diff --git a/protocol/bc/gen.go b/protocol/bc/gen.go
deleted file mode 100644 (file)
index a6f3df3..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-package bc
-
-//go:generate protoc --go_out=. bc.proto
index ab3f8b0..a142030 100644 (file)
@@ -2,7 +2,6 @@ package bc
 
 import (
        "bytes"
-       "database/sql/driver"
        "encoding/binary"
        "encoding/hex"
        "encoding/json"
@@ -12,10 +11,10 @@ import (
        "golang.org/x/crypto/sha3"
 )
 
-// Hash represents a 256-bit hash.
-
+// EmptyStringHash represents a 256-bit hash.
 var EmptyStringHash = NewHash(sha3.Sum256(nil))
 
+// NewHash convert the input byte array to hash
 func NewHash(b32 [32]byte) (h Hash) {
        h.V0 = binary.BigEndian.Uint64(b32[0:8])
        h.V1 = binary.BigEndian.Uint64(b32[8:16])
@@ -24,6 +23,7 @@ func NewHash(b32 [32]byte) (h Hash) {
        return h
 }
 
+// Byte32 return the byte array representation
 func (h Hash) Byte32() (b32 [32]byte) {
        binary.BigEndian.PutUint64(b32[0:8], h.V0)
        binary.BigEndian.PutUint64(b32[8:16], h.V1)
@@ -70,28 +70,12 @@ func (h *Hash) UnmarshalJSON(b []byte) error {
        return h.UnmarshalText([]byte(s))
 }
 
+// Bytes returns the byte representation
 func (h Hash) Bytes() []byte {
        b32 := h.Byte32()
        return b32[:]
 }
 
-// Value satisfies the driver.Valuer interface
-func (h Hash) Value() (driver.Value, error) {
-       return h.Bytes(), nil
-}
-
-// Scan satisfies the driver.Scanner interface
-func (h *Hash) Scan(v interface{}) error {
-       var buf [32]byte
-       b, ok := v.([]byte)
-       if !ok {
-               return fmt.Errorf("Hash.Scan received unsupported type %T", v)
-       }
-       copy(buf[:], b)
-       *h = NewHash(buf)
-       return nil
-}
-
 // WriteTo satisfies the io.WriterTo interface.
 func (h Hash) WriteTo(w io.Writer) (int64, error) {
        n, err := w.Write(h.Bytes())
index 079ff91..34811de 100644 (file)
@@ -4,16 +4,14 @@ import "io"
 
 // Issuance is a source of new value on a blockchain. It satisfies the
 // Entry interface.
-//
-// (Not to be confused with the deprecated type IssuanceInput.)
 
 func (Issuance) typ() string { return "issuance1" }
 func (iss *Issuance) writeForHash(w io.Writer) {
-       mustWriteForHash(w, iss.AnchorId)
+       mustWriteForHash(w, iss.NonceHash)
        mustWriteForHash(w, iss.Value)
-       mustWriteForHash(w, iss.ExtHash)
 }
 
+// SetDestination will link the issuance to the output
 func (iss *Issuance) SetDestination(id *Hash, val *AssetAmount, pos uint64) {
        iss.WitnessDestination = &ValueDestination{
                Ref:      id,
@@ -23,10 +21,10 @@ func (iss *Issuance) SetDestination(id *Hash, val *AssetAmount, pos uint64) {
 }
 
 // NewIssuance creates a new Issuance.
-func NewIssuance(anchorID *Hash, value *AssetAmount, ordinal uint64) *Issuance {
+func NewIssuance(nonceHash *Hash, value *AssetAmount, ordinal uint64) *Issuance {
        return &Issuance{
-               AnchorId: anchorID,
-               Value:    value,
-               Ordinal:  ordinal,
+               NonceHash: nonceHash,
+               Value:     value,
+               Ordinal:   ordinal,
        }
 }
index 900151c..054d443 100644 (file)
@@ -52,7 +52,7 @@ func merkleRoot(nodes []merkleNode) (root Hash, err error) {
        }
 }
 
-// TxMerkleRoot creates a merkle tree from a slice of TxVerifyResult
+// TxStatusMerkleRoot creates a merkle tree from a slice of TxVerifyResult
 func TxStatusMerkleRoot(tvrs []*TxVerifyResult) (root Hash, err error) {
        nodes := []merkleNode{}
        for _, tvr := range tvrs {
index 2f2a609..1452b02 100644 (file)
@@ -7,6 +7,7 @@ import (
        . "github.com/bytom/protocol/bc"
        "github.com/bytom/protocol/bc/types"
        "github.com/bytom/protocol/vm"
+       "github.com/bytom/testutil"
 )
 
 func TestMerkleRoot(t *testing.T) {
@@ -20,7 +21,7 @@ func TestMerkleRoot(t *testing.T) {
                                []byte("00000"),
                        },
                },
-               want: mustDecodeHash("dd26282725467a18bf98ed14e022da9493436dd09372cfeae13080cbaaded00f"),
+               want: testutil.MustDecodeHash("fe34dbd5da0ce3656f423fd7aad7fc7e879353174d33a6446c2ed0e3f3512101"),
        }, {
                witnesses: [][][]byte{
                        {
@@ -32,7 +33,7 @@ func TestMerkleRoot(t *testing.T) {
                                []byte("111111"),
                        },
                },
-               want: mustDecodeHash("a112fb9aea40e6d8b2e9f443ec326d49bea7b61cd616b4bddeb9ebb010e76bf5"),
+               want: testutil.MustDecodeHash("0e4b4c1af18b8f59997804d69f8f66879ad5e30027346ee003ff7c7a512e5554"),
        }, {
                witnesses: [][][]byte{
                        {
@@ -45,7 +46,7 @@ func TestMerkleRoot(t *testing.T) {
                                []byte("222222"),
                        },
                },
-               want: mustDecodeHash("a112fb9aea40e6d8b2e9f443ec326d49bea7b61cd616b4bddeb9ebb010e76bf5"),
+               want: testutil.MustDecodeHash("0e4b4c1af18b8f59997804d69f8f66879ad5e30027346ee003ff7c7a512e5554"),
        }}
 
        for _, c := range cases {
@@ -141,11 +142,3 @@ func TestAllDuplicateLeaves(t *testing.T) {
                t.Error("forged merkle tree with all duplicate leaves")
        }
 }
-
-func mustDecodeHash(s string) (h Hash) {
-       err := h.UnmarshalText([]byte(s))
-       if err != nil {
-               panic(err)
-       }
-       return h
-}
index 415169e..9a99820 100644 (file)
@@ -10,7 +10,6 @@ func (Mux) typ() string { return "mux1" }
 func (m *Mux) writeForHash(w io.Writer) {
        mustWriteForHash(w, m.Sources)
        mustWriteForHash(w, m.Program)
-       mustWriteForHash(w, m.ExtHash)
 }
 
 // NewMux creates a new Mux.
diff --git a/protocol/bc/nonce.go b/protocol/bc/nonce.go
deleted file mode 100644 (file)
index 8458833..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-package bc
-
-import "io"
-
-// Nonce contains data used, among other things, for distinguishing
-// otherwise-identical issuances (when used as those issuances'
-// "anchors"). It satisfies the Entry interface.
-
-func (Nonce) typ() string { return "nonce1" }
-func (n *Nonce) writeForHash(w io.Writer) {
-       mustWriteForHash(w, n.Program)
-       mustWriteForHash(w, n.ExtHash)
-}
-
-// NewNonce creates a new Nonce.
-func NewNonce(p *Program) *Nonce {
-       return &Nonce{
-               Program: p,
-       }
-}
-
-func (n *Nonce) SetAnchored(id *Hash) {
-       n.WitnessAnchoredId = id
-}
index cc339f2..3a29178 100644 (file)
@@ -12,7 +12,6 @@ func (Output) typ() string { return "output1" }
 func (o *Output) writeForHash(w io.Writer) {
        mustWriteForHash(w, o.Source)
        mustWriteForHash(w, o.ControlProgram)
-       mustWriteForHash(w, o.ExtHash)
 }
 
 // NewOutput creates a new Output.
index 9636c21..de1e827 100644 (file)
@@ -9,7 +9,6 @@ import "io"
 func (Retirement) typ() string { return "retirement1" }
 func (r *Retirement) writeForHash(w io.Writer) {
        mustWriteForHash(w, r.Source)
-       mustWriteForHash(w, r.ExtHash)
 }
 
 // NewRetirement creates a new Retirement.
index d957bf9..729c49d 100644 (file)
@@ -10,9 +10,9 @@ import "io"
 func (Spend) typ() string { return "spend1" }
 func (s *Spend) writeForHash(w io.Writer) {
        mustWriteForHash(w, s.SpentOutputId)
-       mustWriteForHash(w, s.ExtHash)
 }
 
+// SetDestination will link the spend to the output
 func (s *Spend) SetDestination(id *Hash, val *AssetAmount, pos uint64) {
        s.WitnessDestination = &ValueDestination{
                Ref:      id,
@@ -28,7 +28,3 @@ func NewSpend(spentOutputID *Hash, ordinal uint64) *Spend {
                Ordinal:       ordinal,
        }
 }
-
-func (s *Spend) SetAnchored(id *Hash) {
-       s.WitnessAnchoredId = id
-}
diff --git a/protocol/bc/translation.md b/protocol/bc/translation.md
deleted file mode 100644 (file)
index 99151b6..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-## Translation Layer
-
-(This is a temporary guide for translating between old-style transaction data structures and new-style transaction data structures.)
-
-### OldTx -> NewTx
-
-This is a first intermediate step that allows keeping old SDK, old tx index and data structures within Core, but refactoring how txs and outputs are hashed for UTXO set and merkle root in block headers.
-
-1. Let `oldtx` be the transaction in old format.
-2. Let `newtx` be a new instance of `TxHeader` entry.
-3. Let `container` be the container for all entries.
-4. Set `newtx.version` to `oldtx.version`.
-5. If `oldtx.data` is non-empty:
-    1. Let `refdata` be a new `Data` entry.
-    2. Set `refdata.body` to `tx.data`.
-    3. Set `newtx.data` to `refdata.id`.
-    4. Add `refdata` to the `container`.
-6. Set `newtx.mintime` to `oldtx.mintime`.
-7. Set `newtx.maxtime` to `oldtx.maxtime`.
-8. Let `mux` be a new `Mux` entry.
-9. For each old input `oldinp`:
-    1. If the old input is issuance:
-        1. Let `is` be a new `Issuance` entry.
-        2. Set `is.value` to `AssetAmount { oldinp.assetid, oldinp.amount }`.
-        3. If `nonce` is empty:
-            1. Set `is.anchor` to the ID of the first new input. (If no input was mapped yet, go back to this step when such input is added.)
-        4. If `nonce` is non-empty:
-            1. Let `a` be a new `Nonce` entry.
-            2. Set `a.program` to (VM1, `PUSHDATA(nonce) DROP ASSET PUSHDATA(oldinp.assetid) EQUAL`. (The program pushes the nonce onto the stack then drops it, then calls the ASSET opcode, pushes the hardcoded old asset ID onto the stack, and checks that they are equal.)
-            3. Let `tr` be a new `TimeRange` entry.
-            4. Set `tr.mintime` to `oldtx.mintime`.
-            5. Set `tr.maxtime` to `oldtx.maxtime`.
-            6. Set `a.timerange` to `tr.id`.
-            7. Set `is.anchor` to `a.id`.
-            8. Add `a` to `container`.
-            9. Add `tr` to `container`.
-        5. Set `is.initial_block_id` to `oldinp.initial_block_id`.
-        6. Set `is.issuance_program` to `oldinp.issuance_program` (with its VM version).
-        7. If `oldinp.asset_definition` is non-empty:
-            1. Let `adef` be a new `Data` entry.
-            2. Set `adef.body` to `oldinp.asset_definition`.
-            3. Set `is.asset_definition` to `adef.id`.
-            4. Add `adef` to `container`.
-        8. If `oldinp.asset_definition` is empty:
-            1. Set `is.asset_definition` to a nil pointer `0x000000...`.
-        9. Create `ValueSource` struct `src`:
-            1. Set `src.ref` to `is.id`.
-            2. Set `src.position` to 0.
-            3. Set `src.value` to `is.value`.
-            4. Add `src` to `mux.sources`.
-        10. Add `is` to `container`.
-    2. If the old input is a spend:
-        1. Let `inp` be a new `Spend` entry.
-        2. Set `inp.spent_output` to `oldinp.output_id`.
-        3. Set `inp.data` to a nil pointer `0x00000...`.
-        4. Create `ValueSource` struct `src`:
-            1. Set `src.ref` to `inp.id`.
-            2. Set `src.position` to 0.
-            3. Set `src.value` to `AssetAmount{ oldinp.spent_output.(assetid,amount) } `.
-            4. Add `src` to `mux.sources`.
-        5. Add `inp` to `container`.
-11. For each output `oldout` at index `i`:
-    1. If the `oldout` contains a retirement program:
-        1. Let `destentry` be a new `Retirement` entry.
-    2. If the `oldout` is not a retirement:
-        1. Let `destentry` be a new `Output` entry.
-        2. Set `destentry.control_program` to `oldout.control_program` (with its VM version).
-    3. Create `ValueSource` struct `src`:
-        1. Set `src.ref` to `mux.id`.
-        2. Set `src.position` to `i`.
-        3. Set `src.value` to `AssetAmount { oldout.asset_id, oldout.amount }`.
-        4. Set `destentry.source` to `src`.
-    4. If `oldout.data` is non-empty:
-        1. Let `data` be a new `Data` entry.
-        2. Set `data.body` to `oldout.data`.
-        3. Set `destentry.data` to `data.id`.
-        4. Add `data` to `container`.
-    5. Add `destentry` to `container`.
-    6. Add `destentry` to `newtx.results`.
-
-
-### OldTxID -> NewTxID
-
-1. Map old tx to `newtx`.
-2. Return new tx's header ID as NewTxID.
-
-### OldWitTxID -> NewWitTxID
-
-1. Map old tx to new tx.
-2. Return new tx's header ID as NewWitTxID. This is the same as NewTxID.
-
-### OldOutputID -> NewOutputID
-
-When indexing old tx's outputs:
-
-1. Map old tx to new tx.
-2. Take corresponding new output.
-3. Compute its entry ID which will be NewOutputID.
-4. Use this new output ID to identify unspent outputs in the DB.
-
-### OldUnspentID -> NewUnspentID
-
-When inserting old tx's outputs into UTXO merkle set:
-
-1. Map old tx to new tx.
-2. Take corresponding new output.
-3. Compute its entry ID which will be NewUnspentID. (This is the same as NewOutputID.)
-4. Use this new unspent ID to insert into UTXO merkle set.
-
-
-### OldIssuanceHash -> NewIssuanceHash
-
-1. Map old tx to new tx.
-2. For each nonce entry in the new tx:
-    1. check its time range is within network-defined limits (not unbounded).
-    2. Use this entry ID as NewIssuanceHash
-    3. Insert new issuance hash in the current _issuance memory_ annotated with expiration date based on `nonce.timerange.maxtime`.
-
-### OldSigHash -> NewSigHash
-
-1. Map old tx to new tx.
-2. For each entry where a program is evaluated (Spend, Issuance or Nonce):
-    1. Compute `sighash = HASH(txid || entryid)`.
-
-
-
-### NewTx -> OldTx
-
-This is a second intermediate step that allows keeping old SDK, but refactoring how txs are represented and stored internally in Core.
-
-TODO: ...
-
-
-## Compression
-
-1. Serialization prefix indicates the format version that specifies how things are serialized and compressed.
-2. Replace hashes with varint offsets, reconstruct hashes in real time and then verify that top hash matches the source (e.g. merkle tree item)
-3. Replace some repeated elements such as initial block id with indices too.
-
-### VM mapping
-
-This shows how the implementation of each of the VM instructions need to be changed. Ones that say "no change" will work as already implemented on the OLD data structure. 
-
-* CHECKOUTPUT:   no change
-* ASSET:         no change
-* AMOUNT:        no change
-* PROGRAM:       no change
-* MINTIME:       no change
-* MAXTIME:       no change
-* INDEX:         no change
-* NONCE:         eliminated
-* TXREFDATAHASH: `newtx.refdatahash()`
-* REFDATAHASH:   `newcurrentinput.refdatahash()`
-* TXSIGHASH:     `hash(newcurrentinput.id() || newtx.id())`
-* OUTPUTID:      `newcurrentinput.spent_output.id()`
-
-
-New opcodes:
-
-* ENTRYID:       `currententry.id()`
-* NONCE:         `currentissuance.anchor.id()` (fails if the entry is not an issuance)
-
-
-### Block header format
-
-The new slightly different serialization format (i.e. the type prefix and extension hash format) should be applied to the block header as well. We are also removing the block witness from the block ID, as discussed above. Finally, we should flatten the confusing "block commitment" and simply make it three separate fields in the block header.
-
-#### BlockHeader entry
-
-    entry {
-        type="blockheader"
-        body:
-            version:                Integer
-            height:                 Integer
-            previous_block_id:      Pointer<BlockHeader>
-            timestamp:              Integer
-            transactions:           MerkleTree<Pointer<TxHeader>>
-            assets:                 PatriciaTree<Pointer<Output>>
-            next_consensus_program: String
-            ext_hash:               Hash
-        witness:
-            ext_hash:               Hash        
-    }
-
-The `MerkleTree` and `PatriciaTree` types are just 32-byte hashes representing the root of those respective trees.
-
-#### OldBlockHeader -> NewBlockHeader
-
-This generates a new BlockHeader data structure, for hashing purposes, from an old block.
-
-1. Let `oldblock` be the block in old format.
-2. Let `newblock` be a new instance of `BlockHeader` entry.
-3. Set `newblock.version` to `oldblock.version`.
-4. Set `newblock.height` to `oldblock.height`.
-5. Set `newblock.previous_block_id` to `oldblock.previous_block_id`.
-6. Set `newblock.timestamp` to `oldblock.timestamp`.
-7. Set `newblock.transactions` to `oldblock.block_commitment.transactions` (i.e. the root of the Merkle tree). Note that this Merkle tree should have been calculated using the new transaction ID.
-7. Set `newblock.assets` to `oldblock.block_commitment.assets` (i.e. the root of the Patricia tree). Note that this Patricia tree should have been calculated using the new Output IDs.
-8. Set `newblock.next_consensus_program` to `oldblock.block_commitment.next_consensus_program`
-
-#### VM mapping
-
-PROGRAM:       same
-NEXTPROGRAM:   same
-BLOCKTIME:     same
-BLOCKSIGHASH:  newblock.id()
index ae14390..c73ea3a 100644 (file)
@@ -12,12 +12,11 @@ type Tx struct {
        Entries  map[Hash]Entry
        InputIDs []Hash // 1:1 correspondence with TxData.Inputs
 
-       // IDs of reachable entries of various kinds
-       NonceIDs       []Hash
        SpentOutputIDs []Hash
        GasInputIDs    []Hash
 }
 
+// SigHash ...
 func (tx *Tx) SigHash(n uint32) (hash Hash) {
        hasher := sha3pool.Get256()
        defer sha3pool.Put256(hasher)
@@ -29,12 +28,12 @@ func (tx *Tx) SigHash(n uint32) (hash Hash) {
 }
 
 // Convenience routines for accessing entries of specific types by ID.
-
 var (
        ErrEntryType    = errors.New("invalid entry type")
        ErrMissingEntry = errors.New("missing entry")
 )
 
+// Output try to get the output entry by given hash
 func (tx *Tx) Output(id Hash) (*Output, error) {
        e, ok := tx.Entries[id]
        if !ok || e == nil {
@@ -47,6 +46,7 @@ func (tx *Tx) Output(id Hash) (*Output, error) {
        return o, nil
 }
 
+// Spend try to get the spend entry by given hash
 func (tx *Tx) Spend(id Hash) (*Spend, error) {
        e, ok := tx.Entries[id]
        if !ok || e == nil {
@@ -59,6 +59,7 @@ func (tx *Tx) Spend(id Hash) (*Spend, error) {
        return sp, nil
 }
 
+// Issuance try to get the issuance entry by given hash
 func (tx *Tx) Issuance(id Hash) (*Issuance, error) {
        e, ok := tx.Entries[id]
        if !ok || e == nil {
@@ -70,15 +71,3 @@ func (tx *Tx) Issuance(id Hash) (*Issuance, error) {
        }
        return iss, nil
 }
-
-func (tx *Tx) Nonce(id Hash) (*Nonce, error) {
-       e, ok := tx.Entries[id]
-       if !ok || e == nil {
-               return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
-       }
-       nonce, ok := e.(*Nonce)
-       if !ok {
-               return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
-       }
-       return nonce, nil
-}
index 743bfe4..2a0674c 100644 (file)
@@ -6,17 +6,17 @@ import (
        "io"
 )
 
-const (
-       TransactionStatusVersion = 1
-)
+const transactionStatusVersion = 1
 
+// NewTransactionStatus create a empty TransactionStatus struct
 func NewTransactionStatus() *TransactionStatus {
        return &TransactionStatus{
-               Version:      TransactionStatusVersion,
+               Version:      transactionStatusVersion,
                VerifyStatus: []*TxVerifyResult{},
        }
 }
 
+// SetStatus set the tx status of given index
 func (ts *TransactionStatus) SetStatus(i int, gasOnly bool) error {
        if i > len(ts.VerifyStatus) {
                return errors.New("setStatus should be set one by one")
@@ -30,6 +30,7 @@ func (ts *TransactionStatus) SetStatus(i int, gasOnly bool) error {
        return nil
 }
 
+// GetStatus get the tx status of given index
 func (ts *TransactionStatus) GetStatus(i int) (bool, error) {
        if i >= len(ts.VerifyStatus) {
                return false, errors.New("GetStatus is out of range")
@@ -38,6 +39,7 @@ func (ts *TransactionStatus) GetStatus(i int) (bool, error) {
        return ts.VerifyStatus[i].StatusFail, nil
 }
 
+// WriteTo will write TxVerifyResult struct to io.Writer
 func (tvr *TxVerifyResult) WriteTo(w io.Writer) (int64, error) {
        bytes, err := json.Marshal(tvr)
        if err != nil {
index f133858..ab24728 100644 (file)
@@ -12,7 +12,6 @@ func (h *TxHeader) writeForHash(w io.Writer) {
        mustWriteForHash(w, h.Version)
        mustWriteForHash(w, h.TimeRange)
        mustWriteForHash(w, h.ResultIds)
-       mustWriteForHash(w, h.ExtHash)
 }
 
 // NewTxHeader creates an new TxHeader.
index d0b3bf4..ff8feeb 100644 (file)
@@ -48,3 +48,12 @@ func (ii *IssuanceInput) AssetDefinitionHash() (defhash bc.Hash) {
        defhash.ReadFrom(sha)
        return defhash
 }
+
+// NonceHash return the hash of the issuance asset definition.
+func (ii *IssuanceInput) NonceHash() (hash bc.Hash) {
+       sha := sha3pool.Get256()
+       defer sha3pool.Put256(sha)
+       sha.Write(ii.Nonce)
+       hash.ReadFrom(sha)
+       return hash
+}
index a5d9120..d719e50 100644 (file)
@@ -2,7 +2,6 @@ package types
 
 import (
        "github.com/bytom/consensus"
-       "github.com/bytom/crypto/sha3pool"
        "github.com/bytom/protocol/bc"
        "github.com/bytom/protocol/vm"
        "github.com/bytom/protocol/vm/vmutil"
@@ -11,56 +10,41 @@ import (
 // MapTx converts a types TxData object into its entries-based
 // representation.
 func MapTx(oldTx *TxData) *bc.Tx {
-       txid, header, entries := mapTx(oldTx)
-
+       txID, txHeader, entries := mapTx(oldTx)
        tx := &bc.Tx{
-               TxHeader: header,
-               ID:       txid,
+               TxHeader: txHeader,
+               ID:       txID,
                Entries:  entries,
                InputIDs: make([]bc.Hash, len(oldTx.Inputs)),
        }
 
-       var (
-               nonceIDs       = make(map[bc.Hash]bool)
-               spentOutputIDs = make(map[bc.Hash]bool)
-       )
+       spentOutputIDs := make(map[bc.Hash]bool)
        for id, e := range entries {
                var ord uint64
                switch e := e.(type) {
                case *bc.Issuance:
-                       anchor, ok := entries[*e.AnchorId]
-                       if !ok {
-                               // this tx will be invalid because this issuance is
-                               // missing an anchor
-                               continue
-                       }
-                       if _, ok := anchor.(*bc.Nonce); ok {
-                               nonceIDs[*e.AnchorId] = true
-                       }
                        ord = e.Ordinal
-                       // resume below after the switch
 
                case *bc.Spend:
-                       spentOutputIDs[*e.SpentOutputId] = true
                        ord = e.Ordinal
-                       // resume below after the switch
+                       spentOutputIDs[*e.SpentOutputId] = true
                        if *e.WitnessDestination.Value.AssetId == *consensus.BTMAssetID {
                                tx.GasInputIDs = append(tx.GasInputIDs, id)
                        }
 
                case *bc.Coinbase:
+                       ord = 0
+
                default:
                        continue
                }
+
                if ord >= uint64(len(oldTx.Inputs)) {
-                       continue // poorly-formed transaction
+                       continue
                }
                tx.InputIDs[ord] = id
        }
 
-       for id := range nonceIDs {
-               tx.NonceIDs = append(tx.NonceIDs, id)
-       }
        for id := range spentOutputIDs {
                tx.SpentOutputIDs = append(tx.SpentOutputIDs, id)
        }
@@ -69,160 +53,123 @@ func MapTx(oldTx *TxData) *bc.Tx {
 
 func mapTx(tx *TxData) (headerID bc.Hash, hdr *bc.TxHeader, entryMap map[bc.Hash]bc.Entry) {
        entryMap = make(map[bc.Hash]bc.Entry)
-
        addEntry := func(e bc.Entry) bc.Hash {
                id := bc.EntryID(e)
                entryMap[id] = e
                return id
        }
 
-       // Loop twice over tx.Inputs, once for spends and once for
-       // issuances.  Do spends first so the entry ID of the first spend is
-       // available in case an issuance needs it for its anchor.
-
        var (
-               spends     []*bc.Spend
-               issuances  []*bc.Issuance
-               coinbase   *bc.Coinbase
-               muxSources = make([]*bc.ValueSource, len(tx.Inputs))
+               spends    []*bc.Spend
+               issuances []*bc.Issuance
+               coinbase  *bc.Coinbase
        )
 
-       for i, inp := range tx.Inputs {
-               if oldSp, ok := inp.TypedInput.(*SpendInput); ok {
-                       prog := &bc.Program{VmVersion: oldSp.VMVersion, Code: oldSp.ControlProgram}
-                       src := &bc.ValueSource{
-                               Ref:      &oldSp.SourceID,
-                               Value:    &oldSp.AssetAmount,
-                               Position: oldSp.SourcePosition,
-                       }
-                       out := bc.NewOutput(src, prog, 0) // ordinal doesn't matter for prevouts, only for result outputs
-                       prevoutID := addEntry(out)
-                       sp := bc.NewSpend(&prevoutID, uint64(i))
-                       sp.WitnessArguments = oldSp.Arguments
-                       id := addEntry(sp)
-                       muxSources[i] = &bc.ValueSource{
-                               Ref:   &id,
-                               Value: &oldSp.AssetAmount,
+       muxSources := make([]*bc.ValueSource, len(tx.Inputs))
+       for i, input := range tx.Inputs {
+               switch inp := input.TypedInput.(type) {
+               case *IssuanceInput:
+                       nonceHash := inp.NonceHash()
+                       assetDefHash := inp.AssetDefinitionHash()
+                       value := input.AssetAmount()
+
+                       issuance := bc.NewIssuance(&nonceHash, &value, uint64(i))
+                       issuance.WitnessAssetDefinition = &bc.AssetDefinition{
+                               Data: &assetDefHash,
+                               IssuanceProgram: &bc.Program{
+                                       VmVersion: inp.VMVersion,
+                                       Code:      inp.IssuanceProgram,
+                               },
                        }
-                       spends = append(spends, sp)
-               }
-       }
-
-       for i, inp := range tx.Inputs {
-               if oldIss, ok := inp.TypedInput.(*IssuanceInput); ok {
-                       // Note: asset definitions, initial block ids, and issuance
-                       // programs are omitted here because they do not contribute to
-                       // the body hash of an issuance.
+                       issuance.WitnessArguments = inp.Arguments
+                       issuanceID := addEntry(issuance)
 
-                       var (
-                               anchorID    bc.Hash
-                               setAnchored = func(*bc.Hash) {}
-                       )
-
-                       if len(oldIss.Nonce) > 0 {
-                               assetID := oldIss.AssetID()
-
-                               builder := vmutil.NewBuilder()
-                               builder.AddData(oldIss.Nonce).AddOp(vm.OP_DROP)
-                               builder.AddOp(vm.OP_ASSET).AddData(assetID.Bytes()).AddOp(vm.OP_EQUAL)
-                               prog, _ := builder.Build() // error is impossible
-
-                               nonce := bc.NewNonce(&bc.Program{VmVersion: 1, Code: prog})
-                               anchorID = addEntry(nonce)
-                               setAnchored = nonce.SetAnchored
+                       muxSources[i] = &bc.ValueSource{
+                               Ref:   &issuanceID,
+                               Value: &value,
                        }
+                       issuances = append(issuances, issuance)
 
-                       val := inp.AssetAmount()
-
-                       assetdefhash := hashData(oldIss.AssetDefinition)
-                       iss := bc.NewIssuance(&anchorID, &val, uint64(i))
-                       iss.WitnessAssetDefinition = &bc.AssetDefinition{
-                               Data: &assetdefhash,
-                               IssuanceProgram: &bc.Program{
-                                       VmVersion: oldIss.VMVersion,
-                                       Code:      oldIss.IssuanceProgram,
-                               },
+               case *SpendInput:
+                       // create entry for prevout
+                       prog := &bc.Program{VmVersion: inp.VMVersion, Code: inp.ControlProgram}
+                       src := &bc.ValueSource{
+                               Ref:      &inp.SourceID,
+                               Value:    &inp.AssetAmount,
+                               Position: inp.SourcePosition,
                        }
-                       iss.WitnessArguments = oldIss.Arguments
-                       issID := addEntry(iss)
-                       setAnchored(&issID)
-
+                       prevout := bc.NewOutput(src, prog, 0) // 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)
+                       // setup mux
                        muxSources[i] = &bc.ValueSource{
-                               Ref:   &issID,
-                               Value: &val,
+                               Ref:   &spendID,
+                               Value: &inp.AssetAmount,
                        }
-                       issuances = append(issuances, iss)
-               }
-       }
+                       spends = append(spends, spend)
 
-       if len(tx.Inputs) == 1 {
-               if oldCB, ok := tx.Inputs[0].TypedInput.(*CoinbaseInput); ok {
-                       cb := bc.NewCoinbase(oldCB.Arbitrary)
-                       cbID := addEntry(cb)
+               case *CoinbaseInput:
+                       coinbase = bc.NewCoinbase(inp.Arbitrary)
+                       coinbaseID := addEntry(coinbase)
 
                        out := tx.Outputs[0]
-                       muxSources = []*bc.ValueSource{{
-                               Ref:   &cbID,
+                       muxSources[i] = &bc.ValueSource{
+                               Ref:   &coinbaseID,
                                Value: &out.AssetAmount,
-                       }}
-                       coinbase = cb
+                       }
                }
        }
 
        mux := bc.NewMux(muxSources, &bc.Program{VmVersion: 1, Code: []byte{byte(vm.OP_TRUE)}})
        muxID := addEntry(mux)
 
-       for _, sp := range spends {
-               spentOutput := entryMap[*sp.SpentOutputId].(*bc.Output)
-               sp.SetDestination(&muxID, spentOutput.Source.Value, sp.Ordinal)
+       // connect the inputs to the mux
+       for _, spend := range spends {
+               spentOutput := entryMap[*spend.SpentOutputId].(*bc.Output)
+               spend.SetDestination(&muxID, spentOutput.Source.Value, spend.Ordinal)
        }
-       for _, iss := range issuances {
-               iss.SetDestination(&muxID, iss.Value, iss.Ordinal)
+       for _, issuance := range issuances {
+               issuance.SetDestination(&muxID, issuance.Value, issuance.Ordinal)
        }
 
        if coinbase != nil {
-               muxSource := mux.Sources[0]
-               cb := entryMap[*muxSource.Ref].(*bc.Coinbase)
-               cb.SetDestination(&muxID, muxSource.Value, 0)
+               coinbase.SetDestination(&muxID, mux.Sources[0].Value, 0)
        }
 
+       // convert types.outputs to the bc.output
        var resultIDs []*bc.Hash
-
        for i, out := range tx.Outputs {
                src := &bc.ValueSource{
                        Ref:      &muxID,
                        Value:    &out.AssetAmount,
                        Position: uint64(i),
                }
-               var dest *bc.ValueDestination
+               var resultID bc.Hash
                if vmutil.IsUnspendable(out.ControlProgram) {
                        // retirement
                        r := bc.NewRetirement(src, uint64(i))
-                       rID := addEntry(r)
-                       resultIDs = append(resultIDs, &rID)
-                       dest = &bc.ValueDestination{
-                               Ref:      &rID,
-                               Position: 0,
-                       }
+                       resultID = addEntry(r)
                } else {
                        // non-retirement
                        prog := &bc.Program{out.VMVersion, out.ControlProgram}
                        o := bc.NewOutput(src, prog, uint64(i))
-                       oID := addEntry(o)
-                       resultIDs = append(resultIDs, &oID)
-                       dest = &bc.ValueDestination{
-                               Ref:      &oID,
-                               Position: 0,
-                       }
+                       resultID = addEntry(o)
                }
-               dest.Value = src.Value
+
+               dest := &bc.ValueDestination{
+                       Value:    src.Value,
+                       Ref:      &resultID,
+                       Position: 0,
+               }
+               resultIDs = append(resultIDs, &resultID)
                mux.WitnessDestinations = append(mux.WitnessDestinations, dest)
        }
 
        h := bc.NewTxHeader(tx.Version, tx.SerializedSize, tx.TimeRange, resultIDs)
-       headerID = addEntry(h)
-
-       return headerID, h, entryMap
+       return addEntry(h), h, entryMap
 }
 
 func mapBlockHeader(old *BlockHeader) (bc.Hash, *bc.BlockHeader) {
@@ -243,9 +190,3 @@ func MapBlock(old *Block) *bc.Block {
        }
        return b
 }
-
-func hashData(data []byte) bc.Hash {
-       var b32 [32]byte
-       sha3pool.Sum256(b32[:], data)
-       return bc.NewHash(b32)
-}
index c89c6fd..21913f3 100644 (file)
@@ -4,132 +4,156 @@ import (
        "bytes"
        "testing"
 
+       "github.com/davecgh/go-spew/spew"
+
+       "github.com/bytom/consensus"
        "github.com/bytom/protocol/bc"
        "github.com/bytom/testutil"
-       "github.com/davecgh/go-spew/spew"
 )
 
-func TestMapTx(t *testing.T) {
-       // sample data copied from transaction_test.go
-       // TODO(bobg): factor out into reusable test utility
-
-       oldTx := sampleTx()
-       oldOuts := oldTx.Outputs
-
-       _, header, entryMap := mapTx(oldTx)
-       t.Log(spew.Sdump(entryMap))
-
-       if header.Version != 1 {
-               t.Errorf("header.Version is %d, expected 1", header.Version)
-       }
-       if header.SerializedSize != oldTx.SerializedSize {
-               t.Errorf("header.SerializedSize is %d, expected %d", header.SerializedSize, oldTx.SerializedSize)
-       }
-       if len(header.ResultIds) != len(oldOuts) {
-               t.Errorf("header.ResultIds contains %d item(s), expected %d", len(header.ResultIds), len(oldOuts))
+func TestMapSpendTx(t *testing.T) {
+       cases := []*TxData{
+               &TxData{
+                       Inputs: []*TxInput{
+                               NewSpendInput(nil, testutil.MustDecodeHash("fad5195a0c8e3b590b86a3c0a95e7529565888508aecca96e9aeda633002f409"), *consensus.BTMAssetID, 88, 3, []byte{1}),
+                       },
+                       Outputs: []*TxOutput{
+                               NewTxOutput(*consensus.BTMAssetID, 80, []byte{1}),
+                       },
+               },
+               &TxData{
+                       Inputs: []*TxInput{
+                               NewIssuanceInput([]byte("nonce"), 254354, []byte("issuanceProgram"), [][]byte{[]byte("arguments1"), []byte("arguments2")}, []byte("assetDefinition")),
+                       },
+                       Outputs: []*TxOutput{
+                               NewTxOutput(*consensus.BTMAssetID, 80, []byte{1}),
+                       },
+               },
+               &TxData{
+                       Inputs: []*TxInput{
+                               NewIssuanceInput([]byte("nonce"), 254354, []byte("issuanceProgram"), [][]byte{[]byte("arguments1"), []byte("arguments2")}, []byte("assetDefinition")),
+                               NewSpendInput(nil, testutil.MustDecodeHash("db7b16ac737440d6e38559996ddabb207d7ce84fbd6f3bfd2525d234761dc863"), *consensus.BTMAssetID, 88, 3, []byte{1}),
+                       },
+                       Outputs: []*TxOutput{
+                               NewTxOutput(*consensus.BTMAssetID, 80, []byte{1}),
+                               NewTxOutput(*consensus.BTMAssetID, 80, []byte{1}),
+                       },
+               },
        }
 
-       for i, oldOut := range oldOuts {
-               if resultEntry, ok := entryMap[*header.ResultIds[i]]; ok {
-                       if newOut, ok := resultEntry.(*bc.Output); ok {
-                               if *newOut.Source.Value != oldOut.AssetAmount {
-                                       t.Errorf("header.ResultIds[%d].(*output).Source is %v, expected %v", i, newOut.Source.Value, oldOut.AssetAmount)
-                               }
-                               if newOut.ControlProgram.VmVersion != 1 {
-                                       t.Errorf("header.ResultIds[%d].(*output).ControlProgram.VMVersion is %d, expected 1", i, newOut.ControlProgram.VmVersion)
+       for _, txData := range cases {
+               tx := MapTx(txData)
+               if len(tx.ResultIds) != len(txData.Outputs) {
+                       t.Errorf("ResultIds contains %d item(s), expected %d", len(tx.ResultIds), len(txData.Outputs))
+               }
+
+               for i, oldIn := range txData.Inputs {
+                       resultEntry, ok := tx.Entries[tx.InputIDs[i]]
+                       if !ok {
+                               t.Errorf("entryMap contains nothing for tx.InputIDs[%d] (%x)", i, tx.InputIDs[i].Bytes())
+                       }
+                       switch newInput := resultEntry.(type) {
+                       case *bc.Issuance:
+                               if *newInput.Value.AssetId != oldIn.AssetID() || newInput.Value.Amount != oldIn.Amount() {
+                                       t.Errorf("tx.InputIDs[%d]'s asset amount is not equal after map'", i)
                                }
-                               if !bytes.Equal(newOut.ControlProgram.Code, oldOut.ControlProgram) {
-                                       t.Errorf("header.ResultIds[%d].(*output).ControlProgram.Code is %x, expected %x", i, newOut.ControlProgram.Code, oldOut.ControlProgram)
+                       case *bc.Spend:
+                               spendOut, err := tx.Output(*newInput.SpentOutputId)
+                               if err != nil {
+                                       t.Fatal(err)
                                }
-                               if !newOut.ExtHash.IsZero() {
-                                       t.Errorf("header.ResultIds[%d].(*output).ExtHash is %x, expected zero", i, newOut.ExtHash.Bytes())
+                               if *spendOut.Source.Value != oldIn.AssetAmount() {
+                                       t.Errorf("tx.InputIDs[%d]'s asset amount is not equal after map'", i)
                                }
-                       } else {
+                       default:
+                               t.Errorf("unexpect input type")
+                       }
+               }
+
+               for i, oldOut := range txData.Outputs {
+                       resultEntry, ok := tx.Entries[*tx.ResultIds[i]]
+                       if !ok {
+                               t.Errorf("entryMap contains nothing for header.ResultIds[%d] (%x)", i, tx.ResultIds[i].Bytes())
+                       }
+                       newOut, ok := resultEntry.(*bc.Output)
+                       if !ok {
                                t.Errorf("header.ResultIds[%d] has type %T, expected *Output", i, resultEntry)
                        }
-               } else {
-                       t.Errorf("entryMap contains nothing for header.ResultIds[%d] (%x)", i, header.ResultIds[i].Bytes())
+
+                       if *newOut.Source.Value != oldOut.AssetAmount {
+                               t.Errorf("header.ResultIds[%d].(*output).Source is %v, expected %v", i, newOut.Source.Value, oldOut.AssetAmount)
+                       }
+                       if newOut.ControlProgram.VmVersion != 1 {
+                               t.Errorf("header.ResultIds[%d].(*output).ControlProgram.VMVersion is %d, expected 1", i, newOut.ControlProgram.VmVersion)
+                       }
+                       if !bytes.Equal(newOut.ControlProgram.Code, oldOut.ControlProgram) {
+                               t.Errorf("header.ResultIds[%d].(*output).ControlProgram.Code is %x, expected %x", i, newOut.ControlProgram.Code, oldOut.ControlProgram)
+                       }
+
                }
        }
 }
 
 func TestMapCoinbaseTx(t *testing.T) {
-       // define the BTM asset id, the soul asset of Bytom
-       var BTMAssetID = &bc.AssetID{
-               V0: uint64(18446744073709551615),
-               V1: uint64(18446744073709551615),
-               V2: uint64(18446744073709551615),
-               V3: uint64(18446744073709551615),
-       }
-       oldTx := &TxData{
-               Version: 1,
+       txData := &TxData{
                Inputs: []*TxInput{
-                       NewCoinbaseInput(nil),
+                       NewCoinbaseInput([]byte("TestMapCoinbaseTx")),
                },
                Outputs: []*TxOutput{
-                       NewTxOutput(*BTMAssetID, 800000000000, []byte{1}),
+                       NewTxOutput(*consensus.BTMAssetID, 800000000000, []byte{1}),
                },
        }
-       oldOut := oldTx.Outputs[0]
+       oldOut := txData.Outputs[0]
+
+       tx := MapTx(txData)
+       t.Log(spew.Sdump(tx.Entries))
 
-       _, header, entryMap := mapTx(oldTx)
-       t.Log(spew.Sdump(entryMap))
+       if len(tx.InputIDs) != 1 {
+               t.Errorf("expect to  only have coinbase input id")
+       }
+       if len(tx.SpentOutputIDs) != 0 {
+               t.Errorf("coinbase tx doesn't spend any utxo")
+       }
+       if len(tx.GasInputIDs) != 0 {
+               t.Errorf("coinbase tx doesn't spend any gas input")
+       }
+       if len(tx.ResultIds) != 1 {
+               t.Errorf("expect to  only have one output")
+       }
 
-       outEntry, ok := entryMap[*header.ResultIds[0]]
+       outEntry, ok := tx.Entries[*tx.ResultIds[0]]
        if !ok {
                t.Errorf("entryMap contains nothing for output")
-               return
        }
        newOut, ok := outEntry.(*bc.Output)
        if !ok {
                t.Errorf("header.ResultIds[0] has type %T, expected *Output", outEntry)
-               return
        }
        if *newOut.Source.Value != oldOut.AssetAmount {
                t.Errorf("(*output).Source is %v, expected %v", newOut.Source.Value, oldOut.AssetAmount)
-               return
        }
 
-       muxEntry, ok := entryMap[*newOut.Source.Ref]
+       muxEntry, ok := tx.Entries[*newOut.Source.Ref]
        if !ok {
                t.Errorf("entryMap contains nothing for mux")
-               return
        }
        mux, ok := muxEntry.(*bc.Mux)
        if !ok {
                t.Errorf("muxEntry has type %T, expected *Mux", muxEntry)
-               return
        }
-       if *mux.WitnessDestinations[0].Value != oldOut.AssetAmount {
-               t.Errorf("(*Mux).Source is %v, expected %v", newOut.Source.Value, oldOut.AssetAmount)
-               return
+       if *mux.WitnessDestinations[0].Value != *newOut.Source.Value {
+               t.Errorf("(*Mux).Destinations is %v, expected %v", *mux.WitnessDestinations[0].Value, *newOut.Source.Value)
        }
 
-       if coinbaseEntry, ok := entryMap[*mux.Sources[0].Ref]; ok {
-               if coinbase, ok := coinbaseEntry.(*bc.Coinbase); ok {
-                       if *coinbase.WitnessDestination.Value != oldOut.AssetAmount {
-                               t.Errorf("(*Coinbase).Source is %v, expected %v", newOut.Source.Value, oldOut.AssetAmount)
-                       }
-               } else {
-                       t.Errorf("inputEntry has type %T, expected *Coinbase", coinbaseEntry)
-               }
-       } else {
-               t.Errorf("entryMap contains nothing for input")
+       coinbaseEntry, ok := tx.Entries[tx.InputIDs[0]]
+       if !ok {
+               t.Errorf("entryMap contains nothing for coinbase input")
        }
-}
-
-func sampleTx() *TxData {
-       assetID := bc.ComputeAssetID([]byte{1}, 1, &bc.EmptyStringHash)
-       return &TxData{
-               Version:        1,
-               SerializedSize: 66,
-               Inputs: []*TxInput{
-                       NewSpendInput(nil, testutil.MustDecodeHash("dd385f6fe25d91d8c1bd0fa58951ad56b0c5229dcc01f61d9f9e8b9eb92d3292"), assetID, 1000000000000, 1, []byte{1}),
-                       NewSpendInput(nil, bc.NewHash([32]byte{0x11}), assetID, 1, 1, []byte{2}),
-               },
-               Outputs: []*TxOutput{
-                       NewTxOutput(assetID, 600000000000, []byte{1}),
-                       NewTxOutput(assetID, 400000000000, []byte{2}),
-               },
+       coinbase, ok := coinbaseEntry.(*bc.Coinbase)
+       if !ok {
+               t.Errorf("inputEntry has type %T, expected *Coinbase", coinbaseEntry)
+       }
+       if coinbase.WitnessDestination.Value != mux.Sources[0].Value {
+               t.Errorf("(*Coinbase).Destination is %v, expected %v", coinbase.WitnessDestination.Value, *mux.Sources[0].Value)
        }
 }
index 6c406c5..933cf28 100644 (file)
@@ -11,10 +11,7 @@ import (
        "github.com/bytom/protocol/bc"
 )
 
-const (
-       currentTransactionVersion = 1   // the latest supported tx version.
-       serRequired               = 0x7 // Bit mask accepted serialization flag.
-)
+const serRequired = 0x7 // Bit mask accepted serialization flag.
 
 // Tx holds a transaction along with its hash.
 type Tx struct {
index b73f18d..101c1ac 100644 (file)
@@ -36,7 +36,7 @@ func TestTransaction(t *testing.T) {
                                "00", // inputs count
                                "00", // outputs count
                        }, ""),
-                       hash: testutil.MustDecodeHash("b28048bd60c4c13144fd34f408627d1be68f6cb4fdd34e879d6d791060ea7d60"),
+                       hash: testutil.MustDecodeHash("8e88b9cb4615128c7209dff695f68b8de5b38648bf3d44d2d0e6a674848539c9"),
                },
                {
                        tx: NewTx(TxData{
@@ -101,7 +101,7 @@ func TestTransaction(t *testing.T) {
                                "74727565", // output 0: control program
                                "00",       // output 0: witness length
                        }, ""),
-                       hash: testutil.MustDecodeHash("556bd11337f7a54b8f79c6abf0abcdfdf8c0560ab8f1a1a32bfad73439ba06b3"),
+                       hash: testutil.MustDecodeHash("a0ece5ca48dca27708394852599cb4d04af22c36538c03cb72663f3091406c17"),
                },
                {
                        tx: NewTx(TxData{
@@ -144,7 +144,7 @@ func TestTransaction(t *testing.T) {
                                "66616c7365", // output 1: control program
                                "00",         // output 1: witness length
                        }, ""),
-                       hash: testutil.MustDecodeHash("f9619fba57770ce6d9aaf0e53211cdaef8ced77292acbef21dbc3422515c3f02"),
+                       hash: testutil.MustDecodeHash("c2e2f388706fc06cca6aba5e85e0e85029f772872e1b6e6c32a70da22d0309dc"),
                },
        }
        for i, test := range cases {
index 7c3a33c..7dd1ab7 100644 (file)
@@ -171,10 +171,6 @@ func checkValid(vs *validationState, e bc.Entry) (err error) {
                        if len(e.ResultIds) == 0 {
                                return errEmptyResults
                        }
-
-                       if e.ExtHash != nil && !e.ExtHash.IsZero() {
-                               return errNonemptyExtHash
-                       }
                }
 
        case *bc.Coinbase:
@@ -256,10 +252,6 @@ func checkValid(vs *validationState, e bc.Entry) (err error) {
                        }
                }
 
-               if vs.tx.Version == 1 && e.ExtHash != nil && !e.ExtHash.IsZero() {
-                       return errNonemptyExtHash
-               }
-
                if err := vs.gasStatus.setGasVaild(); err != nil {
                        return err
                }
@@ -273,20 +265,6 @@ func checkValid(vs *validationState, e bc.Entry) (err error) {
                        }
                }
 
-       case *bc.Nonce:
-               //TODO: add block heigh range check on the control program
-               gasLeft, err := vm.Verify(NewTxVMContext(vs, e, e.Program, e.WitnessArguments), vs.gasStatus.GasLeft)
-               if err != nil {
-                       return errors.Wrap(err, "checking nonce program")
-               }
-               if err = vs.gasStatus.updateUsage(gasLeft); err != nil {
-                       return err
-               }
-
-               if vs.tx.Version == 1 && e.ExtHash != nil && !e.ExtHash.IsZero() {
-                       return errNonemptyExtHash
-               }
-
        case *bc.Output:
                vs2 := *vs
                vs2.sourcePos = 0
@@ -295,10 +273,6 @@ func checkValid(vs *validationState, e bc.Entry) (err error) {
                        return errors.Wrap(err, "checking output source")
                }
 
-               if vs.tx.Version == 1 && e.ExtHash != nil && !e.ExtHash.IsZero() {
-                       return errNonemptyExtHash
-               }
-
        case *bc.Retirement:
                vs2 := *vs
                vs2.sourcePos = 0
@@ -307,21 +281,12 @@ func checkValid(vs *validationState, e bc.Entry) (err error) {
                        return errors.Wrap(err, "checking retirement source")
                }
 
-               if vs.tx.Version == 1 && e.ExtHash != nil && !e.ExtHash.IsZero() {
-                       return errNonemptyExtHash
-               }
-
        case *bc.Issuance:
                computedAssetID := e.WitnessAssetDefinition.ComputeAssetID()
                if computedAssetID != *e.Value.AssetId {
                        return errors.WithDetailf(errMismatchedAssetID, "asset ID is %x, issuance wants %x", computedAssetID.Bytes(), e.Value.AssetId.Bytes())
                }
 
-               anchor, ok := vs.tx.Entries[*e.AnchorId]
-               if !ok {
-                       return errors.Wrapf(bc.ErrMissingEntry, "entry for issuance anchor %x not found", e.AnchorId.Bytes())
-               }
-
                gasLeft, err := vm.Verify(NewTxVMContext(vs, e, e.WitnessAssetDefinition.IssuanceProgram, e.WitnessArguments), vs.gasStatus.GasLeft)
                if err != nil {
                        return errors.Wrap(err, "checking issuance program")
@@ -330,32 +295,6 @@ func checkValid(vs *validationState, e bc.Entry) (err error) {
                        return err
                }
 
-               var anchored *bc.Hash
-               switch a := anchor.(type) {
-               case *bc.Nonce:
-                       anchored = a.WitnessAnchoredId
-
-               case *bc.Spend:
-                       anchored = a.WitnessAnchoredId
-
-               case *bc.Issuance:
-                       anchored = a.WitnessAnchoredId
-
-               default:
-                       return errors.WithDetailf(bc.ErrEntryType, "issuance anchor has type %T, should be nonce, spend, or issuance", anchor)
-               }
-
-               if *anchored != vs.entryID {
-                       return errors.WithDetailf(errMismatchedReference, "issuance %x anchor is for %x", vs.entryID.Bytes(), anchored.Bytes())
-               }
-
-               anchorVS := *vs
-               anchorVS.entryID = *e.AnchorId
-               err = checkValid(&anchorVS, anchor)
-               if err != nil {
-                       return errors.Wrap(err, "checking issuance anchor")
-               }
-
                destVS := *vs
                destVS.destPos = 0
                err = checkValidDest(&destVS, e.WitnessDestination)
@@ -363,10 +302,6 @@ func checkValid(vs *validationState, e bc.Entry) (err error) {
                        return errors.Wrap(err, "checking issuance destination")
                }
 
-               if vs.tx.Version == 1 && e.ExtHash != nil && !e.ExtHash.IsZero() {
-                       return errNonemptyExtHash
-               }
-
        case *bc.Spend:
                if e.SpentOutputId == nil {
                        return errors.Wrap(errMissingField, "spend without spent output ID")
@@ -405,10 +340,6 @@ func checkValid(vs *validationState, e bc.Entry) (err error) {
                        return errors.Wrap(err, "checking spend destination")
                }
 
-               if vs.tx.Version == 1 && e.ExtHash != nil && !e.ExtHash.IsZero() {
-                       return errNonemptyExtHash
-               }
-
        default:
                return fmt.Errorf("entry has unexpected type %T", e)
        }
index a5c9030..8a5f80a 100644 (file)
@@ -187,47 +187,6 @@ func TestTxValidation(t *testing.T) {
                        err: errUnbalanced,
                },
                {
-                       desc: "nonempty mux exthash",
-                       f: func() {
-                               mux.ExtHash = newHash(1)
-                       },
-                       err: errNonemptyExtHash,
-               },
-               {
-                       desc: "nonempty mux exthash, but that's OK",
-                       f: func() {
-                               tx.Version = 2
-                               mux.ExtHash = newHash(1)
-                       },
-               },
-               {
-                       desc: "failing nonce program",
-                       f: func() {
-                               iss := txIssuance(t, tx, 0)
-                               nonce := tx.Entries[*iss.AnchorId].(*bc.Nonce)
-                               nonce.Program.Code = []byte{byte(vm.OP_FALSE)}
-                       },
-                       err: vm.ErrFalseVMResult,
-               },
-               {
-                       desc: "nonce exthash nonempty",
-                       f: func() {
-                               iss := txIssuance(t, tx, 0)
-                               nonce := tx.Entries[*iss.AnchorId].(*bc.Nonce)
-                               nonce.ExtHash = newHash(1)
-                       },
-                       err: errNonemptyExtHash,
-               },
-               {
-                       desc: "nonce exthash nonempty, but that's OK",
-                       f: func() {
-                               tx.Version = 2
-                               iss := txIssuance(t, tx, 0)
-                               nonce := tx.Entries[*iss.AnchorId].(*bc.Nonce)
-                               nonce.ExtHash = newHash(1)
-                       },
-               },
-               {
                        desc: "mismatched output source / mux dest position",
                        f: func() {
                                tx.Entries[*tx.ResultIds[0]].(*bc.Output).Source.Position = 1
@@ -271,20 +230,6 @@ func TestTxValidation(t *testing.T) {
                        err: errMismatchedValue,
                },
                {
-                       desc: "output exthash nonempty",
-                       f: func() {
-                               tx.Entries[*tx.ResultIds[0]].(*bc.Output).ExtHash = newHash(1)
-                       },
-                       err: errNonemptyExtHash,
-               },
-               {
-                       desc: "output exthash nonempty, but that's OK",
-                       f: func() {
-                               tx.Version = 2
-                               tx.Entries[*tx.ResultIds[0]].(*bc.Output).ExtHash = newHash(1)
-                       },
-               },
-               {
                        desc: "empty tx results",
                        f: func() {
                                tx.ResultIds = nil
@@ -299,20 +244,6 @@ func TestTxValidation(t *testing.T) {
                        },
                },
                {
-                       desc: "tx header exthash nonempty",
-                       f: func() {
-                               tx.ExtHash = newHash(1)
-                       },
-                       err: errNonemptyExtHash,
-               },
-               {
-                       desc: "tx header exthash nonempty, but that's OK",
-                       f: func() {
-                               tx.Version = 2
-                               tx.ExtHash = newHash(1)
-                       },
-               },
-               {
                        desc: "issuance program failure",
                        f: func() {
                                iss := txIssuance(t, tx, 0)
@@ -321,22 +252,6 @@ func TestTxValidation(t *testing.T) {
                        err: vm.ErrFalseVMResult,
                },
                {
-                       desc: "issuance exthash nonempty",
-                       f: func() {
-                               iss := txIssuance(t, tx, 0)
-                               iss.ExtHash = newHash(1)
-                       },
-                       err: errNonemptyExtHash,
-               },
-               {
-                       desc: "issuance exthash nonempty, but that's OK",
-                       f: func() {
-                               tx.Version = 2
-                               iss := txIssuance(t, tx, 0)
-                               iss.ExtHash = newHash(1)
-                       },
-               },
-               {
                        desc: "spend control program failure",
                        f: func() {
                                spend := txSpend(t, tx, 1)
@@ -356,22 +271,6 @@ func TestTxValidation(t *testing.T) {
                        },
                        err: errMismatchedValue,
                },
-               {
-                       desc: "spend exthash nonempty",
-                       f: func() {
-                               spend := txSpend(t, tx, 1)
-                               spend.ExtHash = newHash(1)
-                       },
-                       err: errNonemptyExtHash,
-               },
-               {
-                       desc: "spend exthash nonempty, but that's OK",
-                       f: func() {
-                               tx.Version = 2
-                               spend := txSpend(t, tx, 1)
-                               spend.ExtHash = newHash(1)
-                       },
-               },
        }
 
        for _, c := range cases {
index e698c30..7404d47 100644 (file)
@@ -21,26 +21,15 @@ func NewTxVMContext(vs *validationState, entry bc.Entry, prog *bc.Program, args
                assetID       *[]byte
                amount        *uint64
                destPos       *uint64
-               anchorID      *[]byte
                spentOutputID *[]byte
        )
 
        switch e := entry.(type) {
-       case *bc.Nonce:
-               anchored := tx.Entries[*e.WitnessAnchoredId]
-               if iss, ok := anchored.(*bc.Issuance); ok {
-                       a1 := iss.Value.AssetId.Bytes()
-                       assetID = &a1
-                       amount = &iss.Value.Amount
-               }
-
        case *bc.Issuance:
                a1 := e.Value.AssetId.Bytes()
                assetID = &a1
                amount = &e.Value.Amount
                destPos = &e.WitnessDestination.Position
-               a2 := e.AnchorId.Bytes()
-               anchorID = &a2
 
        case *bc.Spend:
                spentOutput := tx.Entries[*e.SpentOutputId].(*bc.Output)
@@ -89,7 +78,6 @@ func NewTxVMContext(vs *validationState, entry bc.Entry, prog *bc.Program, args
                AssetID:       assetID,
                Amount:        amount,
                DestPos:       destPos,
-               AnchorID:      anchorID,
                SpentOutputID: spentOutputID,
                CheckOutput:   ec.checkOutput,
        }
index 6053c28..853e91c 100644 (file)
@@ -28,7 +28,6 @@ type Context struct {
        AssetID       *[]byte
        Amount        *uint64
        DestPos       *uint64
-       AnchorID      *[]byte
        SpentOutputID *[]byte
 
        TxSigHash   func() []byte
index 01a2c57..72aaab0 100644 (file)
@@ -112,18 +112,6 @@ func opOutputID(vm *virtualMachine) error {
        return vm.push(*vm.context.SpentOutputID, true)
 }
 
-func opNonce(vm *virtualMachine) error {
-       err := vm.applyCost(1)
-       if err != nil {
-               return err
-       }
-
-       if vm.context.AnchorID == nil {
-               return ErrContext
-       }
-       return vm.push(*vm.context.AnchorID, true)
-}
-
 func opBlockHeight(vm *virtualMachine) error {
        err := vm.applyCost(1)
        if err != nil {
index a510be7..d2a2885 100644 (file)
@@ -12,7 +12,6 @@ import (
 func TestOutputIDAndNonceOp(t *testing.T) {
        // arbitrary
        outputID := mustDecodeHex("0a60f9b12950c84c221012a808ef7782823b7e16b71fe2ba01811cda96a217df")
-       nonceID := mustDecodeHex("c4a6e6256debfca379595e444b91af56846397e8007ea87c40c622170dd13ff7")
 
        prog := []byte{uint8(OP_OUTPUTID)}
        vm := &virtualMachine{
@@ -41,34 +40,6 @@ func TestOutputIDAndNonceOp(t *testing.T) {
        if err != ErrContext {
                t.Errorf("expected ErrContext, got %v", err)
        }
-
-       prog = []byte{uint8(OP_NONCE)}
-       vm = &virtualMachine{
-               runLimit: 50000,
-               program:  prog,
-               context:  &Context{AnchorID: nil},
-       }
-       err = vm.step()
-       if err != ErrContext {
-               t.Errorf("expected ErrContext, got %v", err)
-       }
-
-       prog = []byte{uint8(OP_NONCE)}
-       vm = &virtualMachine{
-               runLimit: 50000,
-               program:  prog,
-               context:  &Context{AnchorID: &nonceID},
-       }
-       err = vm.step()
-       if err != nil {
-               t.Fatal(err)
-       }
-       gotVM = vm
-
-       expectedStack = [][]byte{nonceID}
-       if !testutil.DeepEqual(gotVM.dataStack, expectedStack) {
-               t.Errorf("expected stack %v, got %v", expectedStack, gotVM.dataStack)
-       }
 }
 
 func TestBlockHeight(t *testing.T) {
index dd9ef81..ef4c567 100644 (file)
@@ -208,7 +208,6 @@ const (
        OP_INDEX       Op = 0xc9
        OP_ENTRYID     Op = 0xca
        OP_OUTPUTID    Op = 0xcb
-       OP_NONCE       Op = 0xcc
        OP_BLOCKHEIGHT Op = 0xcd
 )
 
@@ -315,7 +314,6 @@ var (
                OP_INDEX:       {OP_INDEX, "INDEX", opIndex},
                OP_ENTRYID:     {OP_ENTRYID, "ENTRYID", opEntryID},
                OP_OUTPUTID:    {OP_OUTPUTID, "OUTPUTID", opOutputID},
-               OP_NONCE:       {OP_NONCE, "NONCE", opNonce},
                OP_BLOCKHEIGHT: {OP_BLOCKHEIGHT, "BLOCKHEIGHT", opBlockHeight},
        }