Skip to content

Commit

Permalink
vochain: add set_process_duration transaction
Browse files Browse the repository at this point in the history
With this transaction we can now modify the duration of an
existing project (while in READY or PAUSE state).

If interruptible=false the duration can only be extended.

The cost of the transactions is computed dynamically by:
 max(nextPrice - previousPrice, txBaseCost)

Signed-off-by: p4u <[email protected]>
  • Loading branch information
p4u committed Jun 20, 2024
1 parent 7926087 commit c83caf2
Show file tree
Hide file tree
Showing 19 changed files with 257 additions and 56 deletions.
17 changes: 10 additions & 7 deletions test/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"go.vocdoni.io/dvote/types"
"go.vocdoni.io/dvote/util"
"go.vocdoni.io/dvote/vochain"
"go.vocdoni.io/dvote/vochain/genesis"
"go.vocdoni.io/dvote/vochain/indexer/indexertypes"
"go.vocdoni.io/dvote/vochain/processid"
"go.vocdoni.io/dvote/vochain/state"
Expand Down Expand Up @@ -189,9 +190,9 @@ func TestAPIaccount(t *testing.T) {
err := json.Unmarshal(resp, &countAccts)
qt.Assert(t, err, qt.IsNil)

// 2 accounts must exist: the previously new created account and the auxiliary
// 3 accounts must exist: the previously new created account plus burn + faucet
// account used to transfer to the new account
qt.Assert(t, countAccts.Count, qt.Equals, uint64(2))
qt.Assert(t, countAccts.Count, qt.Equals, uint64(3))

// get the accounts info
resp, code = c.Request("GET", nil, "accounts", "page", "0")
Expand Down Expand Up @@ -228,7 +229,7 @@ func TestAPIElectionCost(t *testing.T) {
},
10000, 5000,
5, 1000,
6)
2)

// bigger census size, duration, reduced network capacity, etc
runAPIElectionCostWithParams(t,
Expand All @@ -241,7 +242,7 @@ func TestAPIElectionCost(t *testing.T) {
},
200000, 6000,
10, 100,
762)
753)

// very expensive election
runAPIElectionCostWithParams(t,
Expand All @@ -254,7 +255,7 @@ func TestAPIElectionCost(t *testing.T) {
},
100000, 700000,
10, 100,
547026)
547017)
}

