github.com/filecoin-project/specs-actors/v4@v4.0.2/actors/test/multisig_delete_self_test.go (about)

     1  package test
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"testing"
     7  
     8  	"github.com/filecoin-project/go-address"
     9  	"github.com/filecoin-project/go-state-types/big"
    10  	"github.com/filecoin-project/go-state-types/exitcode"
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  
    14  	"github.com/filecoin-project/specs-actors/v4/actors/builtin"
    15  	init_ "github.com/filecoin-project/specs-actors/v4/actors/builtin/init"
    16  	"github.com/filecoin-project/specs-actors/v4/actors/builtin/multisig"
    17  	"github.com/filecoin-project/specs-actors/v4/support/ipld"
    18  	vm "github.com/filecoin-project/specs-actors/v4/support/vm"
    19  )
    20  
    21  func TestMultisigDeleteSelf2Of3RemovedIsProposer(t *testing.T) {
    22  	ctx := context.Background()
    23  	v := vm.NewVMWithSingletons(ctx, t, ipld.NewBlockStoreInMemory())
    24  	addrs := vm.CreateAccounts(ctx, t, v, 3, big.Mul(big.NewInt(10_000), big.NewInt(1e18)), 93837778)
    25  
    26  	multisigParams := multisig.ConstructorParams{
    27  		Signers:               addrs,
    28  		NumApprovalsThreshold: 2,
    29  	}
    30  
    31  	paramBuf := new(bytes.Buffer)
    32  	err := multisigParams.MarshalCBOR(paramBuf)
    33  	require.NoError(t, err)
    34  
    35  	initParam := init_.ExecParams{
    36  		CodeCID:           builtin.MultisigActorCodeID,
    37  		ConstructorParams: paramBuf.Bytes(),
    38  	}
    39  	ret := vm.ApplyOk(t, v, addrs[0], builtin.InitActorAddr, big.Zero(), builtin.MethodsPower.CreateMiner, &initParam)
    40  	initRet := ret.(*init_.ExecReturn)
    41  	assert.NotNil(t, initRet)
    42  	multisigAddr := initRet.IDAddress
    43  
    44  	removeParams := multisig.RemoveSignerParams{
    45  		Signer:   addrs[0],
    46  		Decrease: false,
    47  	}
    48  
    49  	paramBuf = new(bytes.Buffer)
    50  	err = removeParams.MarshalCBOR(paramBuf)
    51  	require.NoError(t, err)
    52  
    53  	proposeRemoveSignerParams := multisig.ProposeParams{
    54  		To:     multisigAddr,
    55  		Value:  big.Zero(),
    56  		Method: builtin.MethodsMultisig.RemoveSigner,
    57  		Params: paramBuf.Bytes(),
    58  	}
    59  
    60  	// first proposal goes ok and should have txnid = 0
    61  	vm.ApplyOk(t, v, addrs[0], multisigAddr, big.Zero(), builtin.MethodsMultisig.Propose, &proposeRemoveSignerParams)
    62  	// approval goes through
    63  	approveRemoveSignerParams := multisig.TxnIDParams{ID: multisig.TxnID(0)}
    64  	vm.ApplyOk(t, v, addrs[1], multisigAddr, big.Zero(), builtin.MethodsMultisig.Approve, &approveRemoveSignerParams)
    65  
    66  	// txnid not found when third approval gets processed indicating that the transaction has gone through successfully
    67  	_, code := v.ApplyMessage(addrs[2], multisigAddr, big.Zero(), builtin.MethodsMultisig.Approve, &approveRemoveSignerParams)
    68  	assert.Equal(t, exitcode.ErrNotFound, code)
    69  
    70  }
    71  
    72  func TestMultisigDeleteSelf2Of3RemovedIsApprover(t *testing.T) {
    73  	ctx := context.Background()
    74  	v := vm.NewVMWithSingletons(ctx, t, ipld.NewBlockStoreInMemory())
    75  	addrs := vm.CreateAccounts(ctx, t, v, 3, big.Mul(big.NewInt(10_000), big.NewInt(1e18)), 93837778)
    76  
    77  	multisigParams := multisig.ConstructorParams{
    78  		Signers:               addrs,
    79  		NumApprovalsThreshold: 2,
    80  	}
    81  
    82  	paramBuf := new(bytes.Buffer)
    83  	err := multisigParams.MarshalCBOR(paramBuf)
    84  	require.NoError(t, err)
    85  
    86  	initParam := init_.ExecParams{
    87  		CodeCID:           builtin.MultisigActorCodeID,
    88  		ConstructorParams: paramBuf.Bytes(),
    89  	}
    90  	ret := vm.ApplyOk(t, v, addrs[0], builtin.InitActorAddr, big.Zero(), builtin.MethodsPower.CreateMiner, &initParam)
    91  	initRet := ret.(*init_.ExecReturn)
    92  	assert.NotNil(t, initRet)
    93  	multisigAddr := initRet.IDAddress
    94  
    95  	removeParams := multisig.RemoveSignerParams{
    96  		Signer:   addrs[0],
    97  		Decrease: false,
    98  	}
    99  
   100  	paramBuf = new(bytes.Buffer)
   101  	err = removeParams.MarshalCBOR(paramBuf)
   102  	require.NoError(t, err)
   103  
   104  	proposeRemoveSignerParams := multisig.ProposeParams{
   105  		To:     multisigAddr,
   106  		Value:  big.Zero(),
   107  		Method: builtin.MethodsMultisig.RemoveSigner,
   108  		Params: paramBuf.Bytes(),
   109  	}
   110  
   111  	// first proposal goes ok and should have txnid = 0
   112  	vm.ApplyOk(t, v, addrs[1], multisigAddr, big.Zero(), builtin.MethodsMultisig.Propose, &proposeRemoveSignerParams)
   113  	// approval goes through
   114  	approveRemoveSignerParams := multisig.TxnIDParams{ID: multisig.TxnID(0)}
   115  	vm.ApplyOk(t, v, addrs[0], multisigAddr, big.Zero(), builtin.MethodsMultisig.Approve, &approveRemoveSignerParams)
   116  
   117  	// txnid not found when third approval gets processed indicating that the transaction has gone through successfully
   118  	_, code := v.ApplyMessage(addrs[2], multisigAddr, big.Zero(), builtin.MethodsMultisig.Approve, &approveRemoveSignerParams)
   119  	assert.Equal(t, exitcode.ErrNotFound, code)
   120  
   121  }
   122  
   123  func TestMultisigDeleteSelf2Of2(t *testing.T) {
   124  	ctx := context.Background()
   125  	v := vm.NewVMWithSingletons(ctx, t, ipld.NewBlockStoreInMemory())
   126  	addrs := vm.CreateAccounts(ctx, t, v, 2, big.Mul(big.NewInt(10_000), big.NewInt(1e18)), 93837778)
   127  
   128  	multisigParams := multisig.ConstructorParams{
   129  		Signers:               addrs,
   130  		NumApprovalsThreshold: 2,
   131  	}
   132  
   133  	paramBuf := new(bytes.Buffer)
   134  	err := multisigParams.MarshalCBOR(paramBuf)
   135  	require.NoError(t, err)
   136  
   137  	initParam := init_.ExecParams{
   138  		CodeCID:           builtin.MultisigActorCodeID,
   139  		ConstructorParams: paramBuf.Bytes(),
   140  	}
   141  	ret := vm.ApplyOk(t, v, addrs[0], builtin.InitActorAddr, big.Zero(), builtin.MethodsPower.CreateMiner, &initParam)
   142  	initRet := ret.(*init_.ExecReturn)
   143  	assert.NotNil(t, initRet)
   144  	multisigAddr := initRet.IDAddress
   145  
   146  	removeParams := multisig.RemoveSignerParams{
   147  		Signer:   addrs[0],
   148  		Decrease: true,
   149  	}
   150  
   151  	paramBuf = new(bytes.Buffer)
   152  	err = removeParams.MarshalCBOR(paramBuf)
   153  	require.NoError(t, err)
   154  
   155  	// first proposal goes ok and should have txnid = 0
   156  	proposeRemoveSignerParams := multisig.ProposeParams{
   157  		To:     multisigAddr,
   158  		Value:  big.Zero(),
   159  		Method: builtin.MethodsMultisig.RemoveSigner,
   160  		Params: paramBuf.Bytes(),
   161  	}
   162  	vm.ApplyOk(t, v, addrs[0], multisigAddr, big.Zero(), builtin.MethodsMultisig.Propose, &proposeRemoveSignerParams)
   163  	// approval goes through
   164  	approveRemoveSignerParams := multisig.TxnIDParams{ID: multisig.TxnID(0)}
   165  	vm.ApplyOk(t, v, addrs[1], multisigAddr, big.Zero(), builtin.MethodsMultisig.Approve, &approveRemoveSignerParams)
   166  
   167  	// txnid not found when another approval gets processed indicating that the transaction has gone through successfully
   168  	_, code := v.ApplyMessage(addrs[1], multisigAddr, big.Zero(), builtin.MethodsMultisig.Approve, &approveRemoveSignerParams)
   169  	assert.Equal(t, exitcode.ErrNotFound, code)
   170  }
   171  
   172  func TestMultisigSwapsSelf2Of3(t *testing.T) {
   173  	ctx := context.Background()
   174  	v := vm.NewVMWithSingletons(ctx, t, ipld.NewBlockStoreInMemory())
   175  	addrs := vm.CreateAccounts(ctx, t, v, 4, big.Mul(big.NewInt(10_000), big.NewInt(1e18)), 93837778)
   176  	alice := addrs[0]
   177  	bob := addrs[1]
   178  	chuck := addrs[2]
   179  	dinesh := addrs[3]
   180  
   181  	multisigParams := multisig.ConstructorParams{
   182  		Signers:               []address.Address{alice, bob, chuck},
   183  		NumApprovalsThreshold: 2,
   184  	}
   185  
   186  	paramBuf := new(bytes.Buffer)
   187  	err := multisigParams.MarshalCBOR(paramBuf)
   188  	require.NoError(t, err)
   189  
   190  	initParam := init_.ExecParams{
   191  		CodeCID:           builtin.MultisigActorCodeID,
   192  		ConstructorParams: paramBuf.Bytes(),
   193  	}
   194  	ret := vm.ApplyOk(t, v, addrs[0], builtin.InitActorAddr, big.Zero(), builtin.MethodsPower.CreateMiner, &initParam)
   195  	initRet := ret.(*init_.ExecReturn)
   196  	assert.NotNil(t, initRet)
   197  	multisigAddr := initRet.IDAddress
   198  
   199  	// Case 1 swapped out is proposer (swap alice for dinesh, alice is removed)
   200  	swapParams := multisig.SwapSignerParams{
   201  		From: alice,
   202  		To:   dinesh,
   203  	}
   204  
   205  	paramBuf = new(bytes.Buffer)
   206  	err = swapParams.MarshalCBOR(paramBuf)
   207  	require.NoError(t, err)
   208  
   209  	proposeSwapSignerParams := multisig.ProposeParams{
   210  		To:     multisigAddr,
   211  		Value:  big.Zero(),
   212  		Method: builtin.MethodsMultisig.SwapSigner,
   213  		Params: paramBuf.Bytes(),
   214  	}
   215  
   216  	// proposal from swapped address goes ok and should have txnid = 0
   217  	vm.ApplyOk(t, v, alice, multisigAddr, big.Zero(), builtin.MethodsMultisig.Propose, &proposeSwapSignerParams)
   218  
   219  	// approval goes through
   220  	approveSwapSignerParams := multisig.TxnIDParams{ID: multisig.TxnID(0)}
   221  	vm.ApplyOk(t, v, bob, multisigAddr, big.Zero(), builtin.MethodsMultisig.Approve, &approveSwapSignerParams)
   222  
   223  	// Case 2 swapped out is approver (swap dinesh for alice, dinesh is removed)
   224  	swapParams2 := multisig.SwapSignerParams{
   225  		From: dinesh,
   226  		To:   alice,
   227  	}
   228  
   229  	paramBuf2 := new(bytes.Buffer)
   230  	err = swapParams2.MarshalCBOR(paramBuf2)
   231  	require.NoError(t, err)
   232  
   233  	proposeSwapSignerParams2 := multisig.ProposeParams{
   234  		To:     multisigAddr,
   235  		Value:  big.Zero(),
   236  		Method: builtin.MethodsMultisig.SwapSigner,
   237  		Params: paramBuf2.Bytes(),
   238  	}
   239  
   240  	// proposal from regular address goes ok txnid = 1
   241  	vm.ApplyOk(t, v, bob, multisigAddr, big.Zero(), builtin.MethodsMultisig.Propose, &proposeSwapSignerParams2)
   242  
   243  	// approve from swapped address goes ok
   244  	approveSwapSignerParams2 := multisig.TxnIDParams{ID: multisig.TxnID(1)}
   245  	vm.ApplyOk(t, v, dinesh, multisigAddr, big.Zero(), builtin.MethodsMultisig.Approve, &approveSwapSignerParams2)
   246  
   247  }
   248  
   249  func TestMultisigDeleteSigner1Of2(t *testing.T) {
   250  	ctx := context.Background()
   251  	v := vm.NewVMWithSingletons(ctx, t, ipld.NewBlockStoreInMemory())
   252  	addrs := vm.CreateAccounts(ctx, t, v, 2, big.Mul(big.NewInt(10_000), big.NewInt(1e18)), 93837778)
   253  
   254  	multisigParams := multisig.ConstructorParams{
   255  		Signers:               addrs,
   256  		NumApprovalsThreshold: 1,
   257  	}
   258  
   259  	paramBuf := new(bytes.Buffer)
   260  	err := multisigParams.MarshalCBOR(paramBuf)
   261  	require.NoError(t, err)
   262  
   263  	initParam := init_.ExecParams{
   264  		CodeCID:           builtin.MultisigActorCodeID,
   265  		ConstructorParams: paramBuf.Bytes(),
   266  	}
   267  	ret := vm.ApplyOk(t, v, addrs[0], builtin.InitActorAddr, big.Zero(), builtin.MethodsPower.CreateMiner, &initParam)
   268  	initRet := ret.(*init_.ExecReturn)
   269  	assert.NotNil(t, initRet)
   270  	multisigAddr := initRet.IDAddress
   271  
   272  	removeParams := multisig.RemoveSignerParams{
   273  		Signer:   addrs[0],
   274  		Decrease: false,
   275  	}
   276  
   277  	paramBuf = new(bytes.Buffer)
   278  	err = removeParams.MarshalCBOR(paramBuf)
   279  	require.NoError(t, err)
   280  
   281  	proposeRemoveSignerParams := multisig.ProposeParams{
   282  		To:     multisigAddr,
   283  		Value:  big.Zero(),
   284  		Method: builtin.MethodsMultisig.RemoveSigner,
   285  		Params: paramBuf.Bytes(),
   286  	}
   287  	// address 0 succeeds when trying to execute the transaction removing address 0
   288  	vm.ApplyOk(t, v, addrs[0], multisigAddr, big.Zero(), builtin.MethodsMultisig.Propose, &proposeRemoveSignerParams)
   289  }
   290  
   291  func TestMultisigSwapsSelf1Of2(t *testing.T) {
   292  	ctx := context.Background()
   293  	v := vm.NewVMWithSingletons(ctx, t, ipld.NewBlockStoreInMemory())
   294  	addrs := vm.CreateAccounts(ctx, t, v, 3, big.Mul(big.NewInt(10_000), big.NewInt(1e18)), 93837778)
   295  	alice := addrs[0]
   296  	bob := addrs[1]
   297  	chuck := addrs[2]
   298  
   299  	multisigParams := multisig.ConstructorParams{
   300  		Signers:               []address.Address{alice, bob},
   301  		NumApprovalsThreshold: 1,
   302  	}
   303  
   304  	paramBuf := new(bytes.Buffer)
   305  	err := multisigParams.MarshalCBOR(paramBuf)
   306  	require.NoError(t, err)
   307  
   308  	initParam := init_.ExecParams{
   309  		CodeCID:           builtin.MultisigActorCodeID,
   310  		ConstructorParams: paramBuf.Bytes(),
   311  	}
   312  	ret := vm.ApplyOk(t, v, addrs[0], builtin.InitActorAddr, big.Zero(), builtin.MethodsPower.CreateMiner, &initParam)
   313  	initRet := ret.(*init_.ExecReturn)
   314  	assert.NotNil(t, initRet)
   315  	multisigAddr := initRet.IDAddress
   316  
   317  	swapParams := multisig.SwapSignerParams{
   318  		From: alice,
   319  		To:   chuck,
   320  	}
   321  
   322  	paramBuf = new(bytes.Buffer)
   323  	err = swapParams.MarshalCBOR(paramBuf)
   324  	require.NoError(t, err)
   325  
   326  	proposeSwapSignerParams := multisig.ProposeParams{
   327  		To:     multisigAddr,
   328  		Value:  big.Zero(),
   329  		Method: builtin.MethodsMultisig.SwapSigner,
   330  		Params: paramBuf.Bytes(),
   331  	}
   332  
   333  	// alice succeeds when trying to execute the transaction swapping alice for chuck
   334  	vm.ApplyOk(t, v, alice, multisigAddr, big.Zero(), builtin.MethodsMultisig.Propose, &proposeSwapSignerParams)
   335  }