From 576d8815fe4accf8574fa16f35df50472b75b556 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Wed, 4 Jun 2014 01:40:17 -0700 Subject: [PATCH] draft of blocks package --- blocks/block.go | 35 +++++++ blocks/data.go | 244 +++++++++++++++++++++++++++++++++++++++++++ blocks/data_test.go | 29 +++++ blocks/signature.go | 113 ++++++++++++++++++++ blocks/validation.go | 78 ++++++++++++++ 5 files changed, 499 insertions(+) create mode 100644 blocks/block.go create mode 100644 blocks/data.go create mode 100644 blocks/data_test.go create mode 100644 blocks/signature.go create mode 100644 blocks/validation.go diff --git a/blocks/block.go b/blocks/block.go new file mode 100644 index 000000000..27e0a908e --- /dev/null +++ b/blocks/block.go @@ -0,0 +1,35 @@ +package blocks + +import ( + "io" +) + +// BlockHeader + +type BlockHeader struct { + Name string + Height uint64 + Version uint8 + Fees uint64 + Time uint64 + PrevBlockHash []byte + ValidationHash []byte + DataHash []byte +} + +func (self *BlockHeader) WriteTo(w io.Writer) (n int64, err error) { + return 0, nil +} + +// Block + +type Block struct { + Header *BlockHeader + Validation *BlockValidation + Data *BlockData + //Checkpoint *BlockCheckpoint +} + +func (self *Block) Validate() bool { + return false +} diff --git a/blocks/data.go b/blocks/data.go new file mode 100644 index 000000000..ba5f50efc --- /dev/null +++ b/blocks/data.go @@ -0,0 +1,244 @@ +package blocks + +import ( + . "github.com/tendermint/tendermint/binary" + "github.com/tendermint/tendermint/merkle" + "io" +) + +/* BlockData */ + +type BlockData struct { + Txs []Tx +} + +func (self *BlockData) WriteTo(w io.Writer) (n int64, err error) { + var n_ int64 + for _, tx := range self.Txs { + n_, err = tx.WriteTo(w) + n += n_ + if err != nil { return } + } + return +} + +func (self *BlockData) Hash() ByteSlice { + bs := make([]Binary, 0, len(self.Txs)) + for i, tx := range self.Txs { + bs[i] = Binary(tx) + } + return merkle.HashFromBinarySlice(bs) +} + +func (self *BlockData) AddTx(tx Tx) { + self.Txs = append(self.Txs, tx) +} + +func NewBlockData() *BlockData { + return &BlockData{} +} + +/* + +Tx wire format: + + |T|L...|MMM...|A...|SSS...| + + T type of the tx (1 byte) + L length of M, varint encoded (1+ bytes) + M Tx bytes (L bytes) + A account number, varint encoded (1+ bytes) + S signature of all prior bytes (32 bytes) + +*/ + +type Tx interface { + Binary + Type() Byte +} + +const ( + TX_TYPE_SEND = Byte(0x00) + TX_TYPE_BOND = Byte(0x11) + TX_TYPE_UNBOND = Byte(0x12) + TX_TYPE_NAME = Byte(0x20) +) + +/* SendTx < Tx */ + +type SendTx struct { + Signature + Fee UInt64 + To AccountId + Amount UInt64 +} + +func (self *SendTx) Type() Byte { + return TX_TYPE_SEND +} + +func (self *SendTx) ByteSize() int { + return 1 + + self.Signature.ByteSize() + + self.Fee.ByteSize() + + self.To.ByteSize() + + self.Amount.ByteSize() +} + +func (self *SendTx) Equals(other Binary) bool { + if o, ok := other.(*SendTx); ok { + return self.Signature.Equals(&o.Signature) && + self.Fee.Equals(o.Fee) && + self.To.Equals(o.To) && + self.Amount.Equals(o.Amount) + } else { + return false + } +} + +func (self *SendTx) WriteTo(w io.Writer) (n int64, err error) { + var n_ int64 + n_, err = self.Type().WriteTo(w) + n += n_; if err != nil { return n, err } + n_, err = self.Signature.WriteTo(w) + n += n_; if err != nil { return n, err } + n_, err = self.Fee.WriteTo(w) + n += n_; if err != nil { return n, err } + n_, err = self.To.WriteTo(w) + n += n_; if err != nil { return n, err } + n_, err = self.Amount.WriteTo(w) + n += n_; return +} + +/* BondTx < Tx */ + +type BondTx struct { + Signature + Fee UInt64 + UnbondTo AccountId + Amount UInt64 +} + +func (self *BondTx) Type() Byte { + return TX_TYPE_BOND +} + +func (self *BondTx) ByteSize() int { + return 1 + + self.Signature.ByteSize() + + self.Fee.ByteSize() + + self.UnbondTo.ByteSize() + + self.Amount.ByteSize() +} + +func (self *BondTx) Equals(other Binary) bool { + if o, ok := other.(*BondTx); ok { + return self.Signature.Equals(&o.Signature) && + self.Fee.Equals(o.Fee) && + self.UnbondTo.Equals(o.UnbondTo) && + self.Amount.Equals(o.Amount) + } else { + return false + } +} + +func (self *BondTx) WriteTo(w io.Writer) (n int64, err error) { + var n_ int64 + n_, err = self.Type().WriteTo(w) + n += n_; if err != nil { return n, err } + n_, err = self.Signature.WriteTo(w) + n += n_; if err != nil { return n, err } + n_, err = self.Fee.WriteTo(w) + n += n_; if err != nil { return n, err } + n_, err = self.UnbondTo.WriteTo(w) + n += n_; if err != nil { return n, err } + n_, err = self.Amount.WriteTo(w) + n += n_; return +} + +/* UnbondTx < Tx */ + +type UnbondTx struct { + Signature + Fee UInt64 + Amount UInt64 +} + +func (self *UnbondTx) Type() Byte { + return TX_TYPE_UNBOND +} + +func (self *UnbondTx) ByteSize() int { + return 1 + + self.Signature.ByteSize() + + self.Fee.ByteSize() + + self.Amount.ByteSize() +} + +func (self *UnbondTx) Equals(other Binary) bool { + if o, ok := other.(*UnbondTx); ok { + return self.Signature.Equals(&o.Signature) && + self.Fee.Equals(o.Fee) && + self.Amount.Equals(o.Amount) + } else { + return false + } +} + +func (self *UnbondTx) WriteTo(w io.Writer) (n int64, err error) { + var n_ int64 + n_, err = self.Type().WriteTo(w) + n += n_; if err != nil { return n, err } + n_, err = self.Signature.WriteTo(w) + n += n_; if err != nil { return n, err } + n_, err = self.Fee.WriteTo(w) + n += n_; if err != nil { return n, err } + n_, err = self.Amount.WriteTo(w) + n += n_; return +} + +/* NameTx < Tx */ + +type NameTx struct { + Signature + Fee UInt64 + Name String + PubKey ByteSlice +} + +func (self *NameTx) Type() Byte { + return TX_TYPE_NAME +} + +func (self *NameTx) ByteSize() int { + return 1 + + self.Signature.ByteSize() + + self.Fee.ByteSize() + + self.Name.ByteSize() + + self.PubKey.ByteSize() +} + +func (self *NameTx) Equals(other Binary) bool { + if o, ok := other.(*NameTx); ok { + return self.Signature.Equals(&o.Signature) && + self.Fee.Equals(o.Fee) && + self.Name.Equals(o.Name) && + self.PubKey.Equals(o.PubKey) + } else { + return false + } +} + +func (self *NameTx) WriteTo(w io.Writer) (n int64, err error) { + var n_ int64 + n_, err = self.Type().WriteTo(w) + n += n_; if err != nil { return n, err } + n_, err = self.Signature.WriteTo(w) + n += n_; if err != nil { return n, err } + n_, err = self.Fee.WriteTo(w) + n += n_; if err != nil { return n, err } + n_, err = self.Name.WriteTo(w) + n += n_; if err != nil { return n, err } + n_, err = self.PubKey.WriteTo(w) + n += n_; return +} diff --git a/blocks/data_test.go b/blocks/data_test.go new file mode 100644 index 000000000..afe0fcc0f --- /dev/null +++ b/blocks/data_test.go @@ -0,0 +1,29 @@ +package blocks + +import ( + . "github.com/tendermint/tendermint/binary" + "testing" + "bytes" + "fmt" +) + +func TestBlockData(t *testing.T) { + var bd = NewBlockData() + var tx Tx + + tx = &SendTx{ + Signature: Signature{AccountNumber(0), ByteSlice([]byte{7})}, + Fee: 1, + To: AccountNumber(2), + Amount: 3, + } + + bd.AddTx(tx) + + + buf := bytes.NewBuffer(nil) + bd.WriteTo(buf) + + fmt.Println(len(buf.Bytes())) + +} diff --git a/blocks/signature.go b/blocks/signature.go new file mode 100644 index 000000000..ed87b4c75 --- /dev/null +++ b/blocks/signature.go @@ -0,0 +1,113 @@ +package blocks + +import ( + . "github.com/tendermint/tendermint/binary" + "io" +) + +type AccountId interface { + Binary + Type() Byte +} + +const ( + ACCOUNT_TYPE_NUMBER = Byte(0x00) + ACCOUNT_TYPE_PUBKEY = Byte(0x01) +) + +/* AccountNumber < AccountId */ + +type AccountNumber uint64 + +func (self AccountNumber) Type() Byte { + return ACCOUNT_TYPE_NUMBER +} + +func (self AccountNumber) Equals(o Binary) bool { + return self == o +} + +func (self AccountNumber) ByteSize() int { + return 1 + 8 +} + +func (self AccountNumber) WriteTo(w io.Writer) (n int64, err error) { + var n_ int64 + n_, err = self.Type().WriteTo(w) + n += n_; if err != nil { return n, err } + n_, err = UInt64(self).WriteTo(w) + n += n_; return +} + +/* AccountPubKey < AccountId */ + +type AccountPubKey []byte + +func (self AccountPubKey) Type() Byte { + return ACCOUNT_TYPE_PUBKEY +} + +func (self AccountPubKey) Equals(o Binary) bool { + return ByteSlice(self).Equals(o) +} + +func (self AccountPubKey) ByteSize() int { + return 1 + ByteSlice(self).ByteSize() +} + +func (self AccountPubKey) WriteTo(w io.Writer) (n int64, err error) { + var n_ int64 + n_, err = self.Type().WriteTo(w) + n += n_; if err != nil { return n, err } + n_, err = ByteSlice(self).WriteTo(w) + n += n_; return +} + +/* + +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 { + Signer AccountId + SigBytes ByteSlice +} + +func (self *Signature) Equals(other Binary) bool { + if o, ok := other.(*Signature); ok { + return self.Signer.Equals(o.Signer) && + self.SigBytes.Equals(o.SigBytes) + } else { + return false + } +} + +func (self *Signature) ByteSize() int { + return self.Signer.ByteSize() + + self.SigBytes.ByteSize() +} + +func (self *Signature) WriteTo(w io.Writer) (n int64, err error) { + var n_ int64 + n_, err = self.Signer.WriteTo(w) + n += n_; if err != nil { return n, err } + n_, err = self.SigBytes.WriteTo(w) + n += n_; return +} + +func (self *Signature) Verify(msg ByteSlice) bool { + return false +} + +func ReadSignature(buf []byte, start int) (*Signature, int) { + return nil, 0 +} + diff --git a/blocks/validation.go b/blocks/validation.go new file mode 100644 index 000000000..651428c80 --- /dev/null +++ b/blocks/validation.go @@ -0,0 +1,78 @@ +package blocks + +import ( + "github.com/tendermint/tendermint/merkle" + "io" +) + +/* Validation */ + +type BlockValidation struct { + Votes merkle.Tree + Adjustments merkle.Tree +} + +/* Votes */ + +type Votes struct { + Tree merkle.Tree +} + +func NewVotesFromHash(hash []byte) *Votes { + return nil +} + +func (self *Votes) GetVote(validator AccountId) *Vote { + return nil +} + +func (self *Votes) PutVote(vote *Vote) bool { + return false +} + +func (self *Votes) Verify() bool { + return false +} + +func (self *Votes) WriteTo(w io.Writer) (n int64, err error) { + return 0, nil +} + +/* + +The canonical representation of a Vote for signing: + + |L|NNN...|h...|HHH...| + + L length of network name (1 byte) + N name of network (max 255 bytes) + h height of block, varint encoded (1+ bytes) + H blockhash voted for height h + +The wire format of a vote is usually simply a Signature. +The network name, height, and blockhash are omitted because +they are implied from context. When it is not, e.g. evidence +for double-signing, the wire format is: + + |h...|HHH...|A...|SSS...| + +*/ + +type Vote struct { + Signature + + Height uint32 + BlockHash []byte +} + +/* |h...|HHH...|A...|SSS...| */ +func ReadVote(buf []byte, start int) (*Vote, int) { + return nil, 0 +} + +/* |L|NNN...|h...|HHH...| */ +func (self *Vote) WriteTo(w io.Writer) (n int64, err error) { + return 0, nil +} + +/* Adjustments */