OSDN Git Service

bc level ice lock
authorColt <colt@ColtdeMBP.lan>
Thu, 24 Aug 2017 08:10:24 +0000 (16:10 +0800)
committerColt <colt@ColtdeMBP.lan>
Thu, 24 Aug 2017 08:10:24 +0000 (16:10 +0800)
protocol/bc/legacy/block_header.go
protocol/bc/legacy/block_test.go
protocol/bc/legacy/map.go
protocol/bc/legacy/map_test.go
protocol/bc/legacy/transaction.go
protocol/bc/legacy/transaction_test.go

index e4b3642..f2efe0a 100644 (file)
@@ -127,6 +127,11 @@ func (bh *BlockHeader) readFrom(r *blockchain.Reader) (uint8, error) {
                return 0, err
        }
 
+       _, err = blockchain.ReadExtensibleString(r, bh.BlockCommitment.readFrom)
+       if err != nil {
+               return 0, err
+       }
+
        bh.Nonce, err = blockchain.ReadVarint63(r)
        if err != nil {
                return 0, err
@@ -168,6 +173,10 @@ func (bh *BlockHeader) writeTo(w io.Writer, serflags uint8) error {
        if err != nil {
                return err
        }
+       _, err = blockchain.WriteExtensibleString(w, nil, bh.BlockCommitment.writeTo)
+       if err != nil {
+               return err
+       }
        _, err = blockchain.WriteVarint63(w, bh.Nonce)
        if err != nil {
                return err
index 23fe780..6ae5bec 100644 (file)
@@ -41,12 +41,12 @@ func TestMarshalBlock(t *testing.T) {
                "01" + // block height
                "0000000000000000000000000000000000000000000000000000000000000000" + // prev block hash
                "00" + // timestamp
-               "41" + // commitment extensible field length
+               "40" + // commitment extensible field length
                "0000000000000000000000000000000000000000000000000000000000000000" + // tx merkle root
                "0000000000000000000000000000000000000000000000000000000000000000" + // assets merkle root
-               "00" + // consensus program
-               "01" + // witness extensible string length
-               "00" + // witness number of witness args
+               "00" + // nonce
+               "00" + // bits
+
                "01" + // num transactions
                "07" + // tx 0, serialization flags
                "01" + // tx 0, tx version
@@ -101,12 +101,11 @@ func TestEmptyBlock(t *testing.T) {
                "01" + // block height
                "0000000000000000000000000000000000000000000000000000000000000000" + // prev block hash
                "00" + // timestamp
-               "41" + // commitment extensible field length
+               "40" + // commitment extensible field length
                "0000000000000000000000000000000000000000000000000000000000000000" + // transactions merkle root
                "0000000000000000000000000000000000000000000000000000000000000000" + // assets merkle root
-               "00" + // consensus program
-               "01" + // witness extensible string length
-               "00" + // witness number of witness args
+               "00" + // nonce
+               "00" + // bits
                "00") // num transactions
        want, _ := hex.DecodeString(wantHex)
        if !bytes.Equal(got, want) {
@@ -119,18 +118,17 @@ func TestEmptyBlock(t *testing.T) {
                "01" + // block height
                "0000000000000000000000000000000000000000000000000000000000000000" + // prev block hash
                "00" + // timestamp
-               "41" + // commitment extensible field length
+               "40" + // commitment extensible field length
                "0000000000000000000000000000000000000000000000000000000000000000" + // transactions merkle root
                "0000000000000000000000000000000000000000000000000000000000000000" + // assets merkle root
-               "00" + // consensus program
-               "01" + // witness extensible string length
-               "00") // witness number of witness args
+               "00" + // nonce
+               "00") // bits
        want, _ = hex.DecodeString(wantHex)
        if !bytes.Equal(got, want) {
                t.Errorf("empty block header bytes = %x want %x", got, want)
        }
 
-       wantHash := mustDecodeHash("6a73cbca99e33c8403d589664623c74df34dd6d7328ab6e7f27dd3e60d959850")
+       wantHash := mustDecodeHash("f2e8d5be16096e275a51866eb5207b385c9aa02ec570a1540f445efcba05e04d")
        if h := block.Hash(); h != wantHash {
                t.Errorf("got block hash %x, want %x", h.Bytes(), wantHash.Bytes())
        }
@@ -156,12 +154,11 @@ func TestSmallBlock(t *testing.T) {
                "01" + // block height
                "0000000000000000000000000000000000000000000000000000000000000000" + // prev block hash
                "00" + // timestamp
-               "41" + // commitment extensible field length
+               "40" + // commitment extensible field length
                "0000000000000000000000000000000000000000000000000000000000000000" + // transactions merkle root
                "0000000000000000000000000000000000000000000000000000000000000000" + // assets merkle root
-               "00" + // consensus program
-               "01" + // witness extensible string length
-               "00" + // witness num witness args
+               "00" + // nonce
+               "00" + // bits
                "01" + // num transactions
                "070102000000000000") // transaction
        want, _ := hex.DecodeString(wantHex)
index c25cb77..85b5fd7 100644 (file)
@@ -161,15 +161,15 @@ func mapTx(tx *TxData) (headerID bc.Hash, hdr *bc.TxHeader, entryMap map[bc.Hash
                }
        }
 
-       if len(tx.Inputs) == 0 && len(tx.Outputs) == 1 {
+       if tx.IsCoinbase() {
                cb := bc.NewCoinbase()
                cbId := addEntry(cb)
 
                out := tx.Outputs[0]
-               muxSources[0] = &bc.ValueSource{
+               muxSources = []*bc.ValueSource{{
                        Ref:   &cbId,
                        Value: &out.AssetAmount,
-               }
+               }}
        }
 
        mux := bc.NewMux(muxSources, &bc.Program{VmVersion: 1, Code: []byte{byte(vm.OP_TRUE)}})
@@ -183,10 +183,10 @@ func mapTx(tx *TxData) (headerID bc.Hash, hdr *bc.TxHeader, entryMap map[bc.Hash
                iss.SetDestination(&muxID, iss.Value, iss.Ordinal)
        }
 
-       if len(tx.Inputs) == 0 && len(tx.Outputs) == 1 {
-               cbId := muxSources[0].Ref
-               cb := entryMap[*cbId].(*bc.Coinbase)
-               cb.SetDestination(&muxID, muxSources[0].Value, 0)
+       if tx.IsCoinbase() {
+               muxSource := mux.Sources[0]
+               cb := entryMap[*muxSource.Ref].(*bc.Coinbase)
+               cb.SetDestination(&muxID, muxSource.Value, 0)
        }
 
        var resultIDs []*bc.Hash
index 9ea0d5a..123113f 100644 (file)
@@ -7,6 +7,7 @@ import (
        "github.com/davecgh/go-spew/spew"
 
        "github.com/bytom/protocol/bc"
+       "github.com/bytom/protocol/validation"
 )
 
 func TestMapTx(t *testing.T) {
@@ -59,3 +60,59 @@ func TestMapTx(t *testing.T) {
                }
        }
 }
+
+func TestMapCoinbaseTx(t *testing.T) {
+       oldTx := &TxData{
+               Version: 1,
+               Inputs:  []*TxInput{},
+               Outputs: []*TxOutput{
+                       NewTxOutput(*validation.BTMAssetID, 800000000000, []byte{1}, nil),
+               },
+       }
+       oldOut := oldTx.Outputs[0]
+
+       _, header, entryMap := mapTx(oldTx)
+       t.Log(spew.Sdump(entryMap))
+
+       outEntry, ok := entryMap[*header.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]
+       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 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")
+       }
+}
index 1e98bce..5c48030 100644 (file)
@@ -107,6 +107,11 @@ func (tx *TxData) HasIssuance() bool {
        return false
 }
 
+// IsCoinbase returns true if this transaction is coinbase transaction.
+func (tx *TxData) IsCoinbase() bool {
+       return len(tx.Inputs) == 0 && len(tx.Outputs) == 1
+}
+
 func (tx *TxData) UnmarshalText(p []byte) error {
        b := make([]byte, hex.DecodedLen(len(p)))
        _, err := hex.Decode(b, p)
index cfc4ee3..d202346 100644 (file)
@@ -111,7 +111,7 @@ func TestTransaction(t *testing.T) {
                                "066f7574707574" + // output 0, reference data
                                "00" + // output 0, output witness
                                "0869737375616e6365"), // reference data
-                       hash: mustDecodeHash("cd4669d5363374f8661621273501c23e613fc98b0fab9d5d858f30e16ccd24ce"),
+                       hash: mustDecodeHash("515774561625cfe07629e49d4cf938d641aeb62af58e1b3ae2c582fee41dc628"),
                },
                {
                        tx: NewTx(TxData{
@@ -278,6 +278,43 @@ func TestHasIssuance(t *testing.T) {
        }
 }
 
+func TestIsCoinbase(t *testing.T) {
+       cases := []struct {
+               tx   *TxData
+               want bool
+       }{{
+               tx: &TxData{
+                       Inputs: []*TxInput{NewIssuanceInput(nil, 0, nil, bc.Hash{}, nil, nil, nil)},
+               },
+               want: false,
+       }, {
+               tx: &TxData{
+                       Inputs: []*TxInput{
+                               NewSpendInput(nil, bc.Hash{}, bc.AssetID{}, 0, 0, nil, bc.Hash{}, nil),
+                               NewIssuanceInput(nil, 0, nil, bc.Hash{}, nil, nil, nil),
+                       },
+                       Outputs: []*TxOutput{
+                               NewTxOutput(bc.AssetID{}, 0, nil, nil),
+                       },
+               },
+               want: false,
+       }, {
+               tx: &TxData{
+                       Outputs: []*TxOutput{
+                               NewTxOutput(bc.AssetID{}, 0, nil, nil),
+                       },
+               },
+               want: true,
+       }}
+
+       for _, c := range cases {
+               got := c.tx.IsCoinbase()
+               if got != c.want {
+                       t.Errorf("IsCoinbase(%+v) = %v want %v", c.tx, got, c.want)
+               }
+       }
+}
+
 func TestInvalidIssuance(t *testing.T) {
        hex := ("07" + // serflags
                "01" + // transaction version