diff --git a/backend/README.md b/backend/README.md index 04970145d..b398881e6 100644 --- a/backend/README.md +++ b/backend/README.md @@ -2,7 +2,7 @@ ## Prerequisites -- [GoLang 1.6](https://golang.org/doc/install) +- [GoLang 1.16+](https://golang.org/doc/install) - [PostgreSQL 14.1](https://www.postgresql.org/download/) - [Flow CLI](https://docs.onflow.org/flow-cli/install/) - Note: See below for how install v0.30.2 (required) @@ -45,6 +45,17 @@ CREATE DATABASE flow_snapshot; CREATE DATABASE flow_snapshot_test; ``` +NOTE: in some system configurations `sudo -i -u postgres` will return an error so you can run the following: + +```bash +psql +CREATE USER postgres; +ALTER USER postgres PASSWORD 'admin'; +ALTER USER postgres WITH SUPERUSER; +CREATE DATABASE flow_snapshot WITH OWNER = postgres; +CREATE DATABASE flow_snapshot_test WITH OWNER = postgres; +``` + #### Install Migrate Tool To run the `make` migrate scripts, you need to have the `migrate` CLI installed in your local path. Follow the [steps here](https://github.com/golang-migrate/migrate/tree/master/cmd/migrate) to install `migrate` on your machine. @@ -87,10 +98,14 @@ make testmigratedown #### Dealing with Dirty Schema Migrations +Reset Schema Migrations +```bash +UPDATE schema_migrations SET dirty = false +``` ### Testing -1. Run `flow emulator` from this top-level directory (the private key for the `emulator-account` in `flow.json` must match the private key hard-coded in the test suite). Install the `flow` CLI [here](https://docs.onflow.org/flow-cli/install/) +1. Run `flow emulator` from this top-level directory (the private key for the `emulator-account` in top level `flow.json` must match the private key hard-coded in the test suite eg. `backend/cadence/V2/tests/flow.json`). Install the `flow` CLI [here](https://docs.onflow.org/flow-cli/install/) 2. Run migrations against the test database (if migrations aren't up to date): `make testmigrateup` 3. Run the test suite: `make test` @@ -110,7 +125,7 @@ docker run -it --network=host --rm --name vt-test vt-test:latest Before running the app you should: -1. Run `flow emulator` from this top-level directory (the private key for the `emulator-account` in `flow.json` must match the private key hard-coded in the test suite). Install the `flow` CLI [here](https://docs.onflow.org/flow-cli/install/) +1. Run `flow emulator` from this top-level directory (the private key for the `emulator-account` in top level`flow.json` must match the private key hard-coded in the test suite eg. `backend/cadence/V2/tests/flow.json`). Install the `flow` CLI [here](https://docs.onflow.org/flow-cli/install/) 2. Run migrations against the database (if migrations aren't up to date): `make migrateup` #### Go Executable diff --git a/backend/main/server/app.go b/backend/main/server/app.go index d34ce98f5..e5dc2be02 100644 --- a/backend/main/server/app.go +++ b/backend/main/server/app.go @@ -292,6 +292,7 @@ func (a *App) getResultsForProposal(w http.ResponseWriter, r *http.Request) { // First, get the proposal by proposalId p := models.Proposal{ID: proposalId} + if err := p.GetProposalById(a.DB); err != nil { switch err.Error() { case pgx.ErrNoRows.Error(): diff --git a/backend/main/shared/snapshot-flow.go b/backend/main/shared/snapshot-flow.go index a49b5ccd0..376aaa5d3 100644 --- a/backend/main/shared/snapshot-flow.go +++ b/backend/main/shared/snapshot-flow.go @@ -157,11 +157,9 @@ func (c *SnapshotClient) GetAddressBalanceAtBlockHeight( address string, blockheight uint64, balancePointer interface{}, - contract Contract) error { - // Send dummy data for tests + contract Contract, +) error { if c.bypass() { - DummyBalance.Addr = address - balancePointer = &DummyBalance return nil } var url string diff --git a/backend/main/strategies/staked_token_weighted_default.go b/backend/main/strategies/staked_token_weighted_default.go index a4bbee936..1f7ea8927 100644 --- a/backend/main/strategies/staked_token_weighted_default.go +++ b/backend/main/strategies/staked_token_weighted_default.go @@ -31,16 +31,19 @@ func (s *StakedTokenWeightedDefault) FetchBalance( Addr: c.Contract_addr, } - if err := s.SnapshotClient.GetAddressBalanceAtBlockHeight(b.Addr, b.BlockHeight, b, *contract); err != nil { - log.Error().Err(err).Msg("error querying address b at blockheight") + if err := s.SnapshotClient.GetAddressBalanceAtBlockHeight( + b.Addr, + b.BlockHeight, + b, + *contract, + ); err != nil { + log.Error().Err(err).Msg("error fetching balance") return nil, err } - if b.ID == "" { - if err := b.CreateBalance(db); err != nil { - log.Error().Err(err).Msg("error saving b to DB") - return nil, err - } + if err := b.CreateBalance(db); err != nil { + log.Error().Err(err).Msg("error creating balance in the DB") + return nil, err } return b, nil diff --git a/backend/main/strategies/token_weighted_default.go b/backend/main/strategies/token_weighted_default.go index ffe666e3b..de9ad6788 100644 --- a/backend/main/strategies/token_weighted_default.go +++ b/backend/main/strategies/token_weighted_default.go @@ -7,6 +7,7 @@ import ( "github.com/DapperCollectives/CAST/backend/main/models" "github.com/DapperCollectives/CAST/backend/main/shared" s "github.com/DapperCollectives/CAST/backend/main/shared" + "github.com/jackc/pgx/v4" "github.com/rs/zerolog/log" ) @@ -26,21 +27,30 @@ func (s *TokenWeightedDefault) FetchBalance( return nil, err } + if err := b.GetBalanceByAddressAndBlockHeight(db); err != nil && err.Error() != pgx.ErrNoRows.Error() { + log.Error().Err(err).Msg("error fetching balance from DB") + return nil, err + } + + //@TODO should get contract by matching strategy name var contract = &shared.Contract{ Name: c.Contract_name, Addr: c.Contract_addr, } - if err := s.SnapshotClient.GetAddressBalanceAtBlockHeight(b.Addr, b.BlockHeight, b, *contract); err != nil { - log.Error().Err(err).Msg("error querying address b at blockheight") + if err := s.SnapshotClient.GetAddressBalanceAtBlockHeight( + b.Addr, + b.BlockHeight, + b, + *contract, + ); err != nil { + log.Error().Err(err).Msg("error fetching balance") return nil, err } - if b.ID == "" { - if err := b.CreateBalance(db); err != nil { - log.Error().Err(err).Msg("error saving b to DB") - return nil, err - } + if err := b.CreateBalance(db); err != nil { + log.Error().Err(err).Msg("error creating balance in the DB") + return nil, err } return b, nil diff --git a/backend/main/strategies_test.go b/backend/main/strategies_test.go index dfeb23724..8d6464312 100644 --- a/backend/main/strategies_test.go +++ b/backend/main/strategies_test.go @@ -191,6 +191,7 @@ func TestBalanceOfNFTsStrategy(t *testing.T) { //weight should be the same as before the cheat vote was added //because the cheat vote should be ignored by the server //therefor the cheatResults should be the same as the correctResults + assert.Equal(t, correctResults.Proposal_id, cheatResults.Proposal_id) assert.Equal(t, correctResults.Results_float["a"], cheatResults.Results_float["a"]) assert.Equal(t, correctResults.Results_float["b"], cheatResults.Results_float["b"]) diff --git a/backend/main/test_utils/community_utils.go b/backend/main/test_utils/community_utils.go index 3bf717f73..1a095e75c 100644 --- a/backend/main/test_utils/community_utils.go +++ b/backend/main/test_utils/community_utils.go @@ -244,18 +244,3 @@ func (otu *OverflowTestUtils) GetCommunityUsersAPIByType(id int, userType string response := otu.ExecuteRequest(req) return response } - -// func GenerateValidUpdateCommunityPayload(addr string) []byte { -// // this does a deep copy -// community := ValidUpdateCommunityStruct - -// community.Signing_addr = addr -// timestamp := fmt.Sprint(time.Now().UnixNano() / int64(time.Millisecond)) -// community.Timestamp = timestamp -// compositeSignatures := SignMessage(ServiceAccountAddress, ValidServiceAccountKey, timestamp) - -// community.Composite_signatures = compositeSignatures - -// jsonStr, _ := json.Marshal(community) -// fmt.Printf("payload: %v\n", string(jsonStr)) -// return []byte(jsonStr) diff --git a/backend/main/test_utils/factory.go b/backend/main/test_utils/factory.go index 9b3bfc494..4dc30dcdc 100644 --- a/backend/main/test_utils/factory.go +++ b/backend/main/test_utils/factory.go @@ -21,19 +21,6 @@ var InvalidServiceAccountKey = "5687d75f957bf64591b55eb19227706e3c8712c1387225b8 // VOTES ////////// -// func GenerateValidVotePayload(proposalId int, choice string) []byte { -// timestamp := time.Now().UnixNano() / int64(time.Millisecond) -// hexChoice := hex.EncodeToString([]byte(choice)) -// message := "1:" + hexChoice + ":" + fmt.Sprint(timestamp) -// compositeSignatures := SignMessage(ServiceAccountAddress, ValidServiceAccountKey, message) - -// vote := models.Vote{Proposal_id: proposalId, Addr: ServiceAccountAddress, Choice: choice, -// Composite_signatures: compositeSignatures, Message: message} - -// jsonStr, _ := json.Marshal(vote) -// return []byte(jsonStr) -// } - func (otu *OverflowTestUtils) AddDummyVotesAndBalances(votes *[]VoteWithBalance) { for _, vote := range *votes { // Insert Vote @@ -49,7 +36,7 @@ func (otu *OverflowTestUtils) AddDummyVotesAndBalances(votes *[]VoteWithBalance) _, err = otu.A.DB.Conn.Exec(otu.A.DB.Context, ` INSERT INTO balances(id, addr, primary_account_balance, secondary_address, secondary_account_balance, staking_balance, script_result, stakes, block_height) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9) - `, uuid.New(), vote.Addr, vote.Primary_account_balance, "0x0", 0, vote.Staking_balance, "SUCCESS", []string{}, vote.Block_height) + `, uuid.New(), vote.Addr, vote.Primary_account_balance, "0x0", 0, vote.Staking_balance, "SUCCESS", []string{}, 1) if err != nil { log.Error().Err(err).Msg("AddDummyVotesAndBalances DB err - balances") } @@ -58,6 +45,7 @@ func (otu *OverflowTestUtils) AddDummyVotesAndBalances(votes *[]VoteWithBalance) func (otu *OverflowTestUtils) AddDummyVotesAndNFTs(votes *[]VoteWithBalance) { for _, vote := range *votes { + // Insert Vote _, err := otu.A.DB.Conn.Exec(otu.A.DB.Context, ` INSERT INTO votes(proposal_id, addr, choice, composite_signatures, message) diff --git a/backend/main/test_utils/proposal_utils.go b/backend/main/test_utils/proposal_utils.go index 9d3277ed3..3a93b2fbf 100644 --- a/backend/main/test_utils/proposal_utils.go +++ b/backend/main/test_utils/proposal_utils.go @@ -17,23 +17,25 @@ import ( // PROPOSALS ////////////// -var strategy = "token-weighted-default" -var proposalBody = "something" -var published = "published" -var blockHeight uint64 = 1 - -var DefaultProposalStruct = models.Proposal{ - Name: "Test Proposal", - Body: &proposalBody, - Choices: []shared.Choice{ - {Choice_text: "a"}, - {Choice_text: "b"}, - }, - Creator_addr: ServiceAccountAddress, - Strategy: &strategy, - Status: &published, - Block_height: &blockHeight, -} +var ( + proposalBody = "something" + published = "published" + tokenWeightedDefault = "token-weighted-default" + blockHeight uint64 = 1 + + DefaultProposalStruct = models.Proposal{ + Name: "Test Proposal", + Body: &proposalBody, + Choices: []shared.Choice{ + {Choice_text: "a"}, + {Choice_text: "b"}, + }, + Creator_addr: ServiceAccountAddress, + Strategy: &tokenWeightedDefault, + Status: &published, + Block_height: &blockHeight, + } +) func (otu *OverflowTestUtils) GetProposalsForCommunityAPI(communityId int) *httptest.ResponseRecorder { req, _ := http.NewRequest("GET", "/communities/"+strconv.Itoa(communityId)+"/proposals", nil) diff --git a/backend/main/test_utils/strategy_utils.go b/backend/main/test_utils/strategy_utils.go index 1d3430688..47b274bed 100644 --- a/backend/main/test_utils/strategy_utils.go +++ b/backend/main/test_utils/strategy_utils.go @@ -40,6 +40,8 @@ func (otu *OverflowTestUtils) TallyResultsForStakedTokenWeightedDefault( r *models.ProposalResults, ) *models.ProposalResults { + fmt.Printf("Tallying results for staked token weighted default\n") + for _, v := range *votes { r.Results_float[v.Choice] += float64(v.Staking_balance) * math.Pow(10, -8) } diff --git a/backend/migrations/000026_update_voting_strategy_desc.down.sql b/backend/migrations/000026_update_voting_strategy_desc.down.sql new file mode 100644 index 000000000..0f594df42 --- /dev/null +++ b/backend/migrations/000026_update_voting_strategy_desc.down.sql @@ -0,0 +1,6 @@ +UPDATE voting_strategies + SET description = 'one address is simply only allowed one vote, assets do not come into play.' + WHERE key = 'one-address-one-vote'; +UPDATE voting_strategies + SET description = 'a weight will be added for each NFT in a user address that matches the contract of the proposal' + WHERE key = 'balance-of-nfts'; \ No newline at end of file diff --git a/backend/migrations/000026_update_voting_strategy_desc.up.sql b/backend/migrations/000026_update_voting_strategy_desc.up.sql new file mode 100644 index 000000000..b75160159 --- /dev/null +++ b/backend/migrations/000026_update_voting_strategy_desc.up.sql @@ -0,0 +1,6 @@ +UPDATE voting_strategies + SET description = 'A weight will be added for each NFT in a user address that matches the contract of the proposal' + WHERE key = 'balance-of-nfts'; +UPDATE voting_strategies + SET description = 'One address is simply only allowed one vote, assets do not come into play.' + WHERE key = 'one-address-one-vote'; \ No newline at end of file diff --git a/frontend/README.md b/frontend/README.md index 84405bf0f..fb3cf52ca 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -3,8 +3,8 @@ ## Prerequisites - [Yarn](https://classic.yarnpkg.com/lang/en/docs/install) -- [GoLang 1.6](https://golang.org/doc/install) -- [Node/NPM](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) +- [GoLang 1.16+](https://golang.org/doc/install) +- [Node/NPM v16](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) - [Flow CLI](https://docs.onflow.org/flow-cli/install/) - Note: See below for how install v0.30.2 (required) @@ -14,6 +14,13 @@ yarn install ``` +Installing Node via [NVM](https://github.com/nvm-sh/nvm#installation-and-update) +```bash +nvm install v16.13.0 +nvm use 16 +node -v +``` + ## Development #### Contracts diff --git a/frontend/packages/client/src/components/Community/CommunityEditorDetails.js b/frontend/packages/client/src/components/Community/CommunityEditorDetails.js index be8cd2388..44fadb78f 100644 --- a/frontend/packages/client/src/components/Community/CommunityEditorDetails.js +++ b/frontend/packages/client/src/components/Community/CommunityEditorDetails.js @@ -41,7 +41,7 @@ export const CommunityUsersForm = ({
{textAbout}
- Admin addresses will be added automatically as authors and - members for the community. -
-- In addition, community creator address will be set as - admin and member by default. -
-Strategies
+Strategy
{strategy.name}
-- {strategy.description} -
-{strategy?.name}
++ {strategy?.description} +
+