mirror of
https://github.com/tendermint/tendermint.git
synced 2026-09-19 06:31:57 +00:00
draft of consensus+state code, compiles.
This commit is contained in:
@@ -1,63 +0,0 @@
|
||||
package blocks
|
||||
|
||||
import (
|
||||
. "github.com/tendermint/tendermint/binary"
|
||||
"io"
|
||||
)
|
||||
|
||||
// NOTE: consensus/Validator embeds this, so..
|
||||
type Account struct {
|
||||
Id uint64 // Numeric id of account, incrementing.
|
||||
PubKey []byte
|
||||
}
|
||||
|
||||
func (self *Account) Verify(msg []byte, sig []byte) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
type PrivAccount struct {
|
||||
Account
|
||||
PrivKey []byte
|
||||
}
|
||||
|
||||
func (self *PrivAccount) Sign(msg []byte) Signature {
|
||||
return Signature{}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Signature message wire format:
|
||||
|
||||
|A...|SSS...|
|
||||
|
||||
A account number, varint encoded (1+ bytes)
|
||||
S signature of all prior bytes (32 bytes)
|
||||
|
||||
It usually follows the message to be signed.
|
||||
|
||||
*/
|
||||
|
||||
type Signature struct {
|
||||
SignerId uint64
|
||||
Bytes []byte
|
||||
}
|
||||
|
||||
func ReadSignature(r io.Reader, n *int64, err *error) Signature {
|
||||
return Signature{
|
||||
SignerId: ReadUInt64(r, n, err),
|
||||
Bytes: ReadByteSlice(r, n, err),
|
||||
}
|
||||
}
|
||||
|
||||
func (sig Signature) IsZero() bool {
|
||||
return len(sig.Bytes) == 0
|
||||
}
|
||||
|
||||
func (sig Signature) WriteTo(w io.Writer) (n int64, err error) {
|
||||
WriteUInt64(w, sig.SignerId, &n, &err)
|
||||
WriteByteSlice(w, sig.Bytes, &n, &err)
|
||||
return
|
||||
}
|
||||
@@ -155,21 +155,6 @@ func (bp *BlockPart) BlockPartHash() []byte {
|
||||
}
|
||||
}
|
||||
|
||||
// Signs the URI, which includes all data and metadata.
|
||||
// XXX implement or change
|
||||
func (bp *BlockPart) Sign(acc *PrivAccount) {
|
||||
// TODO: populate Signature
|
||||
}
|
||||
|
||||
// XXX maybe change.
|
||||
func (bp *BlockPart) ValidateWithSigner(signer *Account) error {
|
||||
// TODO: Sanity check height, index, total, bytes, etc.
|
||||
if !signer.Verify([]byte(bp.URI()), bp.Signature.Bytes) {
|
||||
return ErrInvalidBlockPartSignature
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/* Header is part of a Block */
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
package blocks
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Helper for keeping track of block parts.
|
||||
type BlockPartSet struct {
|
||||
mtx sync.Mutex
|
||||
signer *Account
|
||||
height uint32
|
||||
round uint16 // Not used
|
||||
total uint16
|
||||
numParts uint16
|
||||
parts []*BlockPart
|
||||
|
||||
_block *Block // cache
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidBlockPartSignature = errors.New("Invalid block part signature") // Peer gave us a fake part
|
||||
ErrInvalidBlockPartConflict = errors.New("Invalid block part conflict") // Signer signed conflicting parts
|
||||
)
|
||||
|
||||
// Signer may be nil if signer is unknown beforehand.
|
||||
func NewBlockPartSet(height uint32, round uint16, signer *Account) *BlockPartSet {
|
||||
return &BlockPartSet{
|
||||
signer: signer,
|
||||
height: height,
|
||||
round: round,
|
||||
}
|
||||
}
|
||||
|
||||
// In the case where the signer wasn't known prior to NewBlockPartSet(),
|
||||
// user should call SetSigner() prior to AddBlockPart().
|
||||
func (bps *BlockPartSet) SetSigner(signer *Account) {
|
||||
bps.mtx.Lock()
|
||||
defer bps.mtx.Unlock()
|
||||
if bps.signer != nil {
|
||||
panic("BlockPartSet signer already set.")
|
||||
}
|
||||
bps.signer = signer
|
||||
}
|
||||
|
||||
func (bps *BlockPartSet) BlockParts() []*BlockPart {
|
||||
bps.mtx.Lock()
|
||||
defer bps.mtx.Unlock()
|
||||
return bps.parts
|
||||
}
|
||||
|
||||
func (bps *BlockPartSet) BitArray() []byte {
|
||||
bps.mtx.Lock()
|
||||
defer bps.mtx.Unlock()
|
||||
if bps.parts == nil {
|
||||
return nil
|
||||
}
|
||||
bitArray := make([]byte, (len(bps.parts)+7)/8)
|
||||
for i, part := range bps.parts {
|
||||
if part != nil {
|
||||
bitArray[i/8] |= 1 << uint(i%8)
|
||||
}
|
||||
}
|
||||
return bitArray
|
||||
}
|
||||
|
||||
// If the part isn't valid, returns an error.
|
||||
// err can be ErrInvalidBlockPart[Conflict|Signature]
|
||||
func (bps *BlockPartSet) AddBlockPart(part *BlockPart) (added bool, err error) {
|
||||
bps.mtx.Lock()
|
||||
defer bps.mtx.Unlock()
|
||||
|
||||
// If part is invalid, return an error.
|
||||
err = part.ValidateWithSigner(bps.signer)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if bps.parts == nil {
|
||||
// First received part for this round.
|
||||
bps.parts = make([]*BlockPart, part.Total)
|
||||
bps.total = uint16(part.Total)
|
||||
bps.parts[int(part.Index)] = part
|
||||
bps.numParts++
|
||||
return true, nil
|
||||
} else {
|
||||
// Check part.Index and part.Total
|
||||
if uint16(part.Index) >= bps.total {
|
||||
return false, ErrInvalidBlockPartConflict
|
||||
}
|
||||
if uint16(part.Total) != bps.total {
|
||||
return false, ErrInvalidBlockPartConflict
|
||||
}
|
||||
// Check for existing parts.
|
||||
existing := bps.parts[part.Index]
|
||||
if existing != nil {
|
||||
if bytes.Equal(existing.Bytes, part.Bytes) {
|
||||
// Ignore duplicate
|
||||
return false, nil
|
||||
} else {
|
||||
return false, ErrInvalidBlockPartConflict
|
||||
}
|
||||
} else {
|
||||
bps.parts[int(part.Index)] = part
|
||||
bps.numParts++
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (bps *BlockPartSet) IsComplete() bool {
|
||||
bps.mtx.Lock()
|
||||
defer bps.mtx.Unlock()
|
||||
return bps.total > 0 && bps.total == bps.numParts
|
||||
}
|
||||
|
||||
func (bps *BlockPartSet) Block() *Block {
|
||||
if !bps.IsComplete() {
|
||||
return nil
|
||||
}
|
||||
bps.mtx.Lock()
|
||||
defer bps.mtx.Unlock()
|
||||
if bps._block == nil {
|
||||
blockBytes := []byte{}
|
||||
for _, part := range bps.parts {
|
||||
blockBytes = append(blockBytes, part.Bytes...)
|
||||
}
|
||||
var n int64
|
||||
var err error
|
||||
block := ReadBlock(bytes.NewReader(blockBytes), &n, &err)
|
||||
bps._block = block
|
||||
}
|
||||
return bps._block
|
||||
}
|
||||
@@ -33,13 +33,6 @@ func randTime() time.Time {
|
||||
return time.Unix(int64(randUInt64()), 0)
|
||||
}
|
||||
|
||||
func randAccount() Account {
|
||||
return Account{
|
||||
Id: randUInt64(),
|
||||
PubKey: randBytes(32),
|
||||
}
|
||||
}
|
||||
|
||||
func randBytes(n int) []byte {
|
||||
bs := make([]byte, n)
|
||||
for i := 0; i < n; i++ {
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package blocks
|
||||
|
||||
import (
|
||||
. "github.com/tendermint/tendermint/binary"
|
||||
"io"
|
||||
)
|
||||
|
||||
/*
|
||||
Signature message wire format:
|
||||
|
||||
|a...|sss...|
|
||||
|
||||
a Account number, varint encoded (1+ bytes)
|
||||
s Signature of all prior bytes (32 bytes)
|
||||
|
||||
It usually follows the message to be signed.
|
||||
|
||||
*/
|
||||
|
||||
type Signature struct {
|
||||
SignerId uint64
|
||||
Bytes []byte
|
||||
}
|
||||
|
||||
func ReadSignature(r io.Reader, n *int64, err *error) Signature {
|
||||
return Signature{
|
||||
SignerId: ReadUInt64(r, n, err),
|
||||
Bytes: ReadByteSlice(r, n, err),
|
||||
}
|
||||
}
|
||||
|
||||
func (sig Signature) IsZero() bool {
|
||||
return len(sig.Bytes) == 0
|
||||
}
|
||||
|
||||
func (sig Signature) WriteTo(w io.Writer) (n int64, err error) {
|
||||
WriteUInt64(w, sig.SignerId, &n, &err)
|
||||
WriteByteSlice(w, sig.Bytes, &n, &err)
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user