Пример #1
0
func makeTransactionForChainWithHoursFee(t *testing.T, bc *Blockchain,
	ux coin.UxOut, sec cipher.SecKey, hours, fee uint64) (coin.Transaction, cipher.SecKey) {
	chrs := ux.CoinHours(bc.Time())
	if chrs < hours+fee {
		log.Panicf("CoinHours underflow. Have %d, need at least %d", chrs,
			hours+fee)
	}
	assert.Equal(t, cipher.AddressFromPubKey(cipher.PubKeyFromSecKey(sec)), ux.Body.Address)
	knownUx, exists := bc.GetUnspent().Get(ux.Hash())
	assert.True(t, exists)
	assert.Equal(t, knownUx, ux)
	tx := coin.Transaction{}
	tx.PushInput(ux.Hash())
	p, newSec := cipher.GenerateKeyPair()
	addr := cipher.AddressFromPubKey(p)
	tx.PushOutput(addr, 1e6, hours)
	coinsOut := ux.Body.Coins - 1e6
	if coinsOut > 0 {
		tx.PushOutput(genAddress, coinsOut, chrs-hours-fee)
	}
	tx.SignInputs([]cipher.SecKey{sec})
	assert.Equal(t, len(tx.Sigs), 1)
	assert.Nil(t, cipher.ChkSig(ux.Body.Address, cipher.AddSHA256(tx.HashInner(), tx.In[0]), tx.Sigs[0]))
	tx.UpdateHeader()
	assert.Nil(t, tx.Verify())
	err := bc.VerifyTransaction(tx)
	assert.Nil(t, err)
	return tx, newSec
}
Пример #2
0
func TestSerialize(t *testing.T) {

	routeId := RandRouteId()
	transportId := RandTransportId()
	datagram := []byte{'t', 'e', 's', 't'}

	msg := InRouteMessage{transportId, routeId, datagram}
	serialized := Serialize((uint16)(MsgInRouteMessage), msg)
	msg1 := InRouteMessage{}
	err := Deserialize(serialized, &msg1)
	assert.Nil(t, err)
	assert.Equal(t, msg.TransportId, msg1.TransportId)
	assert.Equal(t, msg.RouteId, msg1.RouteId)
	assert.Equal(t, msg.Datagram, msg1.Datagram)

	sequence := (uint32)(rand.Intn(65536))
	msg2 := TransportDatagramTransfer{RandRouteId(), sequence, datagram}
	serialized = Serialize((uint16)(MsgTransportDatagramTransfer), msg2)
	msg3 := TransportDatagramTransfer{}
	err = Deserialize(serialized, &msg3)
	assert.Nil(t, err)
	assert.Equal(t, msg2.RouteId, msg3.RouteId)
	assert.Equal(t, msg2.Sequence, msg3.Sequence)
	assert.Equal(t, msg2.Datagram, msg3.Datagram)

	nodeId, _ := cipher.GenerateKeyPair()
	msg4 := AddRouteControlMessage{nodeId, routeId}
	serialized = Serialize((uint16)(MsgAddRouteControlMessage), msg4)
	msg5 := AddRouteControlMessage{}
	err = Deserialize(serialized, &msg5)
	assert.Nil(t, err)
	assert.Equal(t, msg4.NodeId, msg5.NodeId)
	assert.Equal(t, msg4.RouteId, msg5.RouteId)
}
Пример #3
0
func TestFullTransaction(t *testing.T) {
	p1, s1 := cipher.GenerateKeyPair()
	a1 := cipher.AddressFromPubKey(p1)
	bc := NewBlockchain()
	bc.CreateGenesisBlock(a1, _genTime, _genCoins)
	tx := Transaction{}
	ux := bc.Unspent.Array()[0]
	tx.PushInput(ux.Hash())
	p2, s2 := cipher.GenerateKeyPair()
	a2 := cipher.AddressFromPubKey(p2)
	tx.PushOutput(a1, ux.Body.Coins-6e6, 100)
	tx.PushOutput(a2, 1e6, 100)
	tx.PushOutput(a2, 5e6, 100)
	tx.SignInputs([]cipher.SecKey{s1})
	tx.UpdateHeader()
	assert.Nil(t, tx.Verify())
	assert.Nil(t, bc.VerifyTransaction(tx))
	b, err := bc.NewBlockFromTransactions(Transactions{tx}, bc.Time()+_incTime)
	assert.Nil(t, err)
	_, err = bc.ExecuteBlock(b)
	assert.Nil(t, err)

	txo := CreateUnspents(bc.Head().Head, tx)
	tx = Transaction{}
	assert.Equal(t, txo[0].Body.Address, a1)
	assert.Equal(t, txo[1].Body.Address, a2)
	assert.Equal(t, txo[2].Body.Address, a2)
	ux0, ok := bc.Unspent.Get(txo[0].Hash())
	assert.True(t, ok)
	ux1, ok := bc.Unspent.Get(txo[1].Hash())
	assert.True(t, ok)
	ux2, ok := bc.Unspent.Get(txo[2].Hash())
	assert.True(t, ok)
	tx.PushInput(ux0.Hash())
	tx.PushInput(ux1.Hash())
	tx.PushInput(ux2.Hash())
	tx.PushOutput(a2, 10e6, 200)
	tx.PushOutput(a1, ux.Body.Coins-10e6, 100)
	tx.SignInputs([]cipher.SecKey{s1, s2, s2})
	tx.UpdateHeader()
	assert.Nil(t, tx.Verify())
	assert.Nil(t, bc.VerifyTransaction(tx))
	b, err = bc.NewBlockFromTransactions(Transactions{tx}, bc.Time()+_incTime)
	assert.Nil(t, err)
	_, err = bc.ExecuteBlock(b)
	assert.Nil(t, err)
}
Пример #4
0
func TestBlockStat_01(t *testing.T) {
	bs := BlockStat{}
	bs.Init()

	_, seckey := cipher.GenerateKeyPair()
	hash := cipher.SumSHA256(secp256k1.RandByte(888))
	sig := cipher.SignHash(hash, seckey)

	var r int = -1

	r = bs.try_add_hash_and_sig(hash, cipher.Sig{})
	if r != 4 {
		t.Log("BlockStat::try_add_hash_and_sig() failed to detect invalid signature.")
		t.Fail()
	}
	r = bs.try_add_hash_and_sig(cipher.SHA256{}, sig)
	if r != 4 {
		t.Log("BlockStat::try_add_hash_and_sig() failed to detect invalid hash and signature.")
		t.Fail()
	}
	r = bs.try_add_hash_and_sig(cipher.SHA256{}, cipher.Sig{})
	if r != 4 {
		t.Log("BlockStat::try_add_hash_and_sig() failed to detect invalid hash and signature.")
		t.Fail()
	}

	//signer_pubkey, err := cipher.PubKeyFromSig(cipher.Sig{}, cipher.SHA256{})
	//if err != nil {
	//fmt.Printf("Got pubkey='%s' from all-zero sig and all-zero hash.\n", signer_pubkey.Hex())
	//}

	bs.frozen = true
	r2 := bs.try_add_hash_and_sig(hash, sig)
	if r2 != 3 {
		t.Log("BlockStat::try_add_hash_and_sig() failed to detect frozen.")
		t.Fail()
	}
	bs.frozen = false

	r3 := bs.try_add_hash_and_sig(hash, sig)
	if r3 != 0 {
		t.Log("BlockStat::try_add_hash_and_sig() failed to add.")
		t.Fail()
	}

	sig2 := cipher.SignHash(hash, seckey) // Redo signing.
	r4 := bs.try_add_hash_and_sig(hash, sig2)
	if r4 != 1 {
		t.Log("BlockStat::try_add_hash_and_sig() failed to detect duplicate (hash,pubkey).")
		t.Fail()
	}

	r5 := bs.try_add_hash_and_sig(hash, sig)
	if r5 != 1 {
		t.Log("BlockStat::try_add_hash_and_sig() failed to detect duplicate (hash,sig).")
		t.Fail()
	}

}
Пример #5
0
func TestCrypto1(t *testing.T) {
	for i := 0; i < 10; i++ {
		_, seckey := cipher.GenerateKeyPair()
		if cipher.TestSecKey(seckey) != nil {
			t.Fatal("CRYPTOGRAPHIC INTEGRITY CHECK FAILED")
		}
	}
}
Пример #6
0
func makeUxBodyWithSecret(t *testing.T) (coin.UxBody, cipher.SecKey) {
	p, s := cipher.GenerateKeyPair()
	return coin.UxBody{
		SrcTransaction: cipher.SumSHA256(randBytes(t, 128)),
		Address:        cipher.AddressFromPubKey(p),
		Coins:          10e6,
		Hours:          100,
	}, s
}
Пример #7
0
//Generate Blockchain configuration for client only Blockchain, not intended to be synced to network
func NewLocalBlockchain() Blockchain {
	pubkey, seckey := cipher.GenerateKeyPair() //generate new/random pubkey/private key

	fmt.Printf("NewLocalBlockchain: genesis address seckey= %v \n", seckey.Hex())
	VC := NewBlockchain()
	VC.SecKey = seckey
	VC.Genesis.GenesisAddress = cipher.AddressFromPubKey(pubkey)
	VC.Genesis.GenesisTime = uint64(time.Now().Unix())
	VC.InjectGenesisBlock()
	return VC
}
Пример #8
0
func TestBlockStat_02(t *testing.T) {
	bs := BlockStat{}
	bs.Init()

	hash1 := cipher.SumSHA256(secp256k1.RandByte(888))
	n1 := 3

	for i := 0; i < n1; i++ {
		_, seckey := cipher.GenerateKeyPair()
		sig := cipher.SignHash(hash1, seckey)
		bs.try_add_hash_and_sig(hash1, sig)
	}

	hash2 := cipher.SumSHA256(secp256k1.RandByte(888))
	n2 := 2

	for i := 0; i < n2; i++ {
		_, seckey := cipher.GenerateKeyPair()
		sig := cipher.SignHash(hash2, seckey)
		bs.try_add_hash_and_sig(hash2, sig)
	}

	hash3 := cipher.SumSHA256(secp256k1.RandByte(888))
	n3 := 1

	for i := 0; i < n3; i++ {
		_, seckey := cipher.GenerateKeyPair()
		sig := cipher.SignHash(hash3, seckey)
		bs.try_add_hash_and_sig(hash3, sig)
	}

	best_hash, _, _ := bs.GetBestHashPubkeySig()
	if best_hash != hash1 {
		t.Log("BlockStat::try_add_hash_and_sig() or BlockStat::GetBestHashPubkeySig() issue.")
		t.Fail()
	}
}
Пример #9
0
func makeTx(s cipher.SecKey, ux *UxOut, outs []outAddr, tm uint64, seq uint64) (*Transaction, UxArray, error) {
	if ux == nil {
		// genesis block tx.
		tx := Transaction{}
		tx.PushOutput(outs[0].Addr, outs[0].Coins, outs[0].Hours)
		_, s = cipher.GenerateKeyPair()
		ux := UxOut{
			Head: UxHead{
				Time:  100,
				BkSeq: 0,
			},
			Body: UxBody{
				SrcTransaction: tx.InnerHash,
				Address:        outs[0].Addr,
				Coins:          outs[0].Coins,
				Hours:          outs[0].Hours,
			},
		}
		return &tx, []UxOut{ux}, nil
	}

	tx := Transaction{}
	tx.PushInput(ux.Hash())
	tx.SignInputs([]cipher.SecKey{s})
	for _, o := range outs {
		tx.PushOutput(o.Addr, o.Coins, o.Hours)
	}
	tx.UpdateHeader()

	uxo := make(UxArray, len(tx.Out))
	for i := range tx.Out {
		uxo[i] = UxOut{
			Head: UxHead{
				Time:  tm,
				BkSeq: seq,
			},
			Body: UxBody{
				SrcTransaction: tx.Hash(),
				Address:        tx.Out[i].Address,
				Coins:          tx.Out[i].Coins,
				Hours:          tx.Out[i].Hours,
			},
		}
	}
	return &tx, uxo, nil
}
Пример #10
0
func NewConsensusParticipantPtr(pMan ConnectionManagerInterface) *ConsensusParticipant {

	node := ConsensusParticipant{
		pConnectionManager:   pMan,
		block_queue:          BlockchainTail{},
		Incoming_block_count: 0,
	}
	node.block_queue.Init()
	//node.block_stat_queue.Init()

	// In PROD: each reads/loads the keys. In case the class does not
	// expect to sign anything, SecKey should not be stored.

	// In SIMU: generate random keys.
	node.SetPubkeySeckey(cipher.GenerateKeyPair())

	return &node
}
Пример #11
0
func TestInitDir(t *testing.T) {
	// dir, teardown, err := setup(t)
	dir, _, err := setup(t)
	if err != nil {
		t.Fatal(err)
	}

	fmt.Println(dir)
	// defer teardown()
	// check the exitence of dir.
	if _, err := os.Stat(dir); os.IsNotExist(err) {
		t.Fatal("account init dir failed")
	}

	// store some account.
	p, s := cipher.GenerateKeyPair()
	acnt := account.Account{
		Pubkey: p.Hex(),
		Seckey: s.Hex(),
	}

	v := fmt.Sprintf(`{"active_account":"%s","accounts":[{"pubkey":"%s", "seckey":"%s"}]}`, p.Hex(), p.Hex(), s.Hex())

	if err := ioutil.WriteFile(filepath.Join(dir, "data.act"), []byte(v), 0777); err != nil {
		t.Fatal(err)
	}

	// init dir again.
	account.InitDir(dir)

	// check if the account is loaded.
	a, err := account.Get(p.Hex())
	if err != nil {
		t.Fatal(err)
	}
	assert.Equal(t, acnt.Pubkey, a.Pubkey)
	assert.Equal(t, acnt.Seckey, a.Seckey)

	activeAccount, err := account.GetActive()
	if err != nil {
		t.Fatal(err)
	}
	assert.Equal(t, activeAccount.Pubkey, p.Hex())
}
Пример #12
0
func TestVerifyTransaction(t *testing.T) {
	ft := FakeTree{}
	bc := NewBlockchain(&ft, nil)
	gb := bc.CreateGenesisBlock(genAddress, _genCoins, _genTime)
	// Genesis block is not valid by normal standards
	assert.NotNil(t, bc.VerifyTransaction(gb.Body.Transactions[0]))
	assert.Equal(t, bc.Len(), uint64(1))
	_, ux := addBlockToBlockchain(t, bc)
	assert.Equal(t, bc.Len(), uint64(3))

	// Valid txn
	tx, _ := makeTransactionForChainWithHoursFee(t, bc, ux, genSecret, 100, 50)
	assert.Nil(t, bc.VerifyTransaction(tx))
	assert.Equal(t, bc.Len(), uint64(3))

	// Failure, spending unknown output
	tx, _ = makeTransactionForChainWithHoursFee(t, bc, ux, genSecret, 100, 50)
	tx.Sigs = nil
	tx.In[0] = cipher.SHA256{}
	tx.SignInputs([]cipher.SecKey{genSecret})
	tx.UpdateHeader()
	assertError(t, bc.VerifyTransaction(tx), "Unspent output does not exist")
	assert.Equal(t, bc.Len(), uint64(3))

	// Failure, duplicate input
	tx, _ = makeTransactionForChainWithHoursFee(t, bc, ux, genSecret, 100, 50)
	tx.Sigs = nil
	tx.In = append(tx.In, tx.In[0])
	tx.SignInputs([]cipher.SecKey{genSecret, genSecret})
	tx.UpdateHeader()
	assertError(t, bc.VerifyTransaction(tx), "Duplicate spend")
	assert.Equal(t, bc.Len(), uint64(3))

	// Failure, zero coin output
	tx, _ = makeTransactionForChainWithHoursFee(t, bc, ux, genSecret, 100, 50)
	tx.Sigs = nil
	tx.PushOutput(genAddress, 0, 100)
	tx.SignInputs([]cipher.SecKey{genSecret})
	tx.UpdateHeader()
	assertError(t, bc.VerifyTransaction(tx), "Zero coin output")

	// Failure, hash collision with unspents
	tx, _ = makeTransactionForChainWithHoursFee(t, bc, ux, genSecret, 100, 50)
	uxOut := coin.CreateUnspents(bc.Head().Head, tx)
	bc.GetUnspent().Add(uxOut[0])
	assertError(t, bc.VerifyTransaction(tx),
		"New unspent collides with existing unspent")

	// Failure, not spending enough coins
	tx, _ = makeTransactionForChainWithHoursFee(t, bc, ux, genSecret, 100, 50)
	tx.PushOutput(genAddress, 10e6, 100)
	tx.Sigs = nil
	tx.SignInputs([]cipher.SecKey{genSecret})
	tx.UpdateHeader()
	assertError(t, bc.VerifyTransaction(tx), "Insufficient coins")

	// Failure, spending outputs we don't own
	_, s := cipher.GenerateKeyPair()
	tx = coin.Transaction{}
	for _, u := range bc.GetUnspent().Pool {
		if u.Body.Address != genAddress {
			ux = u
			break
		}
	}
	assert.NotEqual(t, ux.Body.Address, genAddress)
	tx.PushInput(ux.Hash())
	tx.PushOutput(genAddress, ux.Body.Coins, ux.Body.Hours)
	tx.SignInputs([]cipher.SecKey{s})
	tx.UpdateHeader()
	assertError(t, bc.VerifyTransaction(tx),
		"Signature not valid for output being spent")

	// Failure, wrong signature for txn hash
	tx = coin.Transaction{}
	tx.PushInput(ux.Hash())
	tx.SignInputs([]cipher.SecKey{genSecret})
	tx.PushOutput(genAddress, ux.Body.Coins, ux.Body.Hours)
	tx.UpdateHeader()
	assertError(t, bc.VerifyTransaction(tx),
		"Signature not valid for output being spent")
}
Пример #13
0
func NewWalletEntry() WalletEntry {
	pub, sec := cipher.GenerateKeyPair()
	return NewWalletEntryFromKeypair(pub, sec)
}
Пример #14
0
func makeAddress() cipher.Address {
	p, _ := cipher.GenerateKeyPair()
	return cipher.AddressFromPubKey(p)
}
Пример #15
0
func init() {
	_, s := cipher.GenerateKeyPair()
	gSeckey = s.Hex()
}
Пример #16
0
func _gensec() cipher.SecKey {
	_, s := cipher.GenerateKeyPair()
	return s
}
Пример #17
0
package coin

