continue
}
- if block.Witness[node.Order] == nil {
+ if block.Get(node.Order) == nil {
cachekey := signCacheKey(blockHash.String(), pubKey)
if signature, ok := c.signatureCache.Get(cachekey); ok {
- block.Witness[node.Order] = signature.([]byte)
+ block.Set(node.Order, signature.([]byte))
} else {
continue
}
}
- if err := c.checkNodeSign(&block.BlockHeader, node, block.Witness[node.Order]); err == errDoubleSignBlock {
+ if err := c.checkNodeSign(&block.BlockHeader, node, block.Get(node.Order)); err == errDoubleSignBlock {
log.WithFields(log.Fields{"module": logModule, "blockHash": blockHash.String(), "pubKey": pubKey}).Warn("the consensus node double sign the same height of different block")
- block.Witness[node.Order] = nil
+ block.Delete(node.Order)
continue
} else if err != nil {
return err
}
}
- signature := block.Witness[node.Order]
+ signature := block.Get(node.Order)
if len(signature) == 0 {
signature = xprv.Sign(block.Hash().Bytes())
- block.Witness[node.Order] = signature
+ block.Set(node.Order, signature)
}
return signature, nil
}
return err
}
- block.Witness[nodeOrder] = signature
+ block.Set(nodeOrder, signature)
+
txStatus, err := c.store.GetTransactionStatus(&blockNode.Hash)
if err != nil {
return err
bw.Witness, err = blockchain.ReadVarstrList(r)
return err
}
+
+func (bw *BlockWitness) Set(index uint64, data []byte) {
+ if uint64(len(bw.Witness)) <= index {
+ newWitness := make([][]byte, index+1, index+1)
+ copy(newWitness, bw.Witness)
+ bw.Witness = newWitness
+ }
+ bw.Witness[index] = data
+}
+
+func (bw *BlockWitness) Delete(index uint64) {
+ if uint64(len(bw.Witness)) > index {
+ bw.Witness[index] = nil
+ }
+}
+
+func (bw *BlockWitness) Get(index uint64) []byte {
+ if uint64(len(bw.Witness)) > index {
+ return bw.Witness[index]
+ }
+ return nil
+}
}
}
}
+
+func TestBlockWitnessSet(t *testing.T) {
+ cases := []struct {
+ bw BlockWitness
+ index uint64
+ data []byte
+ want BlockWitness
+ }{
+ {
+ bw: BlockWitness{Witness: [][]byte{}},
+ index: uint64(0),
+ data: []byte{0x01, 0x02, 0x03, 0x04},
+ want: BlockWitness{Witness: [][]byte{[]byte{0x01, 0x02, 0x03, 0x04}}},
+ },
+ {
+ bw: BlockWitness{Witness: [][]byte{[]byte{0x01, 0x02, 0x03, 0x04}}},
+ index: uint64(1),
+ data: []byte{0x01, 0x01, 0x01, 0x01},
+ want: BlockWitness{Witness: [][]byte{[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x01, 0x01, 0x01}}},
+ },
+ {
+ bw: BlockWitness{Witness: [][]byte{[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}}},
+ index: uint64(4),
+ data: []byte{0x04, 0x04, 0x04, 0x04},
+ want: BlockWitness{Witness: [][]byte{[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, []byte{}, []byte{}, []byte{0x04, 0x04, 0x04, 0x04}}},
+ },
+ }
+
+ for i, c := range cases {
+ newbw := c.bw
+ newbw.Set(c.index, c.data)
+ if !testutil.DeepEqual(c.want, newbw) {
+ t.Errorf("update result mismatch: %v, got:%v, want:%v", i, newbw, c.want)
+ }
+ }
+}
+
+func TestBlockWitnessDelete(t *testing.T) {
+ cases := []struct {
+ bw BlockWitness
+ index uint64
+ want BlockWitness
+ }{
+ {
+ bw: BlockWitness{Witness: [][]byte{}},
+ index: uint64(0),
+ want: BlockWitness{Witness: [][]byte{}},
+ },
+ {
+ bw: BlockWitness{Witness: [][]byte{[]byte{0x01, 0x02, 0x03, 0x04}}},
+ index: uint64(0),
+ want: BlockWitness{Witness: [][]byte{[]byte{}}},
+ },
+ {
+ bw: BlockWitness{Witness: [][]byte{[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}}},
+ index: uint64(1),
+ want: BlockWitness{Witness: [][]byte{[]byte{0x01, 0x02, 0x03, 0x04}, []byte{}}},
+ },
+ {
+ bw: BlockWitness{Witness: [][]byte{[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}}},
+ index: uint64(100),
+ want: BlockWitness{Witness: [][]byte{[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}}},
+ },
+ }
+
+ for i, c := range cases {
+ newbw := c.bw
+ newbw.Delete(c.index)
+ if !testutil.DeepEqual(c.want, newbw) {
+ t.Errorf("update result mismatch: %v, got:%v, want:%v", i, newbw, c.want)
+ }
+ }
+}