From 11a79f11e03076172d6dbaa2f375aaebee7d8190 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Fri, 3 Oct 2014 17:59:54 -0700 Subject: [PATCH] ... --- state/account.go | 46 ++++++++++++++++++++++++++++++++++++------- state/account_test.go | 28 ++++++++++++++++++++++++++ state/state.go | 11 +++++------ 3 files changed, 72 insertions(+), 13 deletions(-) create mode 100644 state/account_test.go diff --git a/state/account.go b/state/account.go index 3270dd489..6a94b8b8a 100644 --- a/state/account.go +++ b/state/account.go @@ -3,10 +3,11 @@ package state import ( . "github.com/tendermint/tendermint/binary" . "github.com/tendermint/tendermint/blocks" + . "github.com/tendermint/tendermint/common" + "github.com/tendermint/tendermint/crypto" "io" ) -// NOTE: consensus/Validator embeds this, so.. type Account struct { Id uint64 // Numeric id of account, incrementing. PubKey []byte @@ -19,11 +20,24 @@ func ReadAccount(r io.Reader, n *int64, err *error) *Account { } } -func (self *Account) Verify(msg []byte, sig Signature) bool { - if sig.SignerId != self.Id { - return false +func (account *Account) Verify(msg []byte, sig Signature) bool { + if sig.SignerId != account.Id { + panic("Account.Id doesn't match sig.SignerId") } - return false + v1 := &crypto.Verify{ + Message: msg, + PubKey: account.PubKey, + Signature: sig.Bytes, + } + ok := crypto.VerifyBatch([]*crypto.Verify{v1}) + return ok +} + +//----------------------------------------------------------------------------- + +type AccountBalance struct { + Account + Balance uint64 } //----------------------------------------------------------------------------- @@ -33,6 +47,24 @@ type PrivAccount struct { PrivKey []byte } -func (self *PrivAccount) Sign(msg []byte) Signature { - return Signature{} +// Generates a new account with private key. +// The Account.Id is empty since it isn't in the blockchain. +func GenPrivAccount() *PrivAccount { + privKey := RandBytes(32) + pubKey := crypto.MakePubKey(privKey) + return &PrivAccount{ + Account: Account{ + Id: uint64(0), + PubKey: pubKey, + }, + PrivKey: privKey, + } +} + +func (pa *PrivAccount) Sign(msg []byte) Signature { + signature := crypto.SignMessage(msg, pa.PrivKey, pa.PubKey) + return Signature{ + SignerId: pa.Id, + Bytes: signature, + } } diff --git a/state/account_test.go b/state/account_test.go new file mode 100644 index 000000000..78abec04d --- /dev/null +++ b/state/account_test.go @@ -0,0 +1,28 @@ +package state + +import ( + . "github.com/tendermint/tendermint/common" + "testing" +) + +func TestSignAndValidate(t *testing.T) { + + privAccount := GenPrivAccount() + account := &privAccount.Account + + msg := RandBytes(128) + sig := privAccount.Sign(msg) + t.Logf("msg: %X, sig: %X", msg, sig) + + // Test the signature + if !account.Verify(msg, sig) { + t.Errorf("Account message signature verification failed") + } + + // Mutate the signature, just one bit. + sig.Bytes[0] ^= byte(0x01) + + if account.Verify(msg, sig) { + t.Errorf("Account message signature verification should have failed but passed instead") + } +} diff --git a/state/state.go b/state/state.go index 10eee0dd1..06d44ee35 100644 --- a/state/state.go +++ b/state/state.go @@ -28,15 +28,14 @@ type State struct { validators *ValidatorSet } +func GenesisState(commitTime time.Time, accounts merkle.Tree, validators *ValidatorSet) *State { +} + func LoadState(db db_.Db) *State { s := &State{} buf := db.Get(stateKey) if len(buf) == 0 { - s.height = uint32(0) - s.commitTime = time.Unix(0, 0) // XXX BOOTSTRAP - s.blockHash = nil // XXX BOOTSTRAP - s.accounts = merkle.NewIAVLTree(db) // XXX BOOTSTRAP - s.validators = NewValidatorSet(nil) // XXX BOOTSTRAP + return nil } else { reader := bytes.NewReader(buf) var n int64 @@ -112,7 +111,7 @@ func (s *State) commitTx(tx Tx) error { return ErrStateInvalidSequenceNumber } */ - // TODO commit the tx + // XXX commit the tx panic("Implement CommitTx()") return nil }