import (
	"encoding/hex"
	"math/rand"
	"testing"
	"time"

	"github.com/skycoin/skycoin/src/cipher"
	"github.com/stretchr/testify/assert"
)

var (
	genPublic, genSecret        = cipher.GenerateKeyPair()
	genAddress                  = cipher.AddressFromPubKey(genPublic)
	testMaxSize                 = 1024 * 1024
	_genTime             uint64 = 1000
	_incTime             uint64 = 3600 * 1000
	_genCoins            uint64 = 1000e6
	_genCoinHours        uint64 = 1000 * 1000
)

func assertError(t *testing.T, err error, msg string) {
	assert.NotNil(t, err)
	assert.Equal(t, err.Error(), msg)
}

func tNow() uint64 {
	return uint64(time.Now().UTC().Unix())
}
Пример #18
0
func CreatePubKey() cipher.PubKey {
	pub, _ := cipher.GenerateKeyPair()
	return pub
}
Пример #19
0
func TestVerifyTransactionSpending(t *testing.T) {
	ft := FakeTree{}
	bc := NewBlockchain(&ft, nil)
	bc.CreateGenesisBlock(genAddress, _genCoins, _genTime)

	// Overspending hours

	tx := coin.Transaction{}
	uxs := bc.GetUnspent().Array()
	tx.PushInput(uxs[0].Hash())
	tx.PushOutput(genAddress, 1e6, uxs[0].Body.Hours)
	tx.PushOutput(genAddress, uxs[0].Body.Coins-1e6, 1)
	uxIn, err := bc.GetUnspent().GetMultiple(tx.In)
	assert.Nil(t, err)
	uxOut := coin.CreateUnspents(bc.Head().Head, tx)
	assertError(t, coin.VerifyTransactionSpending(bc.Time(), uxIn, uxOut),
		"Insufficient coin hours")

	// add block to blockchain.
	_, ux := addBlockToBlockchain(t, bc)
	// addBlockToBlockchain(t, bc)

	// Valid
	tx, _ = makeTransactionForChainWithHoursFee(t, bc, ux, genSecret, 100, 50)
	uxIn, err = bc.GetUnspent().GetMultiple(tx.In)
	assert.Nil(t, err)
	uxOut = coin.CreateUnspents(bc.Head().Head, tx)
	assert.Nil(t, coin.VerifyTransactionSpending(bc.Time(), uxIn, uxOut))

	// Destroying coins
	tx = coin.Transaction{}
	tx.PushInput(ux.Hash())
	tx.PushOutput(genAddress, 1e6, 100)
	tx.PushOutput(genAddress, 10e6, 100)
	uxIn, err = bc.GetUnspent().GetMultiple(tx.In)
	assert.Nil(t, err)
	uxOut = coin.CreateUnspents(bc.Head().Head, tx)
	err = coin.VerifyTransactionSpending(bc.Time(), uxIn, uxOut)
	assert.NotNil(t, err)
	assert.Equal(t, err.Error(),
		"Transactions may not create or destroy coins")
	assertError(t, coin.VerifyTransactionSpending(bc.Time(), uxIn, uxOut),
		"Transactions may not create or destroy coins")

	// Insufficient coins
	tx = coin.Transaction{}
	tx.PushInput(ux.Hash())
	p, s := cipher.GenerateKeyPair()
	a := cipher.AddressFromPubKey(p)
	coins := ux.Body.Coins
	assert.True(t, coins > 1e6)
	tx.PushOutput(a, 1e6, 100)
	tx.PushOutput(genAddress, coins-1e6, 100)
	tx.SignInputs([]cipher.SecKey{genSecret})
	tx.UpdateHeader()
	b, err := bc.NewBlockFromTransactions(coin.Transactions{tx}, bc.Time()+_incTime)
	assert.Nil(t, err)
	uxs, err = bc.ExecuteBlock(&b)
	assert.Nil(t, err)
	tx = coin.Transaction{}
	tx.PushInput(uxs[0].Hash())
	tx.PushOutput(a, 10e6, 1)
	tx.SignInputs([]cipher.SecKey{s})
	tx.UpdateHeader()
	uxIn, err = bc.GetUnspent().GetMultiple(tx.In)
	assert.Nil(t, err)
	uxOut = coin.CreateUnspents(bc.Head().Head, tx)
	assertError(t, coin.VerifyTransactionSpending(bc.Time(), uxIn, uxOut),
		"Insufficient coins")
}