func TestAPIAccountTokentxs(t *testing.T) {
Expand Down Expand Up @@ -382,15 +383,16 @@ func TestAPIAccountTokentxs(t *testing.T) {
qt.Assert(t, gotAcct2.Address.String(), qt.Equals, hex.EncodeToString(signer2.Address().Bytes()))

// compare the balance expected for the account 2 in the account list
qt.Assert(t, gotAcct2.Balance, qt.Equals, initBalance+amountAcc1toAcct2-amountAcc2toAcct1)
txBasePrice := genesis.DefaultTransactionCosts().SendTokens
qt.Assert(t, gotAcct2.Balance, qt.Equals, initBalance+amountAcc1toAcct2-amountAcc2toAcct1-uint64(txBasePrice))

gotAcct1 := accts.Accounts[2]

// compare the address in list of accounts with the account1 address previously created
qt.Assert(t, gotAcct1.Address.String(), qt.Equals, hex.EncodeToString(signer.Address().Bytes()))

// compare the balance expected for the account 1 in the account list
qt.Assert(t, gotAcct1.Balance, qt.Equals, initBalance+amountAcc2toAcct1-amountAcc1toAcct2)
qt.Assert(t, gotAcct1.Balance, qt.Equals, initBalance+amountAcc2toAcct1-amountAcc1toAcct2-uint64(txBasePrice))

}

Expand Down Expand Up @@ -418,6 +420,7 @@ func runAPIElectionCostWithParams(t *testing.T,
err = server.VochainAPP.State.SetElectionPriceCalc()
qt.Assert(t, err, qt.IsNil)
server.VochainAPP.State.ElectionPriceCalc.SetCapacity(networkCapacity)
server.VochainAPP.State.ElectionPriceCalc.SetBasePrice(1)

// Block 1
server.VochainAPP.AdvanceTestBlock()
Expand Down
3 changes: 2 additions & 1 deletion test/testcommon/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ func (d *APIserver) Start(t testing.TB, apis ...string) {
// create and add balance for the pre-created Account
err = d.VochainAPP.State.CreateAccount(d.Account.Address(), "", nil, 1000000)
qt.Assert(t, err, qt.IsNil)
d.VochainAPP.CommitState()
_, err = d.VochainAPP.CommitState()
qt.Assert(t, err, qt.IsNil)

// create vochain info (we do not start since it is not required)
d.VochainInfo = vochaininfo.NewVochainInfo(d.VochainAPP)
Expand Down
2 changes: 2 additions & 0 deletions vochain/apptest.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ func TestBaseApplicationWithChainID(tb testing.TB, chainID string) *BaseApplicat
if err != nil {
tb.Fatal(err)
}
app.State.ElectionPriceCalc.SetBasePrice(1)
app.State.ElectionPriceCalc.SetCapacity(10000)
// TODO: should this be a Close on the entire BaseApplication?
tb.Cleanup(func() {
if err := app.State.Close(); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion vochain/apputils.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func NewTemplateGenesisFile(dir string, validators int) (*genesis.Doc, error) {
Balance: 100000,
},
},
TxCost: genesis.TransactionCosts{},
TxCost: genesis.DefaultTransactionCosts(),
}
appState.MaxElectionSize = 100000

Expand Down
57 changes: 25 additions & 32 deletions vochain/genesis/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,22 +179,7 @@ var initialAppStateForTest = AppState{
Balance: 1000000000000,
},
},
TxCost: TransactionCosts{
SetProcessStatus: 1,
SetProcessCensus: 1,
SetProcessQuestionIndex: 1,
RegisterKey: 1,
NewProcess: 10,
SendTokens: 2,
SetAccountInfoURI: 2,
CreateAccount: 2,
AddDelegateForAccount: 2,
DelDelegateForAccount: 2,
CollectFaucet: 1,
SetAccountSIK: 1,
DelAccountSIK: 1,
SetAccountValidator: 100,
},
TxCost: DefaultTransactionCosts(),
}

var initialAppStateForDev = AppState{
Expand Down Expand Up @@ -244,22 +229,7 @@ var initialAppStateForDev = AppState{
Balance: 100000000,
},
},
TxCost: TransactionCosts{
SetProcessStatus: 2,
SetProcessCensus: 2,
SetProcessQuestionIndex: 1,
RegisterKey: 1,
NewProcess: 5,
SendTokens: 1,
SetAccountInfoURI: 1,
CreateAccount: 1,
AddDelegateForAccount: 1,
DelDelegateForAccount: 1,
CollectFaucet: 1,
SetAccountSIK: 1,
DelAccountSIK: 1,
SetAccountValidator: 10000,
},
TxCost: DefaultTransactionCosts(),
}

