2019-07-25 22:15:03 +00:00
package state
2019-07-20 21:57:31 +00:00
import (
2020-01-22 19:53:06 +00:00
"context"
2020-03-19 00:23:59 +00:00
"fmt"
2019-07-20 21:57:31 +00:00
"testing"
2020-09-17 15:30:15 +00:00
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
2020-03-05 01:19:15 +00:00
2019-12-19 20:13:17 +00:00
address "github.com/filecoin-project/go-address"
2020-09-28 23:23:46 +00:00
"github.com/filecoin-project/go-state-types/network"
2020-10-08 01:09:33 +00:00
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
2020-09-17 15:30:15 +00:00
"github.com/filecoin-project/lotus/build"
2019-10-18 04:47:41 +00:00
"github.com/filecoin-project/lotus/chain/types"
2019-07-20 21:57:31 +00:00
)
func BenchmarkStateTreeSet ( b * testing . B ) {
2020-02-04 22:19:05 +00:00
cst := cbor . NewMemCborStore ( )
2020-10-08 01:09:33 +00:00
st , err := NewStateTree ( cst , types . StateTreeVersion1 )
2019-07-20 21:57:31 +00:00
if err != nil {
b . Fatal ( err )
}
b . ResetTimer ( )
b . ReportAllocs ( )
for i := 0 ; i < b . N ; i ++ {
a , err := address . NewIDAddress ( uint64 ( i ) )
if err != nil {
b . Fatal ( err )
}
err = st . SetActor ( a , & types . Actor {
Balance : types . NewInt ( 1258812523 ) ,
2020-10-08 01:09:33 +00:00
Code : builtin2 . StorageMinerActorCodeID ,
Head : builtin2 . AccountActorCodeID ,
2019-07-20 21:57:31 +00:00
Nonce : uint64 ( i ) ,
} )
if err != nil {
b . Fatal ( err )
}
}
}
func BenchmarkStateTreeSetFlush ( b * testing . B ) {
2020-02-04 22:19:05 +00:00
cst := cbor . NewMemCborStore ( )
2020-10-06 22:22:54 +00:00
st , err := NewStateTree ( cst , VersionForNetwork ( build . NewestNetworkVersion ) )
2019-07-20 21:57:31 +00:00
if err != nil {
b . Fatal ( err )
}
b . ResetTimer ( )
b . ReportAllocs ( )
for i := 0 ; i < b . N ; i ++ {
a , err := address . NewIDAddress ( uint64 ( i ) )
if err != nil {
b . Fatal ( err )
}
err = st . SetActor ( a , & types . Actor {
Balance : types . NewInt ( 1258812523 ) ,
2020-10-08 01:09:33 +00:00
Code : builtin2 . StorageMinerActorCodeID ,
Head : builtin2 . AccountActorCodeID ,
2019-07-20 21:57:31 +00:00
Nonce : uint64 ( i ) ,
} )
if err != nil {
b . Fatal ( err )
}
2020-01-22 19:53:06 +00:00
if _ , err := st . Flush ( context . TODO ( ) ) ; err != nil {
2019-07-20 21:57:31 +00:00
b . Fatal ( err )
}
}
}
2020-10-19 23:25:41 +00:00
func TestResolveCache ( t * testing . T ) {
cst := cbor . NewMemCborStore ( )
st , err := NewStateTree ( cst , VersionForNetwork ( build . NewestNetworkVersion ) )
if err != nil {
t . Fatal ( err )
}
nonId := address . NewForTestGetter ( ) ( )
id , _ := address . NewIDAddress ( 1000 )
st . lookupIDFun = func ( a address . Address ) ( address . Address , error ) {
if a == nonId {
return id , nil
}
2020-10-19 23:32:51 +00:00
return address . Undef , types . ErrActorNotFound
2020-10-19 23:25:41 +00:00
}
err = st . SetActor ( nonId , & types . Actor { Nonce : 1 } )
if err != nil {
t . Fatal ( err )
}
{
err = st . Snapshot ( context . TODO ( ) )
if err != nil {
t . Fatal ( err )
}
act , err := st . GetActor ( nonId )
if err != nil {
t . Fatal ( err )
}
if act . Nonce != 1 {
t . Fatalf ( "expected nonce 1, got %d" , act . Nonce )
}
err = st . SetActor ( nonId , & types . Actor { Nonce : 2 } )
if err != nil {
t . Fatal ( err )
}
act , err = st . GetActor ( nonId )
if err != nil {
t . Fatal ( err )
}
if act . Nonce != 2 {
t . Fatalf ( "expected nonce 2, got %d" , act . Nonce )
}
if err := st . Revert ( ) ; err != nil {
t . Fatal ( err )
}
st . ClearSnapshot ( )
}
act , err := st . GetActor ( nonId )
if err != nil {
t . Fatal ( err )
}
if act . Nonce != 1 {
t . Fatalf ( "expected nonce 1, got %d" , act . Nonce )
}
{
err = st . Snapshot ( context . TODO ( ) )
if err != nil {
t . Fatal ( err )
}
act , err := st . GetActor ( nonId )
if err != nil {
t . Fatal ( err )
}
if act . Nonce != 1 {
t . Fatalf ( "expected nonce 1, got %d" , act . Nonce )
}
err = st . SetActor ( nonId , & types . Actor { Nonce : 2 } )
if err != nil {
t . Fatal ( err )
}
act , err = st . GetActor ( nonId )
if err != nil {
t . Fatal ( err )
}
if act . Nonce != 2 {
t . Fatalf ( "expected nonce 2, got %d" , act . Nonce )
}
st . ClearSnapshot ( )
}
act , err = st . GetActor ( nonId )
if err != nil {
t . Fatal ( err )
}
if act . Nonce != 2 {
t . Fatalf ( "expected nonce 2, got %d" , act . Nonce )
}
}
2019-07-20 21:57:31 +00:00
func BenchmarkStateTree10kGetActor ( b * testing . B ) {
2020-02-04 22:19:05 +00:00
cst := cbor . NewMemCborStore ( )
2020-10-06 22:22:54 +00:00
st , err := NewStateTree ( cst , VersionForNetwork ( build . NewestNetworkVersion ) )
2019-07-20 21:57:31 +00:00
if err != nil {
b . Fatal ( err )
}
for i := 0 ; i < 10000 ; i ++ {
a , err := address . NewIDAddress ( uint64 ( i ) )
if err != nil {
b . Fatal ( err )
}
err = st . SetActor ( a , & types . Actor {
Balance : types . NewInt ( 1258812523 + uint64 ( i ) ) ,
2020-10-08 01:09:33 +00:00
Code : builtin2 . StorageMinerActorCodeID ,
Head : builtin2 . AccountActorCodeID ,
2019-07-20 21:57:31 +00:00
Nonce : uint64 ( i ) ,
} )
if err != nil {
b . Fatal ( err )
}
}
2020-01-22 19:53:06 +00:00
if _ , err := st . Flush ( context . TODO ( ) ) ; err != nil {
2019-07-20 21:57:31 +00:00
b . Fatal ( err )
}
b . ResetTimer ( )
b . ReportAllocs ( )
for i := 0 ; i < b . N ; i ++ {
a , err := address . NewIDAddress ( uint64 ( i % 10000 ) )
if err != nil {
b . Fatal ( err )
}
_ , err = st . GetActor ( a )
if err != nil {
b . Fatal ( err )
}
}
}
2019-09-23 09:52:53 +00:00
func TestSetCache ( t * testing . T ) {
2020-02-04 22:19:05 +00:00
cst := cbor . NewMemCborStore ( )
2020-10-06 22:22:54 +00:00
st , err := NewStateTree ( cst , VersionForNetwork ( build . NewestNetworkVersion ) )
2019-09-23 09:52:53 +00:00
if err != nil {
t . Fatal ( err )
}
a , err := address . NewIDAddress ( uint64 ( 222 ) )
if err != nil {
t . Fatal ( err )
}
act := & types . Actor {
Balance : types . NewInt ( 0 ) ,
2020-10-08 01:09:33 +00:00
Code : builtin2 . StorageMinerActorCodeID ,
Head : builtin2 . AccountActorCodeID ,
2019-09-23 09:52:53 +00:00
Nonce : 0 ,
}
err = st . SetActor ( a , act )
if err != nil {
t . Fatal ( err )
}
act . Nonce = 1
outact , err := st . GetActor ( a )
if err != nil {
t . Fatal ( err )
}
2020-04-03 00:09:41 +00:00
if outact . Nonce == 1 {
t . Error ( "nonce should not have updated" )
2019-09-23 09:52:53 +00:00
}
}
2020-03-05 01:19:15 +00:00
func TestSnapshots ( t * testing . T ) {
ctx := context . Background ( )
cst := cbor . NewMemCborStore ( )
2020-10-06 22:22:54 +00:00
st , err := NewStateTree ( cst , VersionForNetwork ( build . NewestNetworkVersion ) )
2020-03-05 01:19:15 +00:00
if err != nil {
t . Fatal ( err )
}
var addrs [ ] address . Address
//for _, a := range []string{"t15ocrptbu4i5qucjvvwecihd7fqqgzb27pz5l5zy", "t1dpyvgavvl3f4ujlk6odedss54z6rt5gyuknsuva", "t1feiejbkcvozy7iltt2pxzuoq4d2kpbsusugan7a", "t3rgjfqybjx7bahuhfv7nwfg3tlm4i4zyvldfirjvzm5z5xwjoqbj3rfi2mpmlxpqwxxxafgpkjilqzpg7cefa"} {
for _ , a := range [ ] string { "t0100" , "t0101" , "t0102" , "t0103" } {
addr , err := address . NewFromString ( a )
if err != nil {
t . Fatal ( err )
}
addrs = append ( addrs , addr )
}
if err := st . Snapshot ( ctx ) ; err != nil {
t . Fatal ( err )
}
2020-10-08 01:09:33 +00:00
if err := st . SetActor ( addrs [ 0 ] , & types . Actor { Code : builtin2 . AccountActorCodeID , Head : builtin2 . AccountActorCodeID , Balance : types . NewInt ( 55 ) } ) ; err != nil {
2020-03-05 01:19:15 +00:00
t . Fatal ( err )
}
{ // sub call that will fail
if err := st . Snapshot ( ctx ) ; err != nil {
t . Fatal ( err )
}
2020-10-08 01:09:33 +00:00
if err := st . SetActor ( addrs [ 1 ] , & types . Actor { Code : builtin2 . AccountActorCodeID , Head : builtin2 . AccountActorCodeID , Balance : types . NewInt ( 77 ) } ) ; err != nil {
2020-03-05 01:19:15 +00:00
t . Fatal ( err )
}
if err := st . Revert ( ) ; err != nil {
t . Fatal ( err )
}
st . ClearSnapshot ( )
}
// more operations in top level call...
2020-10-08 01:09:33 +00:00
if err := st . SetActor ( addrs [ 2 ] , & types . Actor { Code : builtin2 . AccountActorCodeID , Head : builtin2 . AccountActorCodeID , Balance : types . NewInt ( 123 ) } ) ; err != nil {
2020-03-05 01:19:15 +00:00
t . Fatal ( err )
}
{ // sub call that succeeds
if err := st . Snapshot ( ctx ) ; err != nil {
t . Fatal ( err )
}
2020-10-08 01:09:33 +00:00
if err := st . SetActor ( addrs [ 3 ] , & types . Actor { Code : builtin2 . AccountActorCodeID , Head : builtin2 . AccountActorCodeID , Balance : types . NewInt ( 5 ) } ) ; err != nil {
2020-03-05 01:19:15 +00:00
t . Fatal ( err )
}
st . ClearSnapshot ( )
}
2020-04-03 00:09:41 +00:00
st . ClearSnapshot ( )
2020-03-05 01:19:15 +00:00
if _ , err := st . Flush ( ctx ) ; err != nil {
t . Fatal ( err )
}
assertHas ( t , st , addrs [ 0 ] )
assertNotHas ( t , st , addrs [ 1 ] )
assertHas ( t , st , addrs [ 2 ] )
assertHas ( t , st , addrs [ 3 ] )
}
func assertHas ( t * testing . T , st * StateTree , addr address . Address ) {
_ , err := st . GetActor ( addr )
if err != nil {
t . Fatal ( err )
}
}
func assertNotHas ( t * testing . T , st * StateTree , addr address . Address ) {
_ , err := st . GetActor ( addr )
if err == nil {
t . Fatal ( "shouldnt have found actor" , addr )
}
}
2020-03-19 00:23:59 +00:00
func TestStateTreeConsistency ( t * testing . T ) {
cst := cbor . NewMemCborStore ( )
2020-09-28 23:23:46 +00:00
// TODO: ActorUpgrade: this test tests pre actors v2
2020-10-06 22:22:54 +00:00
st , err := NewStateTree ( cst , VersionForNetwork ( network . Version3 ) )
2020-03-19 00:23:59 +00:00
if err != nil {
t . Fatal ( err )
}
var addrs [ ] address . Address
for i := 100 ; i < 150 ; i ++ {
a , err := address . NewIDAddress ( uint64 ( i ) )
if err != nil {
t . Fatal ( err )
}
addrs = append ( addrs , a )
}
randomCid , err := cid . Decode ( "bafy2bzacecu7n7wbtogznrtuuvf73dsz7wasgyneqasksdblxupnyovmtwxxu" )
if err != nil {
t . Fatal ( err )
}
for i , a := range addrs {
2020-05-27 20:53:20 +00:00
err := st . SetActor ( a , & types . Actor {
2020-03-19 00:23:59 +00:00
Code : randomCid ,
Head : randomCid ,
Balance : types . NewInt ( uint64 ( 10000 + i ) ) ,
Nonce : uint64 ( 1000 - i ) ,
} )
2020-05-27 20:53:20 +00:00
if err != nil {
t . Fatalf ( "while setting actor: %+v" , err )
}
2020-03-19 00:23:59 +00:00
}
root , err := st . Flush ( context . TODO ( ) )
if err != nil {
t . Fatal ( err )
}
fmt . Println ( "root is: " , root )
2020-07-23 21:03:25 +00:00
if root . String ( ) != "bafy2bzaceb2bhqw75pqp44efoxvlnm73lnctq6djair56bfn5x3gw56epcxbi" {
2020-03-19 00:23:59 +00:00
t . Fatal ( "MISMATCH!" )
}
}