@ -0,0 +1,53 @@ | |||
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) | |||
) | |||
func ReadAccountId(r io.Reader) AccountId { | |||
return nil | |||
} | |||
/* AccountNumber < AccountId */ | |||
type AccountNumber uint64 | |||
func (self AccountNumber) Type() Byte { | |||
return ACCOUNT_TYPE_NUMBER | |||
} | |||
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) 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 | |||
} |
@ -0,0 +1,129 @@ | |||
package blocks | |||
import ( | |||
. "github.com/tendermint/tendermint/binary" | |||
"io" | |||
) | |||
/* Adjustment | |||
1. Bond New validator posts a bond | |||
2. Unbond Validator leaves | |||
3. Timeout Validator times out | |||
4. Dupeout Validator dupes out (signs twice) | |||
TODO: signing a bad checkpoint (block) | |||
*/ | |||
type Adjustment interface { | |||
Type() Byte | |||
Binary | |||
} | |||
const ( | |||
ADJ_TYPE_BOND = Byte(0x01) | |||
ADJ_TYPE_UNBOND = Byte(0x02) | |||
ADJ_TYPE_TIMEOUT = Byte(0x03) | |||
ADJ_TYPE_GUILTOUT = Byte(0x04) | |||
) | |||
func ReadAdjustment(r io.Reader) Adjustment { | |||
return nil | |||
} | |||
/* Bond < Adjustment */ | |||
type Bond struct { | |||
Signature | |||
Fee UInt64 | |||
UnbondTo AccountId | |||
Amount UInt64 | |||
} | |||
func (self *Bond) Type() Byte { | |||
return ADJ_TYPE_BOND | |||
} | |||
func (self *Bond) 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 | |||
} | |||
/* Unbond < Adjustment */ | |||
type Unbond struct { | |||
Signature | |||
Fee UInt64 | |||
Amount UInt64 | |||
} | |||
func (self *Unbond) Type() Byte { | |||
return ADJ_TYPE_UNBOND | |||
} | |||
func (self *Unbond) 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 | |||
} | |||
/* Timeout < Adjustment */ | |||
type Timeout struct { | |||
Account AccountId | |||
Penalty UInt64 | |||
} | |||
func (self *Timeout) Type() Byte { | |||
return ADJ_TYPE_TIMEOUT | |||
} | |||
func (self *Timeout) 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.Account.WriteTo(w) | |||
n += n_; if err != nil { return n, err } | |||
n_, err = self.Penalty.WriteTo(w) | |||
n += n_; return | |||
} | |||
/* Dupeout < Adjustment */ | |||
type Dupeout struct { | |||
VoteA Vote | |||
VoteB Vote | |||
} | |||
func (self *Dupeout) Type() Byte { | |||
return ADJ_TYPE_DUPEOUT | |||
} | |||
func (self *Dupeout) 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.Account.WriteTo(w) | |||
n += n_; if err != nil { return n, err } | |||
n_, err = self.Penalty.WriteTo(w) | |||
n += n_; return | |||
} |
@ -1,35 +1,100 @@ | |||
package blocks | |||
import ( | |||
. "github.com/tendermint/tendermint/binary" | |||
"io" | |||
) | |||
// BlockHeader | |||
type BlockHeader struct { | |||
Name string | |||
Height uint64 | |||
Version uint8 | |||
Fees uint64 | |||
Time uint64 | |||
PrevBlockHash []byte | |||
ValidationHash []byte | |||
DataHash []byte | |||
} | |||
/* Block */ | |||
func (self *BlockHeader) WriteTo(w io.Writer) (n int64, err error) { | |||
return 0, nil | |||
type Block struct { | |||
Header | |||
Validation | |||
Data | |||
// Checkpoint | |||
} | |||
// Block | |||
type Block struct { | |||
Header *BlockHeader | |||
Validation *BlockValidation | |||
Data *BlockData | |||
//Checkpoint *BlockCheckpoint | |||
func ReadBlock(r io.Reader) *Block { | |||
return nil | |||
} | |||
func (self *Block) Validate() bool { | |||
return false | |||
} | |||
/* Block > Header */ | |||
type Header struct { | |||
Name String | |||
Height UInt64 | |||
Fees UInt64 | |||
Time UInt64 | |||
PrevHash ByteSlice | |||
ValidationHash ByteSlice | |||
DataHash ByteSlice | |||
} | |||
func ReadHeader(r io.Reader) *Header { | |||
return nil | |||
} | |||
func (self *Header) WriteTo(w io.Writer) (n int64, err error) { | |||
var n_ int64 | |||
n_, err = self.Name.WriteTo(w) | |||
n += n_; if err != nil { return n, err } | |||
n_, err = self.Height.WriteTo(w) | |||
n += n_; if err != nil { return n, err } | |||
n_, err = self.Fees.WriteTo(w) | |||
n += n_; if err != nil { return n, err } | |||
n_, err = self.Time.WriteTo(w) | |||
n += n_; if err != nil { return n, err } | |||
n_, err = self.PrevHash.WriteTo(w) | |||
n += n_; if err != nil { return n, err } | |||
n_, err = self.ValidationHash.WriteTo(w) | |||
n += n_; if err != nil { return n, err } | |||
n_, err = self.DataHash.WriteTo(w) | |||
n += n_; return | |||
} | |||
/* Block > Validation */ | |||
type Validation struct { | |||
Signatures []*Signature | |||
Adjustments []Adjustment | |||
} | |||
func ReadValidation(r io.Reader) *Validation { | |||
return nil | |||
} | |||
/* Block > Data */ | |||
type Data struct { | |||
Txs []Tx | |||
} | |||
func ReadData(r io.Reader) *Data { | |||
return nil | |||
} | |||
func (self *Data) 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 *Data) MerkleHash() ByteSlice { | |||
bs := make([]Binary, 0, len(self.Txs)) | |||
for i, tx := range self.Txs { | |||
bs[i] = Binary(tx) | |||
} | |||
return merkle.HashFromBinarySlice(bs) | |||
} |
@ -0,0 +1,67 @@ | |||
package blocks | |||
import ( | |||
. "github.com/tendermint/tendermint/binary" | |||
"testing" | |||
"bytes" | |||
"fmt" | |||
"math/rand" | |||
) | |||
// Distributed pseudo-exponentially to test for various cases | |||
func randVar() UInt64 { | |||
bits := rand.Uint32() % 64 | |||
if bits == 0 { return 0 } | |||
n := uint64(1 << (bits-1)) | |||
n += uint64(rand.Int63()) & ((1 << (bits-1)) - 1) | |||
return UInt64(n) | |||
} | |||
func randBytes(n int) ByteSlice { | |||
bs := make([]byte, n) | |||
for i:=0; i<n; i++ { | |||
bs[i] = byte(rand.Intn(256)) | |||
} | |||
return bs | |||
} | |||
func TestBlock(t *testing.T) { | |||
var block = NewBlock() | |||
sendTx := &SendTx{ | |||
Signature: Signature{AccountNumber(randVar()), randBytes(32)}, | |||
Fee: randVar(), | |||
To: AccountNumber(randVar()), | |||
Amount: randVar(), | |||
} | |||
bondTx := &BondTx{ | |||
Signature: Signature{AccountNumber(randVar()), randBytes(32)}, | |||
Fee: randVar(), | |||
UnbondTo: AccountNumber(randVar()), | |||
Amount: randVar(), | |||
} | |||
unbondTx := &UnbondTx{ | |||
Signature: Signature{AccountNumber(randVar()), randBytes(32)}, | |||
Fee: randVar(), | |||
Amount: randVar(), | |||
} | |||
nameTx := &NameTx{ | |||
Signature: Signature{AccountNumber(randVar()), randBytes(32)}, | |||
Fee: randVar(), | |||
Name: String(randBytes(12)), | |||
PubKey: randBytes(32), | |||
} | |||
block.AddTx(sendTx) | |||
block.AddTx(bondTx) | |||
block.AddTx(unbondTx) | |||
block.AddTx(nameTx) | |||
blockBytes := block.Bytes() | |||
fmt.Println(buf.Bytes(), len(buf.Bytes())) | |||
} |
@ -1,244 +0,0 @@ | |||
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 | |||
} |
@ -1,29 +0,0 @@ | |||
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())) | |||
} |
@ -0,0 +1,100 @@ | |||
package blocks | |||
import ( | |||
. "github.com/tendermint/tendermint/binary" | |||
"io" | |||
) | |||
/* | |||
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 { | |||
Type() Byte | |||
Binary | |||
Signature() *Signature | |||
} | |||
const ( | |||
TX_TYPE_SEND = Byte(0x01) | |||
TX_TYPE_NAME = Byte(0x02) | |||
) | |||
func ReadTx(r io.Reader) Tx { | |||
return nil | |||
} | |||
/* SendTx < Tx */ | |||
type SendTx struct { | |||
Signature | |||
Fee UInt64 | |||
To AccountId | |||
Amount UInt64 | |||
} | |||
func (self *SendTx) Type() Byte { | |||
return TX_TYPE_SEND | |||
} | |||
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 | |||
} | |||
func (self *SendTx) Signature() *Signature { | |||
return self.Signature | |||
} | |||
/* NameTx < Tx */ | |||
type NameTx struct { | |||
Signature | |||
Fee UInt64 | |||
Name String | |||
PubKey ByteSlice | |||
} | |||
func (self *NameTx) Type() Byte { | |||
return TX_TYPE_NAME | |||
} | |||
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 | |||
} | |||
func (self *NameTx) Signature() *Signature { | |||
return self.Signature | |||
} |
@ -1,78 +0,0 @@ | |||
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 */ |