Пример #1
0
func TestNewBlockHeaderPanics(t *testing.T) {
	ct := uint64(100)
	head := coin.BlockHeader{Time: ct}
	assert.Panics(t, func() {
		coin.NewBlockHeader(head, coin.NewUnspentPool(), ct, 50, coin.BlockBody{})
	})
	assert.Panics(t, func() {
		coin.NewBlockHeader(head, coin.NewUnspentPool(), ct-1, 50, coin.BlockBody{})
	})
	assert.Panics(t, func() {
		coin.NewBlockHeader(head, coin.NewUnspentPool(), ct-ct, 50, coin.BlockBody{})
	})
	assert.NotPanics(t, func() {
		coin.NewBlockHeader(head, coin.NewUnspentPool(), ct+1, 50, coin.BlockBody{})
	})
}
Пример #2
0
func (fbc *fakeBlockchain) CreateGenesisBlock(genesisAddr cipher.Address, genesisCoins, timestamp uint64) coin.Block {
	txn := coin.Transaction{}
	txn.PushOutput(genesisAddr, genesisCoins, genesisCoins)
	body := coin.BlockBody{coin.Transactions{txn}}
	prevHash := cipher.SHA256{}
	head := coin.BlockHeader{
		Time:     timestamp,
		BodyHash: body.Hash(),
		PrevHash: prevHash,
		BkSeq:    0,
		Version:  0,
		Fee:      0,
		UxHash:   coin.NewUnspentPool().GetUxHash(),
	}
	b := coin.Block{
		Head: head,
		Body: body,
	}
	// b.Body.Transactions[0].UpdateHeader()
	fbc.blocks = append(fbc.blocks, b)
	ux := coin.UxOut{
		Head: coin.UxHead{
			Time:  timestamp,
			BkSeq: 0,
		},
		Body: coin.UxBody{
			SrcTransaction: txn.InnerHash, //user inner hash
			Address:        genesisAddr,
			Coins:          genesisCoins,
			Hours:          genesisCoins, // Allocate 1 coin hour per coin
		},
	}
	fbc.unspent.Add(ux)
	return b
}
Пример #3
0
func TestNewBlock(t *testing.T) {
	// TODO -- update this test for newBlock changes
	prev := coin.Block{Head: coin.BlockHeader{Version: 0x02, Time: 100, BkSeq: 98}}
	unsp := coin.NewUnspentPool()
	unsp.XorHash = randSHA256()
	txns := coin.Transactions{coin.Transaction{}}
	// invalid txn fees panics
	assert.Panics(t, func() { coin.NewBlock(prev, 133, unsp, txns, _badFeeCalc) })
	// no txns panics
	assert.Panics(t, func() {
		coin.NewBlock(prev, 133, unsp, nil, _feeCalc)
	})
	assert.Panics(t, func() {
		coin.NewBlock(prev, 133, unsp, coin.Transactions{}, _feeCalc)
	})
	// valid block is fine
	fee := uint64(121)
	currentTime := uint64(133)
	b := coin.NewBlock(prev, currentTime, unsp, txns, _makeFeeCalc(fee))
	assert.Equal(t, b.Body.Transactions, txns)
	assert.Equal(t, b.Head.Fee, fee*uint64(len(txns)))
	assert.Equal(t, b.Body, coin.BlockBody{txns})
	assert.Equal(t, b.Head.PrevHash, prev.HashHeader())
	assert.Equal(t, b.Head.Time, currentTime)
	assert.Equal(t, b.Head.BkSeq, prev.Head.BkSeq+1)
	assert.Equal(t, b.Head.UxHash,
		unsp.GetUxHash())
}
Пример #4
0
func (self SerializedBlockchain) ToBlockchain() *coin.Blockchain {
	bc := &coin.Blockchain{}
	bc.Blocks = self.Blocks
	pool := coin.NewUnspentPool()
	pool.Rebuild(self.Unspents)
	bc.Unspent = pool
	return bc
}
Пример #5
0
func TestGetUxHash(t *testing.T) {
	unsp := coin.NewUnspentPool()
	xor := randSHA256()
	unsp.XorHash = xor
	//prev := randSHA256(t)
	sh := unsp.GetUxHash()
	assert.True(t, bytes.Equal(xor[:], sh[:]))
	assert.NotEqual(t, sh, [4]byte{})
}
Пример #6
0
// NewBlockchain use the walker go throught the tree and update the head and unspent outputs.
func NewBlockchain(tree BlockTree, walker Walker) *Blockchain {
	bc := &Blockchain{
		tree:    tree,
		walker:  walker,
		unspent: coin.NewUnspentPool(),
	}

	bc.walkTree()
	return bc
}
Пример #7
0
func createUnconfirmedTxns(t *testing.T, up *UnconfirmedTxnPool, n int) []UnconfirmedTxn {
	uts := make([]UnconfirmedTxn, 4)
	usp := coin.NewUnspentPool()
	for i := 0; i < len(uts); i++ {
		tx, _ := makeValidTxn()
		ut := up.createUnconfirmedTxn(&usp, tx)
		uts[i] = ut
		up.Txns[ut.Hash()] = ut
	}
	assert.Equal(t, len(up.Txns), 4)
	return uts
}
Пример #8
0
func TestSpendsForAddresses(t *testing.T) {
	up := NewUnconfirmedTxnPool()
	unspent := coin.NewUnspentPool()
	addrs := make(map[cipher.Address]byte, 0)
	n := 4
	useAddrs := make([]cipher.Address, n)
	for i, _ := range useAddrs {
		useAddrs[i] = makeAddress()
	}
	useAddrs[1] = useAddrs[0]
	for _, a := range useAddrs {
		addrs[a] = byte(1)
	}
	// Make confirmed transactions to add to unspent pool
	uxs := make(coin.UxArray, 0)
	for i := 0; i < n; i++ {
		txn := coin.Transaction{}
		txn.PushInput(randSHA256())
		txn.PushOutput(useAddrs[i], 10e6, 1000)
		uxa := coin.CreateUnspents(coin.BlockHeader{}, txn)
		for _, ux := range uxa {
			unspent.Add(ux)
		}
		uxs = append(uxs, uxa...)
	}
	assert.Equal(t, len(uxs), 4)

	// Make unconfirmed txns that spend those unspents
	for i := 0; i < n; i++ {
		txn := coin.Transaction{}
		txn.PushInput(uxs[i].Hash())
		txn.PushOutput(makeAddress(), 10e6, 1000)
		ut := UnconfirmedTxn{
			Txn: txn,
		}
		up.Txns[ut.Hash()] = ut
	}

	// Now look them up
	assert.Equal(t, len(addrs), 3)
	assert.Equal(t, len(up.Txns), 4)
	auxs := up.SpendsForAddresses(&unspent, addrs)
	assert.Equal(t, len(auxs), 3)
	assert.Equal(t, len(auxs[useAddrs[0]]), 2)
	assert.Equal(t, len(auxs[useAddrs[2]]), 1)
	assert.Equal(t, len(auxs[useAddrs[3]]), 1)
	assert.Equal(t, auxs[useAddrs[0]], coin.UxArray{uxs[0], uxs[1]})
	assert.Equal(t, auxs[useAddrs[2]], coin.UxArray{uxs[2]})
	assert.Equal(t, auxs[useAddrs[3]], coin.UxArray{uxs[3]})
}
Пример #9
0
func makeValidTxn() (coin.Transaction, error) {
	w := wallet.NewWallet("test")
	w.GenerateAddresses(2)
	uncf := NewUnconfirmedTxnPool()
	now := tNow()
	a := makeAddress()
	uxs := makeUxBalancesForAddresses([]wallet.Balance{
		wallet.Balance{10e6, 150},
		wallet.Balance{15e6, 150},
	}, now, w.GetAddresses()[:2])
	unsp := coin.NewUnspentPool()
	addUxArrayToUnspentPool(&unsp, uxs)
	amt := wallet.Balance{10 * 1e6, 0}
	return CreateSpendingTransaction(w, uncf, &unsp, now, amt, a)
}
Пример #10
0
func makeNewBlock() coin.Block {
	unsp := coin.NewUnspentPool()
	body := coin.BlockBody{
		Transactions: coin.Transactions{coin.Transaction{}},
	}
	prev := coin.Block{
		Body: body,
		Head: coin.BlockHeader{
			Version:  0x02,
			Time:     100,
			BkSeq:    0,
			Fee:      10,
			PrevHash: cipher.SHA256{},
			BodyHash: body.Hash(),
		}}
	return coin.NewBlock(prev, 100+20, unsp, coin.Transactions{coin.Transaction{}}, _feeCalc)
}
Пример #11
0
func TestNewBlockHeader(t *testing.T) {
	// TODO -- update this test for newBlockHeader changes
	b := makeNewBlock()
	prev := b.Head
	unsp := coin.NewUnspentPool()
	unsp.XorHash = randSHA256()
	fee := uint64(10)
	bh := coin.NewBlockHeader(prev, unsp, prev.Time+22, fee, b.Body)
	assert.Equal(t, bh.PrevHash, prev.Hash())
	assert.NotEqual(t, bh.PrevHash, prev.PrevHash)
	assert.Equal(t, bh.Time, uint64(prev.Time+22))
	assert.Equal(t, bh.BkSeq, uint64(prev.BkSeq+1))
	assert.Equal(t, bh.Fee, fee)
	assert.Equal(t, bh.Version, prev.Version)
	assert.Equal(t, bh.BodyHash, b.Body.Hash())
	assert.Equal(t, bh.UxHash, unsp.GetUxHash())
}
Пример #12
0
func makeInvalidTxn() (coin.Transaction, error) {
	w := wallet.NewWallet("test")
	w.GenerateAddresses(2)
	uncf := NewUnconfirmedTxnPool()
	now := tNow()
	a := makeAddress()
	uxs := makeUxBalancesForAddresses([]wallet.Balance{}, now, w.GetAddresses()[:2])
	unsp := coin.NewUnspentPool()
	addUxArrayToUnspentPool(&unsp, uxs)
	amt := wallet.Balance{25 * 1e6, 0}
	txn, err := CreateSpendingTransaction(w, uncf, &unsp, now, amt, a)
	if err != nil {
		return txn, err
	}

	txn.Out[0].Address = cipher.Address{}
	return txn, nil
}
Пример #13
0
func TestSerializedBlockchain(t *testing.T) {
	defer cleanupVisor()
	cleanupVisor()
	bc := &coin.Blockchain{}
	bc.Blocks = []coin.Block{}
	for i := uint64(0); i < 10; i++ {
		bc.Blocks = append(bc.Blocks, coin.Block{})
		bc.Blocks[i].Head.BkSeq = i
	}
	assert.Equal(t, len(bc.Blocks), 10)
	bc.Unspent = coin.NewUnspentPool()
	for i := uint64(0); i < 10; i++ {
		bc.Unspent.Add(makeUxOut(t))
	}
	assert.Equal(t, len(bc.Unspent.Pool), 10)

	sbc := NewSerializedBlockchain(bc)
	assert.Equal(t, sbc.Blocks, bc.Blocks)
	assert.Equal(t, len(sbc.Unspents), len(bc.Unspent.Pool))

	// Back to blockchain works
	assert.Equal(t, bc, sbc.ToBlockchain())

	// Saving and reloading works
	assert.Nil(t, sbc.Save(testBlockchainFile))
	assertFileExists(t, testBlockchainFile)

	sbc2, err := LoadSerializedBlockchain(testBlockchainFile)
	assert.Nil(t, err)
	assert.Equal(t, sbc, sbc2)
	assert.Equal(t, bc, sbc2.ToBlockchain())

	bc2, err := LoadBlockchain(testBlockchainFile)
	assert.Nil(t, err)
	assert.Equal(t, bc, bc2)
}
Пример #14
0
func NewUnconfirmedTxnPool() *UnconfirmedTxnPool {
	return &UnconfirmedTxnPool{
		Txns:    make(map[coin.SHA256]UnconfirmedTxn),
		Unspent: coin.NewUnspentPool(),
	}
}
Пример #15
0
func TestCreateSpendingTransaction(t *testing.T) {
	// Setup
	w := wallet.NewSimpleWallet()
	for i := 0; i < 4; i++ {
		w.CreateEntry()
	}
	uncf := NewUnconfirmedTxnPool()
	now := tNow()
	a := makeAddress()

	// Failing createSpends
	amt := wallet.Balance{0, 0}
	unsp := coin.NewUnspentPool()
	_, err := CreateSpendingTransaction(w, uncf, &unsp, now, amt, 0, 0, a)
	assert.NotNil(t, err)

	// Valid txn, fee, no change
	uxs := makeUxBalancesForAddresses([]wallet.Balance{
		wallet.Balance{10e6, 150},
		wallet.Balance{15e6, 150},
	}, now, w.GetAddresses()[:2])
	unsp = coin.NewUnspentPool()
	addUxArrayToUnspentPool(&unsp, uxs)
	amt = wallet.Balance{25e6, 200}
	tx, err := CreateSpendingTransaction(w, uncf, &unsp, now, amt, 100, 0, a)
	assert.Nil(t, err)
	assert.Equal(t, len(tx.Out), 1)
	assert.Equal(t, tx.Out[0], coin.TransactionOutput{
		Coins:   25e6,
		Hours:   200,
		Address: a,
	})
	assert.Equal(t, len(tx.In), 2)
	assert.Equal(t, tx.In, []coin.SHA256{uxs[0].Hash(), uxs[1].Hash()})
	assert.Nil(t, tx.Verify())

	// Valid txn, change
	uxs = makeUxBalancesForAddresses([]wallet.Balance{
		wallet.Balance{10e6, 150},
		wallet.Balance{15e6, 200},
		wallet.Balance{1e6, 125},
	}, now, w.GetAddresses()[:3])
	unsp = coin.NewUnspentPool()
	addUxArrayToUnspentPool(&unsp, uxs)
	amt = wallet.Balance{25e6, 200}
	tx, err = CreateSpendingTransaction(w, uncf, &unsp, now, amt, 100, 0, a)
	assert.Nil(t, err)
	assert.Equal(t, len(tx.Out), 2)
	assert.Equal(t, tx.Out[0], coin.TransactionOutput{
		Coins:   1e6,
		Hours:   (150 + 200 + 125) - (200 + 100),
		Address: w.GetAddresses()[0],
	})
	assert.Equal(t, tx.Out[1], coin.TransactionOutput{
		Coins:   25e6,
		Hours:   200,
		Address: a,
	})
	assert.Equal(t, len(tx.In), 3)
	assert.Equal(t, tx.In, []coin.SHA256{
		uxs[0].Hash(), uxs[1].Hash(), uxs[2].Hash(),
	})
	assert.Nil(t, tx.Verify())

	// Valid txn, but wastes coin hours
	uxs = makeUxBalancesForAddresses([]wallet.Balance{
		wallet.Balance{10e6, 150},
		wallet.Balance{15e6, 200},
	}, now, w.GetAddresses()[:2])
	unsp = coin.NewUnspentPool()
	addUxArrayToUnspentPool(&unsp, uxs)
	amt = wallet.Balance{25e6, 200}
	_, err = CreateSpendingTransaction(w, uncf, &unsp, now, amt, 100, 0, a)
	assertError(t, err, "Have enough coins, but not enough to send coin "+
		"hours change back. Would spend 50 more hours than requested.")

	// Would be valid, but unconfirmed subtraction causes it to not be
	// First, make a txn to subtract
	uxs = makeUxBalancesForAddresses([]wallet.Balance{
		wallet.Balance{10e6, 150},
		wallet.Balance{15e6, 150},
	}, now, w.GetAddresses()[:2])
	unsp = coin.NewUnspentPool()
	addUxArrayToUnspentPool(&unsp, uxs)
	amt = wallet.Balance{25e6, 200}
	tx, err = CreateSpendingTransaction(w, uncf, &unsp, now, amt, 100, 0, a)
	assert.Nil(t, err)
	// Add it to the unconfirmed pool (bypass RecordTxn to avoid blockchain)
	uncf.Txns[tx.Hash()] = uncf.createUnconfirmedTxn(&unsp, tx,
		w.GetAddressSet())
	// Make a spend that must not reuse previous addresses
	_, err = CreateSpendingTransaction(w, uncf, &unsp, now, amt, 100, 0, a)
	assertError(t, err, "Not enough coins")
}
Пример #16
0
func TestCreateSpendingTransaction(t *testing.T) {
	// Setup

	w := wallet.NewWallet("fortest.wlt")

	w.GenerateAddresses(4)
	uncf := NewUnconfirmedTxnPool()
	now := tNow()
	a := makeAddress()

	// Failing createSpends
	amt := wallet.Balance{0, 0}
	unsp := coin.NewUnspentPool()
	_, err := CreateSpendingTransaction(w, uncf, &unsp, now, amt, a)
	assert.NotNil(t, err)

	// Valid txn, fee, no change
	uxs := makeUxBalancesForAddresses([]wallet.Balance{
		wallet.Balance{10e6, 150},
		wallet.Balance{15e6, 150},
	}, now, w.GetAddresses()[:2])
	unsp = coin.NewUnspentPool()
	addUxArrayToUnspentPool(&unsp, uxs)
	amt = wallet.Balance{25e6, 200}
	tx, err := CreateSpendingTransaction(w, uncf, &unsp, now, amt, a)
	assert.Nil(t, err)
	assert.Equal(t, len(tx.Out), 1)
	assert.Equal(t, tx.Out[0], coin.TransactionOutput{
		Coins:   25e6,
		Hours:   37,
		Address: a,
	})
	assert.Equal(t, len(tx.In), 2)
	assert.Equal(t, tx.In, []cipher.SHA256{uxs[0].Hash(), uxs[1].Hash()})
	assert.Nil(t, tx.Verify())

	// Valid txn, change
	uxs = makeUxBalancesForAddresses([]wallet.Balance{
		wallet.Balance{10e6, 150},
		wallet.Balance{15e6, 200},
		wallet.Balance{1e6, 125},
	}, now, w.GetAddresses()[:3])
	unsp = coin.NewUnspentPool()
	addUxArrayToUnspentPool(&unsp, uxs)
	amt = wallet.Balance{25e6, 200}
	tx, err = CreateSpendingTransaction(w, uncf, &unsp, now, amt, a)
	assert.Nil(t, err)
	assert.Equal(t, len(tx.Out), 2)
	assert.Equal(t, tx.Out[0], coin.TransactionOutput{
		Coins:   1e6,
		Hours:   (150 + 200 + 125) / 8,
		Address: w.GetAddresses()[0],
	})
	assert.Equal(t, tx.Out[1], coin.TransactionOutput{
		Coins:   25e6,
		Hours:   (150 + 200 + 125) / 8,
		Address: a,
	})
	assert.Equal(t, len(tx.In), 3)
	assert.Equal(t, tx.In, []cipher.SHA256{
		uxs[0].Hash(), uxs[1].Hash(), uxs[2].Hash(),
	})
	assert.Nil(t, tx.Verify())

	// Would be valid, but unconfirmed subtraction causes it to not be
	// First, make a txn to subtract
	uxs = makeUxBalancesForAddresses([]wallet.Balance{
		wallet.Balance{10e6, 150},
		wallet.Balance{15e6, 150},
	}, now, w.GetAddresses()[:2])
	unsp = coin.NewUnspentPool()
	addUxArrayToUnspentPool(&unsp, uxs)
	amt = wallet.Balance{25e6, 200}
	tx, err = CreateSpendingTransaction(w, uncf, &unsp, now, amt, a)
	assert.Nil(t, err)
	// Add it to the unconfirmed pool (bypass InjectTxn to avoid blockchain)
	uncf.Txns[tx.Hash()] = uncf.createUnconfirmedTxn(&unsp, tx)
	// Make a spend that must not reuse previous addresses
	_, err = CreateSpendingTransaction(w, uncf, &unsp, now, amt, a)
	assertError(t, err, "Not enough coins")
}
Пример #17
0
func newBlockchain() historydb.Blockchainer {
	return &fakeBlockchain{
		unspent: coin.NewUnspentPool(),
	}
}