var initialAppStateForStage = AppState{
Expand Down Expand Up @@ -321,6 +291,7 @@ var initialAppStateForStage = AppState{
TxCost: TransactionCosts{
SetProcessStatus: 2,
SetProcessCensus: 1,
SetProcessDuration: 2,
SetProcessQuestionIndex: 1,
RegisterKey: 1,
NewProcess: 5,
Expand Down Expand Up @@ -412,6 +383,7 @@ var initialAppStateForLTS = AppState{
TxCost: TransactionCosts{
SetProcessStatus: 1,
SetProcessCensus: 5,
SetProcessDuration: 5,
SetProcessQuestionIndex: 1,
RegisterKey: 1,
NewProcess: 10,
Expand Down Expand Up @@ -462,6 +434,27 @@ func DefaultValidatorParams() comettypes.ValidatorParams {
}
}

// DefaultTransactionCosts returns a default set of transaction costs to use as template.
func DefaultTransactionCosts() TransactionCosts {
return TransactionCosts{
SetProcessStatus: 2,
SetProcessCensus: 2,
SetProcessDuration: 2,
SetProcessQuestionIndex: 1,
RegisterKey: 1,
NewProcess: 5,
SendTokens: 1,
SetAccountInfoURI: 1,
CreateAccount: 1,
AddDelegateForAccount: 1,
DelDelegateForAccount: 1,
CollectFaucet: 1,
SetAccountSIK: 1,
DelAccountSIK: 1,
SetAccountValidator: 10000,
}
}

// AvailableNetworks returns the list of hardcoded networks
func AvailableNetworks() []string {
list := []string{}
Expand Down
3 changes: 3 additions & 0 deletions vochain/genesis/txcost.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
type TransactionCosts struct {
SetProcessStatus uint32 `json:"Tx_SetProcessStatus"`
SetProcessCensus uint32 `json:"Tx_SetProcessCensus"`
SetProcessDuration uint32 `json:"Tx_SetProcessDuration"`
SetProcessQuestionIndex uint32 `json:"Tx_SetProcessQuestionIndex"`
RegisterKey uint32 `json:"Tx_RegisterKey"`
NewProcess uint32 `json:"Tx_NewProcess"`
Expand Down Expand Up @@ -43,6 +44,7 @@ func (t *TransactionCosts) AsMap() map[models.TxType]uint64 {
var TxCostNameToTxTypeMap = map[string]models.TxType{
"SetProcessStatus": models.TxType_SET_PROCESS_STATUS,
"SetProcessCensus": models.TxType_SET_PROCESS_CENSUS,
"SetProcessDuration": models.TxType_SET_PROCESS_DURATION,
"SetProcessQuestionIndex": models.TxType_SET_PROCESS_QUESTION_INDEX,
"SendTokens": models.TxType_SEND_TOKENS,
"SetAccountInfoURI": models.TxType_SET_ACCOUNT_INFO_URI,
Expand All @@ -69,6 +71,7 @@ func TxCostNameToTxType(key string) models.TxType {
var TxTypeToCostNameMap = map[models.TxType]string{
models.TxType_SET_PROCESS_STATUS: "SetProcessStatus",
models.TxType_SET_PROCESS_CENSUS: "SetProcessCensus",
models.TxType_SET_PROCESS_DURATION: "SetProcessDuration",
models.TxType_SET_PROCESS_QUESTION_INDEX: "SetProcessQuestionIndex",
models.TxType_SEND_TOKENS: "SendTokens",
models.TxType_SET_ACCOUNT_INFO_URI: "SetAccountInfoURI",
Expand Down
7 changes: 5 additions & 2 deletions vochain/indexer/db/processes.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions vochain/indexer/indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,13 @@ func (idx *Indexer) OnProcessStatusChange(pid []byte, _ models.ProcessStatus, _
idx.blockUpdateProcs[string(pid)] = true
}

// OnProcessDurationChange adds the process to blockUpdateProcs and, if ended, the resultsPool
func (idx *Indexer) OnProcessDurationChange(pid []byte, _ uint32, _ int32) {
idx.blockMu.Lock()
defer idx.blockMu.Unlock()
idx.blockUpdateProcs[string(pid)] = true
}

// OnRevealKeys checks if all keys have been revealed and in such case add the
// process to the results queue
func (idx *Indexer) OnRevealKeys(pid []byte, _ string, _ int32) {
Expand Down
1 change: 1 addition & 0 deletions vochain/indexer/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ func (idx *Indexer) updateProcess(ctx context.Context, queries *indexerdb.Querie
Metadata: p.GetMetadata(),
Status: int64(p.Status),
MaxCensusSize: int64(p.GetMaxCensusSize()),
EndDate: time.Unix(int64(p.StartTime+p.Duration), 0),
}); err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion vochain/indexer/queries/processes.sql
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ SET census_root = sqlc.arg(census_root),
public_keys = sqlc.arg(public_keys),
metadata = sqlc.arg(metadata),
status = sqlc.arg(status),
max_census_size = sqlc.arg(max_census_size)
max_census_size = sqlc.arg(max_census_size),
end_date = sqlc.arg(end_date)
WHERE id = sqlc.arg(id);

-- name: GetProcessStatus :one
Expand Down
3 changes: 3 additions & 0 deletions vochain/keykeeper/keykeeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,3 +276,6 @@ func (*KeyKeeper) OnCensusUpdate(_, _ []byte, _ string, _ uint64) {}

// OnCancel does nothing
func (k *KeyKeeper) OnCancel(_ []byte, _ int32) {}

// OnProcessDurationChange does nothing
func (k *KeyKeeper) OnProcessDurationChange(_ []byte, _ uint32, _ int32) {}
1 change: 1 addition & 0 deletions vochain/offchaindatahandler/offchaindatahandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,4 @@ func (*OffChainDataHandler) OnProcessStatusChange(_ []byte, _ models.ProcessStat
func (*OffChainDataHandler) OnTransferTokens(_ *vochaintx.TokenTransfer) {}
func (*OffChainDataHandler) OnProcessResults(_ []byte, _ *models.ProcessResult, _ int32) {}
func (*OffChainDataHandler) OnSpendTokens(_ []byte, _ models.TxType, _ uint64, _ string) {}
func (*OffChainDataHandler) OnProcessDurationChange(_ []byte, _ uint32, _ int32) {}
Loading

0 comments on commit c83caf2

Please sign in to comment.