mirror of
https://github.com/fluencelabs/tendermint
synced 2025-05-28 13:41:21 +00:00
consensus & account txs are all in Block.Data.Txs
This commit is contained in:
parent
d772282c25
commit
03d1af711a
@ -17,7 +17,7 @@ const (
|
||||
type Block struct {
|
||||
Header
|
||||
Validation
|
||||
Txs
|
||||
Data
|
||||
|
||||
// Volatile
|
||||
hash []byte
|
||||
@ -27,14 +27,14 @@ func ReadBlock(r io.Reader, n *int64, err *error) *Block {
|
||||
return &Block{
|
||||
Header: ReadHeader(r, n, err),
|
||||
Validation: ReadValidation(r, n, err),
|
||||
Txs: ReadTxs(r, n, err),
|
||||
Data: ReadData(r, n, err),
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Block) WriteTo(w io.Writer) (n int64, err error) {
|
||||
WriteBinary(w, &b.Header, &n, &err)
|
||||
WriteBinary(w, &b.Validation, &n, &err)
|
||||
WriteBinary(w, &b.Txs, &n, &err)
|
||||
WriteBinary(w, &b.Data, &n, &err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ func (b *Block) Hash() []byte {
|
||||
hashes := [][]byte{
|
||||
b.Header.Hash(),
|
||||
b.Validation.Hash(),
|
||||
b.Txs.Hash(),
|
||||
b.Data.Hash(),
|
||||
}
|
||||
// Merkle hash from sub-hashes.
|
||||
return merkle.HashFromByteSlices(hashes)
|
||||
@ -79,6 +79,21 @@ func (b *Block) ToBlockPartSet() *BlockPartSet {
|
||||
return NewBlockPartSet(b.Height, parts)
|
||||
}
|
||||
|
||||
// Makes an empty next block.
|
||||
func (b *Block) MakeNextBlock() *Block {
|
||||
return &Block{
|
||||
Header: Header{
|
||||
Name: b.Header.Name,
|
||||
Height: b.Header.Height + 1,
|
||||
//Fees: uint64(0),
|
||||
Time: time.Now(),
|
||||
PrevHash: b.Hash(),
|
||||
//ValidationStateHash: nil,
|
||||
//AccountStateHash: nil,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
@ -133,15 +148,14 @@ func (bp *BlockPart) Hash() []byte {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/* Header is part of a Block */
|
||||
type Header struct {
|
||||
Name string
|
||||
Height uint32
|
||||
Fees uint64
|
||||
Time time.Time
|
||||
PrevHash []byte
|
||||
ValidationHash []byte
|
||||
TxsHash []byte
|
||||
Name string
|
||||
Height uint32
|
||||
Fees uint64
|
||||
Time time.Time
|
||||
PrevHash []byte
|
||||
ValidationStateHash []byte
|
||||
AccountStateHash []byte
|
||||
|
||||
// Volatile
|
||||
hash []byte
|
||||
@ -152,13 +166,13 @@ func ReadHeader(r io.Reader, n *int64, err *error) (h Header) {
|
||||
return Header{}
|
||||
}
|
||||
return Header{
|
||||
Name: ReadString(r, n, err),
|
||||
Height: ReadUInt32(r, n, err),
|
||||
Fees: ReadUInt64(r, n, err),
|
||||
Time: ReadTime(r, n, err),
|
||||
PrevHash: ReadByteSlice(r, n, err),
|
||||
ValidationHash: ReadByteSlice(r, n, err),
|
||||
TxsHash: ReadByteSlice(r, n, err),
|
||||
Name: ReadString(r, n, err),
|
||||
Height: ReadUInt32(r, n, err),
|
||||
Fees: ReadUInt64(r, n, err),
|
||||
Time: ReadTime(r, n, err),
|
||||
PrevHash: ReadByteSlice(r, n, err),
|
||||
ValidationStateHash: ReadByteSlice(r, n, err),
|
||||
AccountStateHash: ReadByteSlice(r, n, err),
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,8 +182,8 @@ func (h *Header) WriteTo(w io.Writer) (n int64, err error) {
|
||||
WriteUInt64(w, h.Fees, &n, &err)
|
||||
WriteTime(w, h.Time, &n, &err)
|
||||
WriteByteSlice(w, h.PrevHash, &n, &err)
|
||||
WriteByteSlice(w, h.ValidationHash, &n, &err)
|
||||
WriteByteSlice(w, h.TxsHash, &n, &err)
|
||||
WriteByteSlice(w, h.ValidationStateHash, &n, &err)
|
||||
WriteByteSlice(w, h.AccountStateHash, &n, &err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -187,10 +201,10 @@ func (h *Header) Hash() []byte {
|
||||
}
|
||||
}
|
||||
|
||||
/* Validation is part of a block */
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
type Validation struct {
|
||||
Signatures []Signature
|
||||
Txs []Tx
|
||||
|
||||
// Volatile
|
||||
hash []byte
|
||||
@ -198,30 +212,20 @@ type Validation struct {
|
||||
|
||||
func ReadValidation(r io.Reader, n *int64, err *error) Validation {
|
||||
numSigs := ReadUInt32(r, n, err)
|
||||
numAdjs := ReadUInt32(r, n, err)
|
||||
sigs := make([]Signature, 0, numSigs)
|
||||
for i := uint32(0); i < numSigs; i++ {
|
||||
sigs = append(sigs, ReadSignature(r, n, err))
|
||||
}
|
||||
tx := make([]Tx, 0, numAdjs)
|
||||
for i := uint32(0); i < numAdjs; i++ {
|
||||
tx = append(tx, ReadTx(r, n, err))
|
||||
}
|
||||
return Validation{
|
||||
Signatures: sigs,
|
||||
Txs: tx,
|
||||
}
|
||||
}
|
||||
|
||||
func (v *Validation) WriteTo(w io.Writer) (n int64, err error) {
|
||||
WriteUInt32(w, uint32(len(v.Signatures)), &n, &err)
|
||||
WriteUInt32(w, uint32(len(v.Txs)), &n, &err)
|
||||
for _, sig := range v.Signatures {
|
||||
WriteBinary(w, sig, &n, &err)
|
||||
}
|
||||
for _, tx := range v.Txs {
|
||||
WriteBinary(w, tx, &n, &err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -239,40 +243,41 @@ func (v *Validation) Hash() []byte {
|
||||
}
|
||||
}
|
||||
|
||||
/* Txs is part of a block */
|
||||
type Txs struct {
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
type Data struct {
|
||||
Txs []Tx
|
||||
|
||||
// Volatile
|
||||
hash []byte
|
||||
}
|
||||
|
||||
func ReadTxs(r io.Reader, n *int64, err *error) Txs {
|
||||
func ReadData(r io.Reader, n *int64, err *error) Data {
|
||||
numTxs := ReadUInt32(r, n, err)
|
||||
txs := make([]Tx, 0, numTxs)
|
||||
for i := uint32(0); i < numTxs; i++ {
|
||||
txs = append(txs, ReadTx(r, n, err))
|
||||
}
|
||||
return Txs{Txs: txs}
|
||||
return Data{Txs: txs}
|
||||
}
|
||||
|
||||
func (txs *Txs) WriteTo(w io.Writer) (n int64, err error) {
|
||||
WriteUInt32(w, uint32(len(txs.Txs)), &n, &err)
|
||||
for _, tx := range txs.Txs {
|
||||
func (data *Data) WriteTo(w io.Writer) (n int64, err error) {
|
||||
WriteUInt32(w, uint32(len(data.Txs)), &n, &err)
|
||||
for _, tx := range data.Txs {
|
||||
WriteBinary(w, tx, &n, &err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (txs *Txs) Hash() []byte {
|
||||
if txs.hash != nil {
|
||||
return txs.hash
|
||||
func (data *Data) Hash() []byte {
|
||||
if data.hash != nil {
|
||||
return data.hash
|
||||
} else {
|
||||
bs := make([]Binary, 0, len(txs.Txs))
|
||||
for i, tx := range txs.Txs {
|
||||
bs := make([]Binary, 0, len(data.Txs))
|
||||
for i, tx := range data.Txs {
|
||||
bs[i] = Binary(tx)
|
||||
}
|
||||
txs.hash = merkle.HashFromBinarySlice(bs)
|
||||
return txs.hash
|
||||
data.hash = merkle.HashFromBinarySlice(bs)
|
||||
return data.hash
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ func TestBlock(t *testing.T) {
|
||||
PubKey: randBytes(32),
|
||||
}
|
||||
|
||||
// Consensus Txs
|
||||
// Validation Txs
|
||||
|
||||
bond := &Bond{
|
||||
Signature: randSig(),
|
||||
@ -106,15 +106,14 @@ func TestBlock(t *testing.T) {
|
||||
Time: randTime(),
|
||||
PrevHash: randBytes(32),
|
||||
ValidationHash: randBytes(32),
|
||||
TxsHash: randBytes(32),
|
||||
DataHash: randBytes(32),
|
||||
},
|
||||
Validation: Validation{
|
||||
Signatures: []Signature{randSig(), randSig()},
|
||||
Txs: []Txs{bond, unbond, timeout, dupeout},
|
||||
},
|
||||
Txs: Txs{
|
||||
Txs: []Tx{sendTx, nameTx},
|
||||
hash: nil,
|
||||
Data: Data{
|
||||
Txs: []Tx{sendTx, nameTx},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ func BenchmarkTestCustom(b *testing.B) {
|
||||
Time: time.Unix(123, 0),
|
||||
PrevHash: []byte("prevhash"),
|
||||
ValidationHash: []byte("validationhash"),
|
||||
TxsHash: []byte("txshash"),
|
||||
DataHash: []byte("datahash"),
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
@ -46,7 +46,7 @@ type HHeader struct {
|
||||
Time uint64 `json:"T"`
|
||||
PrevHash []byte `json:"PH"`
|
||||
ValidationHash []byte `json:"VH"`
|
||||
TxsHash []byte `json:"DH"`
|
||||
DataHash []byte `json:"DH"`
|
||||
}
|
||||
|
||||
func BenchmarkTestJSON(b *testing.B) {
|
||||
@ -59,7 +59,7 @@ func BenchmarkTestJSON(b *testing.B) {
|
||||
Time: 123,
|
||||
PrevHash: []byte("prevhash"),
|
||||
ValidationHash: []byte("validationhash"),
|
||||
TxsHash: []byte("txshash"),
|
||||
DataHash: []byte("datahash"),
|
||||
}
|
||||
h2 := &HHeader{}
|
||||
|
||||
@ -88,7 +88,7 @@ func BenchmarkTestGob(b *testing.B) {
|
||||
Time: time.Unix(123, 0),
|
||||
PrevHash: []byte("prevhash"),
|
||||
ValidationHash: []byte("validationhash"),
|
||||
TxsHash: []byte("txshash"),
|
||||
DataHash: []byte("datahash"),
|
||||
}
|
||||
h2 := &Header{}
|
||||
|
||||
@ -117,7 +117,7 @@ func BenchmarkTestMsgPack(b *testing.B) {
|
||||
Time: time.Unix(123, 0),
|
||||
PrevHash: []byte("prevhash"),
|
||||
ValidationHash: []byte("validationhash"),
|
||||
TxsHash: []byte("txshash"),
|
||||
DataHash: []byte("datahash"),
|
||||
}
|
||||
h2 := &Header{}
|
||||
|
||||
@ -146,7 +146,7 @@ func BenchmarkTestMsgPack2(b *testing.B) {
|
||||
Time: time.Unix(123, 0),
|
||||
PrevHash: []byte("prevhash"),
|
||||
ValidationHash: []byte("validationhash"),
|
||||
TxsHash: []byte("txshash"),
|
||||
DataHash: []byte("datahash"),
|
||||
}
|
||||
h2 := &Header{}
|
||||
var mh codec.MsgpackHandle
|
||||
|
@ -22,7 +22,7 @@ Account Txs:
|
||||
1. Send Send coins to account
|
||||
2. Name Associate account with a name
|
||||
|
||||
Consensus Txs:
|
||||
Validation Txs:
|
||||
3. Bond New validator posts a bond
|
||||
4. Unbond Validator leaves
|
||||
5. Timeout Validator times out
|
||||
@ -35,7 +35,7 @@ type Tx interface {
|
||||
Type() byte
|
||||
GetSequence() uint64
|
||||
GetSignature() *Signature
|
||||
//IsConsensus() bool
|
||||
//IsValidation() bool
|
||||
Binary
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ const (
|
||||
TX_TYPE_SEND = byte(0x01)
|
||||
TX_TYPE_NAME = byte(0x02)
|
||||
|
||||
// Consensus transactions
|
||||
// Validation transactions
|
||||
TX_TYPE_BOND = byte(0x11)
|
||||
TX_TYPE_UNBOND = byte(0x12)
|
||||
TX_TYPE_TIMEOUT = byte(0x13)
|
||||
|
@ -1,12 +1,3 @@
|
||||
package mempool
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
. "github.com/tendermint/tendermint/blocks"
|
||||
. "github.com/tendermint/tendermint/state"
|
||||
)
|
||||
|
||||
/*
|
||||
Mempool receives new transactions and applies them to the latest committed state.
|
||||
If the transaction is acceptable, then it broadcasts a fingerprint to peers.
|
||||
@ -20,24 +11,33 @@ When this node happens to be the next proposer, it simply takes the recently
|
||||
modified state (and the associated transactions) and use that as the proposal.
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
package mempool
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
. "github.com/tendermint/tendermint/blocks"
|
||||
. "github.com/tendermint/tendermint/state"
|
||||
)
|
||||
|
||||
type Mempool struct {
|
||||
mtx sync.Mutex
|
||||
state *State
|
||||
txs []Tx
|
||||
mtx sync.Mutex
|
||||
lastBlock *Block
|
||||
state *State
|
||||
txs []Tx
|
||||
}
|
||||
|
||||
func NewMempool(state *State) *Mempool {
|
||||
func NewMempool(lastBlock *Block, state *State) *Mempool {
|
||||
return &Mempool{
|
||||
state: state,
|
||||
lastBlock: lastBlock,
|
||||
state: state,
|
||||
}
|
||||
}
|
||||
|
||||
// Apply tx to the state and remember it.
|
||||
func (mem *Mempool) AddTx(tx Tx) (err error) {
|
||||
mem.mtx.Lock()
|
||||
defer mem.mtx.Unlock()
|
||||
// Add the tx to the state.
|
||||
err = mem.state.CommitTx(tx)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -46,3 +46,54 @@ func (mem *Mempool) AddTx(tx Tx) (err error) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a new block from the current state and associated transactions.
|
||||
// The block's Validation is empty, and some parts of the header too.
|
||||
func (mem *Mempool) MakeProposal() (*Block, *State) {
|
||||
mem.mtx.Lock()
|
||||
defer mem.mtx.Unlock()
|
||||
nextBlock := mem.lastBlock.MakeNextBlock()
|
||||
nextBlock.Data.Txs = mem.txs
|
||||
return nextBlock, mem.state
|
||||
}
|
||||
|
||||
// Txs that are present in block are discarded from mempool.
|
||||
// Txs that have become invalid in the new state are also discarded.
|
||||
func (mem *Mempool) ResetForBlockandState(block *Block, state *State) {
|
||||
mem.mtx.Lock()
|
||||
defer mem.mtx.Unlock()
|
||||
mem.lastBlock = block
|
||||
mem.state = state.Copy()
|
||||
|
||||
// First, create a lookup map of txns in new block.
|
||||
blockTxsMap := make(map[string]struct{})
|
||||
for _, tx := range block.Data.Txs {
|
||||
txHash := BinaryHash(tx)
|
||||
blockTxsMap[string(txHash)] = struct{}{}
|
||||
}
|
||||
|
||||
// Next, filter all txs from mem.txs that are in blockTxsMap
|
||||
txs := []Tx{}
|
||||
for _, tx := range mem.txs {
|
||||
txHash := BinaryHash(tx)
|
||||
if _, ok := blockTxsMap[string(txHash)]; ok {
|
||||
continue
|
||||
} else {
|
||||
txs = append(txs, tx)
|
||||
}
|
||||
}
|
||||
|
||||
// Next, filter all txs that aren't valid given new state.
|
||||
validTxs := []Tx{}
|
||||
for _, tx := range txs {
|
||||
err := mem.state.CommitTx(tx)
|
||||
if err != nil {
|
||||
validTxs = append(validTxs, tx)
|
||||
} else {
|
||||
// tx is no longer valid.
|
||||
}
|
||||
}
|
||||
|
||||
// We're done!
|
||||
mem.txs = validTxs
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user