Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wire: remove remember indexes #203

Merged
286 changes: 19 additions & 267 deletions blockchain/indexers/flatutreexoproofindex.go

Large diffs are not rendered by default.

201 changes: 7 additions & 194 deletions blockchain/indexers/indexers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,10 @@ func createDB(dbName string) (database.DB, string, error) {
return db, dbPath, nil
}

func initIndexes(interval int32, dbPath string, db database.DB, params *chaincfg.Params) (
func initIndexes(dbPath string, db database.DB, params *chaincfg.Params) (
*Manager, []Indexer, error) {

proofGenInterval := new(int32)
*proofGenInterval = interval
flatUtreexoProofIndex, err := NewFlatUtreexoProofIndex(false, params, proofGenInterval, 50*1024*1024, dbPath, db.Flush)
flatUtreexoProofIndex, err := NewFlatUtreexoProofIndex(false, params, 50*1024*1024, dbPath, db.Flush)
if err != nil {
return nil, nil, err
}
Expand All @@ -93,7 +91,7 @@ func initIndexes(interval int32, dbPath string, db database.DB, params *chaincfg
return indexManager, indexes, nil
}

func indexersTestChain(testName string, proofGenInterval int32) (*blockchain.BlockChain, []Indexer, *chaincfg.Params, *Manager, func()) {
func indexersTestChain(testName string) (*blockchain.BlockChain, []Indexer, *chaincfg.Params, *Manager, func()) {
params := chaincfg.RegressionNetParams
params.CoinbaseMaturity = 1

Expand All @@ -109,7 +107,7 @@ func indexersTestChain(testName string, proofGenInterval int32) (*blockchain.Blo
}

// Create the indexes to be used in the chain.
indexManager, indexes, err := initIndexes(proofGenInterval, dbPath, db, &params)
indexManager, indexes, err := initIndexes(dbPath, db, &params)
if err != nil {
tearDown()
os.RemoveAll(testDbRoot)
Expand Down Expand Up @@ -337,113 +335,6 @@ func syncCsnChain(start, end int32, chainToSyncFrom, csnChain *blockchain.BlockC
return nil
}

// syncCsnChainMultiBlockProof will take in two chains: one to sync from, one to sync.
// Sync will be done from start to end using multi-block proofs.
func syncCsnChainMultiBlockProof(start, end, interval int32, chainToSyncFrom, csnChain *blockchain.BlockChain,
indexes []Indexer) error {

for b := start; b <= end; b++ {
var err error
var ud, multiUd *wire.UData
var dels []utreexo.Hash
var remembers []uint32
if (b % interval) == 0 {
for _, indexer := range indexes {
switch idxType := indexer.(type) {
case *FlatUtreexoProofIndex:
var roots utreexo.Stump
if b != 0 {
roots, err = idxType.fetchRoots(b)
if err != nil {
return err
}
}

_, multiUd, dels, err = idxType.FetchMultiUtreexoProof(b + csnChain.GetUtreexoView().GetProofInterval())
if err != nil {
return err
}

ud, _, _, err = idxType.FetchMultiUtreexoProof(b)
if err != nil {
return err
}

remembers, err = idxType.FetchRemembers(b)
if err != nil {
return err
}

_, err = utreexo.Verify(roots, dels, multiUd.AccProof)
if err != nil {
panic(err)
}
}
}
err = csnChain.GetUtreexoView().AddProof(dels, &multiUd.AccProof)
if err != nil {
return fmt.Errorf("syncCsnChainMultiBlockProof err at height %d. err: %v:", b, err)
}
} else {
for _, indexer := range indexes {
switch idxType := indexer.(type) {
case *FlatUtreexoProofIndex:
ud, err = idxType.FetchUtreexoProof(b, true)
if err != nil {
return err
}

remembers, err = idxType.FetchRemembers(b)
if err != nil {
return err
}
}
}
}

// Fetch the raw block bytes from the database.
block, err := chainToSyncFrom.BlockByHeight(b)
if err != nil {
str := fmt.Errorf("Fail at block height %d err:%s\n", b, err)
return str
}

ud.RememberIdx = remembers
block.MsgBlock().UData = ud

_, _, err = csnChain.ProcessBlock(block, blockchain.BFNone)
if err != nil {
str := fmt.Errorf("ProcessBlock fail at block height %d err: %s\n", b, err)
return str
}

// Fetch and compare the roots after processing the block.
var expectRoots []*chainhash.Hash
for _, indexer := range indexes {
switch idxType := indexer.(type) {
case *FlatUtreexoProofIndex:
// +1 because for bridge indexes, we save the root before the modify.
stump, err := idxType.fetchRoots(block.Height() + 1)
if err != nil {
return err
}
expectRoots = make([]*chainhash.Hash, len(stump.Roots))

for i, root := range stump.Roots {
newRoot := chainhash.Hash(root)
expectRoots[i] = &newRoot
}
}
}
if !csnChain.GetUtreexoView().Equal(expectRoots) {
return fmt.Errorf("expected roots %v but got %v on block %s(%d)",
expectRoots, csnChain.GetUtreexoView().GetRoots(), block.Hash().String(), block.Height())
}
}

return nil
}

// testUtreexoProof tests the generated proof on the exact same accumulator,
// making sure that the verification code pass.
func testUtreexoProof(block *btcutil.Block, chain *blockchain.BlockChain, indexes []Indexer) error {
Expand Down Expand Up @@ -590,7 +481,7 @@ func TestProveUtxos(t *testing.T) {
source := rand.NewSource(timenow)
rand := rand.New(source)

chain, indexes, params, _, tearDown := indexersTestChain("TestProveUtxos", 1)
chain, indexes, params, _, tearDown := indexersTestChain("TestProveUtxos")
defer tearDown()

var allSpends []*blockchain.SpendableOut
Expand Down Expand Up @@ -728,7 +619,7 @@ func TestUtreexoProofIndex(t *testing.T) {
source := rand.NewSource(timenow)
rand := rand.New(source)

chain, indexes, params, _, tearDown := indexersTestChain("TestUtreexoProofIndex", 1)
chain, indexes, params, _, tearDown := indexersTestChain("TestUtreexoProofIndex")
defer tearDown()

tip := btcutil.NewBlock(params.GenesisBlock)
Expand Down Expand Up @@ -845,89 +736,11 @@ func TestUtreexoProofIndex(t *testing.T) {
}
}

func TestMultiBlockProof(t *testing.T) {
// Always remove the root on return.
defer os.RemoveAll(testDbRoot)

timenow := time.Now().UnixNano()
source := rand.NewSource(timenow)
rand := rand.New(source)

chain, indexes, params, _, tearDown := indexersTestChain("TestMultiBlockProof", defaultProofGenInterval)
defer tearDown()

tip := btcutil.NewBlock(params.GenesisBlock)

var allSpends []*blockchain.SpendableOut
nextBlock := tip
nextSpends := []*blockchain.SpendableOut{}

// Create a chain with 100 blocks.
for b := 0; b < 100; b++ {
newBlock, newSpendableOuts, err := blockchain.AddBlock(chain, nextBlock, nextSpends)
if err != nil {
t.Fatalf("timenow:%v. %v", timenow, err)
}
nextBlock = newBlock

allSpends = append(allSpends, newSpendableOuts...)

var nextSpendsTmp []*blockchain.SpendableOut
for i := 0; i < len(allSpends); i++ {
randIdx := rand.Intn(len(allSpends))

spend := allSpends[randIdx] // get
allSpends = append(allSpends[:randIdx], allSpends[randIdx+1:]...) // delete
nextSpendsTmp = append(nextSpendsTmp, spend)
}
nextSpends = nextSpendsTmp

if b%10 == 0 {
// Commit the two base blocks to DB
if err := chain.FlushUtxoCache(blockchain.FlushRequired); err != nil {
t.Fatalf("timenow %v. unexpected error while flushing cache: %v. Rand source %v",
timenow, err, source)
}
}
}

// Create a chain that consumes the data from the indexes and test that this
// chain is able to consume the data properly.
csnChain, _, csnTearDown, err := csnTestChain("TestMultiBlockProof-CsnChain")
defer csnTearDown()
if err != nil {
str := fmt.Errorf("TestMultiBlockProof: csnTestChain err: %v. Rand source: %v", err, source)
t.Fatalf("timenow:%v. %v", timenow, str)
}

csnChain.GetUtreexoView().SetProofInterval(defaultProofGenInterval)

// Sync the csn chain to tip-1 from block 1. We can only sync til one block away from the tip
// as the bridge hasn't built a multiblock proof for the next 10 blocks.
err = syncCsnChainMultiBlockProof(
1, chain.BestSnapshot().Height-1, defaultProofGenInterval, chain, csnChain, indexes)
if err != nil {
t.Fatalf("timenow %v. TestMultiBlockProof: syncCsnChainMultiBlockProof err: %v.", timenow, err)
}

bridgeBlock, err := chain.BlockByHeight(csnChain.BestSnapshot().Height)
if err != nil {
t.Fatalf("timenow:%v. %v", timenow, err)
}

// Sanity check that the csn chain did catch up to the bridge chain.
if *bridgeBlock.Hash() != csnChain.BestSnapshot().Hash {
t.Fatalf("timenow %v. expected tip to be %s(%d) but got %s(%d) for the csn chain",
timenow, bridgeBlock.Hash().String(), bridgeBlock.Height(),
csnChain.BestSnapshot().Hash.String(), csnChain.BestSnapshot().Height)
}
}

func TestBridgeNodePruneUndoDataGen(t *testing.T) {
// Always remove the root on return.
defer os.RemoveAll(testDbRoot)

chain, indexes, params, indexManager, tearDown := indexersTestChain("TestBridgeNodePruneUndoDataGen", 1)
chain, indexes, params, indexManager, tearDown := indexersTestChain("TestBridgeNodePruneUndoDataGen")
defer tearDown()

var allSpends []*blockchain.SpendableOut
Expand Down
Loading
Loading